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:
@@ -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" />
|
||||
|
||||
@@ -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">
|
||||
|
||||
13
src/rct2.c
13
src/rct2.c
@@ -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();
|
||||
|
||||
14
src/rct2.h
14
src/rct2.h
@@ -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
146
src/sawyercoding.c
Normal 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
35
src/sawyercoding.h
Normal 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
|
||||
@@ -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) {
|
||||
|
||||
12
src/title.c
12
src/title.c
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user