1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-06 06:32:56 +01:00

add scenario / saved game decoding

This commit is contained in:
IntelOrca
2014-04-10 00:22:57 +01:00
parent 5f74540a0f
commit 3ae8971340
8 changed files with 218 additions and 17 deletions

View File

@@ -31,6 +31,7 @@
<ClInclude Include="..\src\peep.h" />
<ClInclude Include="..\src\rct2.h" />
<ClInclude Include="..\src\ride.h" />
<ClInclude Include="..\src\sawyercoding.h" />
<ClInclude Include="..\src\scenario.h" />
<ClInclude Include="..\src\sprite.h" />
<ClInclude Include="..\src\sprites.h" />
@@ -59,6 +60,7 @@
<ClCompile Include="..\src\peep.c" />
<ClCompile Include="..\src\rct2.c" />
<ClCompile Include="..\src\ride.c" />
<ClCompile Include="..\src\sawyercoding.c" />
<ClCompile Include="..\src\scenario.c" />
<ClCompile Include="..\src\strings.c" />
<ClCompile Include="..\src\title.c" />

View File

@@ -99,6 +99,9 @@
<ClInclude Include="..\src\editor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\sawyercoding.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\game.c">
@@ -185,6 +188,9 @@
<ClCompile Include="..\src\editor.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\sawyercoding.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\openrct2.exe">

View File

@@ -25,13 +25,16 @@
#include <windows.h>
#include <SDL.h>
#include "addresses.h"
#include "climate.h"
#include "config.h"
#include "date.h"
#include "game.h"
#include "gfx.h"
#include "intro.h"
#include "map.h"
#include "news_item.h"
#include "osinterface.h"
#include "park.h"
#include "rct2.h"
#include "ride.h"
#include "scenario.h"
@@ -120,15 +123,13 @@ void rct2_init()
RCT2_CALLPROC_EBPSAFE(0x0068F083); // window guest list init vars a
RCT2_CALLPROC_EBPSAFE(0x006BD3A4);
map_init();
RCT2_CALLPROC_EBPSAFE(0x00667132); // init_park();
park_init();
RCT2_CALLPROC_EBPSAFE(0x0066B5C0); // 0x0066B5C0 (part of 0x0066B3E8) screen_game_create_windows()
RCT2_CALLPROC_EBPSAFE(0x006C4494); // init_date
RCT2_CALLPROC_X(0x6C45ED, 0, 0, 0, 0, 0, 0, 0); // init_climate_and_date()
date_reset();
climate_reset(CLIMATE_COOL_AND_WET);
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
RCT2_CALLPROC_EBPSAFE(0x006ACA58);
// Window guest list init vars b
RCT2_CALLPROC_EBPSAFE(0x0068F050);
RCT2_CALLPROC_EBPSAFE(0x0068F050); // window guest list init vars b
RCT2_CALLPROC_EBPSAFE(0x006BD39C);
title_load();

View File

@@ -18,8 +18,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef _SDL_RCT2_H_
#define _SDL_RCT2_H_
#ifndef _RCT2_H_
#define _RCT2_H_
#include <stddef.h>
#include <stdlib.h>
@@ -33,8 +33,14 @@ typedef unsigned short uint16;
typedef unsigned long uint32;
typedef unsigned long long uint64;
#define rol32(x, shift) (((x) << (shift)) | ((x) >> (32 - (shift))))
#define ror32(x, shift) (((x) >> (shift)) | ((x) << (32 - (shift))))
#define rol8(x, shift) (((uint8)(x) << (shift)) | ((uint8)(x) >> (8 - (shift))))
#define ror8(x, shift) (((uint8)(x) >> (shift)) | ((uint8)(x) << (8 - (shift))))
#define rol16(x, shift) (((uint16)(x) << (shift)) | ((uint16)(x) >> (16 - (shift))))
#define ror16(x, shift) (((uint16)(x) >> (shift)) | ((uint16)(x) << (16 - (shift))))
#define rol32(x, shift) (((uint32)(x) << (shift)) | ((uint32)(x) >> (32 - (shift))))
#define ror32(x, shift) (((uint32)(x) >> (shift)) | ((uint32)(x) << (32 - (shift))))
#define rol64(x, shift) (((uint64)(x) << (shift)) | ((uint32)(x) >> (64 - (shift))))
#define ror64(x, shift) (((uint64)(x) >> (shift)) | ((uint32)(x) << (64 - (shift))))
#define sgn(x) ((x > 0) ? 1 : ((x < 0) ? -1 : 0))
#define clamp(l, x, h) (min(h, max(l, x)))

146
src/sawyercoding.c Normal file
View File

@@ -0,0 +1,146 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of OpenRCT2.
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include <windows.h>
#include "addresses.h"
#include "rct2.h"
#include "sawyercoding.h"
static int decode_chunk_rle(char *buffer, int length);
static int decode_chunk_repeat(char *buffer, int length);
static void decode_chunk_rotate(char *buffer, int length);
/**
*
* rct2: 0x0067685F
* buffer (esi)
*/
int sawyercoding_read_chunk(HFILE hFile, uint8 *buffer)
{
DWORD numBytesRead;
int i, code;
uint8 encoding;
uint32 length;
// Read chunk encoding and length
ReadFile(hFile, &encoding, 1, &numBytesRead, NULL);
ReadFile(hFile, &length, 4, &numBytesRead, NULL);
// Read chunk data
ReadFile(hFile, buffer, length, &numBytesRead, NULL);
// Decode chunk data
switch (encoding) {
case CHUNK_ENCODING_RLE:
length = decode_chunk_rle(buffer, length);
break;
case CHUNK_ENCODING_RLECOMPRESSED:
length = decode_chunk_rle(buffer, length);
length = decode_chunk_repeat(buffer, length);
break;
case CHUNK_ENCODING_ROTATE:
decode_chunk_rotate(buffer, length);
break;
}
// Set length
RCT2_GLOBAL(0x009E3828, uint32) = length;
return length;
}
/**
*
* rct2: 0x0067693A
*/
static int decode_chunk_rle(char *buffer, int length)
{
int i, j, count;
uint8 *src, *dst, rleCodeByte;
// Backup buffer
src = malloc(length);
memcpy(src, buffer, length);
dst = buffer;
for (i = 0; i < length; i++) {
rleCodeByte = src[i];
if (rleCodeByte & 128) {
i++;
count = 1 - rleCodeByte + 256;
for (j = 0; j < count; j++)
*dst++ = src[i];
} else {
for (j = 0; j < rleCodeByte; j++)
*dst++ = src[++i];
}
}
// Free backup buffer
free(src);
// Return final size
return dst - buffer;
}
/**
*
* rct2: 0x006769F1
*/
static int decode_chunk_repeat(char *buffer, int length)
{
int i, j, count;
uint8 *src, *dst, *copyOffset, rleCodeByte;
// Backup buffer
src = malloc(length);
memcpy(src, buffer, length);
dst = buffer;
for (i = 0; i < length; i++) {
if (src[i] == 0xFF) {
*dst++ = src[++i];
} else {
count = src[i] & 7;
copyOffset = dst + (int)(src[i] >> 3) - 32;
for (j = 0; j < count; j++)
*dst++ = *copyOffset++;
}
}
// Free backup buffer
free(src);
// Return final size
return dst - buffer;
}
/**
*
* rct2: 0x006768F4
*/
static void decode_chunk_rotate(char *buffer, int length)
{
int i, code = 1;
for (i = 0; i < length; i++) {
buffer[i] = ror8(buffer[i], code);
code = (code + 2) % 8;
}
}

35
src/sawyercoding.h Normal file
View File

@@ -0,0 +1,35 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of OpenRCT2.
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef _SAWYERCODING_H_
#define _SAWYERCODING_H_
#include <windows.h>
enum {
CHUNK_ENCODING_NONE,
CHUNK_ENCODING_RLE,
CHUNK_ENCODING_RLECOMPRESSED,
CHUNK_ENCODING_ROTATE
};
int sawyercoding_read_chunk(HFILE hFile, uint8 *buffer);
#endif

View File

@@ -23,6 +23,7 @@
#include <windows.h>
#include "addresses.h"
#include "rct2.h"
#include "sawyercoding.h"
#include "scenario.h"
#include "strings.h"
@@ -237,6 +238,8 @@ static void scenario_scores_save()
}
}
void sub_67685F(HFILE hFile, uint32 address);
/**
* Loads only the basic information from a scenario.
* rct2: 0x006761D6
@@ -250,9 +253,9 @@ static int scenario_load_basic(char *path)
FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
RCT2_GLOBAL(0x009E382C, HANDLE*) = hFile;
RCT2_CALLPROC_X(0x0067685F, 0, 0, 0, 0, 0x009E34E4, 0, 0);
sawyercoding_read_chunk(hFile, 0x009E34E4);
if (RCT2_GLOBAL(0x009E34E4, uint8) == 1) {
RCT2_CALLPROC_X(0x0067685F, 0, 0, 0, 0, 0x0141F570, 0, 0);
sawyercoding_read_chunk(hFile, 0x0141F570);
CloseHandle(hFile);
RCT2_GLOBAL(0x009AA00C, uint8) = 0;
if (RCT2_GLOBAL(0x0141F6F8, uint8) != 255) {

View File

@@ -19,13 +19,15 @@
*****************************************************************************/
#include "addresses.h"
#include "date.h"
#include "game.h"
#include "gfx.h"
#include "intro.h"
#include "map.h"
#include "news_item.h"
#include "park.h"
#include "rct2.h"
#include "ride.h"
#include "intro.h"
#include "viewport.h"
static void title_create_windows();
@@ -51,15 +53,15 @@ void title_load()
RCT2_CALLPROC_EBPSAFE(0x006C4209);
RCT2_CALLPROC_EBPSAFE(0x0069EB13);
ride_init_all();
RCT2_CALLPROC_EBPSAFE(0x0068F083);
RCT2_CALLPROC_EBPSAFE(0x0068F083); // window_guest_list_init_vars_a
RCT2_CALLPROC_EBPSAFE(0x006BD3A4);
map_init();
RCT2_CALLPROC_EBPSAFE(0x00667132);
RCT2_CALLPROC_EBPSAFE(0x006C4494);
park_init();
date_reset();
RCT2_CALLPROC_X(0x006C45ED, 0, 0, 0, 0, 0, 0, 0);
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
RCT2_CALLPROC_EBPSAFE(0x006ACA58);
RCT2_CALLPROC_EBPSAFE(0x0068F050);
RCT2_CALLPROC_EBPSAFE(0x0068F050); // window_guest_list_init_vars_b
RCT2_CALLPROC_EBPSAFE(0x006BD39C);
RCT2_CALLPROC_EBPSAFE(0x0068AFFD);
RCT2_CALLPROC_EBPSAFE(0x0069EBE4);