From bfb132146d039e28e28969a88afb866195e0e6f2 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 4 Oct 2014 11:41:16 +0100 Subject: [PATCH] Fixed bugs in RLE code. Loading now works --- src/object.c | 19 ++++++++-------- src/sawyercoding.c | 54 ++++++++++++++++++++++++++++++++-------------- src/sawyercoding.h | 3 ++- 3 files changed, 50 insertions(+), 26 deletions(-) diff --git a/src/object.c b/src/object.c index 61b0fd23b5..dae1f19074 100644 --- a/src/object.c +++ b/src/object.c @@ -145,21 +145,22 @@ int sub_6A9F42(FILE *file, rct_object_entry* entry){ rct_object_entry* installed_entry = (rct_object_entry*)(entryGroupIndex * 20 + RCT2_ADDRESS(0x98D980, uint32)[type * 2]); + uint8* dst_buffer = malloc(0x600000); + memcpy(dst_buffer, (void*)installed_entry, 16); - fwrite((void*)installed_entry, 1, 16, file); - - //This increases the pointer of installed_entry by 16 - //it also adds together what it jumps over? - //RCT2_CALLPROC_X(0x6762D1, 0, 0, 16, 0, (int)installed_entry, 0, 0); + uint32 size_dst = 16; sawyercoding_chunk_header chunkHeader; - // Encoding type + // Encoding type (not used anymore) RCT2_GLOBAL(0x9E3CBD, uint8) = object_entry_group_encoding[type]; + chunkHeader.encoding = object_entry_group_encoding[type]; chunkHeader.length = *(uint32*)(((uint8*)installed_entry + 16)); - sawyercoding_write_chunk(file, (uint8*)chunk, chunkHeader); - //Function not finished as it requires completing swayer_encoding + size_dst += sawyercoding_write_chunk_buffer(dst_buffer+16, (uint8*)chunk, chunkHeader); + fwrite(dst_buffer, 1, size_dst, file); + + free(dst_buffer); } /** @@ -270,7 +271,7 @@ int object_load_packed(FILE *file) // The following section cannot be finished until 6A9F42 is finished // Run the game once with vanila rct2 to not reach this part of code. RCT2_ERROR("Function not finished. Please run this save once with vanila rct2."); - FILE* obj_file = fopen(path, "w"); + FILE* obj_file = fopen(path, "wb"); if (obj_file){ // Removed progress bar code sub_6A9F42(obj_file, entry); diff --git a/src/sawyercoding.c b/src/sawyercoding.c index 480aa70dd6..c62722f8b7 100644 --- a/src/sawyercoding.c +++ b/src/sawyercoding.c @@ -30,6 +30,20 @@ static void decode_chunk_rotate(char *buffer, int length); int encode_chunk_rle(char *src_buffer, char *dst_buffer, int length); void encode_chunk_rotate(char *buffer, int length); + +int sawyercoding_calculate_checksum(uint8* buffer, uint32 length){ + int checksum = 0; + do { + int bufferSize = min(length , 1024); + + for (int i = 0; i < bufferSize; i++) + checksum += buffer[i]; + length -= bufferSize; + } while (length != 0); + + return checksum; +} + /** * * rct2: 0x00676FD2 @@ -196,33 +210,41 @@ static void decode_chunk_rotate(char *buffer, int length) * rct2: 0x006762E1 * */ -int sawyercoding_write_chunk(FILE *file, uint8* buffer, sawyercoding_chunk_header chunkHeader){ - uint8* dst_buffer; +int sawyercoding_write_chunk_buffer(uint8 *dst_file, uint8* buffer, sawyercoding_chunk_header chunkHeader){ + uint8* encode_buffer; switch (chunkHeader.encoding){ case CHUNK_ENCODING_NONE: - fwrite(&chunkHeader, sizeof(sawyercoding_chunk_header), 1, file); - fwrite(buffer, 1, chunkHeader.length, file); + memcpy(dst_file, &chunkHeader, sizeof(sawyercoding_chunk_header)); + dst_file += sizeof(sawyercoding_chunk_header); + memcpy(dst_file, buffer, chunkHeader.length); + //fwrite(&chunkHeader, sizeof(sawyercoding_chunk_header), 1, file); + //fwrite(buffer, 1, chunkHeader.length, file); break; case CHUNK_ENCODING_RLE: - dst_buffer = malloc(0x600000); - chunkHeader.length = encode_chunk_rle(buffer, dst_buffer, chunkHeader.length); - fwrite(&chunkHeader, sizeof(sawyercoding_chunk_header), 1, file); - fwrite(dst_buffer, 1, chunkHeader.length, file); - free(dst_buffer); + encode_buffer = malloc(0x600000); + chunkHeader.length = encode_chunk_rle(buffer, encode_buffer, chunkHeader.length); + memcpy(dst_file, &chunkHeader, sizeof(sawyercoding_chunk_header)); + dst_file += sizeof(sawyercoding_chunk_header); + memcpy(dst_file, encode_buffer, chunkHeader.length); + + free(encode_buffer); break; case CHUNK_ENCODING_RLECOMPRESSED: + RCT2_ERROR("This has not been implemented"); + return -1; //chunkHeader.length = decode_chunk_rle(src_buffer, buffer, chunkHeader.length); //chunkHeader.length = decode_chunk_repeat(buffer, chunkHeader.length); break; case CHUNK_ENCODING_ROTATE: encode_chunk_rotate(buffer, chunkHeader.length); - fwrite(&chunkHeader, sizeof(sawyercoding_chunk_header), 1, file); - fwrite(buffer, 1, chunkHeader.length, file); + memcpy(dst_file, &chunkHeader, sizeof(sawyercoding_chunk_header)); + dst_file += sizeof(sawyercoding_chunk_header); + memcpy(dst_file, buffer, chunkHeader.length); break; } - return chunkHeader.length; + return chunkHeader.length + sizeof(sawyercoding_chunk_header); } /** @@ -239,14 +261,14 @@ int encode_chunk_rle(char *src_buffer, char *dst_buffer, int length) while (src < end_src - 1){ - if ((count && *src == src[1]) || count > 126){ - *dst++ = count; + if ((count && *src == src[1]) || count > 120){ + *dst++ = count - 1; for (; count != 0; --count){ *dst++ = *src_norm_start++; } } if (*src == src[1]){ - for (; (count < 127) && ((src + count) < end_src); count++){ + for (; (count < 120) && ((src + count) < end_src); count++){ if (*src != src[count]) break; } *dst++ = 257 - count; @@ -262,7 +284,7 @@ int encode_chunk_rle(char *src_buffer, char *dst_buffer, int length) } if (src == end_src - 1)count++; if (count){ - *dst++ = count; + *dst++ = count - 1; for (; count != 0; --count){ *dst++ = *src_norm_start++; } diff --git a/src/sawyercoding.h b/src/sawyercoding.h index 2ab18d76b2..c965d2da94 100644 --- a/src/sawyercoding.h +++ b/src/sawyercoding.h @@ -37,7 +37,8 @@ enum { }; int sawyercoding_validate_checksum(FILE *file); +int sawyercoding_calculate_checksum(uint8* buffer, uint32 length); int sawyercoding_read_chunk(FILE *file, uint8 *buffer); -int sawyercoding_write_chunk(FILE *file, uint8 *buffer, sawyercoding_chunk_header chunkHeader); +int sawyercoding_write_chunk_buffer(uint8 *dst_file, uint8* buffer, sawyercoding_chunk_header chunkHeader); #endif