diff --git a/src/editor.c b/src/editor.c index 00212ac0c0..eaa55e6868 100644 --- a/src/editor.c +++ b/src/editor.c @@ -33,6 +33,7 @@ #include "peep/staff.h" #include "ride/ride.h" #include "util/sawyercoding.h" +#include "util/util.h" #include "world/banner.h" #include "world/map.h" #include "world/park.h" @@ -247,12 +248,8 @@ static int editor_load_landscape_from_sv4(const char *path) return 0; } - // Get length - fseek(fp, 0, SEEK_END); - fpLength = ftell(fp); - rewind(fp); - // Read whole file into a buffer + fpLength = fsize(fp); fpBuffer = malloc(fpLength); fread(fpBuffer, fpLength, 1, fp); fclose(fp); diff --git a/src/ride/track.c b/src/ride/track.c index 5cf6801b9a..9ef270d977 100644 --- a/src/ride/track.c +++ b/src/ride/track.c @@ -18,10 +18,10 @@ * along with this program. If not, see . *****************************************************************************/ -#include -#include #include "../addresses.h" #include "../platform/osinterface.h" +#include "../util/sawyercoding.h" +#include "../util/util.h" #include "ride.h" #include "track.h" @@ -229,26 +229,10 @@ void track_load_list(ride_list_item item) RCT2_CALLPROC_X(0x006CED50, 0, 0, 0, *((uint16*)&item), 0, 0, 0); } -/** - * - * rct2: 0x00676EBA - */ -static uint8 sub_676EBA() +static void read(void *dst, void **src, int length) { - int eax, ebx, ecx, edx, esi, edi, ebp; - RCT2_CALLFUNC_X(0x00676EBA, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - return eax & 0xFF; -} - -/** - * - * rct2: 0x00676EAF - */ -static void sub_676EAF(uint8 *esi, int ecx) -{ - do { - *esi++ = sub_676EBA(); - } while (--ecx != 0); + memcpy(dst, *src, length); + *((char**)src) += length; } /** @@ -258,10 +242,11 @@ static void sub_676EAF(uint8 *esi, int ecx) */ int sub_67726A(const char *path) { - HANDLE *hFile; + FILE *fp; + long fpLength; const char *ch; - char trackFilename[MAX_PATH], *dst; - int i; + char trackFilename[MAX_PATH], *fpBuffer, *decoded, *src, *dst; + int i, decodedLength; uint8* edi; RCT2_GLOBAL(0x009AAC54, uint8) = 1; @@ -275,30 +260,41 @@ int sub_67726A(const char *path) } *dst = 0; - hFile = osinterface_file_open(path); - if (hFile == INVALID_HANDLE_VALUE) + fp = fopen(path, "rb"); + if (fp == NULL) return 0; - RCT2_GLOBAL(0x009E382C, HANDLE) = hFile; - if (!RCT2_CALLPROC_X(0x006770C1, 0, 0, 0, 0, 0, 0, 0)) { - CloseHandle(hFile); - return 0; - } + // Read whole file into a buffer + fpLength = fsize(fp); + fpBuffer = malloc(fpLength); + fread(fpBuffer, fpLength, 1, fp); + fclose(fp); - RCT2_CALLPROC_EBPSAFE(0x00676E7A); + // Validate the checksum + // Not the same checksum algorithm as scenarios and saved games + // sub_6770C1(); + + // Decode the track data + decoded = malloc(0x10000); + decodedLength = sawyercoding_decode_td6(fpBuffer, decoded, fpLength); + realloc(decoded, decodedLength); + free(fpBuffer); + + // Read decoded data + src = decoded; memset((void*)0x009D81D8, 0, 67); - sub_676EAF((void*)0x009D8178, 32); + read((void*)0x009D8178, &src, 32); uint8 al = RCT2_GLOBAL(0x009D817F, uint8) >> 2; if (al >= 2) - sub_676EAF((void*)0x009D8198, 40); + read((void*)0x009D8198, &src, 40); - sub_676EAF((void*)0x009D81C0, 24); + read((void*)0x009D81C0, &src, 24); al = RCT2_GLOBAL(0x009D817F, uint8) >> 2; if (al != 0) - sub_676EAF((void*)0x009D81D8, al == 1 ? 140 : 67); + read((void*)0x009D81D8, &src, al == 1 ? 140 : 67); - sub_676EAF((void*)0x009D821B, 24572); + read((void*)0x009D821B, &src, 24572); al = RCT2_GLOBAL(0x009D817F, uint8) >> 2; if (al < 2) { if (RCT2_GLOBAL(0x009D8178, uint8) == 20) { @@ -317,9 +313,9 @@ int sub_67726A(const char *path) memset(edi, 255, (uint8*)0x009DE217 - edi); } } + free(decoded); - CloseHandle(hFile); - + // al = RCT2_GLOBAL(0x009D817F, uint8) >> 2; if (al > 2) return 0; diff --git a/src/util/sawyercoding.c b/src/util/sawyercoding.c index f6dac8a145..d21ff1f51c 100644 --- a/src/util/sawyercoding.c +++ b/src/util/sawyercoding.c @@ -345,4 +345,9 @@ int sawyercoding_encode_sv4(char *src, char *dst, int length) *((uint32*)&dst[encodedLength]) = checksum; return encodedLength + 4; +} + +int sawyercoding_decode_td6(char *src, char *dst, int length) +{ + return decode_chunk_rle(src, dst, length - 4); } \ No newline at end of file diff --git a/src/util/sawyercoding.h b/src/util/sawyercoding.h index bd2d99a61d..19fe468bd5 100644 --- a/src/util/sawyercoding.h +++ b/src/util/sawyercoding.h @@ -43,5 +43,6 @@ int sawyercoding_write_chunk_buffer(uint8 *dst_file, uint8* buffer, sawyercoding int sawyercoding_decode_sv4(char *src, char *dst, int length); int sawyercoding_decode_sc4(char *src, char *dst, int length); int sawyercoding_encode_sv4(char *src, char *dst, int length); +int sawyercoding_decode_td6(char *src, char *dst, int length); #endif diff --git a/src/util/util.c b/src/util/util.c index 6a151248c8..b17de76cee 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -39,4 +39,16 @@ int mph_to_kmph(int mph) // 1 mph = 1.60934 kmph // RCT2 approximates as 1.609375 return (mph * 1648) / 1024; +} + +long fsize(FILE *fp) +{ + long originalPosition, size; + + originalPosition = ftell(fp); + fseek(fp, 0, SEEK_END); + size = ftell(fp); + fseek(fp, originalPosition, SEEK_SET); + + return size; } \ No newline at end of file diff --git a/src/util/util.h b/src/util/util.h index c93ac1cc69..a5f03b67e0 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -21,8 +21,12 @@ #ifndef _UTIL_H_ #define _UTIL_H_ +#include "../common.h" + int squaredmetres_to_squaredfeet(int squaredMetres); int metres_to_feet(int metres); int mph_to_kmph(int mph); +long fsize(FILE *fp); + #endif