diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index d426230e5d..2f4f995420 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -31,6 +31,7 @@ + @@ -59,6 +60,7 @@ + diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index 81179ea802..405b3f8f65 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -99,6 +99,9 @@ Header Files + + Header Files + @@ -185,6 +188,9 @@ Source Files + + Source Files + diff --git a/src/rct2.c b/src/rct2.c index 88c59870fe..d3854e81af 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -25,13 +25,16 @@ #include #include #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(); diff --git a/src/rct2.h b/src/rct2.h index 4a2c86aa4a..5b083c9bd9 100644 --- a/src/rct2.h +++ b/src/rct2.h @@ -18,8 +18,8 @@ * along with this program. If not, see . *****************************************************************************/ -#ifndef _SDL_RCT2_H_ -#define _SDL_RCT2_H_ +#ifndef _RCT2_H_ +#define _RCT2_H_ #include #include @@ -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))) diff --git a/src/sawyercoding.c b/src/sawyercoding.c new file mode 100644 index 0000000000..f6efff4008 --- /dev/null +++ b/src/sawyercoding.c @@ -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 . + *****************************************************************************/ + +#include +#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; + } +} \ No newline at end of file diff --git a/src/sawyercoding.h b/src/sawyercoding.h new file mode 100644 index 0000000000..52b893504c --- /dev/null +++ b/src/sawyercoding.h @@ -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 . + *****************************************************************************/ + +#ifndef _SAWYERCODING_H_ +#define _SAWYERCODING_H_ + +#include + +enum { + CHUNK_ENCODING_NONE, + CHUNK_ENCODING_RLE, + CHUNK_ENCODING_RLECOMPRESSED, + CHUNK_ENCODING_ROTATE +}; + +int sawyercoding_read_chunk(HFILE hFile, uint8 *buffer); + +#endif \ No newline at end of file diff --git a/src/scenario.c b/src/scenario.c index 70cdfd5ef8..99e9ead251 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -23,6 +23,7 @@ #include #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) { diff --git a/src/title.c b/src/title.c index 71bae058c7..6b14e1daa0 100644 --- a/src/title.c +++ b/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);