1
0
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:
Duncan Frost
2015-03-01 17:45:45 +00:00
parent 9282a782d3
commit c0e957299f
5 changed files with 114 additions and 93 deletions

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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);