mirror of https://github.com/OpenRCT2/OpenRCT2.git
commit
65a58e3177
|
@ -41,6 +41,7 @@
|
|||
#include "ride/ride.h"
|
||||
#include "ride/ride_ratings.h"
|
||||
#include "ride/vehicle.h"
|
||||
#include "ride/track.h"
|
||||
#include "scenario.h"
|
||||
#include "title.h"
|
||||
#include "tutorial.h"
|
||||
|
@ -921,7 +922,7 @@ static uint32 game_do_command_table[58] = {
|
|||
0,
|
||||
0,
|
||||
0,
|
||||
0x006D13FE,
|
||||
0,
|
||||
0,
|
||||
0x006CDEE4,
|
||||
0, // 50
|
||||
|
@ -984,7 +985,7 @@ static GAME_COMMAND_POINTER* new_game_command_table[58] = {
|
|||
game_command_remove_large_scenery,
|
||||
game_command_set_current_loan,
|
||||
game_command_set_research_funding,
|
||||
game_command_emptysub,
|
||||
game_command_place_track,
|
||||
game_command_start_campaign,
|
||||
game_command_emptysub,
|
||||
game_command_place_banner, // 50
|
||||
|
|
|
@ -71,7 +71,7 @@ enum GAME_COMMAND {
|
|||
GAME_COMMAND_REMOVE_LARGE_SCENERY,
|
||||
GAME_COMMAND_SET_CURRENT_LOAN, // 45
|
||||
GAME_COMMAND_SET_RESEARCH_FUNDING, // 46
|
||||
GAME_COMMAND_47,
|
||||
GAME_COMMAND_PLACE_TRACK,
|
||||
GAME_COMMAND_START_MARKETING_CAMPAIGN, // 48
|
||||
GAME_COMMAND_49,
|
||||
GAME_COMMAND_PLACE_BANNER, // New banner? (possibly scenery)
|
||||
|
|
|
@ -298,6 +298,15 @@ enum {
|
|||
RCT1_RIDE_TYPE_LEMONADE_STALL
|
||||
};
|
||||
|
||||
enum{
|
||||
RCT1_TRACK_ELEM_BOOSTER = 100
|
||||
};
|
||||
|
||||
enum{
|
||||
RCT1_RIDE_MODE_POWERED_LAUNCH = 3,
|
||||
|
||||
};
|
||||
|
||||
typedef struct{
|
||||
uint8 type; // 0x00
|
||||
uint8 vehicle_type; // 0x01
|
||||
|
|
181
src/ride/ride.c
181
src/ride/ride.c
|
@ -769,10 +769,173 @@ static void ride_remove_peeps(int rideIndex)
|
|||
ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN;
|
||||
}
|
||||
|
||||
int sub_6C683D(int* x, int* y, int z, int direction, int type, int esi, int edi, int ebp)
|
||||
/* rct2: 0x006C683D
|
||||
* ax : x
|
||||
* bx : direction << 8, type
|
||||
* cx : y
|
||||
* dx : z
|
||||
* si : extra_params
|
||||
* di : output_element
|
||||
* bp : flags
|
||||
*/
|
||||
int sub_6C683D(int* x, int* y, int* z, int direction, int type, uint16 extra_params, rct_map_element** output_element, uint16 flags)
|
||||
{
|
||||
int ebx = (direction << 8) | type;
|
||||
return RCT2_CALLFUNC_X(0x006C683D, x, &ebx, y, &z, &esi, &edi, &ebp)&0x100;
|
||||
//int ebx = (direction << 8) | type;
|
||||
//return RCT2_CALLFUNC_X(0x006C683D, x, &ebx, y, &z, &esi, &edi, &ebp)&0x100;
|
||||
|
||||
rct_map_element* map_element = map_get_first_element_at(*x / 32, *y / 32);
|
||||
rct_map_element* success_map = NULL;
|
||||
|
||||
do{
|
||||
if (map_element->base_height != *z / 8)
|
||||
continue;
|
||||
|
||||
if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_TRACK)
|
||||
continue;
|
||||
|
||||
if ((map_element->type & MAP_ELEMENT_DIRECTION_MASK) != direction)
|
||||
continue;
|
||||
|
||||
if (type != map_element->properties.track.type)
|
||||
continue;
|
||||
|
||||
success_map = map_element;
|
||||
if (!(map_element->properties.track.sequence & 0xF))
|
||||
break;
|
||||
}while(!map_element_is_last_for_tile(map_element++));
|
||||
|
||||
map_element = success_map;
|
||||
|
||||
if (map_element == NULL){
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Possibly z should be &0xF8
|
||||
rct_ride* ride = GET_RIDE(map_element->properties.track.ride_index);
|
||||
rct_preview_track *trackBlock;
|
||||
|
||||
if (RCT2_ADDRESS(RCT2_ADDRESS_RIDE_FLAGS, uint32)[ride->type * 2] & RIDE_TYPE_FLAG_SELLS_FOOD){
|
||||
trackBlock = RCT2_ADDRESS(0x00994A38, rct_preview_track*)[type];
|
||||
}
|
||||
else{
|
||||
trackBlock = RCT2_ADDRESS(0x00994638, rct_preview_track*)[type];
|
||||
}
|
||||
|
||||
int sequence = map_element->properties.track.sequence & 0xF;
|
||||
|
||||
uint8 map_direction = map_element->type & MAP_ELEMENT_DIRECTION_MASK;
|
||||
|
||||
switch (map_direction){
|
||||
case MAP_ELEMENT_DIRECTION_WEST:
|
||||
*x -= trackBlock[sequence].x;
|
||||
*y -= trackBlock[sequence].y;
|
||||
break;
|
||||
case MAP_ELEMENT_DIRECTION_NORTH:
|
||||
*x -= trackBlock[sequence].y;
|
||||
*y += trackBlock[sequence].x;
|
||||
break;
|
||||
case MAP_ELEMENT_DIRECTION_EAST:
|
||||
*x += trackBlock[sequence].x;
|
||||
*y += trackBlock[sequence].y;
|
||||
break;
|
||||
case MAP_ELEMENT_DIRECTION_SOUTH:
|
||||
*x += trackBlock[sequence].y;
|
||||
*y -= trackBlock[sequence].x;
|
||||
break;
|
||||
}
|
||||
|
||||
*z -= trackBlock[sequence].z;
|
||||
|
||||
int start_x = *x, start_y = *y, start_z = *z;
|
||||
|
||||
*z += trackBlock[0].z;
|
||||
|
||||
for (int i = 0; trackBlock[i].var_00 != 0xFF; ++i){
|
||||
int cur_x = start_x, cur_y = start_y, cur_z = start_z;
|
||||
|
||||
switch (map_direction){
|
||||
case MAP_ELEMENT_DIRECTION_WEST:
|
||||
cur_x += trackBlock[i].x;
|
||||
cur_y += trackBlock[i].y;
|
||||
break;
|
||||
case MAP_ELEMENT_DIRECTION_NORTH:
|
||||
cur_x += trackBlock[i].y;
|
||||
cur_y -= trackBlock[i].x;
|
||||
break;
|
||||
case MAP_ELEMENT_DIRECTION_EAST:
|
||||
cur_x -= trackBlock[i].x;
|
||||
cur_y -= trackBlock[i].y;
|
||||
break;
|
||||
case MAP_ELEMENT_DIRECTION_SOUTH:
|
||||
cur_x -= trackBlock[i].y;
|
||||
cur_y += trackBlock[i].x;
|
||||
break;
|
||||
}
|
||||
|
||||
cur_z += trackBlock[i].z;
|
||||
|
||||
map_invalidate_tile_full(cur_x, cur_y);
|
||||
|
||||
map_element = map_get_first_element_at(cur_x / 32, cur_y / 32);
|
||||
success_map = NULL;
|
||||
|
||||
do{
|
||||
if (map_element->base_height != cur_z / 8)
|
||||
continue;
|
||||
|
||||
if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_TRACK)
|
||||
continue;
|
||||
|
||||
if ((map_element->type & MAP_ELEMENT_DIRECTION_MASK) != direction)
|
||||
continue;
|
||||
|
||||
if ((map_element->properties.track.sequence & 0xF) != trackBlock[i].var_00)
|
||||
continue;
|
||||
|
||||
if (type == map_element->properties.track.type)
|
||||
{
|
||||
success_map = map_element;
|
||||
break;
|
||||
}
|
||||
} while (!map_element_is_last_for_tile(map_element++));
|
||||
|
||||
if (success_map == NULL){
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (i == 0 && output_element != NULL)
|
||||
*output_element = map_element;
|
||||
|
||||
if (flags & (1 << 0)){
|
||||
// Quadrant related ??
|
||||
map_element->type &= ~(1 << 6);
|
||||
}
|
||||
|
||||
if (flags & (1 << 1)){
|
||||
// Quadrant related ??
|
||||
map_element->type |= (1 << 6);
|
||||
}
|
||||
|
||||
if (flags & (1 << 2)){
|
||||
map_element->properties.track.colour &= 0xFC;
|
||||
map_element->properties.track.colour |= extra_params & 0xFF;
|
||||
}
|
||||
|
||||
if (flags & (1 << 5)){
|
||||
map_element->properties.track.colour &= 0x0F;
|
||||
map_element->properties.track.colour |= (extra_params & 0xFF) << 4;
|
||||
}
|
||||
|
||||
if (flags & (1 << 3)){
|
||||
map_element->properties.track.colour |= (1 << 3);
|
||||
}
|
||||
|
||||
if (flags & (1 << 4)){
|
||||
map_element->properties.track.colour &= 0xF7;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sub_6C96C0()
|
||||
|
@ -785,11 +948,11 @@ void sub_6C9627()
|
|||
switch (RCT2_GLOBAL(0x00F440A6, uint8)) {
|
||||
case 3:
|
||||
{
|
||||
int x = RCT2_GLOBAL(0x00F440A8, uint16), y = RCT2_GLOBAL(0x00F440AA, uint16);
|
||||
int x = RCT2_GLOBAL(0x00F440A8, uint16), y = RCT2_GLOBAL(0x00F440AA, uint16), z = RCT2_GLOBAL(0x00F440AC, uint16);
|
||||
sub_6C683D(
|
||||
&x,
|
||||
&y,
|
||||
RCT2_GLOBAL(0x00F440AC, uint16),
|
||||
&z,
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8) & 3,
|
||||
RCT2_GLOBAL(0x00F440AF, uint8),
|
||||
0,
|
||||
|
@ -969,7 +1132,7 @@ int ride_modify(rct_xy_element *input)
|
|||
direction = mapElement.element->type & 3;
|
||||
type = mapElement.element->properties.track.type;
|
||||
|
||||
if (sub_6C683D(&x, &y, z, direction, type, 0, 0, 0))
|
||||
if (sub_6C683D(&x, &y, &z, direction, type, 0, 0, 0))
|
||||
return 0;
|
||||
|
||||
RCT2_GLOBAL(0x00F440A7, uint8) = rideIndex;
|
||||
|
@ -2094,8 +2257,8 @@ track_colour ride_get_track_colour(rct_ride *ride, int colourScheme)
|
|||
vehicle_colour ride_get_vehicle_colour(rct_ride *ride, int vehicleIndex)
|
||||
{
|
||||
vehicle_colour result;
|
||||
result.main = ride->vehicle_colours[vehicleIndex] & 0xFF;
|
||||
result.additional_1 = ride->vehicle_colours[vehicleIndex] >> 8;
|
||||
result.main = ride->vehicle_colours[vehicleIndex].body_colour;
|
||||
result.additional_1 = ride->vehicle_colours[vehicleIndex].trim_colour;
|
||||
result.additional_2 = ride->vehicle_colours_extended[vehicleIndex];
|
||||
return result;
|
||||
}
|
||||
|
@ -3709,7 +3872,7 @@ void game_command_demolish_ride(int *eax, int *ebx, int *ecx, int *edx, int *esi
|
|||
RCT2_CALLPROC_X(0x00696707, 0, 0, 0, ride_id, 0, 0, 0);
|
||||
*ebx = ride_get_refund_price(ride_id);
|
||||
|
||||
RCT2_CALLPROC(0x006CB945);
|
||||
RCT2_CALLPROC_X(0x006CB945, 0, 0, 0, ride_id, 0, 0, 0);
|
||||
news_item_disable_news(NEWS_ITEM_RIDE, ride_id);
|
||||
|
||||
for(int i = 0; i < MAX_BANNERS; i++){
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "../common.h"
|
||||
#include "../peep/peep.h"
|
||||
#include "../world/map.h"
|
||||
#include "vehicle.h"
|
||||
|
||||
typedef fixed16_2dp ride_rating;
|
||||
|
||||
|
@ -138,7 +139,7 @@ typedef struct {
|
|||
uint16 pad_002;
|
||||
uint8 mode; // 0x004
|
||||
uint8 colour_scheme_type; // 0x005
|
||||
uint16 vehicle_colours[32]; // 0x006
|
||||
rct_vehicle_colour vehicle_colours[32]; // 0x006
|
||||
uint8 pad_046[0x03];
|
||||
// 0 = closed, 1 = open, 2 = test
|
||||
uint8 status; // 0x049
|
||||
|
@ -753,7 +754,7 @@ void ride_breakdown_add_news_item(int rideIndex);
|
|||
rct_peep *ride_find_closest_mechanic(rct_ride *ride, int forInspection);
|
||||
int sub_6CC3FB(int rideIndex);
|
||||
void sub_6C9627();
|
||||
int sub_6C683D(int* x, int* y, int z, int direction, int type, int esi, int edi, int ebp);
|
||||
int sub_6C683D(int* x, int* y, int* z, int direction, int type, uint16 extra_params, rct_map_element** output_element, uint16 flags);
|
||||
void ride_set_map_tooltip(rct_map_element *mapElement);
|
||||
int ride_music_params_update(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint16 sampleRate, uint32 position, uint8 *tuneId);
|
||||
void ride_music_update_final();
|
||||
|
|
|
@ -51,18 +51,19 @@ static void loc_6B5BB2();
|
|||
static void ride_ratings_calculate(rct_ride *ride);
|
||||
static void ride_ratings_calculate_value(rct_ride *ride);
|
||||
|
||||
static int sub_6C6402(rct_map_element *mapElement, int *x, int *y, int *z)
|
||||
int sub_6C6402(rct_map_element **mapElement, int *x, int *y, int *z)
|
||||
{
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp;
|
||||
|
||||
eax = *x;
|
||||
ecx = *y;
|
||||
esi = (int)mapElement;
|
||||
RCT2_CALLFUNC_X(0x006C6402, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
esi = (int)*mapElement;
|
||||
int result = RCT2_CALLFUNC_X(0x006C6402, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
*x = *((uint16*)&eax);
|
||||
*y = *((uint16*)&ecx);
|
||||
*z = *((uint8*)&edx);
|
||||
return 1;
|
||||
*mapElement = (rct_map_element*)esi;
|
||||
return result & (0x100);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -338,7 +339,7 @@ static void ride_ratings_update_state_5()
|
|||
|
||||
x = RCT2_GLOBAL(0x0138B584, uint16);
|
||||
y = RCT2_GLOBAL(0x0138B586, uint16);
|
||||
if (!sub_6C6402(mapElement, &x, &y, &z)) {
|
||||
if (!sub_6C6402(&mapElement, &x, &y, &z)) {
|
||||
_rideRatingsState = RIDE_RATINGS_STATE_CALCULATE;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -25,5 +25,6 @@
|
|||
#include "ride.h"
|
||||
|
||||
void ride_ratings_update_all();
|
||||
int sub_6C6402(rct_map_element **mapElement, int *x, int *y, int *z);
|
||||
|
||||
#endif
|
1892
src/ride/track.c
1892
src/ride/track.c
File diff suppressed because it is too large
Load Diff
|
@ -42,7 +42,7 @@ typedef struct {
|
|||
uint8 var_00;
|
||||
sint16 x; // 0x01
|
||||
sint16 y; // 0x03
|
||||
uint16 z;
|
||||
sint16 z;
|
||||
uint8 pad_07;
|
||||
uint8 var_08;
|
||||
uint8 var_09;
|
||||
|
@ -57,8 +57,13 @@ typedef struct {
|
|||
struct {
|
||||
sint8 x;
|
||||
sint8 y;
|
||||
uint8 unk_2;
|
||||
uint8 type;
|
||||
union{
|
||||
uint16 maze_entry;
|
||||
struct{
|
||||
uint8 unk_2;
|
||||
uint8 type;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
} rct_maze_element;
|
||||
|
@ -72,14 +77,22 @@ typedef struct{
|
|||
/* Track Scenery entry size: 0x16 */
|
||||
typedef struct{
|
||||
rct_object_entry scenery_object; // 0x00
|
||||
uint8 x; // 0x10
|
||||
uint8 y; // 0x11
|
||||
uint8 z; // 0x12
|
||||
sint8 x; // 0x10
|
||||
sint8 y; // 0x11
|
||||
sint8 z; // 0x12
|
||||
uint8 flags; // 0x13 direction quadrant tertiary colour
|
||||
uint8 primary_colour; // 0x14
|
||||
uint8 secondary_colour; // 0x15
|
||||
}rct_track_scenery;
|
||||
|
||||
/* Track Entrance entry size: 0x6 */
|
||||
typedef struct{
|
||||
sint8 z;
|
||||
uint8 direction; // 0x01
|
||||
sint16 x; // 0x02
|
||||
sint16 y; // 0x04
|
||||
}rct_track_entrance;
|
||||
|
||||
enum{
|
||||
TRACK_ELEMENT_FLAG_CHAIN_LIFT = (1<<7),
|
||||
TRACK_ELEMENT_FLAG_INVERTED = (1<<6),
|
||||
|
@ -92,12 +105,6 @@ enum{
|
|||
|
||||
#define TRACK_PREVIEW_IMAGE_SIZE (370 * 217)
|
||||
|
||||
/* size: 0x2 */
|
||||
typedef struct{
|
||||
uint8 body_colour;
|
||||
uint8 trim_colour;
|
||||
} rct_track_vehicle_colour;
|
||||
|
||||
/**
|
||||
* Track design structure.
|
||||
* size: 0x4E72B
|
||||
|
@ -105,10 +112,20 @@ typedef struct{
|
|||
typedef struct {
|
||||
uint8 type; // 0x00
|
||||
uint8 vehicle_type;
|
||||
money32 cost; // 0x02
|
||||
uint8 var_06;
|
||||
uint8 var_07;
|
||||
rct_track_vehicle_colour vehicle_colours[32]; // 0x08
|
||||
union{
|
||||
// After loading the track this is converted to
|
||||
// a cost but before its a flags register
|
||||
money32 cost; // 0x02
|
||||
uint32 flags; // 0x02
|
||||
};
|
||||
union{
|
||||
// After loading the track this is converted to
|
||||
// a flags register
|
||||
uint8 ride_mode; // 0x06
|
||||
uint8 track_flags; // 0x06
|
||||
};
|
||||
uint8 version_and_colour_scheme; // 0x07 0b0000_VVCC
|
||||
rct_vehicle_colour vehicle_colours[32]; // 0x08
|
||||
union{
|
||||
uint8 pad_48;
|
||||
uint8 track_spine_colour_rct1; // 0x48
|
||||
|
@ -121,16 +138,17 @@ typedef struct {
|
|||
uint8 total_air_time; // 0x4A
|
||||
uint8 track_support_colour_rct1; // 0x4A
|
||||
};
|
||||
uint8 pad_4B;
|
||||
uint8 depart_flags; // 0x4B
|
||||
uint8 number_of_trains; // 0x4C
|
||||
uint8 number_of_cars_per_train; // 0x4D
|
||||
uint8 pad_4E[2];
|
||||
uint8 min_waiting_time; // 0x4E
|
||||
uint8 max_waiting_time; // 0x4F
|
||||
uint8 var_50;
|
||||
uint8 max_speed; // 0x51
|
||||
uint8 average_speed; // 0x52
|
||||
sint8 max_speed; // 0x51
|
||||
sint8 average_speed; // 0x52
|
||||
uint16 ride_length; // 0x53
|
||||
uint8 max_positive_vertical_g; // 0x55
|
||||
sint8 max_negitive_vertical_g; // 0x56
|
||||
sint8 max_negative_vertical_g; // 0x56
|
||||
uint8 max_lateral_g; // 0x57
|
||||
union {
|
||||
uint8 inversions; // 0x58
|
||||
|
@ -141,7 +159,7 @@ typedef struct {
|
|||
uint8 excitement; // 0x5B
|
||||
uint8 intensity; // 0x5C
|
||||
uint8 nausea; // 0x5D
|
||||
uint8 pad_5E[2];
|
||||
money16 upkeep_cost; // 0x5E
|
||||
uint8 track_spine_colour[4]; // 0x60
|
||||
uint8 track_rail_colour[4]; // 0x64
|
||||
uint8 track_support_colour[4]; // 0x68
|
||||
|
@ -150,7 +168,7 @@ typedef struct {
|
|||
uint8 space_required_x; // 0x80
|
||||
uint8 space_required_y; // 0x81
|
||||
uint8 vehicle_additional_colour[32]; // 0x82
|
||||
uint8 var_A2;
|
||||
uint8 lift_hill_speed_num_circuits; // 0xA2 0bCCCL_LLLL
|
||||
} rct_track_td6;
|
||||
|
||||
typedef struct{
|
||||
|
@ -415,11 +433,13 @@ rct_track_design *temp_track_get_info(char* path, uint8** preview);
|
|||
rct_track_td6* load_track_design(const char *path);
|
||||
int track_rename(const char *text);
|
||||
int track_delete();
|
||||
void track_mirror();
|
||||
void reset_track_list_cache();
|
||||
int track_is_connected_by_shape(rct_map_element *a, rct_map_element *b);
|
||||
int sub_6D01B3(int bl, int x, int y, int z);
|
||||
int sub_6D01B3(uint8 bl, uint8 rideIndex, int x, int y, int z);
|
||||
int save_track_design(uint8 rideIndex);
|
||||
int install_track(char* source_path, char* dest_name);
|
||||
void window_track_list_format_name(char *dst, const char *src, char colour, char quotes);
|
||||
void game_command_place_track(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,12 @@
|
|||
|
||||
#include "../common.h"
|
||||
|
||||
/* size: 0x2 */
|
||||
typedef struct{
|
||||
uint8 body_colour;
|
||||
uint8 trim_colour;
|
||||
} rct_vehicle_colour;
|
||||
|
||||
typedef struct {
|
||||
uint8 sprite_identifier; // 0x00
|
||||
uint8 var_01;
|
||||
|
|
|
@ -225,6 +225,43 @@ int sawyercoding_decode_td6(char *src, char *dst, int length)
|
|||
return decode_chunk_rle(src, dst, length - 4);
|
||||
}
|
||||
|
||||
int sawyercoding_encode_td6(char* src, char* dst, int length){
|
||||
int output_length = encode_chunk_rle(src, dst, length);
|
||||
|
||||
uint32 checksum = 0;
|
||||
for (int i = 0; i < output_length; i++){
|
||||
uint8 new_byte = ((checksum & 0xFF) + dst[i]) & 0xFF;
|
||||
checksum = (checksum & 0xFFFFFF00) + new_byte;
|
||||
checksum = rol32(checksum, 3);
|
||||
}
|
||||
checksum -= 0x1D4C1;
|
||||
|
||||
*((uint32*)&dst[output_length]) = checksum;
|
||||
output_length += 4;
|
||||
return output_length;
|
||||
}
|
||||
|
||||
/* Based off of rct2: 0x006770C1 */
|
||||
int sawyercoding_validate_track_checksum(char* src, int length){
|
||||
uint32 file_checksum = *((uint32*)&src[length - 4]);
|
||||
|
||||
uint32 checksum = 0;
|
||||
for (int i = 0; i < length - 4; i++){
|
||||
uint8 new_byte = ((checksum & 0xFF) + src[i]) & 0xFF;
|
||||
checksum = (checksum & 0xFFFFFF00) + new_byte;
|
||||
checksum = rol32(checksum, 3);
|
||||
}
|
||||
|
||||
if (checksum - 0x1D4C1 == file_checksum)
|
||||
return 1; // .TD6
|
||||
else if (checksum - 0x1A67C == file_checksum)
|
||||
return 1; // .TD4
|
||||
else if (checksum - 0x1A650 == file_checksum)
|
||||
return 1; // .TD4
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#pragma region Decoding
|
||||
|
||||
/**
|
||||
|
@ -318,14 +355,14 @@ static int encode_chunk_rle(char *src_buffer, char *dst_buffer, int length)
|
|||
|
||||
while (src < end_src - 1){
|
||||
|
||||
if ((count && *src == src[1]) || count > 120){
|
||||
if ((count && *src == src[1]) || count > 125){
|
||||
*dst++ = count - 1;
|
||||
for (; count != 0; --count){
|
||||
*dst++ = *src_norm_start++;
|
||||
}
|
||||
}
|
||||
if (*src == src[1]){
|
||||
for (; (count < 120) && ((src + count) < end_src); count++){
|
||||
for (; (count < 125) && ((src + count) < end_src); count++){
|
||||
if (*src != src[count]) break;
|
||||
}
|
||||
*dst++ = 257 - count;
|
||||
|
|
|
@ -55,6 +55,8 @@ int sawyercoding_decode_sv4(char *src, char *dst, int length);
|
|||
int sawyercoding_decode_sc4(char *src, char *dst, int length);
|
||||
int sawyercoding_encode_sv4(char *src, char *dst, int length);
|
||||
int sawyercoding_decode_td6(char *src, char *dst, int length);
|
||||
int sawyercoding_encode_td6(char* src, char* dst, int length);
|
||||
int sawyercoding_validate_track_checksum(char* src, int length);
|
||||
|
||||
int sawyercoding_detect_file_type(char *src, int length);
|
||||
|
||||
|
|
|
@ -201,7 +201,7 @@ static void window_install_track_select(rct_window *w, int index)
|
|||
|
||||
trackDesign = track_get_info(index, NULL);
|
||||
if (trackDesign == NULL) return;
|
||||
if (trackDesign->track_td6.var_06 & 4)
|
||||
if (trackDesign->track_td6.track_flags & 4)
|
||||
window_error_open(STR_THIS_DESIGN_WILL_BE_BUILT_WITH_AN_ALTERNATIVE_VEHICLE_TYPE, -1);
|
||||
|
||||
window_close(w);
|
||||
|
@ -339,7 +339,7 @@ static void window_install_track_paint()
|
|||
RCT2_GLOBAL(0x00F44153, uint8) = 0;
|
||||
|
||||
// Warnings
|
||||
if (track_td6->var_06 & 1) {
|
||||
if (track_td6->track_flags & 1) {
|
||||
RCT2_GLOBAL(0x00F44153, uint8) = 1;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_SCENERY_TOGGLE, uint8) == 0) {
|
||||
// Scenery not available
|
||||
|
@ -408,7 +408,7 @@ static void window_install_track_paint()
|
|||
y += 10;
|
||||
|
||||
// Maximum negative verical Gs
|
||||
gForces = track_td6->max_negitive_vertical_g * 32;
|
||||
gForces = track_td6->max_negative_vertical_g * 32;
|
||||
gfx_draw_string_left(dpi, STR_MAX_NEGATIVE_VERTICAL_G, &gForces, 0, x, y);
|
||||
y += 10;
|
||||
|
||||
|
@ -417,7 +417,8 @@ static void window_install_track_paint()
|
|||
gfx_draw_string_left(dpi, STR_MAX_LATERAL_G, &gForces, 0, x, y);
|
||||
y += 10;
|
||||
|
||||
if (track_td6->var_07 / 4 >= 2) {
|
||||
// If .TD6
|
||||
if (track_td6->version_and_colour_scheme / 4 >= 2) {
|
||||
if (track_td6->total_air_time != 0) {
|
||||
// Total air time
|
||||
airTime = track_td6->total_air_time * 25;
|
||||
|
|
|
@ -322,7 +322,7 @@ void window_construction_mouseup_demolish(rct_window* w){
|
|||
ecx = RCT2_GLOBAL(0xF440AA, uint16),
|
||||
edx = RCT2_GLOBAL(0xF440AC, uint16);
|
||||
|
||||
sub_6C683D(&eax, &ecx, edx, RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8), RCT2_GLOBAL(0xF440AF, uint8) & 0x3FF, 0, 0, 0);
|
||||
sub_6C683D(&eax, &ecx, &edx, RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8), RCT2_GLOBAL(0xF440AF, uint8) & 0x3FF, 0, 0, 0);
|
||||
}
|
||||
|
||||
int ride_id = RCT2_GLOBAL(0xF440A7, uint8);
|
||||
|
|
|
@ -190,7 +190,7 @@ static void window_track_list_select(rct_window *w, int index)
|
|||
|
||||
trackDesign = track_get_info(index, NULL);
|
||||
if (trackDesign == NULL) return;
|
||||
if (trackDesign->track_td6.var_06 & 4)
|
||||
if (trackDesign->track_td6.track_flags & 4)
|
||||
window_error_open(STR_THIS_DESIGN_WILL_BE_BUILT_WITH_AN_ALTERNATIVE_VEHICLE_TYPE, -1);
|
||||
|
||||
window_close(w);
|
||||
|
@ -436,13 +436,13 @@ static void window_track_list_paint()
|
|||
|
||||
RCT2_GLOBAL(0x00F44153, uint8) = 0;
|
||||
// Warnings
|
||||
if ((track_td6->var_06 & 4) && !(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER)) {
|
||||
if ((track_td6->track_flags & 4) && !(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER)) {
|
||||
// Vehicle design not available
|
||||
gfx_draw_string_centred_clipped(dpi, STR_VEHICLE_DESIGN_UNAVAILABLE, NULL, 0, x, y, 368);
|
||||
y -= 10;
|
||||
}
|
||||
|
||||
if (track_td6->var_06 & 1) {
|
||||
if (track_td6->track_flags & 1) {
|
||||
RCT2_GLOBAL(0x00F44153, uint8) = 1;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_SCENERY_TOGGLE, uint8) == 0) {
|
||||
// Scenery not available
|
||||
|
@ -509,7 +509,7 @@ static void window_track_list_paint()
|
|||
y += 10;
|
||||
|
||||
// Maximum negative verical Gs
|
||||
gForces = track_td6->max_negitive_vertical_g * 32;
|
||||
gForces = track_td6->max_negative_vertical_g * 32;
|
||||
gfx_draw_string_left(dpi, STR_MAX_NEGATIVE_VERTICAL_G, &gForces, 0, x, y);
|
||||
y += 10;
|
||||
|
||||
|
@ -518,7 +518,8 @@ static void window_track_list_paint()
|
|||
gfx_draw_string_left(dpi, STR_MAX_LATERAL_G, &gForces, 0, x, y);
|
||||
y += 10;
|
||||
|
||||
if (track_td6->var_07 / 4 >= 2) {
|
||||
// If .TD6
|
||||
if (track_td6->version_and_colour_scheme / 4 >= 2) {
|
||||
if (track_td6->total_air_time != 0) {
|
||||
// Total air time
|
||||
airTime = track_td6->total_air_time * 25;
|
||||
|
|
|
@ -308,7 +308,8 @@ static void window_track_place_clear_provisional()
|
|||
{
|
||||
if (_window_track_place_last_was_valid) {
|
||||
sub_6D01B3(
|
||||
(RCT2_GLOBAL(0x00F440EB, uint8) << 8) | 6,
|
||||
6,
|
||||
RCT2_GLOBAL(0x00F440EB, uint8),
|
||||
_window_track_place_last_valid_x,
|
||||
_window_track_place_last_valid_y,
|
||||
_window_track_place_last_valid_z
|
||||
|
@ -342,7 +343,7 @@ static int window_track_place_get_base_z(int x, int y)
|
|||
if (mapElement->properties.surface.terrain & 0x1F)
|
||||
z = max(z, (mapElement->properties.surface.terrain & 0x1F) << 4);
|
||||
|
||||
return z + sub_6D01B3(3, x, y, z);
|
||||
return z + sub_6D01B3(3, 0, x, y, z);
|
||||
}
|
||||
|
||||
static void window_track_place_attempt_placement(int x, int y, int z, int bl, money32 *cost, uint8 *rideIndex)
|
||||
|
@ -354,7 +355,7 @@ static void window_track_place_attempt_placement(int x, int y, int z, int bl, mo
|
|||
ebx = bl;
|
||||
ecx = y;
|
||||
edi = z;
|
||||
result = game_do_command_p(GAME_COMMAND_47, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
result = game_do_command_p(GAME_COMMAND_PLACE_TRACK, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
|
||||
if (cost != NULL) *cost = result;
|
||||
if (rideIndex != NULL) *rideIndex = edi & 0xFF;
|
||||
|
@ -427,7 +428,7 @@ static void window_track_place_mouseup()
|
|||
window_track_place_draw_mini_preview();
|
||||
break;
|
||||
case WIDX_MIRROR:
|
||||
RCT2_CALLPROC_EBPSAFE(0x006D2436);
|
||||
track_mirror();
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint16) = (-RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint16)) & 3;
|
||||
window_invalidate(w);
|
||||
_window_track_place_last_x = 0xFFFF;
|
||||
|
@ -477,7 +478,7 @@ static void window_track_place_toolupdate()
|
|||
|
||||
// Check if tool map position has changed since last update
|
||||
if (x == _window_track_place_last_x && y == _window_track_place_last_y) {
|
||||
sub_6D01B3(0, x, y, 0);
|
||||
sub_6D01B3(0, 0, x, y, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -510,7 +511,7 @@ static void window_track_place_toolupdate()
|
|||
widget_invalidate(w, WIDX_PRICE);
|
||||
}
|
||||
|
||||
sub_6D01B3(0, x, y, z);
|
||||
sub_6D01B3(0, 0, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
|
||||
void sub_673883(int x, int y, int z);
|
||||
void sub_69A48B(int x, int y, int z);
|
||||
void sub_6A6C66(int x, int y, rct_map_element *mapElement, int flags);
|
||||
void sub_6A759F();
|
||||
|
||||
|
||||
enum {
|
||||
FOOTPATH_CONSTRUCTION_FLAG_ALLOW_DURING_PAUSED = 1 << 3
|
||||
|
|
|
@ -49,5 +49,7 @@ void footpath_provisional_update();
|
|||
void footpath_get_coordinates_from_pos(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement);
|
||||
void footpath_bridge_get_info_from_pos(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement);
|
||||
void sub_673883(int x, int y, int z);
|
||||
void sub_6A6C66(int x, int y, rct_map_element *mapElement, int flags);
|
||||
void sub_6A759F();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -174,6 +174,22 @@ rct_map_element *map_get_surface_element_at(int x, int y)
|
|||
return mapElement;
|
||||
}
|
||||
|
||||
rct_map_element* map_get_path_element_at(int x, int y, int z){
|
||||
rct_map_element *mapElement = map_get_first_element_at(x, y);
|
||||
|
||||
uint8 mapFound = 0;
|
||||
// Find the path element at known z
|
||||
do {
|
||||
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_PATH)
|
||||
continue;
|
||||
if (mapElement->base_height != z)
|
||||
continue;
|
||||
|
||||
return mapElement;
|
||||
} while (!map_element_is_last_for_tile(mapElement++));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0068AB4C
|
||||
|
|
|
@ -256,6 +256,7 @@ void map_element_set_terrain(rct_map_element *element, int terrain);
|
|||
void map_element_set_terrain_edge(rct_map_element *element, int terrain);
|
||||
int map_height_from_slope(int x, int y, int slope);
|
||||
rct_map_element *map_get_surface_element_at(int x, int y);
|
||||
rct_map_element* map_get_path_element_at(int x, int y, int z);
|
||||
int map_element_height(int x, int y);
|
||||
void sub_68B089();
|
||||
int map_coord_is_connected(int x, int y, int z, uint8 faceDirection);
|
||||
|
|
Loading…
Reference in New Issue