clean up scenario loading some more

This commit is contained in:
IntelOrca 2014-05-24 22:14:42 +01:00
parent 2a1a4acba8
commit d5ad84a7d1
8 changed files with 96 additions and 121 deletions

View File

@ -1461,23 +1461,20 @@ static void load_landscape()
int game_load_save()
{
rct_window *mainWindow;
HANDLE hFile;
FILE *file;
char *path;
int i, j;
path = (char*)0x0141EF68;
hFile = CreateFile(
path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_NORMAL, NULL
);
if (hFile == NULL) {
file = fopen(path, "rb");
if (file == NULL) {
RCT2_GLOBAL(0x009AC31B, uint8) = 255;
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_FILE_CONTAINS_INVALID_DATA;
return 0;
}
RCT2_GLOBAL(0x009E382C, HANDLE) = hFile;
if (!sawyercoding_validate_checksum(hFile)) {
CloseHandle(hFile);
if (!sawyercoding_validate_checksum(file)) {
fclose(file);
RCT2_GLOBAL(0x009AC31B, uint8) = 255;
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_FILE_CONTAINS_INVALID_DATA;
return 0;
@ -1487,7 +1484,7 @@ int game_load_save()
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
// Read first chunk
sawyercoding_read_chunk(hFile, (uint8*)s6Header);
sawyercoding_read_chunk(file, (uint8*)s6Header);
if (s6Header->type == S6_TYPE_SAVEDGAME) {
// Read packed objects
if (s6Header->num_packed_objects > 0) {
@ -1499,19 +1496,19 @@ int game_load_save()
}
}
object_read_and_load_entries(hFile);
object_read_and_load_entries(file);
// Read flags (16 bytes)
sawyercoding_read_chunk(hFile, (uint8*)RCT2_ADDRESS_CURRENT_MONTH_YEAR);
sawyercoding_read_chunk(file, (uint8*)RCT2_ADDRESS_CURRENT_MONTH_YEAR);
// Read map elements
memset((void*)RCT2_ADDRESS_MAP_ELEMENTS, 0, MAX_MAP_ELEMENTS * sizeof(rct_map_element));
sawyercoding_read_chunk(hFile, (uint8*)RCT2_ADDRESS_MAP_ELEMENTS);
sawyercoding_read_chunk(file, (uint8*)RCT2_ADDRESS_MAP_ELEMENTS);
// Read game data, including sprites
sawyercoding_read_chunk(hFile, (uint8*)0x010E63B8);
sawyercoding_read_chunk(file, (uint8*)0x010E63B8);
CloseHandle(hFile);
fclose(file);
// Check expansion pack
// RCT2_CALLPROC_EBPSAFE(0x006757E6);

View File

@ -45,4 +45,21 @@ fail:
void object_unload(int groupIndex, rct_object_entry_extended *entry)
{
RCT2_CALLPROC_X(0x006A9CAF, 0, groupIndex, 0, 0, 0, 0, (int)entry);
}
/**
*
* rct2: 0x006A9428
*/
int sub_6A9428(rct_object_entry* entry)
{
RCT2_CALLPROC_X(0x006A9428, 0, 0, 0, 0, 0, 0, (int)entry);
#ifdef _MSC_VER
__asm jb fail
#else
__asm__ goto ( "jb %l0" : : : : fail );
#endif
return 1;
fail:
return 0;
}

View File

@ -21,7 +21,7 @@
#ifndef _OBJECT_H_
#define _OBJECT_H_
#include <windows.h>
#include <stdio.h>
#include "rct2.h"
/**
@ -46,11 +46,12 @@ typedef struct {
} rct_object_entry_extended;
void object_list_load();
void object_read_and_load_entries(HANDLE hFile);
void object_read_and_load_entries(FILE *file);
int object_load_packed();
void object_unload_all();
int object_load(int groupIndex, rct_object_entry *entry);
void object_unload(int groupIndex, rct_object_entry_extended *entry);
int sub_6A9428(rct_object_entry* entry);
#endif

View File

@ -24,6 +24,7 @@
#include "sawyercoding.h"
#define OBJECT_ENTRY_GROUP_COUNT 11
#define OBJECT_ENTRY_COUNT 721
typedef struct {
uint32 total_files;
@ -184,19 +185,19 @@ static int check_object_entry(rct_object_entry *entry)
*
* rct2: 0x006AA0C6
*/
void object_read_and_load_entries(HANDLE hFile)
void object_read_and_load_entries(FILE *file)
{
object_unload_all();
int i, j;
rct_object_entry *entries;
// Maximum of 721 object entries in a scenario / saved game
entries = malloc(721 * sizeof(rct_object_entry));
sawyercoding_read_chunk(hFile, (uint8*)entries);
// Read all the object entries
entries = malloc(OBJECT_ENTRY_COUNT * sizeof(rct_object_entry));
sawyercoding_read_chunk(file, (uint8*)entries);
// Load each object
for (i = 0; i < 721; i++) {
for (i = 0; i < OBJECT_ENTRY_COUNT; i++) {
if (!check_object_entry(&entries[i]))
continue;

View File

@ -18,7 +18,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include <windows.h>
#include <string.h>
#include "addresses.h"
#include "rct2.h"
@ -32,24 +31,24 @@ static void decode_chunk_rotate(char *buffer, int length);
*
* rct2: 0x00676FD2
*/
int sawyercoding_validate_checksum(HANDLE hFile)
int sawyercoding_validate_checksum(FILE *file)
{
uint32 i, checksum, fileChecksum;
DWORD dataSize, bufferSize, numBytesRead;
uint32 i, checksum, fileChecksum, dataSize, bufferSize;
uint8 buffer[1024];
// Get data size
if ((dataSize = SetFilePointer(hFile, 0, NULL, FILE_END)) < 8)
fseek(file, 0, SEEK_END);
dataSize = ftell(file);
if (dataSize < 8)
return 0;
dataSize -= 4;
// Calculate checksum
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
fseek(file, 0, SEEK_SET);
checksum = 0;
do {
bufferSize = min(dataSize, 1024);
ReadFile(hFile, buffer, bufferSize, &numBytesRead, NULL);
if (numBytesRead != bufferSize)
if (fread(buffer, bufferSize, 1, file) != 1)
return 0;
for (i = 0; i < bufferSize; i++)
@ -58,12 +57,11 @@ int sawyercoding_validate_checksum(HANDLE hFile)
} while (dataSize != 0);
// Read file checksum
ReadFile(hFile, &fileChecksum, sizeof(fileChecksum), &numBytesRead, NULL);
if (numBytesRead != sizeof(fileChecksum))
if (fread(&fileChecksum, sizeof(fileChecksum), 1, file) != 1)
return 0;
// Reset file position
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
fseek(file, 0, SEEK_SET);
// Validate
return checksum == fileChecksum;
@ -74,21 +72,20 @@ int sawyercoding_validate_checksum(HANDLE hFile)
* rct2: 0x0067685F
* buffer (esi)
*/
int sawyercoding_read_chunk(HANDLE hFile, uint8 *buffer)
int sawyercoding_read_chunk(FILE *file, uint8 *buffer)
{
DWORD numBytesRead;
sawyercoding_chunk_header chunkHeader;
// Read chunk header
ReadFile(hFile, &chunkHeader, sizeof(sawyercoding_chunk_header), &numBytesRead, NULL);
if (sizeof(sawyercoding_chunk_header) != numBytesRead) {
RCT2_ERROR("read error %d != %d\n", sizeof(sawyercoding_chunk_header), numBytesRead);
if (fread(&chunkHeader, sizeof(sawyercoding_chunk_header), 1, file) != 1) {
RCT2_ERROR("Unable to read chunk header!");
return -1;
}
// Read chunk data
ReadFile(hFile, buffer, chunkHeader.length, &numBytesRead, NULL);
if (chunkHeader.length != numBytesRead) {
RCT2_ERROR("read error %d != %d\n", chunkHeader.length, numBytesRead);
if (fread(buffer, chunkHeader.length, 1, file) != 1) {
RCT2_ERROR("Unable to read chunk data!");
return -1;
}
// Decode chunk data

View File

@ -21,7 +21,7 @@
#ifndef _SAWYERCODING_H_
#define _SAWYERCODING_H_
#include <windows.h>
#include <stdio.h>
#include "rct2.h"
typedef struct {
@ -36,7 +36,7 @@ enum {
CHUNK_ENCODING_ROTATE
};
int sawyercoding_validate_checksum(HANDLE hFile);
int sawyercoding_read_chunk(HANDLE hFile, uint8 *buffer);
int sawyercoding_validate_checksum(FILE *file);
int sawyercoding_read_chunk(FILE *file, uint8 *buffer);
#endif

View File

@ -42,68 +42,35 @@
*/
int scenario_load_basic(const char *path)
{
HANDLE hFile;
int _eax;
FILE *file;
rct_s6_header *s6Header = (rct_s6_header*)0x009E34E4;
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
hFile = CreateFile(
path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_NORMAL, NULL
);
if (hFile != INVALID_HANDLE_VALUE) {
RCT2_GLOBAL(0x009E382C, HANDLE*) = hFile;
file = fopen(path, "rb");
if (file != NULL) {
// Read first chunk
sawyercoding_read_chunk(hFile, (uint8*)s6Header);
sawyercoding_read_chunk(file, (uint8*)s6Header);
if (s6Header->type == S6_TYPE_SCENARIO) {
// Read second chunk
sawyercoding_read_chunk(hFile, (uint8*)s6Info);
CloseHandle(hFile);
sawyercoding_read_chunk(file, (uint8*)s6Info);
fclose(file);
RCT2_GLOBAL(0x009AA00C, uint8) = 0;
if ((s6Info->flags & 0xFF) != 255) {
#ifdef _MSC_VER
__asm {
push ebp
mov ebp, 0141F6F8h
mov eax, 006A9428h
call eax
pop ebp
mov _eax, eax
jb loc_67628F
// Checks for a scenario string object (possibly for localisation)
if ((s6Info->entry.flags & 0xFF) != 255) {
if (sub_6A9428(&s6Info->entry)) {
int ebp = RCT2_GLOBAL(0x009ADAF8, uint32);
format_string(s6Info->name, RCT2_GLOBAL(ebp, sint16), NULL);
format_string(s6Info->details, RCT2_GLOBAL(ebp + 4, sint16), NULL);
RCT2_GLOBAL(0x009AA00C, uint8) = RCT2_GLOBAL(ebp + 6, uint8);
// Disposes the scenario string object (0x009ADAF8)
RCT2_CALLPROC_EBPSAFE(0x006A982D);
}
#else
__asm__ ( "\
push ebp \n\
mov ebp, 0x0141F6F8 \n\
mov eax, 0x006A9428 \n\
call eax \n\
pop ebp \n\
mov %[_eax], eax \n\
jb loc_67628F \n\
" : [_eax] "+m" (_eax) : : "eax" );
#endif
int ebp = RCT2_GLOBAL(0x009ADAF8, uint32);
format_string(s6Info->name, RCT2_GLOBAL(ebp, sint16), NULL);
format_string(s6Info->details, RCT2_GLOBAL(ebp + 4, sint16), NULL);
RCT2_GLOBAL(0x009AA00C, uint8) = RCT2_GLOBAL(ebp + 6, uint8);
RCT2_CALLPROC(0x006A982D);
#ifdef _MSC_VER
__asm mov _eax, eax
#else
__asm__ ( "mov %[_eax], eax " : [_eax] "+m" (_eax) );
#endif
#ifdef _MSC_VER
loc_67628F :
#else
__asm__ ( "loc_67628F :");
#endif
return _eax;
}
return 1;
}
CloseHandle(hFile);
fclose(file);
}
RCT2_GLOBAL(0x009AC31B, sint8) = -1;
@ -118,28 +85,25 @@ int scenario_load_basic(const char *path)
*/
void scenario_load(const char *path)
{
HANDLE hFile;
FILE *file;
int i, j;
rct_s6_header *s6Header = (rct_s6_header*)0x009E34E4;
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
hFile = CreateFile(
path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_NORMAL, NULL
);
if (hFile != INVALID_HANDLE_VALUE) {
RCT2_GLOBAL(0x009E382C, HANDLE*) = hFile;
if (!sawyercoding_validate_checksum(hFile)) {
CloseHandle(hFile);
file = fopen(path, "rb");
if (file != NULL) {
if (!sawyercoding_validate_checksum(file)) {
fclose(file);
RCT2_GLOBAL(0x009AC31B, uint8) = 255;
RCT2_GLOBAL(0x009AC31C, uint16) = STR_FILE_CONTAINS_INVALID_DATA;
return;
}
// Read first chunk
sawyercoding_read_chunk(hFile, (uint8*)s6Header);
sawyercoding_read_chunk(file, (uint8*)s6Header);
if (s6Header->type == S6_TYPE_SCENARIO) {
// Read second chunk
sawyercoding_read_chunk(hFile, (uint8*)s6Info);
sawyercoding_read_chunk(file, (uint8*)s6Info);
// Read packed objects
if (s6Header->num_packed_objects > 0) {
@ -150,40 +114,40 @@ void scenario_load(const char *path)
object_list_load();
}
object_read_and_load_entries(hFile);
object_read_and_load_entries(file);
// Read flags (16 bytes)
sawyercoding_read_chunk(hFile, (uint8*)RCT2_ADDRESS_CURRENT_MONTH_YEAR);
sawyercoding_read_chunk(file, (uint8*)RCT2_ADDRESS_CURRENT_MONTH_YEAR);
// Read map elements
memset((void*)RCT2_ADDRESS_MAP_ELEMENTS, 0, MAX_MAP_ELEMENTS * sizeof(rct_map_element));
sawyercoding_read_chunk(hFile, (uint8*)RCT2_ADDRESS_MAP_ELEMENTS);
sawyercoding_read_chunk(file, (uint8*)RCT2_ADDRESS_MAP_ELEMENTS);
// Read game data, including sprites
sawyercoding_read_chunk(hFile, (uint8*)0x010E63B8);
sawyercoding_read_chunk(file, (uint8*)0x010E63B8);
// Read number of guests in park and something else
sawyercoding_read_chunk(hFile, (uint8*)RCT2_ADDRESS_GUESTS_IN_PARK);
sawyercoding_read_chunk(file, (uint8*)RCT2_ADDRESS_GUESTS_IN_PARK);
// Read ?
sawyercoding_read_chunk(hFile, (uint8*)0x01357BC8);
sawyercoding_read_chunk(file, (uint8*)0x01357BC8);
// Read park rating
sawyercoding_read_chunk(hFile, (uint8*)RCT2_ADDRESS_CURRENT_PARK_RATING);
sawyercoding_read_chunk(file, (uint8*)RCT2_ADDRESS_CURRENT_PARK_RATING);
// Read ?
sawyercoding_read_chunk(hFile, (uint8*)0x01357CF2);
sawyercoding_read_chunk(file, (uint8*)0x01357CF2);
// Read ?
sawyercoding_read_chunk(hFile, (uint8*)0x0135832C);
sawyercoding_read_chunk(file, (uint8*)0x0135832C);
// Read ?
sawyercoding_read_chunk(hFile, (uint8*)RCT2_ADDRESS_CURRENT_PARK_VALUE);
sawyercoding_read_chunk(file, (uint8*)RCT2_ADDRESS_CURRENT_PARK_VALUE);
// Read more game data, including research items and rides
sawyercoding_read_chunk(hFile, (uint8*)RCT2_ADDRESS_COMPLETED_COMPANY_VALUE);
sawyercoding_read_chunk(file, (uint8*)RCT2_ADDRESS_COMPLETED_COMPANY_VALUE);
CloseHandle(hFile);
fclose(file);
// Check expansion pack
// RCT2_CALLPROC_EBPSAFE(0x006757E6);
@ -194,7 +158,7 @@ void scenario_load(const char *path)
return;
}
CloseHandle(hFile);
fclose(file);
}
RCT2_GLOBAL(0x009AC31B, uint8) = 255;

View File

@ -22,6 +22,7 @@
#define _SCENARIO_H_
#include "rct2.h"
#include "object.h"
/**
* SV6/SC6 header chunk
@ -49,10 +50,7 @@ typedef struct {
uint8 pad_00A[0x3E];
char name[64]; // 0x48
char details[256]; // 0x88
uint32 flags; // 0x188
uint32 pad_18C;
uint32 pad_190;
uint32 pad_194;
rct_object_entry entry; // 0x188
} rct_s6_info;
/*