mirror of https://github.com/OpenRCT2/OpenRCT2.git
clean up scenario loading some more
This commit is contained in:
parent
2a1a4acba8
commit
d5ad84a7d1
25
src/game.c
25
src/game.c
|
@ -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);
|
||||
|
|
17
src/object.c
17
src/object.c
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
112
src/scenario.c
112
src/scenario.c
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue