mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-11 01:52:32 +01:00
implement object_get_scenario_text
This commit is contained in:
190
src/object.c
190
src/object.c
@@ -18,8 +18,11 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <memory.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include "addresses.h"
|
#include "addresses.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
|
#include "sawyercoding.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -47,19 +50,188 @@ void object_unload(int groupIndex, rct_object_entry_extended *entry)
|
|||||||
RCT2_CALLPROC_X(0x006A9CAF, 0, groupIndex, 0, 0, 0, 0, (int)entry);
|
RCT2_CALLPROC_X(0x006A9CAF, 0, groupIndex, 0, 0, 0, 0, (int)entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int object_entry_compare(rct_object_entry *a, rct_object_entry *b)
|
||||||
|
{
|
||||||
|
if (a->flags & 0xF0) {
|
||||||
|
if ((a->flags & 0x0F) != (b->flags & 0x0F))
|
||||||
|
return 0;
|
||||||
|
if (*((uint32*)a->name) != *((uint32*)b->name))
|
||||||
|
return 0;
|
||||||
|
if (*((uint32*)(&a->name[4])) != *((uint32*)(&b->name[4])))
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
if (a->flags != b->flags)
|
||||||
|
return 0;
|
||||||
|
if (*((uint32*)a->name) != *((uint32*)b->name))
|
||||||
|
return 0;
|
||||||
|
if (*((uint32*)(&a->name[4])) != *((uint32*)(&b->name[4])))
|
||||||
|
return 0;
|
||||||
|
if (a->checksum != b->checksum)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int object_calculate_checksum(rct_object_entry *entry, char *data, int dataLength)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *eee = (char*)entry;
|
||||||
|
int checksum = 0xF369A75B;
|
||||||
|
char *ccc = (char*)&checksum;
|
||||||
|
|
||||||
|
*ccc ^= eee[0];
|
||||||
|
checksum = rol32(checksum, 11);
|
||||||
|
for (i = 4; i < 12; i++) {
|
||||||
|
*ccc ^= eee[i];
|
||||||
|
checksum = rol32(checksum, 11);
|
||||||
|
}
|
||||||
|
for (i = 0; i < dataLength; i++) {
|
||||||
|
*ccc ^= data[i];
|
||||||
|
checksum = rol32(checksum, 11);
|
||||||
|
}
|
||||||
|
|
||||||
|
return checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
int object_paint(int type, int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp)
|
||||||
|
{
|
||||||
|
RCT2_CALLPROC_X(RCT2_ADDRESS(0x0098D9D4, uint32)[type], eax, ebx, ecx, edx, esi, edi, ebp);
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
__asm jb success
|
||||||
|
#else
|
||||||
|
__asm__ goto ( "jb %l0" : : : : success );
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
success:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* rct2: 0x006A9428
|
* rct2: 0x006A9428
|
||||||
*/
|
*/
|
||||||
int sub_6A9428(rct_object_entry* entry)
|
int object_get_scenario_text(rct_object_entry *entry)
|
||||||
{
|
{
|
||||||
RCT2_CALLPROC_X(0x006A9428, 0, 0, 0, 0, 0, 0, (int)entry);
|
// RCT2_CALLPROC_X(0x006A9428, 0, 0, 0, 0, 0, 0, (int)entry); return;
|
||||||
#ifdef _MSC_VER
|
|
||||||
__asm jb fail
|
int i;
|
||||||
#else
|
rct_object_entry *installedObject = RCT2_GLOBAL(0x009ADAE8, rct_object_entry*);
|
||||||
__asm__ goto ( "jb %l0" : : : : fail );
|
for (i = 0; i < RCT2_GLOBAL(0x00F42B6C, sint32); i++) {
|
||||||
#endif
|
if (object_entry_compare(installedObject, entry)) {
|
||||||
return 1;
|
char path[260];
|
||||||
fail:
|
char *objectPath = (char*)installedObject + 16;
|
||||||
|
subsitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), objectPath);
|
||||||
|
|
||||||
|
rct_object_entry openedEntry;
|
||||||
|
FILE *file = fopen(path, "rb");
|
||||||
|
if (file != NULL) {
|
||||||
|
fread(&openedEntry, sizeof(rct_object_entry), 1, file);
|
||||||
|
if (object_entry_compare(&openedEntry, entry)) {
|
||||||
|
|
||||||
|
// Get chunk size
|
||||||
|
char *pos = (char*)installedObject + 16;
|
||||||
|
do {
|
||||||
|
pos++;
|
||||||
|
} while (*(pos - 1) != 0);
|
||||||
|
|
||||||
|
// Read chunk
|
||||||
|
int chunkSize = *((uint32*)pos);
|
||||||
|
char *chunk;
|
||||||
|
if (chunkSize == 0xFFFFFFFF) {
|
||||||
|
chunk = malloc(0x600000);
|
||||||
|
chunkSize = sawyercoding_read_chunk(file, chunk);
|
||||||
|
chunk = realloc(chunk, chunkSize);
|
||||||
|
} else {
|
||||||
|
chunk = malloc(chunkSize);
|
||||||
|
sawyercoding_read_chunk(file, chunk);
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
// Calculate and check checksum
|
||||||
|
if (object_calculate_checksum(&openedEntry, chunk, chunkSize) != openedEntry.checksum) {
|
||||||
|
RCT2_GLOBAL(0x00F42BD9, uint8) = 2;
|
||||||
|
free(chunk);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object_paint(openedEntry.flags & 0x0F, 2, 0, 0, 0, (int)chunk, 0, 0)) {
|
||||||
|
RCT2_GLOBAL(0x00F42BD9, uint8) = 3;
|
||||||
|
free(chunk);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int yyy = RCT2_GLOBAL(0x009ADAF0, uint32);
|
||||||
|
RCT2_GLOBAL(0x009ADAF0, uint32) = 0x726E;
|
||||||
|
RCT2_GLOBAL(0x009ADAF8, uint32) = (int)chunk;
|
||||||
|
*((rct_object_entry*)0x00F42BC8) = openedEntry;
|
||||||
|
|
||||||
|
RCT2_GLOBAL(0x009ADAFC, uint8) = 255;
|
||||||
|
RCT2_GLOBAL(0x009ADAFD, uint8) = 1;
|
||||||
|
object_paint(openedEntry.flags & 0x0F, 0, 0, 0, 0, (int)chunk, 0, 0);
|
||||||
|
RCT2_GLOBAL(0x009ADAFC, uint8) = 0;
|
||||||
|
RCT2_GLOBAL(0x009ADAFD, uint8) = 0;
|
||||||
|
RCT2_GLOBAL(0x009ADAF0, uint32) = yyy;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
installedObject = object_get_next(installedObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
RCT2_GLOBAL(0x00F42BD9, uint8) = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* rct2: 0x006A982D
|
||||||
|
*/
|
||||||
|
void object_free_scenario_text()
|
||||||
|
{
|
||||||
|
if (RCT2_GLOBAL(0x009ADAF8, void*) != NULL) {
|
||||||
|
free(RCT2_GLOBAL(0x009ADAF8, void*));
|
||||||
|
RCT2_GLOBAL(0x009ADAF8, void*) = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int object_get_length(rct_object_entry *entry)
|
||||||
|
{
|
||||||
|
return (int)object_get_next(entry) - (int)entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
rct_object_entry *object_get_next(rct_object_entry *entry)
|
||||||
|
{
|
||||||
|
char *pos = (char*)entry;
|
||||||
|
|
||||||
|
// Skip
|
||||||
|
pos += 16;
|
||||||
|
|
||||||
|
// Skip filename
|
||||||
|
do {
|
||||||
|
pos++;
|
||||||
|
} while (*(pos - 1) != 0);
|
||||||
|
|
||||||
|
// Skip
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
|
// Skip name
|
||||||
|
do {
|
||||||
|
pos++;
|
||||||
|
} while (*(pos - 1) != 0);
|
||||||
|
|
||||||
|
// Skip
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
|
// Skip
|
||||||
|
pos += *pos++ * 16;
|
||||||
|
|
||||||
|
// Skip theme objects
|
||||||
|
pos += *pos++ * 16;
|
||||||
|
|
||||||
|
// Skip
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
|
return (rct_object_entry*)pos;
|
||||||
}
|
}
|
||||||
@@ -52,6 +52,9 @@ void object_unload_all();
|
|||||||
|
|
||||||
int object_load(int groupIndex, rct_object_entry *entry);
|
int object_load(int groupIndex, rct_object_entry *entry);
|
||||||
void object_unload(int groupIndex, rct_object_entry_extended *entry);
|
void object_unload(int groupIndex, rct_object_entry_extended *entry);
|
||||||
int sub_6A9428(rct_object_entry* entry);
|
int object_get_scenario_text(rct_object_entry *entry);
|
||||||
|
void object_free_scenario_text();
|
||||||
|
int object_get_length(rct_object_entry *entry);
|
||||||
|
rct_object_entry *object_get_next(rct_object_entry *entry);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -69,42 +69,14 @@ struct { void **data; rct_object_entry_extended *entries; } object_entry_groups[
|
|||||||
static void object_list_examine()
|
static void object_list_examine()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *object;
|
rct_object_entry *object;
|
||||||
|
|
||||||
object = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, char*);
|
object = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*);
|
||||||
for (i = 0; i < RCT2_GLOBAL(0x00F42B6C, sint32); i++) {
|
for (i = 0; i < RCT2_GLOBAL(0x00F42B6C, sint32); i++) {
|
||||||
if (*object & 0xF0)
|
if (object->flags & 0xF0)
|
||||||
RCT2_GLOBAL(0x00F42BDA, uint8) |= 1;
|
RCT2_GLOBAL(0x00F42BDA, uint8) |= 1;
|
||||||
|
|
||||||
// Skip
|
object = object_get_next(object);
|
||||||
object += 16;
|
|
||||||
|
|
||||||
// Skip filename
|
|
||||||
// printf("%d %s : ", i, object);
|
|
||||||
do {
|
|
||||||
object++;
|
|
||||||
} while (*(object - 1) != 0);
|
|
||||||
|
|
||||||
// Skip
|
|
||||||
object += 4;
|
|
||||||
|
|
||||||
// Skip name
|
|
||||||
// printf("%s\n", object);
|
|
||||||
do {
|
|
||||||
object++;
|
|
||||||
} while (*(object - 1) != 0);
|
|
||||||
|
|
||||||
// Skip
|
|
||||||
object += 4;
|
|
||||||
|
|
||||||
// Skip
|
|
||||||
object += *object++ * 16;
|
|
||||||
|
|
||||||
// Skip theme objects
|
|
||||||
object += *object++ * 16;
|
|
||||||
|
|
||||||
// Skip
|
|
||||||
object += 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,14 +59,12 @@ int scenario_load_basic(const char *path)
|
|||||||
|
|
||||||
// Checks for a scenario string object (possibly for localisation)
|
// Checks for a scenario string object (possibly for localisation)
|
||||||
if ((s6Info->entry.flags & 0xFF) != 255) {
|
if ((s6Info->entry.flags & 0xFF) != 255) {
|
||||||
if (sub_6A9428(&s6Info->entry)) {
|
if (object_get_scenario_text(&s6Info->entry)) {
|
||||||
int ebp = RCT2_GLOBAL(0x009ADAF8, uint32);
|
int ebp = RCT2_GLOBAL(0x009ADAF8, uint32);
|
||||||
format_string(s6Info->name, RCT2_GLOBAL(ebp, sint16), NULL);
|
format_string(s6Info->name, RCT2_GLOBAL(ebp, sint16), NULL);
|
||||||
format_string(s6Info->details, RCT2_GLOBAL(ebp + 4, sint16), NULL);
|
format_string(s6Info->details, RCT2_GLOBAL(ebp + 4, sint16), NULL);
|
||||||
RCT2_GLOBAL(0x009AA00C, uint8) = RCT2_GLOBAL(ebp + 6, uint8);
|
RCT2_GLOBAL(0x009AA00C, uint8) = RCT2_GLOBAL(ebp + 6, uint8);
|
||||||
|
object_free_scenario_text();
|
||||||
// Disposes the scenario string object (0x009ADAF8)
|
|
||||||
RCT2_CALLPROC_EBPSAFE(0x006A982D);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user