mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #735 from duncanspumpkin/track_refactor_s
Track Refactor
This commit is contained in:
commit
01781bed6c
|
@ -129,6 +129,7 @@
|
||||||
#define RCT2_ADDRESS_RIDE_ENTRIES 0x009ACFA4
|
#define RCT2_ADDRESS_RIDE_ENTRIES 0x009ACFA4
|
||||||
|
|
||||||
#define RCT2_ADDRESS_INSTALLED_OBJECT_LIST 0x009ADAE8
|
#define RCT2_ADDRESS_INSTALLED_OBJECT_LIST 0x009ADAE8
|
||||||
|
#define RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST 0x009ADAEC
|
||||||
|
|
||||||
#define RCT2_ADDRESS_CURRENT_SOUND_DEVICE 0x009AF280
|
#define RCT2_ADDRESS_CURRENT_SOUND_DEVICE 0x009AF280
|
||||||
|
|
||||||
|
@ -253,10 +254,11 @@
|
||||||
|
|
||||||
#define RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX 0x00F43908
|
#define RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX 0x00F43908
|
||||||
|
|
||||||
#define RCT2_ADDRESS_TRACK_LIST 0x00F44105
|
#define RCT2_ADDRESS_TRACK_DESIGN_CACHE 0x00F44105
|
||||||
#define RCT2_ADDRESS_TRACK_LIST_CACHE 0x00F44109
|
#define RCT2_ADDRESS_TRACK_DESIGN_INDEX_CACHE 0x00F44109
|
||||||
#define RCT2_ADDRESS_TRACK_LIST_NEXT_INDEX 0x00F44119
|
#define RCT2_ADDRESS_TRACK_DESIGN_NEXT_INDEX_CACHE 0x00F44119
|
||||||
|
|
||||||
|
#define RCT2_ADDRESS_TRACK_LIST 0x00F441EC
|
||||||
|
|
||||||
#define RCT2_ADDRESS_CURRENT_MONTH_YEAR 0x00F663A8
|
#define RCT2_ADDRESS_CURRENT_MONTH_YEAR 0x00F663A8
|
||||||
#define RCT2_ADDRESS_CURRENT_MONTH_TICKS 0x00F663AA
|
#define RCT2_ADDRESS_CURRENT_MONTH_TICKS 0x00F663AA
|
||||||
|
|
|
@ -87,6 +87,8 @@ int object_calculate_checksum(const rct_object_entry *entry, const char *data, i
|
||||||
int object_paint(int type, int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp);
|
int object_paint(int type, int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp);
|
||||||
rct_object_entry *object_get_next(rct_object_entry *entry);
|
rct_object_entry *object_get_next(rct_object_entry *entry);
|
||||||
int sub_6A9F42(FILE *file, rct_object_entry* entry);
|
int sub_6A9F42(FILE *file, rct_object_entry* entry);
|
||||||
|
void sub_6A9FC0();
|
||||||
|
int find_object_in_entry_group(rct_object_entry* entry, uint8* entry_type, uint8* entry_index);
|
||||||
|
|
||||||
rct_object_entry *object_list_find(rct_object_entry *entry);
|
rct_object_entry *object_list_find(rct_object_entry *entry);
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ void sub_6A9FC0()
|
||||||
for (int j = 0; j < object_entry_group_counts[type]; j++){
|
for (int j = 0; j < object_entry_group_counts[type]; j++){
|
||||||
uint8* chunk = object_entry_groups[type].chunks[j];
|
uint8* chunk = object_entry_groups[type].chunks[j];
|
||||||
if (chunk != (uint8*)-1)
|
if (chunk != (uint8*)-1)
|
||||||
object_paint(type, 0, 0, 0, 0, (int)chunk, 0, 0);
|
object_paint(type, 0, j, type, 0, (int)chunk, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -488,6 +488,30 @@ void object_list_create_hash_table()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 0x006A9DA2
|
||||||
|
* bl = entry_index
|
||||||
|
* ecx = entry_type
|
||||||
|
*/
|
||||||
|
int find_object_in_entry_group(rct_object_entry* entry, uint8* entry_type, uint8* entry_index){
|
||||||
|
*entry_type = entry->flags & 0xF;
|
||||||
|
|
||||||
|
rct_object_entry_group entry_group = object_entry_groups[*entry_type];
|
||||||
|
for (*entry_index = 0;
|
||||||
|
*entry_index < object_entry_group_counts[*entry_type];
|
||||||
|
++(*entry_index),
|
||||||
|
entry_group.chunks++,
|
||||||
|
entry_group.entries++){
|
||||||
|
|
||||||
|
if (*entry_group.chunks == (uint8*)-1) continue;
|
||||||
|
|
||||||
|
if (object_entry_compare((rct_object_entry*)entry_group.entries, entry))break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*entry_index == object_entry_group_counts[*entry_type])return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
rct_object_entry *object_list_find(rct_object_entry *entry)
|
rct_object_entry *object_list_find(rct_object_entry *entry)
|
||||||
{
|
{
|
||||||
uint32 hash = object_get_hash_code(entry);
|
uint32 hash = object_get_hash_code(entry);
|
||||||
|
|
134
src/rct1.h
134
src/rct1.h
|
@ -209,5 +209,139 @@ typedef struct {
|
||||||
uint32 expansion_pack_checksum;
|
uint32 expansion_pack_checksum;
|
||||||
} rct1_s4;
|
} rct1_s4;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
RCT1_RIDE_TYPE_NULL = 255,
|
||||||
|
RCT1_RIDE_TYPE_WOODEN_ROLLER_COASTER = 0,
|
||||||
|
RCT1_RIDE_TYPE_STAND_UP_STEEL_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_SUSPENDED_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_INVERTED_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_STEEL_MINI_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_MINIATURE_RAILROAD,
|
||||||
|
RCT1_RIDE_TYPE_MONORAIL,
|
||||||
|
RCT1_RIDE_TYPE_SUSPENDED_SINGLE_RAIL_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_BOAT_HIRE,
|
||||||
|
RCT1_RIDE_TYPE_WOODEN_CRAZY_RODENT_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_SINGLE_RAIL_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_CAR_RIDE,
|
||||||
|
RCT1_RIDE_TYPE_WHOA_BELLY,
|
||||||
|
RCT1_RIDE_TYPE_BOBSLED_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_OBSERVATION_TOWER,
|
||||||
|
RCT1_RIDE_TYPE_STEEL_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_WATER_SLIDE,
|
||||||
|
RCT1_RIDE_TYPE_MINE_TRAIN_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_CHAIRLIFT,
|
||||||
|
RCT1_RIDE_TYPE_STEEL_CORKSCREW_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_HEDGE_MAZE,
|
||||||
|
RCT1_RIDE_TYPE_SPIRAL_SLIDE,
|
||||||
|
RCT1_RIDE_TYPE_GO_KARTS,
|
||||||
|
RCT1_RIDE_TYPE_LOG_FLUME,
|
||||||
|
RCT1_RIDE_TYPE_RIVER_RAPIDS,
|
||||||
|
RCT1_RIDE_TYPE_BUMPER_CARS,
|
||||||
|
RCT1_RIDE_TYPE_SWINGING_SHIP,
|
||||||
|
RCT1_RIDE_TYPE_SWINGING_INVERTER_SHIP,
|
||||||
|
RCT1_RIDE_TYPE_ICE_CREAM_STALL,
|
||||||
|
RCT1_RIDE_TYPE_FRIES_STALL,
|
||||||
|
RCT1_RIDE_TYPE_DRINK_STALL,
|
||||||
|
RCT1_RIDE_TYPE_COTTON_CANDY_STALL,
|
||||||
|
RCT1_RIDE_TYPE_BURGER_BAR,
|
||||||
|
RCT1_RIDE_TYPE_MERRY_GO_ROUND,
|
||||||
|
RCT1_RIDE_TYPE_BALLOON_STALL,
|
||||||
|
RCT1_RIDE_TYPE_INFORMATION_KIOSK,
|
||||||
|
RCT1_RIDE_TYPE_BATHROOM,
|
||||||
|
RCT1_RIDE_TYPE_FERRIS_WHEEL,
|
||||||
|
RCT1_RIDE_TYPE_MOTION_SIMULATOR,
|
||||||
|
RCT1_RIDE_TYPE_3D_CINEMA,
|
||||||
|
RCT1_RIDE_TYPE_GRAVITRON,
|
||||||
|
RCT1_RIDE_TYPE_SPACE_RINGS,
|
||||||
|
RCT1_RIDE_TYPE_REVERSE_WHOA_BELLY_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_SOUVENIR_STALL,
|
||||||
|
RCT1_RIDE_TYPE_VERTICAL_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_PIZZA_STALL,
|
||||||
|
RCT1_RIDE_TYPE_SCRAMBLED_EGGS,
|
||||||
|
RCT1_RIDE_TYPE_HAUNTED_HOUSE,
|
||||||
|
RCT1_RIDE_TYPE_POPCORN_STALL,
|
||||||
|
RCT1_RIDE_TYPE_CIRCUS_SHOW,
|
||||||
|
RCT1_RIDE_TYPE_GHOST_TRAIN,
|
||||||
|
RCT1_RIDE_TYPE_STEEL_TWISTER_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_WOODEN_TWISTER_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_WOODEN_SIDE_FRICTION_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_STEEL_WILD_MOUSE_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_HOT_DOG_STALL,
|
||||||
|
RCT1_RIDE_TYPE_EXOTIC_SEA_FOOD_STALL,
|
||||||
|
RCT1_RIDE_TYPE_HAT_STALL,
|
||||||
|
RCT1_RIDE_TYPE_CANDY_APPLE_STAND,
|
||||||
|
RCT1_RIDE_TYPE_VIRGINIA_REEL,
|
||||||
|
RCT1_RIDE_TYPE_RIVER_RIDE,
|
||||||
|
RCT1_RIDE_TYPE_CYCLE_MONORAIL,
|
||||||
|
RCT1_RIDE_TYPE_FLYING_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_SUSPENDED_MONORAIL,
|
||||||
|
RCT1_RIDE_TYPE_40,
|
||||||
|
RCT1_RIDE_TYPE_WOODEN_REVERSER_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_HEARTLINE_TWISTER_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_MINIATURE_GOLF,
|
||||||
|
RCT1_RIDE_TYPE_44,
|
||||||
|
RCT1_RIDE_TYPE_ROTO_DROP,
|
||||||
|
RCT1_RIDE_TYPE_FLYING_SAUCERS,
|
||||||
|
RCT1_RIDE_TYPE_CROOKED_HOUSE,
|
||||||
|
RCT1_RIDE_TYPE_CYCLE_RAILWAY,
|
||||||
|
RCT1_RIDE_TYPE_SUSPENDED_LOOPING_ROLLER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_WATER_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_INVERTED_WILD_MOUSE_COASTER,
|
||||||
|
RCT1_RIDE_TYPE_JET_SKIS,
|
||||||
|
RCT1_RIDE_TYPE_T_SHIRT_STALL,
|
||||||
|
RCT1_RIDE_TYPE_RAFT_RIDE,
|
||||||
|
RCT1_RIDE_TYPE_DOUGHNUT_SHOP,
|
||||||
|
RCT1_RIDE_TYPE_ENTERPRISE,
|
||||||
|
RCT1_RIDE_TYPE_COFFEE_SHOP,
|
||||||
|
RCT1_RIDE_TYPE_FRIED_CHICKEN_STALL,
|
||||||
|
RCT1_RIDE_TYPE_LEMONADE_STALL
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
uint8 type; // 0x00
|
||||||
|
uint8 vehicle_type; // 0x01
|
||||||
|
uint32 special_track_flags; // 0x02
|
||||||
|
uint8 operating_mode; // 0x06
|
||||||
|
uint8 vehicle_colour_version; // 0x07 Vehicle colour type in first two bits, Version in bits 3,4
|
||||||
|
uint8 body_trim_colour[24]; // 0x08
|
||||||
|
uint8 track_spine_colour_rct1; // 0x20
|
||||||
|
uint8 track_rail_colour_rct1; // 0x21
|
||||||
|
uint8 track_support_colour_rct1; // 0x22
|
||||||
|
uint8 departure_control_flags; // 0x23
|
||||||
|
uint8 number_of_trains; // 0x24
|
||||||
|
uint8 cars_per_train; // 0x25
|
||||||
|
uint8 min_wait_time; // 0x26
|
||||||
|
uint8 max_wait_time; // 0x27
|
||||||
|
uint8 speed; // 0x28
|
||||||
|
uint8 max_speed; // 0x29
|
||||||
|
uint8 average_speed; // 0x2A
|
||||||
|
uint16 ride_length; // 0x2B
|
||||||
|
uint8 max_positive_vertical_g; // 0x2D
|
||||||
|
uint8 max_negitive_vertical_g; // 0x2E
|
||||||
|
uint8 max_lateral_g; // 0x2F
|
||||||
|
union {
|
||||||
|
uint8 inversions; // 0x30
|
||||||
|
uint8 holes; // 0x30
|
||||||
|
};
|
||||||
|
uint8 drops; // 0x31
|
||||||
|
uint8 highest_drop_height; // 0x32
|
||||||
|
uint8 excitement; // 0x33
|
||||||
|
uint8 intensity; // 0x34
|
||||||
|
uint8 nausea; // 0x35
|
||||||
|
uint8 pad_36[2];
|
||||||
|
union{
|
||||||
|
uint16 start_track_data_original; // 0x38
|
||||||
|
uint8 track_spine_colour[4]; // 0x38
|
||||||
|
};
|
||||||
|
uint8 track_rail_colour[4]; // 0x3C
|
||||||
|
union{
|
||||||
|
uint8 track_support_colour[4]; // 0x40
|
||||||
|
uint8 wall_type[4]; // 0x40
|
||||||
|
};
|
||||||
|
uint8 pad_41[0x83];
|
||||||
|
uint16 start_track_data_AA_CF; // 0xC4
|
||||||
|
}rct_track_td4; // Information based off RCTTechDepot
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
353
src/ride/track.c
353
src/ride/track.c
|
@ -22,8 +22,10 @@
|
||||||
#include "../platform/osinterface.h"
|
#include "../platform/osinterface.h"
|
||||||
#include "../util/sawyercoding.h"
|
#include "../util/sawyercoding.h"
|
||||||
#include "../util/util.h"
|
#include "../util/util.h"
|
||||||
|
#include "../rct1.h"
|
||||||
#include "ride.h"
|
#include "ride.h"
|
||||||
#include "track.h"
|
#include "track.h"
|
||||||
|
#include "../platform/platform.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -220,13 +222,223 @@ const rct_trackdefinition gTrackDefinitions[] = {
|
||||||
{ TRACK_HALF_LOOP_2, TRACK_DOWN_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_HALF_LOOP_DOWN }, // ELEM_LEFT_LARGE_HALF_LOOP_DOWN
|
{ TRACK_HALF_LOOP_2, TRACK_DOWN_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_HALF_LOOP_DOWN }, // ELEM_LEFT_LARGE_HALF_LOOP_DOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint32* sub_6AB49A(rct_object_entry* entry){
|
||||||
|
rct_object_entry* object_list_entry = object_list_find(entry);
|
||||||
|
|
||||||
|
if (object_list_entry == NULL) return NULL;
|
||||||
|
|
||||||
|
// Return the address of the last value of the list entry
|
||||||
|
return (((uint32*)object_get_next(object_list_entry)) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_track_idx_path(char *path)
|
||||||
|
{
|
||||||
|
char *homePath = osinterface_get_orct2_homefolder();
|
||||||
|
sprintf(path, "%s%c%s", homePath, osinterface_get_path_separator(), "Tracks.IDX");
|
||||||
|
free(homePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void track_list_query_directory(int *outTotalFiles){
|
||||||
|
int enumFileHandle;
|
||||||
|
file_info enumFileInfo;
|
||||||
|
|
||||||
|
*outTotalFiles = 0;
|
||||||
|
|
||||||
|
// Enumerate through each track in the directory
|
||||||
|
enumFileHandle = platform_enumerate_files_begin(RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char));
|
||||||
|
if (enumFileHandle == INVALID_HANDLE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (platform_enumerate_files_next(enumFileHandle, &enumFileInfo)) {
|
||||||
|
(*outTotalFiles)++;
|
||||||
|
}
|
||||||
|
platform_enumerate_files_end(enumFileHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int track_list_cache_save(int fileCount, uint8* track_list_cache, uint32 track_list_size){
|
||||||
|
char path[MAX_PATH];
|
||||||
|
FILE *file;
|
||||||
|
|
||||||
|
log_verbose("saving track list cache (tracks.idx)");
|
||||||
|
get_track_idx_path(path);
|
||||||
|
file = fopen(path, "wb");
|
||||||
|
if (file == NULL) {
|
||||||
|
log_error("Failed to save %s", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite(&fileCount, sizeof(int), 1, file);
|
||||||
|
fwrite(track_list_cache, track_list_size, 1, file);
|
||||||
|
uint8 last_entry = 0xFE;
|
||||||
|
fwrite(&last_entry, 1, 1, file);
|
||||||
|
fclose(file);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8* track_list_cache_load(int totalFiles){
|
||||||
|
char path[MAX_PATH];
|
||||||
|
FILE *file;
|
||||||
|
|
||||||
|
log_verbose("loading track list cache (tracks.idx)");
|
||||||
|
get_track_idx_path(path);
|
||||||
|
file = fopen(path, "rb");
|
||||||
|
if (file == NULL) {
|
||||||
|
log_error("Failed to load %s", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8* track_list_cache;
|
||||||
|
uint32 fileCount;
|
||||||
|
// Remove 4 for the file count variable
|
||||||
|
long track_list_size = fsize(file) - 4;
|
||||||
|
|
||||||
|
if (track_list_size < 0) return 0;
|
||||||
|
|
||||||
|
fread(&fileCount, 4, 1, file);
|
||||||
|
|
||||||
|
if (fileCount != totalFiles){
|
||||||
|
log_verbose("Track file count is different.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
track_list_cache = malloc(track_list_size);
|
||||||
|
fread(track_list_cache, track_list_size, 1, file);
|
||||||
|
return track_list_cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
void track_list_populate(ride_list_item item, uint8* track_list_cache){
|
||||||
|
uint8* track_pointer = track_list_cache;
|
||||||
|
|
||||||
|
uint8 cur_track_entry_index = 0;
|
||||||
|
for (uint8 track_type = *track_pointer++; track_type != 0xFE;
|
||||||
|
track_pointer += strlen(track_pointer) + 1,
|
||||||
|
track_type = *track_pointer++){
|
||||||
|
rct_object_entry* track_object = (rct_object_entry*)track_pointer;
|
||||||
|
track_pointer += sizeof(rct_object_entry);
|
||||||
|
|
||||||
|
if (track_type != item.type){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 entry_type, entry_index;
|
||||||
|
if (item.entry_index != 0xFF){
|
||||||
|
|
||||||
|
if (!find_object_in_entry_group(track_object, &entry_type, &entry_index))continue;
|
||||||
|
|
||||||
|
if (item.entry_index != entry_index)continue;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if (find_object_in_entry_group(track_object, &entry_type, &entry_index)){
|
||||||
|
if (GET_RIDE_ENTRY(entry_index)->var_008 & 0x3000)continue;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
uint32* esi = sub_6AB49A(track_object);
|
||||||
|
if (esi == NULL) continue;
|
||||||
|
if (*esi & 0x1000000)continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If cur_track_entry_index is greater than max number of tracks
|
||||||
|
if (cur_track_entry_index >= 1000){
|
||||||
|
RCT2_GLOBAL(0xF635ED, uint8) |= 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 track_entry_index = 0;
|
||||||
|
uint8 isBelow = 0;
|
||||||
|
for (; track_entry_index != cur_track_entry_index; track_entry_index++){
|
||||||
|
if (strcicmp(track_pointer, &RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, uint8)[track_entry_index * 128]) < 0){
|
||||||
|
isBelow = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBelow == 1){
|
||||||
|
memmove(
|
||||||
|
&RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, uint8)[track_entry_index * 128 + 128],
|
||||||
|
&RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, uint8)[track_entry_index * 128],
|
||||||
|
(cur_track_entry_index - track_entry_index) * 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(&RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, uint8)[track_entry_index * 128], track_pointer);
|
||||||
|
cur_track_entry_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, uint8)[cur_track_entry_index * 128] = '\0';
|
||||||
|
free(track_list_cache);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* rct2: 0x006CED50
|
* rct2: 0x006CED50
|
||||||
*/
|
*/
|
||||||
void track_load_list(ride_list_item item)
|
void track_load_list(ride_list_item item)
|
||||||
{
|
{
|
||||||
RCT2_CALLPROC_X(0x006CED50, 0, 0, 0, *((uint16*)&item), 0, 0, 0);
|
RCT2_GLOBAL(0xF635ED, uint8) = 0;
|
||||||
|
|
||||||
|
if (item.type < 0x80){
|
||||||
|
rct_ride_type* ride_type = gRideTypeList[item.entry_index];
|
||||||
|
if (!(ride_type->var_008 & 0x2000)){
|
||||||
|
item.entry_index = 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int totalFiles;
|
||||||
|
|
||||||
|
track_list_query_directory(&totalFiles);
|
||||||
|
|
||||||
|
uint8* track_list_cache;
|
||||||
|
|
||||||
|
if (item.type == 0xFC || !(track_list_cache = track_list_cache_load(totalFiles))){
|
||||||
|
uint8* new_track_file;
|
||||||
|
|
||||||
|
new_track_file = malloc(0x40000);
|
||||||
|
|
||||||
|
uint8* new_file_pointer = new_track_file;
|
||||||
|
file_info enumFileInfo;
|
||||||
|
|
||||||
|
int enumFileHandle = platform_enumerate_files_begin(RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char));
|
||||||
|
if (enumFileHandle == INVALID_HANDLE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (platform_enumerate_files_next(enumFileHandle, &enumFileInfo)) {
|
||||||
|
if (new_file_pointer > new_track_file + 0x3FF00)break;
|
||||||
|
|
||||||
|
char path[MAX_PATH];
|
||||||
|
subsitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), enumFileInfo.path);
|
||||||
|
|
||||||
|
rct_track_td6* loaded_track = load_track_design(path);
|
||||||
|
if (loaded_track){
|
||||||
|
*new_file_pointer++ = loaded_track->type;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
*new_file_pointer++ = 0xFF;
|
||||||
|
}
|
||||||
|
memcpy(new_file_pointer, &loaded_track->vehicle_object, sizeof(rct_object_entry));
|
||||||
|
new_file_pointer += sizeof(rct_object_entry);
|
||||||
|
|
||||||
|
int file_name_length = strlen(enumFileInfo.path);
|
||||||
|
strcpy(new_file_pointer, enumFileInfo.path);
|
||||||
|
new_file_pointer += file_name_length + 1;
|
||||||
|
}
|
||||||
|
platform_enumerate_files_end(enumFileHandle);
|
||||||
|
|
||||||
|
if (!track_list_cache_save(totalFiles, new_track_file, new_file_pointer - new_track_file)){
|
||||||
|
log_error("Track list failed to save.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
free(new_track_file);
|
||||||
|
|
||||||
|
track_list_cache = track_list_cache_load(totalFiles);
|
||||||
|
if (!track_list_cache){
|
||||||
|
log_error("Track list failed to load after new save");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
track_list_populate(item, track_list_cache);
|
||||||
|
free(track_list_cache);
|
||||||
|
//RCT2_CALLPROC_X(0x006CED50, 0, 0, 0, *((uint16*)&item), 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read(void *dst, void **src, int length)
|
static void read(void *dst, void **src, int length)
|
||||||
|
@ -240,7 +452,7 @@ static void read(void *dst, void **src, int length)
|
||||||
* rct2: 0x0067726A
|
* rct2: 0x0067726A
|
||||||
* path: 0x0141EF68
|
* path: 0x0141EF68
|
||||||
*/
|
*/
|
||||||
rct_track_design* load_track_design(const char *path)
|
rct_track_td6* load_track_design(const char *path)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
long fpLength;
|
long fpLength;
|
||||||
|
@ -270,72 +482,87 @@ rct_track_design* load_track_design(const char *path)
|
||||||
realloc(decoded, decodedLength);
|
realloc(decoded, decodedLength);
|
||||||
free(fpBuffer);
|
free(fpBuffer);
|
||||||
|
|
||||||
rct_track_design* track_design = RCT2_ADDRESS(0x009D8178, rct_track_design);
|
rct_track_td6* track_design = RCT2_ADDRESS(0x009D8178, rct_track_td6);
|
||||||
// Read decoded data
|
// Read decoded data
|
||||||
src = decoded;
|
src = decoded;
|
||||||
// Clear top of track_design as this is not loaded from the file
|
// Clear top of track_design as this is not loaded from the td4 files
|
||||||
memset(&track_design->pad_60, 0, 67);
|
memset(&track_design->track_spine_colour, 0, 67);
|
||||||
// Read start of track_design
|
// Read start of track_design
|
||||||
read(track_design, &src, 32);
|
read(track_design, &src, 32);
|
||||||
|
|
||||||
uint8 al = track_design->var_07 >> 2;
|
uint8 version = track_design->var_07 >> 2;
|
||||||
if (al >= 2)
|
|
||||||
read(&track_design->pad_20, &src, 40);
|
if (version > 2){
|
||||||
|
free(decoded);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In td6 there are 32 sets of two byte vehicle colour specifiers
|
||||||
|
// In td4 there are 12 sets so the remaining 20 need to be read.
|
||||||
|
if (version == 2)
|
||||||
|
read(&track_design->vehicle_colours[12], &src, 40);
|
||||||
|
|
||||||
read(&track_design->pad_48, &src, 24);
|
read(&track_design->pad_48, &src, 24);
|
||||||
al = track_design->var_07 >> 2;
|
|
||||||
if (al != 0)
|
|
||||||
read(&track_design->pad_60, &src, al == 1 ? 140 : 67);
|
|
||||||
|
|
||||||
read(&track_design->preview, &src, 24572);
|
// In td4 (version AA/CF) and td6 both start actual track data at 0xA3
|
||||||
al = track_design->var_07 >> 2;
|
if (version > 0)
|
||||||
if (al < 2) {
|
read(&track_design->track_spine_colour, &src, version == 1 ? 140 : 67);
|
||||||
if (track_design->type == RIDE_TYPE_MAZE) {
|
|
||||||
edi = (uint8*)(&track_design->preview);
|
uint8* track_elements = RCT2_ADDRESS(0x9D821B, uint8);
|
||||||
while (*edi != 0) {
|
// Read the actual track data.
|
||||||
edi += 4;
|
read(track_elements, &src, 24572);
|
||||||
}
|
|
||||||
edi += 4;
|
uint8* final_track_element_location = track_elements + 24572;
|
||||||
memset(edi, 255, ((uint8*)&track_design->pad_9F) - edi);
|
|
||||||
} else {
|
|
||||||
edi = (uint8*)(&track_design->preview);
|
|
||||||
while (*edi != 255) {
|
|
||||||
edi += 2;
|
|
||||||
}
|
|
||||||
edi++;
|
|
||||||
memset(edi, 255, ((uint8*)&track_design->pad_9F) - edi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(decoded);
|
free(decoded);
|
||||||
|
|
||||||
//
|
// td4 files require some work to be recognised as td6.
|
||||||
al = track_design->var_07 >> 2;
|
if (version < 2) {
|
||||||
if (al > 2)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (al <= 1) {
|
// Set any element passed the tracks to 0xFF
|
||||||
edi = (uint8*)&track_design->pad_08;
|
if (track_design->type == RIDE_TYPE_MAZE) {
|
||||||
|
uint32* maze_element = (uint32*)track_elements;
|
||||||
|
while (*maze_element != 0) {
|
||||||
|
maze_element++;
|
||||||
|
}
|
||||||
|
maze_element++;
|
||||||
|
memset(maze_element, 255, final_track_element_location - (uint8*)maze_element);
|
||||||
|
} else {
|
||||||
|
uint8* track_element = track_elements;
|
||||||
|
while (*track_element != 255) {
|
||||||
|
track_element += 2;
|
||||||
|
}
|
||||||
|
track_element++;
|
||||||
|
memset(track_element, 255, final_track_element_location - track_element);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edit the colours to use the new versions
|
||||||
|
// Unsure why it is 67
|
||||||
|
edi = (uint8*)&track_design->vehicle_colours;
|
||||||
for (i = 0; i < 67; i++)
|
for (i = 0; i < 67; i++)
|
||||||
*edi++ = RCT2_ADDRESS(0x0097F0BC, uint8)[*edi];
|
*edi++ = RCT2_ADDRESS(0x0097F0BC, uint8)[*edi];
|
||||||
|
|
||||||
edi = (uint8*)&track_design->pad_60;
|
// Edit the colours to use the new versions
|
||||||
|
edi = (uint8*)&track_design->track_spine_colour;
|
||||||
for (i = 0; i < 12; i++)
|
for (i = 0; i < 12; i++)
|
||||||
*edi++ = RCT2_ADDRESS(0x0097F0BC, uint8)[*edi];
|
*edi++ = RCT2_ADDRESS(0x0097F0BC, uint8)[*edi];
|
||||||
|
|
||||||
|
// Highest drop height is 1bit = 3/4 a meter in td6
|
||||||
|
// Highest drop height is 1bit = 1/3 a meter in td4
|
||||||
|
// Not sure if this is correct??
|
||||||
track_design->highest_drop_height >>= 1;
|
track_design->highest_drop_height >>= 1;
|
||||||
if (!RCT2_CALLPROC_X(0x00677530, 0, 0, 0, 0, 0, 0, 0))
|
if (0x100 & RCT2_CALLPROC_X(0x00677530, 0, 0, 0, 0, 0, 0, 0))
|
||||||
track_design->type = 255;
|
|
||||||
|
|
||||||
if (track_design->type == RIDE_TYPE_JUNIOR_ROLLER_COASTER)
|
|
||||||
track_design->type = RIDE_TYPE_NULL;
|
track_design->type = RIDE_TYPE_NULL;
|
||||||
|
|
||||||
if (track_design->type == RIDE_TYPE_SPIRAL_ROLLER_COASTER)
|
if (track_design->type == RCT1_RIDE_TYPE_STEEL_MINI_ROLLER_COASTER)
|
||||||
|
track_design->type = RIDE_TYPE_NULL;
|
||||||
|
|
||||||
|
if (track_design->type == RCT1_RIDE_TYPE_WOODEN_ROLLER_COASTER)
|
||||||
track_design->type = RIDE_TYPE_WOODEN_ROLLER_COASTER;
|
track_design->type = RIDE_TYPE_WOODEN_ROLLER_COASTER;
|
||||||
|
|
||||||
if (track_design->type == RIDE_TYPE_CORKSCREW_ROLLER_COASTER) {
|
if (track_design->type == RIDE_TYPE_CORKSCREW_ROLLER_COASTER) {
|
||||||
if (track_design->var_06 == 3)
|
if (track_design->var_06 == 3)
|
||||||
track_design->var_06 = 35;
|
track_design->var_06 = 35;
|
||||||
if (track_design->var_01 == 79) {
|
if (track_design->vehicle_type == 79) {
|
||||||
if (track_design->var_06 == 2)
|
if (track_design->var_06 == 2)
|
||||||
track_design->var_06 = 1;
|
track_design->var_06 = 1;
|
||||||
}
|
}
|
||||||
|
@ -345,15 +572,15 @@ rct_track_design* load_track_design(const char *path)
|
||||||
if (track_design->type == RIDE_TYPE_MAZE) {
|
if (track_design->type == RIDE_TYPE_MAZE) {
|
||||||
vehicle_object = RCT2_ADDRESS(0x0097F66C, rct_object_entry);
|
vehicle_object = RCT2_ADDRESS(0x0097F66C, rct_object_entry);
|
||||||
} else {
|
} else {
|
||||||
int var_01 = track_design->var_01;
|
int vehicle_type = track_design->vehicle_type;
|
||||||
if (var_01 == 3 && track_design->type == 3)
|
if (vehicle_type == 3 && track_design->type == RIDE_TYPE_INVERTED_ROLLER_COASTER)
|
||||||
var_01 = 80;
|
vehicle_type = 80;
|
||||||
vehicle_object = &RCT2_ADDRESS(0x0097F0DC, rct_object_entry)[var_01];
|
vehicle_object = &RCT2_ADDRESS(0x0097F0DC, rct_object_entry)[vehicle_type];
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&track_design->vehicle_object, vehicle_object, sizeof(rct_object_entry));
|
memcpy(&track_design->vehicle_object, vehicle_object, sizeof(rct_object_entry));
|
||||||
for (i = 0; i < 32; i++)
|
for (i = 0; i < 32; i++)
|
||||||
track_design->pad_82[i] = track_design->pad_08[1 + i * 2];
|
track_design->vehicle_additional_colour[i] = track_design->vehicle_colours[i].trim_colour;
|
||||||
|
|
||||||
track_design->space_required_x = 255;
|
track_design->space_required_x = 255;
|
||||||
track_design->space_required_y = 255;
|
track_design->space_required_y = 255;
|
||||||
|
@ -370,11 +597,11 @@ rct_track_design* load_track_design(const char *path)
|
||||||
|
|
||||||
/* rct2: 0x006D1DCE*/
|
/* rct2: 0x006D1DCE*/
|
||||||
void reset_track_list_cache(){
|
void reset_track_list_cache(){
|
||||||
int* track_list_cache = RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST_CACHE, int);
|
int* track_list_cache = RCT2_ADDRESS(RCT2_ADDRESS_TRACK_DESIGN_INDEX_CACHE, int);
|
||||||
for (int i = 0; i < 4; ++i){
|
for (int i = 0; i < 4; ++i){
|
||||||
track_list_cache[i] = -1;
|
track_list_cache[i] = -1;
|
||||||
}
|
}
|
||||||
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_LIST_NEXT_INDEX, uint32) = 0;
|
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_NEXT_INDEX_CACHE, uint32) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -385,49 +612,49 @@ void reset_track_list_cache(){
|
||||||
rct_track_design *track_get_info(int index, uint8** preview)
|
rct_track_design *track_get_info(int index, uint8** preview)
|
||||||
{
|
{
|
||||||
rct_track_design *trackDesign;
|
rct_track_design *trackDesign;
|
||||||
uint8 *trackDesignList = (uint8*)0x00F441EC;
|
uint8 *trackDesignList = RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, uint8);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
trackDesign = NULL;
|
trackDesign = NULL;
|
||||||
|
|
||||||
// Check if track design has already been loaded
|
// Check if track design has already been loaded
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (index == RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST_CACHE, uint32)[i]) {
|
if (index == RCT2_ADDRESS(RCT2_ADDRESS_TRACK_DESIGN_INDEX_CACHE, uint32)[i]) {
|
||||||
trackDesign = &RCT2_GLOBAL(RCT2_ADDRESS_TRACK_LIST, rct_track_design*)[i];
|
trackDesign = &RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_CACHE, rct_track_design*)[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trackDesign == NULL) {
|
if (trackDesign == NULL) {
|
||||||
// Load track design
|
// Load track design
|
||||||
i = RCT2_GLOBAL(RCT2_ADDRESS_TRACK_LIST_NEXT_INDEX, uint32)++;
|
i = RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_NEXT_INDEX_CACHE, uint32)++;
|
||||||
if (RCT2_GLOBAL(RCT2_ADDRESS_TRACK_LIST_NEXT_INDEX, uint32) >= 4)
|
if (RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_NEXT_INDEX_CACHE, uint32) >= 4)
|
||||||
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_LIST_NEXT_INDEX, uint32) = 0;
|
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_NEXT_INDEX_CACHE, uint32) = 0;
|
||||||
|
|
||||||
RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST_CACHE, uint32)[i] = index;
|
RCT2_ADDRESS(RCT2_ADDRESS_TRACK_DESIGN_INDEX_CACHE, uint32)[i] = index;
|
||||||
|
|
||||||
char track_path[MAX_PATH] = { 0 };
|
char track_path[MAX_PATH] = { 0 };
|
||||||
subsitute_path(track_path, (char*)RCT2_ADDRESS_TRACKS_PATH, trackDesignList + (index * 128));
|
subsitute_path(track_path, (char*)RCT2_ADDRESS_TRACKS_PATH, trackDesignList + (index * 128));
|
||||||
|
|
||||||
rct_track_design* loaded_design = NULL;
|
rct_track_td6* loaded_track = NULL;
|
||||||
|
|
||||||
log_verbose("Loading track: %s", trackDesignList + (index * 128));
|
log_verbose("Loading track: %s", trackDesignList + (index * 128));
|
||||||
|
|
||||||
if (!(loaded_design = load_track_design(track_path))) {
|
if (!(loaded_track = load_track_design(track_path))) {
|
||||||
if (preview != NULL) *preview = NULL;
|
if (preview != NULL) *preview = NULL;
|
||||||
log_error("Failed to load track: %s", trackDesignList + (index * 128));
|
log_error("Failed to load track: %s", trackDesignList + (index * 128));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
trackDesign = &RCT2_GLOBAL(RCT2_ADDRESS_TRACK_LIST, rct_track_design*)[i];
|
trackDesign = &RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_CACHE, rct_track_design*)[i];
|
||||||
|
|
||||||
// Copy the track design apart from the preview image
|
// Copy the track design apart from the preview image
|
||||||
memcpy(trackDesign, loaded_design, 163);
|
memcpy(&trackDesign->track_td6, loaded_track, sizeof(rct_track_td6));
|
||||||
// Load in a new preview image, calculate cost variable, calculate var_06
|
// Load in a new preview image, calculate cost variable, calculate var_06
|
||||||
RCT2_CALLPROC_X(0x006D1EF0, 0, 0, 0, 0, 0, (int)&trackDesign->preview, 0);
|
RCT2_CALLPROC_X(0x006D1EF0, 0, 0, 0, 0, 0, (int)&trackDesign->preview, 0);
|
||||||
|
|
||||||
trackDesign->cost = RCT2_GLOBAL(0x00F4411D, money32);
|
trackDesign->track_td6.cost = RCT2_GLOBAL(0x00F4411D, money32);
|
||||||
trackDesign->var_06 = RCT2_GLOBAL(0x00F44151, uint8) & 7;
|
trackDesign->track_td6.var_06 = RCT2_GLOBAL(0x00F44151, uint8) & 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set preview to correct preview image based on rotation
|
// Set preview to correct preview image based on rotation
|
||||||
|
|
|
@ -37,21 +37,29 @@ typedef struct {
|
||||||
|
|
||||||
#define TRACK_PREVIEW_IMAGE_SIZE (370 * 217)
|
#define TRACK_PREVIEW_IMAGE_SIZE (370 * 217)
|
||||||
|
|
||||||
|
/* size: 0x2 */
|
||||||
|
typedef struct{
|
||||||
|
uint8 body_colour;
|
||||||
|
uint8 trim_colour;
|
||||||
|
} rct_track_vehicle_colour;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Track design structure.
|
* Track design structure.
|
||||||
* size: 0x4E72B
|
* size: 0x4E72B
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8 type; // 0x00
|
uint8 type; // 0x00
|
||||||
uint8 var_01;
|
uint8 vehicle_type;
|
||||||
money32 cost; // 0x02
|
money32 cost; // 0x02
|
||||||
uint8 var_06;
|
uint8 var_06;
|
||||||
uint8 var_07;
|
uint8 var_07;
|
||||||
uint8 pad_08[0x18];
|
rct_track_vehicle_colour vehicle_colours[32]; // 0x08
|
||||||
uint8 pad_20[40];
|
|
||||||
uint8 pad_48[2];
|
uint8 pad_48[2];
|
||||||
uint8 total_air_time; // 0x4A
|
uint8 total_air_time; // 0x4A
|
||||||
uint8 pad_4B[0x05];
|
uint8 pad_4B;
|
||||||
|
uint8 number_of_trains; // 0x4C
|
||||||
|
uint8 number_of_cars_per_train; // 0x4D
|
||||||
|
uint8 pad_4E[2];
|
||||||
uint8 var_50;
|
uint8 var_50;
|
||||||
uint8 max_speed; // 0x51
|
uint8 max_speed; // 0x51
|
||||||
uint8 average_speed; // 0x52
|
uint8 average_speed; // 0x52
|
||||||
|
@ -69,17 +77,23 @@ typedef struct {
|
||||||
uint8 intensity; // 0x5C
|
uint8 intensity; // 0x5C
|
||||||
uint8 nausea; // 0x5D
|
uint8 nausea; // 0x5D
|
||||||
uint8 pad_5E[2];
|
uint8 pad_5E[2];
|
||||||
uint8 pad_60[0xC];
|
uint8 track_spine_colour[4]; // 0x60
|
||||||
|
uint8 track_rail_colour[4]; // 0x64
|
||||||
|
uint8 track_support_colour[4]; // 0x68
|
||||||
uint32 var_6C;
|
uint32 var_6C;
|
||||||
rct_object_entry vehicle_object; // 0x70
|
rct_object_entry vehicle_object; // 0x70
|
||||||
uint8 space_required_x; // 0x80
|
uint8 space_required_x; // 0x80
|
||||||
uint8 space_required_y; // 0x81
|
uint8 space_required_y; // 0x81
|
||||||
uint8 pad_82[0x1D];
|
uint8 vehicle_additional_colour[32]; // 0x82
|
||||||
uint8 pad_9F[3];
|
|
||||||
uint8 var_A2;
|
uint8 var_A2;
|
||||||
|
} rct_track_td6;
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
rct_track_td6 track_td6;
|
||||||
uint8 preview[4][TRACK_PREVIEW_IMAGE_SIZE]; // 0xA3
|
uint8 preview[4][TRACK_PREVIEW_IMAGE_SIZE]; // 0xA3
|
||||||
} rct_track_design;
|
} rct_track_design;
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TRACK_NONE = 0,
|
TRACK_NONE = 0,
|
||||||
|
|
||||||
|
@ -140,6 +154,7 @@ enum {
|
||||||
void track_load_list(ride_list_item item);
|
void track_load_list(ride_list_item item);
|
||||||
int sub_67726A(const char *path);
|
int sub_67726A(const char *path);
|
||||||
rct_track_design *track_get_info(int index, uint8** preview);
|
rct_track_design *track_get_info(int index, uint8** preview);
|
||||||
|
rct_track_td6* load_track_design(const char *path);
|
||||||
int track_rename(const char *text);
|
int track_rename(const char *text);
|
||||||
int track_delete();
|
int track_delete();
|
||||||
void reset_track_list_cache();
|
void reset_track_list_cache();
|
||||||
|
|
|
@ -76,3 +76,13 @@ int bitscanforward(int source)
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* case insensitve compare */
|
||||||
|
int strcicmp(char const *a, char const *b)
|
||||||
|
{
|
||||||
|
for (;; a++, b++) {
|
||||||
|
int d = tolower(*a) - tolower(*b);
|
||||||
|
if (d != 0 || !*a)
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,5 +31,6 @@ void path_set_extension(char *path, const char *extension);
|
||||||
long fsize(FILE *fp);
|
long fsize(FILE *fp);
|
||||||
|
|
||||||
int bitscanforward(int source);
|
int bitscanforward(int source);
|
||||||
|
int strcicmp(char const *a, char const *b);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
#include "../interface/widget.h"
|
#include "../interface/widget.h"
|
||||||
#include "../interface/window.h"
|
#include "../interface/window.h"
|
||||||
#include "../object.h"
|
#include "../object.h"
|
||||||
|
#include "../audio/audio.h"
|
||||||
|
#include "../ride/track.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
#pragma region Widgets
|
#pragma region Widgets
|
||||||
|
|
||||||
|
@ -55,9 +58,11 @@ enum WINDOW_STAFF_LIST_WIDGET_IDX {
|
||||||
static void window_editor_object_selection_emptysub() { }
|
static void window_editor_object_selection_emptysub() { }
|
||||||
|
|
||||||
static void window_editor_object_selection_mouseup();
|
static void window_editor_object_selection_mouseup();
|
||||||
|
static void window_editor_object_selection_scroll_mousedown();
|
||||||
|
static void window_editor_object_selection_close();
|
||||||
|
|
||||||
static void* window_editor_object_selection_events[] = {
|
static void* window_editor_object_selection_events[] = {
|
||||||
(void*)0x006AB199,
|
window_editor_object_selection_close,
|
||||||
(void*)window_editor_object_selection_mouseup,
|
(void*)window_editor_object_selection_mouseup,
|
||||||
(void*)window_editor_object_selection_emptysub,
|
(void*)window_editor_object_selection_emptysub,
|
||||||
(void*)window_editor_object_selection_emptysub,
|
(void*)window_editor_object_selection_emptysub,
|
||||||
|
@ -73,7 +78,7 @@ static void* window_editor_object_selection_events[] = {
|
||||||
(void*)window_editor_object_selection_emptysub,
|
(void*)window_editor_object_selection_emptysub,
|
||||||
(void*)window_editor_object_selection_emptysub,
|
(void*)window_editor_object_selection_emptysub,
|
||||||
(void*)0x006AB031,
|
(void*)0x006AB031,
|
||||||
(void*)0x006AB0B6,
|
window_editor_object_selection_scroll_mousedown,
|
||||||
(void*)window_editor_object_selection_emptysub,
|
(void*)window_editor_object_selection_emptysub,
|
||||||
(void*)0x006AB079,
|
(void*)0x006AB079,
|
||||||
(void*)window_editor_object_selection_emptysub,
|
(void*)window_editor_object_selection_emptysub,
|
||||||
|
@ -106,6 +111,10 @@ void window_editor_object_selection_open()
|
||||||
RCT2_CALLPROC_EBPSAFE(0x006AB211);
|
RCT2_CALLPROC_EBPSAFE(0x006AB211);
|
||||||
RCT2_CALLPROC_EBPSAFE(0x006AA770);
|
RCT2_CALLPROC_EBPSAFE(0x006AA770);
|
||||||
|
|
||||||
|
// HACK REMOVE WHEN ALL OBJECT_LOAD CALLS FINISHED
|
||||||
|
// Force Expansion Packs to always pass tests on object load
|
||||||
|
RCT2_GLOBAL(0x9AB4C0, uint16) = 0xFF;
|
||||||
|
|
||||||
window = window_create(
|
window = window_create(
|
||||||
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) / 2 - 300,
|
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) / 2 - 300,
|
||||||
max(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) / 2 - 200, 28),
|
max(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) / 2 - 200, 28),
|
||||||
|
@ -195,3 +204,160 @@ static void window_editor_object_set_page(rct_window *w, int page)
|
||||||
RCT2_CALLPROC_EBPSAFE(0x006A982D); // object_free_scenario_text();
|
RCT2_CALLPROC_EBPSAFE(0x006A982D); // object_free_scenario_text();
|
||||||
window_invalidate(w);
|
window_invalidate(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* rct2: 0x006AA703
|
||||||
|
* Takes the y coordinate of the clicked on scroll list
|
||||||
|
* and converts this into an object selection.
|
||||||
|
* Returns the position in the list.
|
||||||
|
* Object_selection_flags, installed_entry also populated
|
||||||
|
*/
|
||||||
|
int get_object_from_object_selection(uint8 object_type, int y, uint8* object_selection_flags, rct_object_entry** installed_entry){
|
||||||
|
*installed_entry = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*);
|
||||||
|
uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*);
|
||||||
|
int object_count = 0;
|
||||||
|
for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){
|
||||||
|
if (((*installed_entry)->flags & 0xF) == object_type){
|
||||||
|
if (!(*selection_flags & 0x20)){
|
||||||
|
y -= 12;
|
||||||
|
*object_selection_flags = *selection_flags;
|
||||||
|
if (y < 0)return object_count;
|
||||||
|
object_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*installed_entry = object_get_next(*installed_entry);
|
||||||
|
selection_flags++;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rct2: 0x006D33E2 */
|
||||||
|
void sub_6d33e2(){
|
||||||
|
RCT2_GLOBAL(0x1357404, sint32) = -1;
|
||||||
|
RCT2_GLOBAL(0x1357408, sint32) = -1;
|
||||||
|
RCT2_GLOBAL(0x135740C, sint32) = -1;
|
||||||
|
RCT2_GLOBAL(0x1357410, sint32) = -1;
|
||||||
|
|
||||||
|
for (int i = 0; i < 128; ++i){
|
||||||
|
RCT2_ADDRESS(0x1357444, uint32)[i] = RCT2_ADDRESS(0x97C468, uint32)[i];
|
||||||
|
RCT2_ADDRESS(0x1357644, uint32)[i] = RCT2_ADDRESS(0x97C5D4, uint32)[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; ++i){
|
||||||
|
RCT2_ADDRESS(0x1357424, sint32)[i] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
RCT2_GLOBAL(0x141F570, uint8) = 7;
|
||||||
|
|
||||||
|
int entry_index = 0;
|
||||||
|
for (; ((int)object_entry_groups[0].chunks[entry_index]) == -1; ++entry_index);
|
||||||
|
|
||||||
|
//RCT2_GLOBAL(0xF44157, uint8) = entry_index;
|
||||||
|
|
||||||
|
rct_ride_type* ride_entry = GET_RIDE_ENTRY(entry_index);
|
||||||
|
uint8* ride_type_array = &ride_entry->var_00C;
|
||||||
|
|
||||||
|
int ride_type;
|
||||||
|
for (int i = 0; (ride_type = ride_type_array[i]) == 0xFF; i++);
|
||||||
|
//RCT2_GLOBAL(0xF44158, uint8) = ride_type;
|
||||||
|
|
||||||
|
ride_list_item item = { ride_type, entry_index };
|
||||||
|
track_load_list(item);
|
||||||
|
window_track_list_open(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rct2: 0x006AB0B6 */
|
||||||
|
static void window_editor_object_selection_scroll_mousedown(){
|
||||||
|
short x, y, scrollIndex;
|
||||||
|
rct_window *w;
|
||||||
|
|
||||||
|
window_scrollmouse_get_registers(w, scrollIndex, x, y);
|
||||||
|
|
||||||
|
uint8 object_selection_flags;
|
||||||
|
rct_object_entry* installed_entry;
|
||||||
|
int selected_object = get_object_from_object_selection((w->selected_tab & 0xFF), y, &object_selection_flags, &installed_entry);
|
||||||
|
if (selected_object == -1) return;
|
||||||
|
|
||||||
|
if (object_selection_flags & 0x20)return;
|
||||||
|
|
||||||
|
window_invalidate(w);
|
||||||
|
|
||||||
|
sound_play_panned(SOUND_CLICK_1, RCT2_GLOBAL(0x142406C,uint32), 0, 0, 0);
|
||||||
|
|
||||||
|
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER){
|
||||||
|
if (RCT2_CALLPROC_X(0x6AB54F, 0, 1, 0, 0, 0, 0, (int)installed_entry) & 0x100)return;
|
||||||
|
|
||||||
|
window_close(w);
|
||||||
|
|
||||||
|
//This function calls window_track_list_open
|
||||||
|
sub_6d33e2();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ebx = 6;
|
||||||
|
// If already selected
|
||||||
|
if (!(object_selection_flags & 1))
|
||||||
|
ebx = 7;
|
||||||
|
|
||||||
|
RCT2_GLOBAL(0xF43411, uint8) = 0;
|
||||||
|
if (0x100 & RCT2_CALLPROC_X(0x6AB54F, 0, ebx, 0, 0, 0, 0, (int)installed_entry)){
|
||||||
|
|
||||||
|
rct_string_id error_title;
|
||||||
|
if (ebx & 1)
|
||||||
|
error_title = 3176;
|
||||||
|
else
|
||||||
|
error_title = 3177;
|
||||||
|
|
||||||
|
window_error_open(error_title, RCT2_GLOBAL(0x141E9AC, uint16));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!RCT2_GLOBAL(0xF43411, uint8) & 1)return;
|
||||||
|
|
||||||
|
window_error_open(3374, 3375);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rct2:0x006ABBBE */
|
||||||
|
static void editor_load_selected_objects(){
|
||||||
|
uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*);
|
||||||
|
rct_object_entry* installed_entry = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*);
|
||||||
|
|
||||||
|
if (RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32) == 0)return;
|
||||||
|
|
||||||
|
for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i != 0; --i, selection_flags++){
|
||||||
|
|
||||||
|
if (*selection_flags & 1){
|
||||||
|
|
||||||
|
uint8 entry_index, entry_type;
|
||||||
|
if (!find_object_in_entry_group(installed_entry, &entry_type, &entry_index)){
|
||||||
|
int chunk_size;
|
||||||
|
if (!object_load(-1, installed_entry, &chunk_size)){
|
||||||
|
log_error("Failed to load entry %.8s", installed_entry->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
installed_entry = object_get_next(installed_entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rct2: 0x006AB199 */
|
||||||
|
static void window_editor_object_selection_close(){
|
||||||
|
rct_window* w;
|
||||||
|
window_get_register(w);
|
||||||
|
|
||||||
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) &
|
||||||
|
(SCREEN_FLAGS_SCENARIO_EDITOR |
|
||||||
|
SCREEN_FLAGS_TRACK_MANAGER |
|
||||||
|
SCREEN_FLAGS_TRACK_MANAGER))
|
||||||
|
)return;
|
||||||
|
|
||||||
|
RCT2_CALLPROC_EBPSAFE(0x6ABB66);
|
||||||
|
editor_load_selected_objects();
|
||||||
|
sub_6A9FC0();
|
||||||
|
RCT2_CALLPROC_EBPSAFE(0x6A982D);
|
||||||
|
RCT2_CALLPROC_EBPSAFE(0x6AB316);
|
||||||
|
RCT2_CALLPROC_EBPSAFE(0x685675);
|
||||||
|
RCT2_CALLPROC_EBPSAFE(0x68585B);
|
||||||
|
window_new_ride_init_vars();
|
||||||
|
}
|
|
@ -126,7 +126,7 @@ void window_track_list_open(ride_list_item item)
|
||||||
if (mem == NULL)
|
if (mem == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_LIST, void*) = mem;
|
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_CACHE, void*) = mem;
|
||||||
reset_track_list_cache();
|
reset_track_list_cache();
|
||||||
|
|
||||||
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) {
|
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) {
|
||||||
|
@ -136,7 +136,7 @@ void window_track_list_open(ride_list_item item)
|
||||||
x = 0;
|
x = 0;
|
||||||
y = 29;
|
y = 29;
|
||||||
}
|
}
|
||||||
w = window_create(0, 29, 600, 400, (uint32*)window_track_list_events, WC_TRACK_DESIGN_LIST, 0);
|
w = window_create(x, y, 600, 400, (uint32*)window_track_list_events, WC_TRACK_DESIGN_LIST, 0);
|
||||||
w->widgets = window_track_list_widgets;
|
w->widgets = window_track_list_widgets;
|
||||||
w->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_ROTATE) | (1 << WIDX_TOGGLE_SCENERY);
|
w->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_ROTATE) | (1 << WIDX_TOGGLE_SCENERY);
|
||||||
window_init_scroll_widgets(w);
|
window_init_scroll_widgets(w);
|
||||||
|
@ -144,7 +144,7 @@ void window_track_list_open(ride_list_item item)
|
||||||
w->colours[1] = 26;
|
w->colours[1] = 26;
|
||||||
w->colours[2] = 26;
|
w->colours[2] = 26;
|
||||||
w->track_list.var_480 = 0xFFFF;
|
w->track_list.var_480 = 0xFFFF;
|
||||||
w->track_list.var_482 = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER ? 1 : 0;
|
w->track_list.var_482 = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER ? 0 : 1;
|
||||||
w->track_list.var_484 = 0;
|
w->track_list.var_484 = 0;
|
||||||
RCT2_GLOBAL(0x00F44152, uint8) = 0;
|
RCT2_GLOBAL(0x00F44152, uint8) = 0;
|
||||||
window_push_others_right(w);
|
window_push_others_right(w);
|
||||||
|
@ -157,7 +157,7 @@ void window_track_list_open(ride_list_item item)
|
||||||
*/
|
*/
|
||||||
static void window_track_list_select(rct_window *w, int index)
|
static void window_track_list_select(rct_window *w, int index)
|
||||||
{
|
{
|
||||||
uint8 *trackDesignItem, *trackDesignList = (uint8*)0x00F441EC;
|
uint8 *trackDesignItem, *trackDesignList = RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, uint8);
|
||||||
rct_track_design *trackDesign;
|
rct_track_design *trackDesign;
|
||||||
|
|
||||||
w->track_list.var_480 = index;
|
w->track_list.var_480 = index;
|
||||||
|
@ -186,14 +186,15 @@ static void window_track_list_select(rct_window *w, int index)
|
||||||
FORMAT_WHITE
|
FORMAT_WHITE
|
||||||
);
|
);
|
||||||
|
|
||||||
subsitute_path((char*)0x0141EF68, (char*)RCT2_ADDRESS_TRACKS_PATH, trackDesignItem);
|
char track_path[MAX_PATH] = { 0 };
|
||||||
|
subsitute_path(track_path, (char*)RCT2_ADDRESS_TRACKS_PATH, trackDesignItem);
|
||||||
|
|
||||||
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) {
|
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) {
|
||||||
window_track_manage_open();
|
window_track_manage_open();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!RCT2_CALLPROC_X(0x0067726A, 0, 0, 0, 0, 0, 0, 0)) {
|
if (!load_track_design(track_path)) {
|
||||||
w->track_list.var_480 = 0xFFFF;
|
w->track_list.var_480 = 0xFFFF;
|
||||||
window_invalidate(w);
|
window_invalidate(w);
|
||||||
return;
|
return;
|
||||||
|
@ -201,7 +202,7 @@ static void window_track_list_select(rct_window *w, int index)
|
||||||
|
|
||||||
trackDesign = track_get_info(index, NULL);
|
trackDesign = track_get_info(index, NULL);
|
||||||
if (trackDesign == NULL) return;
|
if (trackDesign == NULL) return;
|
||||||
if (trackDesign->var_06 & 4)
|
if (trackDesign->track_td6.var_06 & 4)
|
||||||
window_error_open(STR_THIS_DESIGN_WILL_BE_BUILT_WITH_AN_ALTERNATIVE_VEHICLE_TYPE, -1);
|
window_error_open(STR_THIS_DESIGN_WILL_BE_BUILT_WITH_AN_ALTERNATIVE_VEHICLE_TYPE, -1);
|
||||||
|
|
||||||
window_close(w);
|
window_close(w);
|
||||||
|
@ -211,7 +212,7 @@ static void window_track_list_select(rct_window *w, int index)
|
||||||
static int window_track_list_get_list_item_index_from_position(int x, int y)
|
static int window_track_list_get_list_item_index_from_position(int x, int y)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
uint8 *trackDesignItem, *trackDesignList = (uint8*)0x00F441EC;
|
uint8 *trackDesignItem, *trackDesignList = RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, uint8);
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER)) {
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER)) {
|
||||||
|
@ -237,7 +238,7 @@ static int window_track_list_get_list_item_index_from_position(int x, int y)
|
||||||
*/
|
*/
|
||||||
static void window_track_list_close()
|
static void window_track_list_close()
|
||||||
{
|
{
|
||||||
free(RCT2_GLOBAL(RCT2_ADDRESS_TRACK_LIST, void*));
|
free(RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_CACHE, void*));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -281,7 +282,7 @@ static void window_track_list_scrollgetsize()
|
||||||
{
|
{
|
||||||
rct_window *w;
|
rct_window *w;
|
||||||
int width, height;
|
int width, height;
|
||||||
uint8 *trackDesignItem, *trackDesignList = (uint8*)0x00F441EC;
|
uint8 *trackDesignItem, *trackDesignList = RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, uint8);
|
||||||
|
|
||||||
window_get_register(w);
|
window_get_register(w);
|
||||||
|
|
||||||
|
@ -400,7 +401,7 @@ static void window_track_list_paint()
|
||||||
rct_drawpixelinfo *dpi;
|
rct_drawpixelinfo *dpi;
|
||||||
rct_widget *widget;
|
rct_widget *widget;
|
||||||
rct_track_design *trackDesign = NULL;
|
rct_track_design *trackDesign = NULL;
|
||||||
uint8 *image, *trackDesignList = (uint8*)0x00F441EC;
|
uint8 *image, *trackDesignList = RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, uint8);
|
||||||
uint16 holes, speed, drops, dropHeight, inversions;
|
uint16 holes, speed, drops, dropHeight, inversions;
|
||||||
fixed32_2dp rating;
|
fixed32_2dp rating;
|
||||||
int trackIndex, x, y, colour, gForces, airTime;
|
int trackIndex, x, y, colour, gForces, airTime;
|
||||||
|
@ -429,6 +430,8 @@ static void window_track_list_paint()
|
||||||
if (trackDesign == NULL)
|
if (trackDesign == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
rct_track_td6* track_td6 = &trackDesign->track_td6;
|
||||||
|
|
||||||
subsituteElement = &g1Elements[0];
|
subsituteElement = &g1Elements[0];
|
||||||
tmpElement = *subsituteElement;
|
tmpElement = *subsituteElement;
|
||||||
subsituteElement->offset = image;
|
subsituteElement->offset = image;
|
||||||
|
@ -445,13 +448,13 @@ static void window_track_list_paint()
|
||||||
|
|
||||||
RCT2_GLOBAL(0x00F44153, uint8) = 0;
|
RCT2_GLOBAL(0x00F44153, uint8) = 0;
|
||||||
// Warnings
|
// Warnings
|
||||||
if ((trackDesign->var_06 & 4) && !(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER)) {
|
if ((track_td6->var_06 & 4) && !(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER)) {
|
||||||
// Vehicle design not available
|
// Vehicle design not available
|
||||||
gfx_draw_string_centred_clipped(dpi, STR_VEHICLE_DESIGN_UNAVAILABLE, NULL, 0, x, y, 368);
|
gfx_draw_string_centred_clipped(dpi, STR_VEHICLE_DESIGN_UNAVAILABLE, NULL, 0, x, y, 368);
|
||||||
y -= 10;
|
y -= 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trackDesign->var_06 & 1) {
|
if (track_td6->var_06 & 1) {
|
||||||
RCT2_GLOBAL(0x00F44153, uint8) = 1;
|
RCT2_GLOBAL(0x00F44153, uint8) = 1;
|
||||||
if (RCT2_GLOBAL(0x00F44152, uint8) == 0) {
|
if (RCT2_GLOBAL(0x00F44152, uint8) == 0) {
|
||||||
// Scenery not available
|
// Scenery not available
|
||||||
|
@ -468,89 +471,89 @@ static void window_track_list_paint()
|
||||||
x = w->x + widget->left + 1;
|
x = w->x + widget->left + 1;
|
||||||
y = w->y + widget->bottom + 2;
|
y = w->y + widget->bottom + 2;
|
||||||
|
|
||||||
if (trackDesign->var_6C & 0x80000000) {
|
if (track_td6->var_6C & 0x80000000) {
|
||||||
// Six flags logo
|
// Six flags logo
|
||||||
gfx_draw_sprite(dpi, SPR_SIX_FLAGS, w->x + widget->right - 50, y + 4, 0);
|
gfx_draw_sprite(dpi, SPR_SIX_FLAGS, w->x + widget->right - 50, y + 4, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stats
|
// Stats
|
||||||
rating = trackDesign->excitement * 10;
|
rating = track_td6->excitement * 10;
|
||||||
gfx_draw_string_left(dpi, STR_TRACK_LIST_EXCITEMENT_RATING, &rating, 0, x, y);
|
gfx_draw_string_left(dpi, STR_TRACK_LIST_EXCITEMENT_RATING, &rating, 0, x, y);
|
||||||
y += 10;
|
y += 10;
|
||||||
|
|
||||||
rating = trackDesign->intensity * 10;
|
rating = track_td6->intensity * 10;
|
||||||
gfx_draw_string_left(dpi, STR_TRACK_LIST_INTENSITY_RATING, &rating, 0, x, y);
|
gfx_draw_string_left(dpi, STR_TRACK_LIST_INTENSITY_RATING, &rating, 0, x, y);
|
||||||
y += 10;
|
y += 10;
|
||||||
|
|
||||||
rating = trackDesign->nausea * 10;
|
rating = track_td6->nausea * 10;
|
||||||
gfx_draw_string_left(dpi, STR_TRACK_LIST_NAUSEA_RATING, &rating, 0, x, y);
|
gfx_draw_string_left(dpi, STR_TRACK_LIST_NAUSEA_RATING, &rating, 0, x, y);
|
||||||
y += 14;
|
y += 14;
|
||||||
|
|
||||||
if (trackDesign->type != RIDE_TYPE_MAZE) {
|
if (track_td6->type != RIDE_TYPE_MAZE) {
|
||||||
if (trackDesign->type == RIDE_TYPE_MINI_GOLF) {
|
if (track_td6->type == RIDE_TYPE_MINI_GOLF) {
|
||||||
// Holes
|
// Holes
|
||||||
holes = trackDesign->holes & 0x1F;
|
holes = track_td6->holes & 0x1F;
|
||||||
gfx_draw_string_left(dpi, STR_HOLES, &holes, 0, x, y);
|
gfx_draw_string_left(dpi, STR_HOLES, &holes, 0, x, y);
|
||||||
y += 10;
|
y += 10;
|
||||||
} else {
|
} else {
|
||||||
// Maximum speed
|
// Maximum speed
|
||||||
speed = ((trackDesign->max_speed << 16) * 9) >> 18;
|
speed = ((track_td6->max_speed << 16) * 9) >> 18;
|
||||||
gfx_draw_string_left(dpi, STR_MAX_SPEED, &speed, 0, x, y);
|
gfx_draw_string_left(dpi, STR_MAX_SPEED, &speed, 0, x, y);
|
||||||
y += 10;
|
y += 10;
|
||||||
|
|
||||||
// Average speed
|
// Average speed
|
||||||
speed = ((trackDesign->average_speed << 16) * 9) >> 18;
|
speed = ((track_td6->average_speed << 16) * 9) >> 18;
|
||||||
gfx_draw_string_left(dpi, STR_AVERAGE_SPEED, &speed, 0, x, y);
|
gfx_draw_string_left(dpi, STR_AVERAGE_SPEED, &speed, 0, x, y);
|
||||||
y += 10;
|
y += 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ride length
|
// Ride length
|
||||||
RCT2_GLOBAL(0x013CE952 + 0, uint16) = 1345;
|
RCT2_GLOBAL(0x013CE952 + 0, uint16) = 1345;
|
||||||
RCT2_GLOBAL(0x013CE952 + 2, uint16) = trackDesign->ride_length;
|
RCT2_GLOBAL(0x013CE952 + 2, uint16) = track_td6->ride_length;
|
||||||
gfx_draw_string_left_clipped(dpi, STR_TRACK_LIST_RIDE_LENGTH, (void*)0x013CE952, 0, x, y, 214);
|
gfx_draw_string_left_clipped(dpi, STR_TRACK_LIST_RIDE_LENGTH, (void*)0x013CE952, 0, x, y, 214);
|
||||||
y += 10;
|
y += 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (trackDesign->type * 8), uint32) & 0x80) {
|
if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (track_td6->type * 8), uint32) & 0x80) {
|
||||||
// Maximum positive vertical Gs
|
// Maximum positive vertical Gs
|
||||||
gForces = trackDesign->max_positive_vertical_g * 32;
|
gForces = track_td6->max_positive_vertical_g * 32;
|
||||||
gfx_draw_string_left(dpi, STR_MAX_POSITIVE_VERTICAL_G, &gForces, 0, x, y);
|
gfx_draw_string_left(dpi, STR_MAX_POSITIVE_VERTICAL_G, &gForces, 0, x, y);
|
||||||
y += 10;
|
y += 10;
|
||||||
|
|
||||||
// Maximum negative verical Gs
|
// Maximum negative verical Gs
|
||||||
gForces = trackDesign->max_negitive_vertical_g * 32;
|
gForces = track_td6->max_negitive_vertical_g * 32;
|
||||||
gfx_draw_string_left(dpi, STR_MAX_NEGATIVE_VERTICAL_G, &gForces, 0, x, y);
|
gfx_draw_string_left(dpi, STR_MAX_NEGATIVE_VERTICAL_G, &gForces, 0, x, y);
|
||||||
y += 10;
|
y += 10;
|
||||||
|
|
||||||
// Maximum lateral Gs
|
// Maximum lateral Gs
|
||||||
gForces = trackDesign->max_lateral_g * 32;
|
gForces = track_td6->max_lateral_g * 32;
|
||||||
gfx_draw_string_left(dpi, STR_MAX_LATERAL_G, &gForces, 0, x, y);
|
gfx_draw_string_left(dpi, STR_MAX_LATERAL_G, &gForces, 0, x, y);
|
||||||
y += 10;
|
y += 10;
|
||||||
|
|
||||||
if (trackDesign->var_07 / 4 >= 2) {
|
if (track_td6->var_07 / 4 >= 2) {
|
||||||
if (trackDesign->total_air_time != 0) {
|
if (track_td6->total_air_time != 0) {
|
||||||
// Total air time
|
// Total air time
|
||||||
airTime = trackDesign->total_air_time * 25;
|
airTime = track_td6->total_air_time * 25;
|
||||||
gfx_draw_string_left(dpi, STR_TOTAL_AIR_TIME, &airTime, 0, x, y);
|
gfx_draw_string_left(dpi, STR_TOTAL_AIR_TIME, &airTime, 0, x, y);
|
||||||
y += 10;
|
y += 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (trackDesign->type * 8), uint32) & 0x400) {
|
if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (track_td6->type * 8), uint32) & 0x400) {
|
||||||
// Drops
|
// Drops
|
||||||
drops = trackDesign->drops & 0x3F;
|
drops = track_td6->drops & 0x3F;
|
||||||
gfx_draw_string_left(dpi, STR_DROPS, &drops, 0, x, y);
|
gfx_draw_string_left(dpi, STR_DROPS, &drops, 0, x, y);
|
||||||
y += 10;
|
y += 10;
|
||||||
|
|
||||||
// Drop height is multiplied by 0.75
|
// Drop height is multiplied by 0.75
|
||||||
dropHeight = (trackDesign->highest_drop_height + (trackDesign->highest_drop_height / 2)) / 2;
|
dropHeight = (track_td6->highest_drop_height + (track_td6->highest_drop_height / 2)) / 2;
|
||||||
gfx_draw_string_left(dpi, STR_HIGHEST_DROP_HEIGHT, &drops, 0, x, y);
|
gfx_draw_string_left(dpi, STR_HIGHEST_DROP_HEIGHT, &drops, 0, x, y);
|
||||||
y += 10;
|
y += 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trackDesign->type != RIDE_TYPE_MINI_GOLF) {
|
if (track_td6->type != RIDE_TYPE_MINI_GOLF) {
|
||||||
inversions = trackDesign->inversions & 0x1F;
|
inversions = track_td6->inversions & 0x1F;
|
||||||
if (inversions != 0) {
|
if (inversions != 0) {
|
||||||
// Inversions
|
// Inversions
|
||||||
gfx_draw_string_left(dpi, STR_INVERSIONS, &inversions, 0, x, y);
|
gfx_draw_string_left(dpi, STR_INVERSIONS, &inversions, 0, x, y);
|
||||||
|
@ -559,16 +562,16 @@ static void window_track_list_paint()
|
||||||
}
|
}
|
||||||
y += 4;
|
y += 4;
|
||||||
|
|
||||||
if (trackDesign->space_required_x != 0xFF) {
|
if (track_td6->space_required_x != 0xFF) {
|
||||||
// Space required
|
// Space required
|
||||||
RCT2_GLOBAL(0x013CE952 + 0, uint16) = trackDesign->space_required_x;
|
RCT2_GLOBAL(0x013CE952 + 0, uint16) = track_td6->space_required_x;
|
||||||
RCT2_GLOBAL(0x013CE952 + 2, uint16) = trackDesign->space_required_y;
|
RCT2_GLOBAL(0x013CE952 + 2, uint16) = track_td6->space_required_y;
|
||||||
gfx_draw_string_left(dpi, STR_TRACK_LIST_SPACE_REQUIRED, (void*)0x013CE952, 0, x, y);
|
gfx_draw_string_left(dpi, STR_TRACK_LIST_SPACE_REQUIRED, (void*)0x013CE952, 0, x, y);
|
||||||
y += 10;
|
y += 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trackDesign->cost != 0) {
|
if (track_td6->cost != 0) {
|
||||||
gfx_draw_string_left(dpi, STR_TRACK_LIST_COST_AROUND, &trackDesign->cost, 0, x, y);
|
gfx_draw_string_left(dpi, STR_TRACK_LIST_COST_AROUND, &track_td6->cost, 0, x, y);
|
||||||
y += 14;
|
y += 14;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -583,7 +586,7 @@ static void window_track_list_scrollpaint()
|
||||||
rct_drawpixelinfo *dpi;
|
rct_drawpixelinfo *dpi;
|
||||||
rct_string_id stringId, stringId2;
|
rct_string_id stringId, stringId2;
|
||||||
int i, x, y, colour;
|
int i, x, y, colour;
|
||||||
uint8 *trackDesignItem, *trackDesignList = (uint8*)0x00F441EC;
|
uint8 *trackDesignItem, *trackDesignList = RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, uint8);
|
||||||
|
|
||||||
window_paint_get_registers(w, dpi);
|
window_paint_get_registers(w, dpi);
|
||||||
|
|
||||||
|
@ -615,9 +618,9 @@ static void window_track_list_scrollpaint()
|
||||||
stringId2 = STR_BUILD_CUSTOM_DESIGN;
|
stringId2 = STR_BUILD_CUSTOM_DESIGN;
|
||||||
gfx_draw_string_left(dpi, stringId, &stringId2, 0, x, y - 1);
|
gfx_draw_string_left(dpi, stringId, &stringId2, 0, x, y - 1);
|
||||||
y += 10;
|
y += 10;
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
|
||||||
while (*trackDesignItem != 0) {
|
while (*trackDesignItem != 0) {
|
||||||
if (y + 10 >= dpi->y && y < dpi->y + dpi->height) {
|
if (y + 10 >= dpi->y && y < dpi->y + dpi->height) {
|
||||||
if (i == w->track_list.var_482) {
|
if (i == w->track_list.var_482) {
|
||||||
|
|
|
@ -171,7 +171,7 @@ static void window_track_place_draw_mini_preview()
|
||||||
originY -= ((maxY + minY) >> 6) << 5;
|
originY -= ((maxY + minY) >> 6) << 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (design->type != RIDE_TYPE_MAZE) {
|
if (design->track_td6.type != RIDE_TYPE_MAZE) {
|
||||||
#pragma region Track
|
#pragma region Track
|
||||||
|
|
||||||
rotation = RCT2_GLOBAL(0x00F440AE, uint8) + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32);
|
rotation = RCT2_GLOBAL(0x00F440AE, uint8) + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32);
|
||||||
|
|
Loading…
Reference in New Issue