mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-16 19:43:06 +01:00
Refactored paint_path. Labelled known offsets
This commit is contained in:
@@ -133,6 +133,8 @@
|
||||
#define RCT2_ADDRESS_INSTALLED_OBJECT_LIST 0x009ADAE8
|
||||
#define RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST 0x009ADAEC
|
||||
|
||||
#define RCT2_ADDRESS_TOTAL_NO_IMAGES 0x009ADAF0
|
||||
|
||||
#define RCT2_ADDRESS_CURRENT_SOUND_DEVICE 0x009AF280
|
||||
|
||||
#define RCT2_ADDRESS_VEHICLE_SOUND_LIST 0x009AF288
|
||||
@@ -258,6 +260,7 @@
|
||||
#define RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS 0x00F42B6C
|
||||
#define RCT2_ADDRESS_ORIGINAL_RCT2_OBJECT_COUNT 0x00F42B70
|
||||
|
||||
#define RCT2_ADDRESS_CURR_OBJECT_BASE_STRING_ID 0x00F42BBC
|
||||
#define RCT2_ADDRESS_CURR_OBJECT_CHUNK_POINTER 0x00F42BC0
|
||||
|
||||
#define RCT2_ADDRESS_VOLUME_ADJUST_ZOOM 0x00F438AC
|
||||
|
||||
@@ -233,56 +233,71 @@ const int OpenRCT2LangIdToObjectLangId[] = {
|
||||
/* rct2: 0x006A9E24*/
|
||||
rct_string_id object_get_localised_text(uint8_t** pStringTable/*ebp*/, int type/*ecx*/, int index/*ebx*/, int tableindex/*edx*/)
|
||||
{
|
||||
char* pString;
|
||||
char* pString = NULL;
|
||||
int result = 0;
|
||||
while (true)
|
||||
{
|
||||
uint8_t language_code = ((uint8_t*)*pStringTable)[0];
|
||||
(*pStringTable)++;
|
||||
uint8_t language_code = *(*pStringTable)++;
|
||||
|
||||
if (language_code == 0xFF) //end of string table
|
||||
break;
|
||||
|
||||
// This is the ideal situation. Language found
|
||||
if (language_code == OpenRCT2LangIdToObjectLangId[gCurrentLanguage])//1)
|
||||
{
|
||||
pString = *pStringTable;
|
||||
result |= 1;
|
||||
}
|
||||
|
||||
// Just in case always load english into pString
|
||||
if (language_code == 0 && !(result & 1))
|
||||
{
|
||||
pString = *pStringTable;
|
||||
result |= 2;
|
||||
}
|
||||
|
||||
// Failing that fall back to whatever is first string
|
||||
if (!(result & 7))
|
||||
{
|
||||
pString = *pStringTable;
|
||||
result |= 4;
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
uint8_t character = ((uint8_t*)*pStringTable)[0];
|
||||
(*pStringTable)++;
|
||||
if (character == 0) break;
|
||||
}
|
||||
|
||||
// Skip over the actual string entry to get to the next
|
||||
// entry
|
||||
while (*(*pStringTable)++ != 0);
|
||||
}
|
||||
|
||||
// If not scenario text
|
||||
if (RCT2_GLOBAL(0x9ADAFC, uint8_t) == 0)
|
||||
{
|
||||
int stringid = 0xD87;
|
||||
int i;
|
||||
for (i = 0; i < type; i++)
|
||||
int stringid = 3463;
|
||||
for (int i = 0; i < type; i++)
|
||||
{
|
||||
int nrobjects = object_entry_group_counts[i];
|
||||
int nrstringtables = RCT2_GLOBAL(0x98DA16 + i * 2, uint16_t);//the number of string tables in a type
|
||||
int nrstringtables = RCT2_ADDRESS(0x98DA16, uint16)[i];//the number of string tables in a type
|
||||
stringid += nrobjects * nrstringtables;
|
||||
}
|
||||
stringid += index * RCT2_GLOBAL(0x98DA16 + type * 2, uint16_t);
|
||||
RCT2_GLOBAL(0x00F42BBC, uint32) = stringid;
|
||||
stringid += index * RCT2_ADDRESS(0x98DA16, uint16)[type];
|
||||
// Used by the object list to allocate name in plugin.dat
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURR_OBJECT_BASE_STRING_ID, uint32) = stringid;
|
||||
stringid += tableindex;
|
||||
RCT2_GLOBAL(0x009BF2D4 + stringid * 4, char*) = pString;//put pointer in stringtable
|
||||
|
||||
//put pointer in stringtable
|
||||
language_strings[stringid] = pString;
|
||||
// Until all string related functions are finished copy
|
||||
// to old array as well.
|
||||
RCT2_ADDRESS(0x009BF2D4, char*)[stringid] = pString;
|
||||
return stringid;
|
||||
}
|
||||
else
|
||||
{
|
||||
int stringid = 0xD77 + tableindex;
|
||||
RCT2_GLOBAL(0x009BF2D4 + stringid * 4, char*) = pString;//put pointer in stringtable
|
||||
int stringid = 3447 + tableindex;
|
||||
//put pointer in stringtable
|
||||
language_strings[stringid] = pString;
|
||||
// Until all string related functions are finished copy
|
||||
// to old array as well.
|
||||
RCT2_ADDRESS(0x009BF2D4, char*)[stringid] = pString;
|
||||
return stringid;
|
||||
}
|
||||
}
|
||||
116
src/object.c
116
src/object.c
@@ -105,10 +105,8 @@ int object_load_file(int groupIndex, const rct_object_entry *entry, int* chunkSi
|
||||
return 0;
|
||||
}
|
||||
|
||||
int yyy = RCT2_GLOBAL(0x009ADAF0, uint32);
|
||||
|
||||
if (yyy >= 0x4726E){
|
||||
log_error("Object Load failed due to yyy failure.");
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) >= 0x4726E){
|
||||
log_error("Object Load failed due to too many images loaded.");
|
||||
RCT2_GLOBAL(0x00F42BD9, uint8) = 4;
|
||||
rct2_free(chunk);
|
||||
return 0;
|
||||
@@ -231,9 +229,7 @@ int object_load_packed(FILE *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int yyy = RCT2_GLOBAL(0x009ADAF0, uint32);
|
||||
|
||||
if (yyy >= 0x4726E){
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) >= 0x4726E){
|
||||
rct2_free(chunk);
|
||||
return 0;
|
||||
}
|
||||
@@ -388,7 +384,7 @@ int object_calculate_checksum(const rct_object_entry *entry, const char *data, i
|
||||
/* rct2: 0x006A9ED1 */
|
||||
int object_chunk_load_image_directory(uint8_t** chunk)
|
||||
{
|
||||
int image_start_no = RCT2_GLOBAL(0x9ADAF0, uint32_t);
|
||||
int image_start_no = RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32_t);
|
||||
|
||||
// First dword of chunk is no_images
|
||||
int no_images = *((uint32_t*)(*chunk));
|
||||
@@ -397,7 +393,7 @@ int object_chunk_load_image_directory(uint8_t** chunk)
|
||||
int length_of_data = *((uint32_t*)(*chunk));
|
||||
*chunk += 4;
|
||||
|
||||
RCT2_GLOBAL(0x9ADAF0, uint32_t) = no_images + image_start_no;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32_t) = no_images + image_start_no;
|
||||
|
||||
rct_g1_element* g1_dest = &RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[image_start_no];
|
||||
|
||||
@@ -781,61 +777,63 @@ int paint_ride_entry(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo* dp
|
||||
//rct2: 0x006A8621
|
||||
int paint_path_entry(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo* dpi, int esi, int ebp)
|
||||
{
|
||||
if ((flags & 0xFF) != 3)
|
||||
{
|
||||
if ((flags & 0xFF) != 1)
|
||||
{
|
||||
if ((flags & 0xFF) <= 1)//0
|
||||
{
|
||||
uint8_t* pStringTable = (uint8_t*)(esi + 0xE);
|
||||
((rct_path_type*)esi)->pad_00 = object_get_localised_text(&pStringTable, ecx, ebx, 0);
|
||||
if ((flags & 0xFF) == 0){
|
||||
// Object Load
|
||||
|
||||
int image_id = object_chunk_load_image_directory(&pStringTable);
|
||||
((rct_path_type*)esi)->image = image_id;
|
||||
image_id += 0x6D;
|
||||
((rct_path_type*)esi)->pad_06 = image_id;
|
||||
if (RCT2_GLOBAL(0x9ADAF4, uint32_t) != 0xFFFFFFFF) RCT2_GLOBAL(0x9ADAF4, uint16_t*)[0] = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_ID, sint16) = 0;
|
||||
int b = -1;
|
||||
while (true)
|
||||
{
|
||||
b++;
|
||||
if (b >= 0x10) break;
|
||||
uint8_t* edi = object_entry_groups[5].chunks[ebx];
|
||||
if ((uint32_t)edi == 0xFFFFFFFF) continue;
|
||||
if (!(edi[0xB] & 4))
|
||||
{
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_ID, sint16) = ebx;
|
||||
break;
|
||||
}
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_ID, sint16) = ebx;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
else
|
||||
rct_path_type* path_type = (rct_path_type*)esi;
|
||||
// String table starts after path entry
|
||||
// Note there are 2 spare bytes after
|
||||
// the path entry.
|
||||
uint8* chunk = (uint8*)(esi + 0xE);
|
||||
|
||||
// Only 1 string table for paths
|
||||
path_type->string_idx = object_get_localised_text(&chunk, ecx, ebx, 0);
|
||||
|
||||
int image_id = object_chunk_load_image_directory(&chunk);
|
||||
path_type->image = image_id;
|
||||
path_type->bridge_image = image_id + 109;
|
||||
|
||||
if (RCT2_GLOBAL(0x9ADAF4, uint32) != 0xFFFFFFFF) *RCT2_GLOBAL(0x9ADAF4, uint16*) = 0;
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_ID, sint16) = 0;
|
||||
// Set the default path for when opening footpath window
|
||||
for (int i = 0; i < object_entry_group_counts[OBJECT_TYPE_PATHS]; ++i){
|
||||
rct_path_type* path_type_entry = (rct_path_type*)object_entry_groups[OBJECT_TYPE_PATHS].chunks[i];
|
||||
if ((uint32)path_type_entry == 0xFFFFFFFF) continue;
|
||||
if (!(path_type_entry->flags & 4))
|
||||
{
|
||||
if (((rct_path_type*)esi)->pad_0A >= 2) return 1;//actually the carry bit should be set (stc)
|
||||
else return 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_ID, sint16) = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
((rct_path_type*)esi)->pad_00 = 0;
|
||||
((rct_path_type*)esi)->image = 0;
|
||||
((rct_path_type*)esi)->pad_06 = 0;
|
||||
return flags;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_ID, sint16) = i;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else if ((flags & 0xFF) == 1){
|
||||
// Object Unload
|
||||
|
||||
rct_path_type* path_type = (rct_path_type*)esi;
|
||||
path_type->string_idx = 0;
|
||||
path_type->image = 0;
|
||||
path_type->bridge_image = 0;
|
||||
}
|
||||
else if ((flags & 0xFF) == 2){
|
||||
|
||||
rct_path_type* path_type = (rct_path_type*)esi;
|
||||
if (path_type->var_0A >= 2) return 1;//actually the carry bit should be set (stc)
|
||||
else return 0;
|
||||
}
|
||||
else if ((flags & 0xFF) == 3){
|
||||
rct_path_type* path_type = (rct_path_type*)ebp;
|
||||
if (!((flags >> 8) & 0xFF))
|
||||
{
|
||||
//Draws preview for scenario editor!
|
||||
gfx_draw_sprite(dpi, ((rct_path_type*)ebp)->image + 71, ecx - 49, edx - 17, ebp);
|
||||
gfx_draw_sprite(dpi, ((rct_path_type*)ebp)->image + 72, ecx + 4, edx - 17, ebp);
|
||||
gfx_draw_sprite(dpi, path_type->image + 71, ecx - 49, edx - 17, ebp);
|
||||
gfx_draw_sprite(dpi, path_type->image + 72, ecx + 4, edx - 17, ebp);
|
||||
}
|
||||
return flags;
|
||||
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
//rct2: 0x00666E42
|
||||
@@ -1051,8 +1049,10 @@ int object_get_scenario_text(rct_object_entry *entry)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int yyy = RCT2_GLOBAL(0x009ADAF0, uint32);
|
||||
RCT2_GLOBAL(0x009ADAF0, uint32) = 0x726E;
|
||||
int total_no_images = RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32);
|
||||
// This is being changed to force the images to be loaded into a different
|
||||
// image id.
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = 0x726E;
|
||||
RCT2_GLOBAL(0x009ADAF8, uint32) = (int)chunk;
|
||||
*((rct_object_entry*)0x00F42BC8) = openedEntry;
|
||||
|
||||
@@ -1061,7 +1061,7 @@ int object_get_scenario_text(rct_object_entry *entry)
|
||||
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;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = total_no_images;
|
||||
return 1;
|
||||
}
|
||||
fclose(file);
|
||||
@@ -1101,7 +1101,7 @@ rct_object_entry *object_get_next(rct_object_entry *entry)
|
||||
// Skip filename
|
||||
while (*pos++);
|
||||
|
||||
// Skip
|
||||
// Skip no of images
|
||||
pos += 4;
|
||||
|
||||
// Skip name
|
||||
|
||||
@@ -179,7 +179,7 @@ void sub_6A9FC0()
|
||||
{
|
||||
reset_9E32F8();
|
||||
|
||||
RCT2_GLOBAL(0x009ADAF0, uint32) = 0xF26E;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = 0xF26E;
|
||||
|
||||
for (int type = 0; type < 11; ++type){
|
||||
for (int j = 0; j < object_entry_group_counts[type]; j++){
|
||||
@@ -606,7 +606,7 @@ static uint32 install_object_entry(rct_object_entry* entry, rct_object_entry* in
|
||||
*((uint16*)(installed_entry_pointer + 9)) = 0;
|
||||
*((uint32*)(installed_entry_pointer + 11)) = 0;
|
||||
|
||||
RCT2_GLOBAL(0x9ADAF0, uint32) = 0xF26E;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) = 0xF26E;
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32)++;
|
||||
|
||||
@@ -648,28 +648,31 @@ static uint32 install_object_entry(rct_object_entry* entry, rct_object_entry* in
|
||||
|
||||
uint8* chunk = RCT2_GLOBAL(RCT2_ADDRESS_CURR_OBJECT_CHUNK_POINTER, uint8*); // Loaded in object_load
|
||||
|
||||
// When made of two parts i.e Wooden Roller Coaster (Dream Woodie Cars);
|
||||
if (objectType == OBJECT_TYPE_RIDE && !(*((uint32*)(chunk + 8)) & 0x1000)) {
|
||||
rct_string_id obj_string = chunk[12];
|
||||
// When made of two parts i.e Wooden Roller Coaster (Dream Woodie Cars)
|
||||
if ((objectType == OBJECT_TYPE_RIDE) && !((((rct_ride_type*)chunk)->var_008) & 0x1000)) {
|
||||
rct_ride_type* ride_type = (rct_ride_type*)chunk;
|
||||
rct_string_id obj_string = ride_type->var_00C;
|
||||
if (obj_string == 0xFF){
|
||||
obj_string = chunk[13];
|
||||
obj_string = ride_type->var_00D;
|
||||
if (obj_string == 0xFF) {
|
||||
obj_string = chunk[14];
|
||||
obj_string = ride_type->var_00E;
|
||||
}
|
||||
}
|
||||
|
||||
obj_string += 2;
|
||||
format_string(installed_entry_pointer, obj_string, 0);
|
||||
format_string(installed_entry_pointer, obj_string + 2, 0);
|
||||
strcat(installed_entry_pointer, "\t (");
|
||||
strcat(installed_entry_pointer, language_get_string((rct_string_id)RCT2_GLOBAL(0x00F42BBC, uint32)));
|
||||
strcat(installed_entry_pointer, language_get_string((rct_string_id)RCT2_GLOBAL(RCT2_ADDRESS_CURR_OBJECT_BASE_STRING_ID, uint32)));
|
||||
strcat(installed_entry_pointer, ")");
|
||||
while (*installed_entry_pointer++);
|
||||
}
|
||||
else{
|
||||
strcpy(installed_entry_pointer, language_get_string((rct_string_id)RCT2_GLOBAL(0x00F42BBC, uint32)));
|
||||
strcpy(installed_entry_pointer, language_get_string((rct_string_id)RCT2_GLOBAL(RCT2_ADDRESS_CURR_OBJECT_BASE_STRING_ID, uint32)));
|
||||
while (*installed_entry_pointer++);
|
||||
}
|
||||
*((uint32*)installed_entry_pointer) = RCT2_GLOBAL(0x009ADAF0, uint32) - 0xF26E;
|
||||
|
||||
// This is deceptive. Due to setting the total no images earlier to 0xF26E
|
||||
// this is actually the no_images in this entry.
|
||||
*((uint32*)installed_entry_pointer) = RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32) - 0xF26E;
|
||||
installed_entry_pointer += 4;
|
||||
|
||||
uint8* esi = RCT2_ADDRESS(0x00F42BDB, uint8);
|
||||
|
||||
@@ -29,11 +29,11 @@ enum {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint16 pad_00;
|
||||
uint32 image; // 0x02
|
||||
uint32 pad_06;
|
||||
uint8 pad_0A;
|
||||
uint8 flags; // 0x0B
|
||||
rct_string_id string_idx; // 0x00
|
||||
uint32 image; // 0x02
|
||||
uint32 bridge_image; // 0x06
|
||||
uint8 var_0A;
|
||||
uint8 flags; // 0x0B
|
||||
} rct_path_type;
|
||||
|
||||
void game_command_place_footpath(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
|
||||
Reference in New Issue
Block a user