From 1dc5b6576700b1f2db5c8bba2750b6f78b6a31d3 Mon Sep 17 00:00:00 2001 From: lnz Date: Wed, 21 May 2014 14:04:08 +0200 Subject: [PATCH 01/53] Initial implementation of ride reachability checks --- src/ride.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++++ src/ride.h | 5 +- src/scenario.c | 2 +- 3 files changed, 209 insertions(+), 2 deletions(-) diff --git a/src/ride.c b/src/ride.c index 42f32287ff..296936e935 100644 --- a/src/ride.c +++ b/src/ride.c @@ -19,6 +19,9 @@ *****************************************************************************/ #include "addresses.h" +#include "map.h" +#include "news_item.h" +#include "sprite.h" #include "ride.h" #include "sprite.h" #include "peep.h" @@ -200,3 +203,204 @@ void ride_update_favourited_stat() window_invalidate_by_id(WC_RIDE_LIST, 0); } + +int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) +{ + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate / 4]; + + do { + rct_map_element_path_properties props = tile->properties.path; + uint8 path_type = props.type >> 2, path_dir = props.type & 3; + uint8 element_type = tile->type & 0x3C; + + if (!(element_type & PATH_ROAD)) + continue; + + if (path_type & 1) { + if (path_dir == face_direction) { + if (height == tile->base_height + 2) + return 1; + } + else if (path_dir ^ 2 == face_direction && height == tile->base_height) { + return 1; + } + } else { + if (height == tile->base_height) + return 1; + } + + } while (!(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) && tile++); + + return 0; +} + + + +/** + * rct2: 0x006B7C59 + * @return 1 if the coordinate is reachable or has no entrance, 0 otw + */ +int ride_is_reachable(uint16 coordinate, rct_ride* ride, int index) { + int x = ((coordinate >> 8) & 0xFF) << 5, // cx + y = (coordinate & 0xFF) << 5; // ax + uint8 station_height = ride->pad_05A[index]; // pad_05a is uint8 station_base_height[4] + int tile_idx = ((x << 8) | y) >> 3; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + + while(1) { + uint8 element_type = tile->type & 0x3C; + if (element_type == MAP_ELEMENT_TYPE_ENTRANCE && station_height == tile->base_height) { + break; + } else if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) { + return 1; + } + tile++; + } + + uint8 face_direction = tile->type & 3; + y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; + x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; + tile_idx = ((x << 8) | y) >> 3; + + return map_coord_is_connected(tile_idx, station_height, face_direction); + /* while (1) { */ + /* rct_map_element_path_properties props; */ + + /* element_type = tile->type & 0x3C; */ + /* if (!(element_type & MAP_ELEMENT_TYPE_PATH)) */ + /* goto end; */ + + /* props = tile->properties.path; */ + /* if ( props.type & PATH_ROAD) { // with roads slopes count as connected sometimes */ + /* if ((props.type & 3) == face_direction) { */ + /* if (station_height == tile->base_height + 2) */ + /* return 1; */ + /* } */ + /* else { */ + /* uint8 madness = (props.type & 3) ^ 2; */ + /* if (madness == face_direction && station_height == tile->base_height) */ + /* return 1; */ + /* } */ + /* } else { // off-road only same height counts as connected */ + /* if (station_height == tile->base_height) */ + /* return 1; */ + /* } */ + + /* end: */ + /* if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) */ + /* return 0; */ + /* tile++; */ + /* } */ +} + + +void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) +{ + for (int i = 0; i < 4; ++i) { + uint16 station_start = ride->station_starts[i], + entrance = ride->entrances[i], + exit = ride->exits[i]; + + if (station_start == -1 ) + continue; + if (entrance != -1 && !ride_is_reachable(entrance, ride, i)) { + RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; + RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; + news_item_add_to_queue(1, 0xb26, ride_idx); + ride->var_1AF = 3; + } + + if (exit != -1 && !ride_is_reachable(exit, ride, i)) { + RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; + RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; + news_item_add_to_queue(1, 0xb27, ride_idx); + ride->var_1AF = 3; + } + + } +} + + +void blue_reachable(rct_ride* ride, int ride_idx) +{ + uint16 coordinate = ride->station_starts[ride_idx]; + int x = ((coordinate >> 8) & 0xFF) << 5, // cx + y = (coordinate & 0xFF) << 5; // ax + uint16 magic = 0; + int tile_idx = ((x << 8) | y) >> 3, count = 0; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + + while (1) { + // First find the appropriate track element for our ride + uint8 element_type = tile->type & 0x3C; + if(element_type == MAP_ELEMENT_TYPE_TRACK && tile->properties.track.ride_index == ride_idx) + break; + + if(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) + return; + tile++; + } + + uint8 track_type = tile->properties.track.type; + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { + magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; + } else { + magic = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; + } + + magic = magic << (tile->type & 3); + magic = ((magic >> 12) | magic) & 0xF; + + for (int count = 0; magic != 0; ++count) { + if (!(magic & 1)) { + magic >>= 1; + continue; + } + + uint8 face_direction = count ^ 2; + y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; + x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; + tile_idx = ((x << 8) | y) >> 3; + + if (map_coord_is_connected(tile, tile->base_height, face_direction)) + return; + } + + RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; + RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; + news_item_add_to_queue(1, 0xb26, ride_idx); + ride->var_1AF = 3; +} + + + +/** + * rct2: 0x006B7A5E + **/ +void ride_check_all_reachable() +{ +/* XXX: coordinates gleich um 5 shiften und / 4 ueberall weg */ + rct_ride *ride; + + for (int i = 0; i < MAX_RIDES; i++) { + ride = GET_RIDE(i); + if (ride->type == RIDE_TYPE_NULL) + continue; + if (ride->var_1AF != 0) + ride->var_1AF--; + if (ride->status != RIDE_STATUS_OPEN || ride->var_1AF != 0) + continue; + + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) { + //lightblue + blue_reachable(ride, i); + return; + } + else { + //pink + ride_entrance_exit_connected(ride, i); + } + + } +} + diff --git a/src/ride.h b/src/ride.h index 84eb778120..a782f19f64 100644 --- a/src/ride.h +++ b/src/ride.h @@ -79,7 +79,9 @@ typedef struct { uint16 var_196; uint8 pad_198; uint8 var_199; - uint8 pad_19A[0x1A]; + uint8 pad_19A[0x15]; + uint8 var_1AF; + uint32 pad_1B0; sint32 profit; // 0x1B4 uint8 queue_time[4]; // 0x1B8 uint8 pad_1BC[0x12]; @@ -262,5 +264,6 @@ int ride_get_max_queue_time(rct_ride *ride); void ride_init_all(); void reset_all_ride_build_dates(); void ride_update_favourited_stat(); +void ride_check_all_reachable(); #endif diff --git a/src/scenario.c b/src/scenario.c index 81f97bbd08..c71abc6b55 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -874,7 +874,7 @@ void scenario_update() finance_pay_interest(); scenario_marketing_update(); peep_problem_warnings_update(); - RCT2_CALLPROC_EBPSAFE(0x006B7A5E); // check ride reachability + ride_check_all_reachable(); ride_update_favourited_stat(); if (month <= 1 && RCT2_GLOBAL(0x009ADAE0, sint32) != -1 && RCT2_GLOBAL(0x009ADAE0 + 14, uint16) & 1) { From 8bdba74ba690be5507567fb62cc96f1172f9eb3d Mon Sep 17 00:00:00 2001 From: lnz Date: Mon, 26 May 2014 15:22:52 +0200 Subject: [PATCH 02/53] Cleanup and refactoring of ride reachability stuff --- src/map.c | 38 +++++++++++++++++++- src/map.h | 2 ++ src/ride.c | 95 ++++++++++---------------------------------------- src/scenario.c | 1 + 4 files changed, 59 insertions(+), 77 deletions(-) diff --git a/src/map.c b/src/map.c index 581eabdf30..b7e1ca0ae4 100644 --- a/src/map.c +++ b/src/map.c @@ -329,4 +329,40 @@ void sub_68B089() } while (mapElement->base_height == 255); mapElement++; RCT2_GLOBAL(0x0140E9A4, rct_map_element*) = mapElement; -} \ No newline at end of file +} + + +/** + * Checks if the tile at coordinate at height counts as connected. + * @return 1 if connected, 0 otherwisei + */ +int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) +{ + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate]; + + do { + rct_map_element_path_properties props = tile->properties.path; + uint8 path_type = props.type >> 2, path_dir = props.type & 3; + uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; + + if (!(element_type & PATH_ROAD)) + continue; + + if (path_type & 1) { + if (path_dir == face_direction) { + if (height == tile->base_height + 2) + return 1; + } + else if (path_dir ^ 2 == face_direction && height == tile->base_height) { + return 1; + } + } else { + if (height == tile->base_height) + return 1; + } + + } while (!(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) && tile++); + + return 0; +} + diff --git a/src/map.h b/src/map.h index 88e76d7e11..1a44bd616c 100644 --- a/src/map.h +++ b/src/map.h @@ -186,5 +186,7 @@ void map_init(); void map_update_tile_pointers(); int map_element_height(int x, int y); void sub_68B089(); +int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction); + #endif diff --git a/src/ride.c b/src/ride.c index 296936e935..34cba0b8ef 100644 --- a/src/ride.c +++ b/src/ride.c @@ -204,51 +204,21 @@ void ride_update_favourited_stat() } -int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) -{ - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate / 4]; - - do { - rct_map_element_path_properties props = tile->properties.path; - uint8 path_type = props.type >> 2, path_dir = props.type & 3; - uint8 element_type = tile->type & 0x3C; - - if (!(element_type & PATH_ROAD)) - continue; - - if (path_type & 1) { - if (path_dir == face_direction) { - if (height == tile->base_height + 2) - return 1; - } - else if (path_dir ^ 2 == face_direction && height == tile->base_height) { - return 1; - } - } else { - if (height == tile->base_height) - return 1; - } - - } while (!(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) && tile++); - - return 0; -} - /** * rct2: 0x006B7C59 * @return 1 if the coordinate is reachable or has no entrance, 0 otw */ -int ride_is_reachable(uint16 coordinate, rct_ride* ride, int index) { +int ride_entrance_exit_is_reachable(uint16 coordinate, rct_ride* ride, int index) { int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax uint8 station_height = ride->pad_05A[index]; // pad_05a is uint8 station_base_height[4] - int tile_idx = ((x << 8) | y) >> 3; - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + int tile_idx = ((x << 8) | y) >> 5; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; while(1) { - uint8 element_type = tile->type & 0x3C; + uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; if (element_type == MAP_ELEMENT_TYPE_ENTRANCE && station_height == tile->base_height) { break; } else if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) { @@ -260,37 +230,9 @@ int ride_is_reachable(uint16 coordinate, rct_ride* ride, int index) { uint8 face_direction = tile->type & 3; y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; - tile_idx = ((x << 8) | y) >> 3; + tile_idx = ((x << 8) | y) >> 5; return map_coord_is_connected(tile_idx, station_height, face_direction); - /* while (1) { */ - /* rct_map_element_path_properties props; */ - - /* element_type = tile->type & 0x3C; */ - /* if (!(element_type & MAP_ELEMENT_TYPE_PATH)) */ - /* goto end; */ - - /* props = tile->properties.path; */ - /* if ( props.type & PATH_ROAD) { // with roads slopes count as connected sometimes */ - /* if ((props.type & 3) == face_direction) { */ - /* if (station_height == tile->base_height + 2) */ - /* return 1; */ - /* } */ - /* else { */ - /* uint8 madness = (props.type & 3) ^ 2; */ - /* if (madness == face_direction && station_height == tile->base_height) */ - /* return 1; */ - /* } */ - /* } else { // off-road only same height counts as connected */ - /* if (station_height == tile->base_height) */ - /* return 1; */ - /* } */ - - /* end: */ - /* if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) */ - /* return 0; */ - /* tile++; */ - /* } */ } @@ -303,14 +245,14 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) if (station_start == -1 ) continue; - if (entrance != -1 && !ride_is_reachable(entrance, ride, i)) { + if (entrance != -1 && !ride_entrance_exit_is_reachable(entrance, ride, i)) { RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb26, ride_idx); ride->var_1AF = 3; } - if (exit != -1 && !ride_is_reachable(exit, ride, i)) { + if (exit != -1 && !ride_entrance_exit_is_reachable(exit, ride, i)) { RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb27, ride_idx); @@ -321,18 +263,17 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) } -void blue_reachable(rct_ride* ride, int ride_idx) +void ride_is_shop_reachable(rct_ride* ride, int ride_idx) { uint16 coordinate = ride->station_starts[ride_idx]; int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax uint16 magic = 0; - int tile_idx = ((x << 8) | y) >> 3, count = 0; - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + int tile_idx = ((x << 8) | y) >> 5, count = 0; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; while (1) { - // First find the appropriate track element for our ride - uint8 element_type = tile->type & 0x3C; + uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; if(element_type == MAP_ELEMENT_TYPE_TRACK && tile->properties.track.ride_index == ride_idx) break; @@ -342,7 +283,8 @@ void blue_reachable(rct_ride* ride, int ride_idx) } uint8 track_type = tile->properties.track.type; - if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { + ride = GET_RIDE(tile->properties.track.ride_index); + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { // buggy but why magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; } else { magic = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; @@ -350,7 +292,9 @@ void blue_reachable(rct_ride* ride, int ride_idx) magic = magic << (tile->type & 3); magic = ((magic >> 12) | magic) & 0xF; - + if (magic == 0) + return; + for (int count = 0; magic != 0; ++count) { if (!(magic & 1)) { magic >>= 1; @@ -360,7 +304,7 @@ void blue_reachable(rct_ride* ride, int ride_idx) uint8 face_direction = count ^ 2; y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; - tile_idx = ((x << 8) | y) >> 3; + tile_idx = ((x << 8) | y) >> 5; if (map_coord_is_connected(tile, tile->base_height, face_direction)) return; @@ -379,7 +323,6 @@ void blue_reachable(rct_ride* ride, int ride_idx) **/ void ride_check_all_reachable() { -/* XXX: coordinates gleich um 5 shiften und / 4 ueberall weg */ rct_ride *ride; for (int i = 0; i < MAX_RIDES; i++) { @@ -392,8 +335,8 @@ void ride_check_all_reachable() continue; if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) { - //lightblue - blue_reachable(ride, i); + //blue + ride_is_shop_reachable(ride, i); return; } else { diff --git a/src/scenario.c b/src/scenario.c index c71abc6b55..e3137d1296 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -858,6 +858,7 @@ void scenario_update() RCT2_CALLPROC_EBPSAFE(0x0069E79A); // daily profit update RCT2_CALLPROC_EBPSAFE(0x0069C35E); // some kind of peeps days_visited update loop get_local_time(); + ride_check_all_reachable(); RCT2_CALLPROC_EBPSAFE(0x0066A13C); // objective 6 dragging if (objective_type == 10 || objective_type == 9 || objective_type == 8 || objective_type == 6 || objective_type == 5) { From 4993e6bed0c9b499934a6534a12c952d488c5e2f Mon Sep 17 00:00:00 2001 From: lnz Date: Mon, 26 May 2014 17:39:18 +0200 Subject: [PATCH 03/53] Fix lots of disgusting bugs --- src/map.c | 6 +++--- src/ride.c | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/map.c b/src/map.c index b7e1ca0ae4..ce32cde185 100644 --- a/src/map.c +++ b/src/map.c @@ -336,16 +336,16 @@ void sub_68B089() * Checks if the tile at coordinate at height counts as connected. * @return 1 if connected, 0 otherwisei */ -int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) +int map_coord_is_connected(uint16 tile_idx, uint8 height, uint8 face_direction) { - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate]; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; do { rct_map_element_path_properties props = tile->properties.path; uint8 path_type = props.type >> 2, path_dir = props.type & 3; uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; - if (!(element_type & PATH_ROAD)) + if (element_type != PATH_ROAD) continue; if (path_type & 1) { diff --git a/src/ride.c b/src/ride.c index 34cba0b8ef..8a8aba7d39 100644 --- a/src/ride.c +++ b/src/ride.c @@ -284,10 +284,10 @@ void ride_is_shop_reachable(rct_ride* ride, int ride_idx) uint8 track_type = tile->properties.track.type; ride = GET_RIDE(tile->properties.track.ride_index); - if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { // buggy but why - magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; - } else { + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { magic = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; + } else { + magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; } magic = magic << (tile->type & 3); @@ -295,18 +295,19 @@ void ride_is_shop_reachable(rct_ride* ride, int ride_idx) if (magic == 0) return; - for (int count = 0; magic != 0; ++count) { + for (int count = 0; magic != 0; ++count) { if (!(magic & 1)) { - magic >>= 1; + magic >>= 1; continue; } + magic >>= 1; uint8 face_direction = count ^ 2; y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; tile_idx = ((x << 8) | y) >> 5; - if (map_coord_is_connected(tile, tile->base_height, face_direction)) + if (map_coord_is_connected(tile_idx, tile->base_height, face_direction)) return; } @@ -337,7 +338,6 @@ void ride_check_all_reachable() if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) { //blue ride_is_shop_reachable(ride, i); - return; } else { //pink From ee67b3b7037adface5d38dc6e92e00597d543852 Mon Sep 17 00:00:00 2001 From: lnz Date: Mon, 26 May 2014 18:19:34 +0200 Subject: [PATCH 04/53] More critical bugfixes for the reachability code. --- src/ride.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ride.c b/src/ride.c index 8a8aba7d39..0110d83caa 100644 --- a/src/ride.c +++ b/src/ride.c @@ -265,13 +265,17 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) void ride_is_shop_reachable(rct_ride* ride, int ride_idx) { - uint16 coordinate = ride->station_starts[ride_idx]; + uint16 coordinate = ride->station_starts[0]; + if (coordinate == 0xFFFF) + return; + int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax uint16 magic = 0; int tile_idx = ((x << 8) | y) >> 5, count = 0; rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; + while (1) { uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; if(element_type == MAP_ELEMENT_TYPE_TRACK && tile->properties.track.ride_index == ride_idx) From 15e5a8b3cf24a075261bbb3d5b9d90276d29c1f8 Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Tue, 27 May 2014 21:55:53 +0200 Subject: [PATCH 05/53] Initial support for saving settings to config.ini Supported settings: * currency * measurement_format * temperature_format * sound_quality --- src/config.c | 146 ++++++++++++++++++++++++++++++++----------- src/config.h | 19 ++++++ src/window_options.c | 6 +- 3 files changed, 134 insertions(+), 37 deletions(-) diff --git a/src/config.c b/src/config.c index ad58991810..2db90e92f4 100644 --- a/src/config.c +++ b/src/config.c @@ -76,7 +76,7 @@ static const uint16 _defaultShortcutKeys[SHORTCUT_COUNT] = { general_configuration_t gGeneral_config; general_configuration_t gGeneral_config_default = { - 1, + 0, 1, SCREENSHOT_FORMAT_PNG, "", @@ -100,6 +100,10 @@ static void config_create_default(char *path); static int config_parse_currency(char* currency); static void config_error(char *msg); +void config_save_ini(char *path); +void config_write_ini_general(FILE *fp); +void config_write_ini_sound(FILE *fp); + /** * * rct2: 0x006E3604 @@ -189,6 +193,7 @@ void config_load() RCT2_GLOBAL(0x009AA00D, sint8) = 1; } + /** * Save configuration to the data/config.cfg file * rct2: 0x00675487 @@ -196,14 +201,116 @@ void config_load() void config_save() { FILE *fp=NULL; + char *configIniPath = osinterface_get_orct2_homefolder();; + fp = fopen(get_file_path(PATH_ID_GAMECFG), "wb"); if (fp != NULL){ fwrite(&MagicNumber, 4, 1, fp); fwrite((void*)0x009AAC5C, 2155, 1, fp); fclose(fp); } + + sprintf(configIniPath, "%s%c%s", configIniPath, osinterface_get_path_separator(), "config.ini"); + config_save_ini(configIniPath); } +void config_save_ini(char *path) +{ + FILE *fp = NULL; + + + fp = fopen(path, "wt+"); + + config_write_ini_general(fp); + config_write_ini_sound(fp); + + fclose(fp); +} + +void config_write_ini_sound(FILE *fp) +{ + fprintf(fp, "[sound]\n"); + if (gSound_config.sound_quality == SOUND_QUALITY_LOW) { + fprintf(fp, "sound_quality = low\n"); + } + else if (gSound_config.sound_quality == SOUND_QUALITY_MEDIUM) { + fprintf(fp, "sound_quality = medium\n"); + } + else{ + fprintf(fp, "sound_quality = high\n"); + } + + if (gSound_config.forced_software_buffering){ + fprintf(fp, "forced_software_buffering = true\n"); + } + else { + fprintf(fp, "forced_software_buffering = false\n"); + } +} + +void config_write_ini_general(FILE *fp) +{ + int currencyIterator = 0; + + fprintf(fp, "[general]\n"); + fprintf(fp, "game_path = %s\n", gGeneral_config.game_path); + + switch (gGeneral_config.screenshot_format) + { + case SCREENSHOT_FORMAT_BMP: + fprintf(fp, "screenshot_format = BMP\n"); + break; + case SCREENSHOT_FORMAT_PNG: + fprintf(fp, "screenshot_format = PNG\n"); + break; + default: + config_error("error saving config.ini: wrong screenshot_format"); + break; + } + + if (gGeneral_config.play_intro){ + fprintf(fp, "play_intro = true\n"); + } + else { + fprintf(fp, "play_intro = false\n"); + } + + if (gGeneral_config.confirmation_prompt){ + fprintf(fp, "confirmation_prompt = true\n"); + } + else { + fprintf(fp, "confirmation_prompt = false\n"); + } + + if (gGeneral_config.edge_scrolling){ + fprintf(fp, "edge_scrolling = true\n"); + } + else { + fprintf(fp, "edge_scrolling = false\n"); + } + + for (currencyIterator = 0; currencyIterator < countof(_currencyLookupTable); currencyIterator++) { + if (_currencyLookupTable[currencyIterator].value == gGeneral_config.currency_format) { + gGeneral_config.currency_format = _currencyLookupTable[currencyIterator].value; + fprintf(fp, "currency = %s\n", _currencyLookupTable[currencyIterator].key); + break; // There are more than one valid item for Pound, Euro and Dollar ... + } + } + + if (gGeneral_config.measurement_format == MEASUREMENT_FORMAT_IMPERIAL) { + fprintf(fp, "measurement_format = imperial\n"); + } + else { + fprintf(fp, "measurement_format = metric\n"); + } + + if (gGeneral_config.temperature_format == TEMPERATURE_FORMAT_F) { + fprintf(fp, "temperature_format = fahrenheit\n"); + } + else { + fprintf(fp, "temperature_format = celsius\n"); + } +} /** * Initilise the settings. @@ -278,8 +385,7 @@ static int config_find_rct2_path(char *resultPath) */ static void config_create_default(char *path) { - FILE* fp; - + gGeneral_config = gGeneral_config_default; if (!config_find_rct2_path(gGeneral_config.game_path)) { osinterface_show_messagebox("Unable to find RCT2 installation directory. Please select the directory where you installed RCT2!"); @@ -287,20 +393,7 @@ static void config_create_default(char *path) strcpy(gGeneral_config.game_path, res); } - fp = fopen(path, "w"); - fprintf(fp, "[general]\n"); - fprintf(fp, "game_path = %s\n", gGeneral_config.game_path); - fprintf(fp, "screenshot_format = PNG\n"); - fprintf(fp, "play_intro = false\n"); - fprintf(fp, "confirmation_prompt = true\n"); - fprintf(fp, "edge_scrolling = true\n"); - fprintf(fp, "currency = GBP\n"); - fprintf(fp, "measurement_format = imperial\n"); - fprintf(fp, "temperature_format = fahrenheit\n"); - fprintf(fp, "[sound]\n"); - fprintf(fp, "sound_quality = high\n"); - fprintf(fp, "forced_software_buffering = false\n"); - fclose(fp); + config_save_ini(path); } @@ -588,25 +681,6 @@ static int config_parse_section(FILE *fp, char *setting, char *value){ return 1; } -static const struct { char *key; int value; } _currencyLookupTable[] = { - { "GBP", CURRENCY_POUNDS }, - { "USD", CURRENCY_DOLLARS }, - { "FRF", CURRENCY_FRANC }, - { "DEM", CURRENCY_DEUTSCHMARK }, - { "YEN", CURRENCY_YEN }, - { "ESP", CURRENCY_PESETA }, - { "ITL", CURRENCY_LIRA }, - { "NLG", CURRENCY_GUILDERS }, - { "NOK", CURRENCY_KRONA }, - { "SEK", CURRENCY_KRONA }, - { "DEK", CURRENCY_KRONA }, - { "EUR", CURRENCY_EUROS }, - - { "£", CURRENCY_POUNDS }, - { "$", CURRENCY_DOLLARS }, - { "€", CURRENCY_EUROS } -}; - static int config_parse_currency(char *currency) { int i; diff --git a/src/config.h b/src/config.h index eb86ab5da2..b0b445101a 100644 --- a/src/config.h +++ b/src/config.h @@ -139,6 +139,25 @@ typedef struct general_configuration { } general_configuration_t; +static const struct { char *key; int value; } _currencyLookupTable[] = { + { "GBP", CURRENCY_POUNDS }, + { "USD", CURRENCY_DOLLARS }, + { "FRF", CURRENCY_FRANC }, + { "DEM", CURRENCY_DEUTSCHMARK }, + { "YEN", CURRENCY_YEN }, + { "ESP", CURRENCY_PESETA }, + { "ITL", CURRENCY_LIRA }, + { "NLG", CURRENCY_GUILDERS }, + { "NOK", CURRENCY_KRONA }, + { "SEK", CURRENCY_KRONA }, + { "DEK", CURRENCY_KRONA }, + { "EUR", CURRENCY_EUROS }, + + { "£", CURRENCY_POUNDS }, + { "$", CURRENCY_DOLLARS }, + { "€", CURRENCY_EUROS } +}; + //typedef struct hotkey_configuration{ //}; diff --git a/src/window_options.c b/src/window_options.c index edc4730f25..c87c5f7576 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -463,17 +463,20 @@ static void window_options_dropdown() // TODO: no clue what this does (and if it's correct) RCT2_GLOBAL(0x009AAC75, uint8) = RCT2_GLOBAL(0x009AF601 + dropdownIndex, uint8); RCT2_GLOBAL(0x009AAC76, uint8) = RCT2_GLOBAL(0x009AF604 + dropdownIndex, uint8); - + gSound_config.sound_quality = dropdownIndex; config_save(); window_invalidate(w); break; case WIDX_CURRENCY_DROPDOWN: RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CURRENCY, uint8) = dropdownIndex | 0xC0; + gGeneral_config.currency_format = dropdownIndex; config_save(); gfx_invalidate_screen(); break; case WIDX_DISTANCE_DROPDOWN: RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, uint8) = (uint8)dropdownIndex; + gGeneral_config.measurement_format = dropdownIndex; + config_save(); window_options_update_height_markers(); break; case WIDX_RESOLUTION_DROPDOWN: @@ -488,6 +491,7 @@ static void window_options_dropdown() case WIDX_TEMPERATURE_DROPDOWN: if (dropdownIndex != RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, uint8)) { RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, uint8) = (uint8)dropdownIndex; + gGeneral_config.temperature_format = dropdownIndex; config_save(); gfx_invalidate_screen(); } From 2d216ff47afe99abb3ee1036cff03b4f1dd5a087 Mon Sep 17 00:00:00 2001 From: anyc Date: Tue, 27 May 2014 23:24:09 +0200 Subject: [PATCH 06/53] better struct packing for MinGW --- CMakeLists_mingw.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists_mingw.txt b/CMakeLists_mingw.txt index df0bbfacd1..7fb25965c1 100644 --- a/CMakeLists_mingw.txt +++ b/CMakeLists_mingw.txt @@ -17,9 +17,9 @@ else() endif (APPLE) # potential flags to make code more similar to MSVC: -# -fshort-wchar -fshort-enums -mms-bitfields -fpack-struct=1 +# -fshort-wchar -fshort-enums -mms-bitfields # -set(CMAKE_C_FLAGS "-masm=intel -std=gnu99" CACHE STRING "" FORCE) +set(CMAKE_C_FLAGS "-masm=intel -std=gnu99 -fpack-struct=2" CACHE STRING "" FORCE) set(CMAKE_SHARED_LINKER_FLAGS "-static-libgcc" CACHE STRING "" FORCE) include_directories("/usr/include/wine/windows/") From 4c9c1fa5bd0f523d7c22ccacd51f7559dc0febe2 Mon Sep 17 00:00:00 2001 From: anyc Date: Tue, 27 May 2014 23:33:16 +0200 Subject: [PATCH 07/53] save_prompt actually opens save dialog --- src/game.c | 29 +++++++++++++++++++++++++++++ src/game.h | 1 + src/window_game_top_toolbar.c | 25 +------------------------ src/window_save_prompt.c | 11 ++++++----- 4 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/game.c b/src/game.c index 0a9e82f4ab..07457c0bdd 100644 --- a/src/game.c +++ b/src/game.c @@ -1597,6 +1597,35 @@ static void load_game() } } +char save_game() +{ + int eax, ebx, ecx, edx, esi, edi, ebp; + RCT2_CALLFUNC_X(0x006750E9, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + if (eax == 0) { + // user pressed "cancel" + gfx_invalidate_screen(); + return 0; + } + + char *src = (char*)0x0141EF67; + do { + src++; + } while (*src != '.' && *src != '\0'); + strcpy(src, ".SV6"); + strcpy((char*) RCT2_ADDRESS_SAVED_GAMES_PATH_2, (char*) 0x0141EF68); + + eax = 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & 8) + eax |= 1; + RCT2_CALLPROC_X(0x006754F5, eax, 0, 0, 0, 0, 0, 0); + // check success? + + game_do_command(0, 1047, 0, -1, 0, 0, 0); + gfx_invalidate_screen(); + + return 1; +} + /** * * rct2: 0x006E3879 diff --git a/src/game.h b/src/game.h index 8619d04526..4b1bd42d4c 100644 --- a/src/game.h +++ b/src/game.h @@ -29,5 +29,6 @@ int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int eb void game_load_or_quit_no_save_prompt(); int game_load_save(); +char save_game(); #endif diff --git a/src/window_game_top_toolbar.c b/src/window_game_top_toolbar.c index 5346a67b6f..2f91c6c122 100644 --- a/src/window_game_top_toolbar.c +++ b/src/window_game_top_toolbar.c @@ -384,30 +384,7 @@ static void window_game_top_toolbar_dropdown() break; case 1: // save game tool_cancel(); - { - int eax, ebx, ecx, edx, esi, edi, ebp; - RCT2_CALLFUNC_X(0x006750E9, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - if (eax == 0) { - gfx_invalidate_screen(); - break; - } - - char *src = (char*)0x0141EF67; - do { - src++; - } while (*src != '.' && *src != '\0'); - strcpy(src, ".SV6"); - strcpy((char*) RCT2_ADDRESS_SAVED_GAMES_PATH_2, (char*) 0x0141EF68); - - eax = 0; - if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & 8) - eax |= 1; - RCT2_CALLPROC_X(0x006754F5, eax, 0, 0, 0, 0, 0, 0); - // check success? - - game_do_command(0, 1047, 0, -1, 0, 0, 0); - gfx_invalidate_screen(); - } + save_game(); break; case 3: // about window_about_open(); diff --git a/src/window_save_prompt.c b/src/window_save_prompt.c index a941875889..52413e3cd5 100644 --- a/src/window_save_prompt.c +++ b/src/window_save_prompt.c @@ -257,11 +257,12 @@ static void window_save_prompt_mouseup() } else { switch (widgetIndex) { case WIDX_SAVE: - // TODO to avoid data loss, treat SAVE as CANCEL - RCT2_ERROR("TODO"); - window_close(w); - window_save_prompt_close(); - return; + if (!save_game()) { + // user pressed cancel + window_close(w); + window_save_prompt_close(); + return; + } break; case WIDX_DONT_SAVE: break; From cc85e93e9e1ed82bc38ceb239e3df6d639d2f705 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 28 May 2014 00:05:11 +0100 Subject: [PATCH 08/53] add initial s6 structure --- src/scenario.h | 277 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) diff --git a/src/scenario.h b/src/scenario.h index cb3822c147..4ab1e2d2b2 100644 --- a/src/scenario.h +++ b/src/scenario.h @@ -83,6 +83,283 @@ typedef struct { char completed_by[64]; // 0x0270 } rct_scenario_basic; +/* This will be useful for backwards compatibility +typedef struct { + // SC6[0] + rct_s6_header header; + + // SC6[1] + rct_s6_info info; + + // SC6[2] + // packed objects + + // SC6[3] + rct_object_entry objects[721]; + + // SC6[4] + uint16 elapsed_months; + uint16 current_day; + uint32 dword_F663AC; + uint32 scenario_srand_0; + uint32 scenario_srand_1; + + // SC6[5] + rct_map_element map_elements[0x30000]; + + // SC6[6] + uint32 dword_010E63B8; + rct_sprite sprites[10000]; + uint16 sprites_next_index; + uint16 sprites_start_vehicle; + uint16 sprites_start_peep; + uint16 sprites_start_textfx; + uint16 sprites_start_litter; + uint8 pad_013573C6[2]; + uint16 word_013573C8; + uint8 pad_013573CA[4]; + uint16 word_013573CE; + uint16 word_013573D0; + uint8 pad_013573D2[2]; + uint16 word_013573D4; + uint8 pad_013573D6[4]; + uint32 dword_013573D8; + uint32 dword_013573DC; + money32 current_loan; + uint32 park_flags; + money16 park_entrance_fee; + uint16 word_013573EA; + uint16 word_013573EC; + uint8 pad_013573EE[16]; + uint8 byte_013573F0; + uint8 pad_013573F1[2]; + rct2_peep_spawn peep_spawns[2]; + uint8 guest_count_change_modifier; + uint8 byte_013573FF; + uint8 pad_01357400[4]; + uint32 dword_01357404; + uint32 dword_01357408; + uint32 dword_0135740C; + uint32 dword_01357410[5]; + uint32 dword_01357424[8]; + uint32 dword_01357444[128]; + uint32 dword_01357644[128]; + + // SC6[7] + uint16 guests_in_park; + uint16 guests_heading_for_park; + + // Ignored in scenario + money32 expenditure_table[14]; + uint32 dword_01357880[5]; + uint32 dword_01357894; + uint32 dword_01357898; + uint32 dword_0135789C; + uint32 dword_013578A0; + uint32 dword_013578A4[201]; + + // SC6[8] + uint16 last_guests_in_park; + uint8 pad_01357BCA[3]; + uint8 handyman_colour; + uint8 mechanic_colour; + uint8 security_colour; + + // Ignored in scenario + uint32 dword_01357BD0[56]; + + // SC6[9] + uint16 park_rating; + + // Ignored in scenario + uint8 park_rating_history[32]; + uint8 guests_in_park_history[32]; + + // SC6[10] + uint16 word_01357CF2; + uint32 word_01357CF4; + uint8 byte_01357CF8[1000]; + uint32 dword_013580E0[32]; + uint16 word_013580E4[16]; + uint8 byte_013580E6; + uint8 byte_013580E7; + uint8 byte_013580E8; + uint8 byte_013580E9; + uint16 park_size; + uint16 guest_generation_probability; + uint16 total_ride_value; + uint32 dword_013580F0; + uint16 dword_013580F4; + uint8 dword_013580F6; + uint8 dword_013580F7; + uint8 objective_type; + uint8 objective_year; + uint8 pad_013580FA[4]; + money32 objective_currency; + uint16 objective_guests; + uint8 campaign_weeks_left[20]; + uint8 campaign_ride_index[22]; + + // Ignored in scenario + money32 balance_history[128]; + + // SC6[11] + uint32 dword_0135832C; + uint32 current_profit; + uint32 dword_01358334; + uint16 word_01358338; + uint8 pad_0135833A[2]; + + // Ignored in scenario + uint8 pad_0135833C[2]; + money32 park_value; + money32 park_value_history[128]; + + // SC6[12] + money32 completed_company_value; + uint32 total_admissions; + money32 income_from_admissions; + money32 company_value; + uint8 byte_01358750[16]; + rct_award awards[4]; + uint16 word_01358770; + uint16 word_01358772; + uint16 word_01358774; + uint8 pad_01358776[4]; + uint32 dword_01358778[17]; + uint32 dword_013587BC; + uint32 dword_013587C0; + uint32 dword_013587C4; + uint16 dword_013587C8; + uint8 pad_013587CA[16]; + uint32 dword_013587D0; + uint8 pad_013587D4[8]; + uint16 word_013587D8[16]; + money32 cash; + uint8 pad_013587FC[50]; + uint16 word_0135882E; + uint16 word_01358830; + uint16 word_01358832; + uint16 map_size; + uint16 word_01358836; + uint32 word_01358838; + uint16 suggested_max_guests; + uint16 word_0135883E; + uint8 word_01358840; + uint8 word_01358841; + uint8 pad_01358842[4]; + uint32 dword_01358844; + uint8 pad_01358848; + uint32 dword_01358849; + uint8 pad_0135884D[2]; + uint8 dword_0135884E[622]; + uint8 pad_01359206[2]; + uint16 word_01359208; + char scenario_name[64]; + char scenario_description[255]; + uint8 byte_01359349; + uint8 byte_0135934A; + uint8 pad_0135934B[3]; + uint32 dword_0135934C; + uint16 park_entrance_x[4]; + uint16 park_entrance_y[4]; + uint16 park_entrance_z[4]; + uint8 byte_01359368; + uint8 pad_01359369[3]; + uint8 byte_0135936C[256]; + uint8 byte_0135946C[3256]; + uint8 byte_0135A124; + uint8 byte_0135A125; + uint16 word_0135A126; + uint8 byte_0135A128; + uint8 byte_0135A129; + uint8 byte_0135A12A; + uint8 byte_0135A12B[793]; + uint8 byte_0135A444[1200]; + char custom_strings[0x8000]; + uint32 game_ticks_1; + rct_ride rides[255]; + uint16 word_01388698; + uint16 saved_view_x; + uint16 saved_view_y; + uint16 saved_view_zoom_and_rotation; + uint8 byte_013886A0[6000]; + uint8 byte_01389E10[6000]; + uint16 word_0138B580; + uint8 pad_0138B580[2]; + uint16 word_0138B584; + uint16 word_0138B586; + uint16 word_0138B588; + uint16 word_0138B58A; + uint16 word_0138B58C; + uint16 word_0138B58E; + uint8 byte_0138B590; + uint8 byte_0138B591; + uint8 byte_0138B592; + uint8 byte_0138B593; + uint16 word_0138B594; + uint16 word_0138B596; + uint16 word_0138B598; + uint16 word_0138B59A; + uint16 word_0138B59C; + uint16 word_0138B59E; + uint16 word_0138B5A0; + uint16 word_0138B5A2; + uint16 word_0138B5A4; + uint16 word_0138B5A6; + uint16 word_0138B5A8; + uint16 word_0138B5AA; + uint16 word_0138B5AC; + uint16 word_0138B5AE; + uint16 word_0138B5B0; + uint16 word_0138B5B2; + uint16 word_0138B5B4; + uint16 word_0138B5B6; + uint16 word_0138B5B8; + uint16 word_0138B5BA; + uint16 word_0138B5BC; + uint16 word_0138B5BE; + uint16 word_0138B5C0; + uint16 word_0138B5C2; + uint16 word_0138B5C4; + uint16 word_0138B5C6; + uint16 word_0138B5C8; + uint16 word_0138B5CA; + uint16 word_0138B5CC; + uint16 word_0138B5CE[31]; + uint8 ride_measurements[0x25860]; + uint32 dword_13B0E6C; + uint16 word_13B0E70; + uint32 dword_13B0E72[0x6600]; + uint8 byte_13CA672[116]; + uint8 byte_13CA6E6[84]; + uint8 byte_13CA73A[4]; + uint8 unk_13CA73E; + uint8 pad_13CA73E; + uint8 byte_13CA740; + uint8 byte_13CA741; + uint8 byte_13CA7424[4]; + uint8 climate; + uint8 pad_013CA747; + uint16 climate_update_timer; + uint8 current_weather; + uint8 next_weather; + uint8 temperature; + uint8 next_temperature; + uint8 current_weather_effect; + uint8 next_weather_effect; + uint8 current_weather_gloom; + uint8 next_weather_gloom; + uint8 current_rain_level; + uint8 next_rain_level; + rct_news_item news_items[61]; + uint8 byte_13CE730[64]; + uint32 dword_13CE770; + uint16 word_13CE774; + uint16 word_13CE776[217]; +} rct_s6_data; +*/ + enum { SCENARIO_FLAGS_VISIBLE = (1 << 0), SCENARIO_FLAGS_COMPLETED = (1 << 1), From d8a61d97921971c6ae30a57c69f40e05df07a00e Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 28 May 2014 01:50:50 +0100 Subject: [PATCH 09/53] fix award window bug and clean reset history --- src/award.c | 7 +++++++ src/award.h | 1 + src/finance.c | 9 +++++++++ src/finance.h | 1 + src/park.c | 19 ++++--------------- src/park.h | 2 +- src/scenario.c | 4 +++- src/window_park.c | 4 ++-- 8 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/award.c b/src/award.c index 12084559ca..25c843ddd9 100644 --- a/src/award.c +++ b/src/award.c @@ -568,6 +568,13 @@ static int award_is_deserved(int awardType, int activeAwardTypes) #pragma endregion +void award_reset() +{ + int i; + for (i = 0; i < MAX_AWARDS; i++) + RCT2_ADDRESS(RCT2_ADDRESS_AWARD_LIST, rct_award)[i].time = 0; +} + /** * * rct2: 0x0066A86C diff --git a/src/award.h b/src/award.h index 26074cdaa8..aba8cb9456 100644 --- a/src/award.h +++ b/src/award.h @@ -52,6 +52,7 @@ enum { #define MAX_AWARDS 4 int award_is_positive(int type); +void award_reset(); void award_update_all(); #endif \ No newline at end of file diff --git a/src/finance.c b/src/finance.c index f61def04c4..a900c9ec82 100644 --- a/src/finance.c +++ b/src/finance.c @@ -137,6 +137,15 @@ void finance_pay_ride_upkeep() } } +void finance_reset_history() +{ + int i; + for (i = 0; i < 128; i++) { + RCT2_ADDRESS(RCT2_ADDRESS_BALANCE_HISTORY, money32)[i] = MONEY32_UNDEFINED; + RCT2_ADDRESS(RCT2_ADDRESS_WEEKLY_PROFIT_HISTORY, money32)[i] = MONEY32_UNDEFINED; + RCT2_ADDRESS(RCT2_ADDRESS_PARK_VALUE_HISTORY, money32)[i] = MONEY32_UNDEFINED; + } +} /** * diff --git a/src/finance.h b/src/finance.h index fb63ae127f..ace3b157ae 100644 --- a/src/finance.h +++ b/src/finance.h @@ -38,6 +38,7 @@ void finance_pay_wages(); void finance_pay_research(); void finance_pay_interest(); void finance_pay_ride_upkeep(); +void finance_reset_history(); void finance_init(); void sub_69E869(); diff --git a/src/park.c b/src/park.c index e007cb335c..e897bf3eb4 100644 --- a/src/park.c +++ b/src/park.c @@ -104,7 +104,9 @@ void park_init() RCT2_GLOBAL(0x01358772, uint16) = 400; RCT2_GLOBAL(0x01358774, uint16) = 0; RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) = PARK_FLAGS_11 | PARK_FLAGS_SHOW_REAL_GUEST_NAMES; - park_reset_awards_and_history(); + park_reset_history(); + finance_reset_history(); + award_reset(); rct_s6_info *info = (rct_s6_info*)0x0141F570; info->name[0] = '\0'; @@ -115,26 +117,13 @@ void park_init() * * rct2: 0x0066729F */ -void park_reset_awards_and_history() +void park_reset_history() { int i; - - // Reset park rating and guests in park history for (i = 0; i < 32; i++) { RCT2_ADDRESS(RCT2_ADDRESS_PARK_RATING_HISTORY, uint8)[i] = 255; RCT2_ADDRESS(RCT2_ADDRESS_GUESTS_IN_PARK_HISTORY, uint8)[i] = 255; } - - // Reset finance history - for (i = 0; i < 128; i++) { - RCT2_ADDRESS(RCT2_ADDRESS_BALANCE_HISTORY, money32)[i] = MONEY32_UNDEFINED; - RCT2_ADDRESS(RCT2_ADDRESS_WEEKLY_PROFIT_HISTORY, money32)[i] = MONEY32_UNDEFINED; - RCT2_ADDRESS(RCT2_ADDRESS_PARK_VALUE_HISTORY, money32)[i] = MONEY32_UNDEFINED; - } - - // Reset awards - for (i = 0; i < 4; i++) - RCT2_ADDRESS(RCT2_ADDRESS_AWARD_LIST, rct_award)[i].time = 0; } /** diff --git a/src/park.h b/src/park.h index 8908e4a31f..12808a50c3 100644 --- a/src/park.h +++ b/src/park.h @@ -45,7 +45,7 @@ enum { int park_is_open(); void park_init(); -void park_reset_awards_and_history(); +void park_reset_history(); int park_calculate_size(); int calculate_park_rating(); diff --git a/src/scenario.c b/src/scenario.c index dbdd382f1e..7d0957031b 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -279,7 +279,9 @@ void scenario_load_and_play(const rct_scenario_basic *scenario) RCT2_GLOBAL(RCT2_ADDRESS_INCOME_FROM_ADMISSIONS, uint32) = 0; RCT2_GLOBAL(0x013587D8, uint16) = 63; sub_69E869(); // (loan related, called above already) - park_reset_awards_and_history(); + park_reset_history(); + finance_reset_history(); + award_reset(); reset_all_ride_build_dates(); date_reset(); RCT2_CALLPROC_EBPSAFE(0x00674576); diff --git a/src/window_park.c b/src/window_park.c index d2057e99ad..9899bda5bf 100644 --- a/src/window_park.c +++ b/src/window_park.c @@ -2259,13 +2259,13 @@ static void window_park_awards_paint() y = w->y + window_park_awards_widgets[WIDX_PAGE_BACKGROUND].top + 4; count = 0; - for (i = 0; i < 4; i++) { + for (i = 0; i < MAX_AWARDS; i++) { award = &RCT2_ADDRESS(RCT2_ADDRESS_AWARD_LIST, rct_award)[i]; if (award->time == 0) continue; gfx_draw_sprite(dpi, SPR_AWARD_MOST_UNTIDY + award->type, x, y); - gfx_draw_string_left_wrapped(dpi, NULL, x + 34, y + 6, 180, STR_AWARD_MOST_UNTIDY, 0); + gfx_draw_string_left_wrapped(dpi, NULL, x + 34, y + 6, 180, STR_AWARD_MOST_UNTIDY + award->type, 0); y += 32; count++; From c89cd803f66463c4a3d50537f2d2b6aee07d2c7e Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Wed, 28 May 2014 09:56:49 +0200 Subject: [PATCH 10/53] edge_scrolling and forced_software_buffering can now be edited ingame. * edge_scrolling * forced_software_buffering --- src/window_options.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/window_options.c b/src/window_options.c index c87c5f7576..4fe88b75d0 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -223,6 +223,7 @@ static void window_options_mouseup() break; case WIDX_SCREEN_EDGE_SCROLLING: RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_EDGE_SCROLLING, uint8) ^= 1; + gGeneral_config.edge_scrolling ^= 1; config_save(); window_invalidate(w); break; @@ -271,6 +272,7 @@ static void window_options_mouseup() case WIDX_SOUND_SW_BUFFER_CHECKBOX: pause_sounds(); RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, uint8) ^= 1; + gSound_config.forced_software_buffering ^= 1; config_save(); unpause_sounds(); window_invalidate(w); From 0e6e11798bdb6b55c2bfc1db138f0d4a781a69b7 Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Wed, 28 May 2014 10:36:55 +0200 Subject: [PATCH 11/53] New setting: always_show_gridlines. --- src/config.c | 44 ++++++++++++++++++++++++++++++++++---------- src/config.h | 2 +- src/window_options.c | 2 ++ 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/config.c b/src/config.c index 2db90e92f4..f79357266f 100644 --- a/src/config.c +++ b/src/config.c @@ -76,15 +76,16 @@ static const uint16 _defaultShortcutKeys[SHORTCUT_COUNT] = { general_configuration_t gGeneral_config; general_configuration_t gGeneral_config_default = { - 0, - 1, - SCREENSHOT_FORMAT_PNG, - "", - MEASUREMENT_FORMAT_IMPERIAL, - TEMPERATURE_FORMAT_F, - 0, - 0, - 1, + 0, // play_intro + 1, // confirmation_prompt + SCREENSHOT_FORMAT_PNG, // screenshot_format + "", // game_path + MEASUREMENT_FORMAT_IMPERIAL, // measurement_format + TEMPERATURE_FORMAT_F, // temperature_format + CURRENCY_POUNDS, // currency_format + 0, // construction_marker_colour + 1, // edge_scrolling + 0, // always_show_gridlines }; sound_configuration_t gSound_config; @@ -140,6 +141,15 @@ void config_load() RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, sint8) = gGeneral_config.measurement_format; RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, sint8) = gGeneral_config.temperature_format; + // always show gridlines + if (gGeneral_config.always_show_gridlines){ + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES; + } + else { + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &= !CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES; + } + + //sound configuration RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_QUALITY, sint8) = gSound_config.sound_quality; @@ -310,6 +320,13 @@ void config_write_ini_general(FILE *fp) else { fprintf(fp, "temperature_format = celsius\n"); } + + if (gGeneral_config.always_show_gridlines){ + fprintf(fp, "always_show_gridlines = true\n"); + } + else { + fprintf(fp, "always_show_gridlines = false\n"); + } } /** @@ -508,7 +525,14 @@ static void config_general(char *setting, char *value){ else if (strcmp(setting, "currency") == 0){ config_parse_currency(value); } - + else if (strcmp(setting, "always_show_gridlines") == 0){ + if (strcmp(value, "true") == 0){ + gGeneral_config.always_show_gridlines = 1; + } + else { + gGeneral_config.always_show_gridlines = 0; + } + } } /** diff --git a/src/config.h b/src/config.h index b0b445101a..44079612d4 100644 --- a/src/config.h +++ b/src/config.h @@ -136,7 +136,7 @@ typedef struct general_configuration { sint8 currency_format; sint8 construction_marker_colour; sint8 edge_scrolling; - + sint8 always_show_gridlines; } general_configuration_t; static const struct { char *key; int value; } _currencyLookupTable[] = { diff --git a/src/window_options.c b/src/window_options.c index 4fe88b75d0..48175172cf 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -254,6 +254,8 @@ static void window_options_mouseup() break; case WIDX_GRIDLINES_CHECKBOX: RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) ^= CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES; + gGeneral_config.always_show_gridlines = RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) + & CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES; config_save(); gfx_invalidate_screen(); From fe9757acfff9b691f9667443083dcdfe17dfa0b3 Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Wed, 28 May 2014 17:39:58 +0900 Subject: [PATCH 12/53] add note about debugging routines --- src/window_game_top_toolbar.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/window_game_top_toolbar.c b/src/window_game_top_toolbar.c index 2f91c6c122..5fd19964d2 100644 --- a/src/window_game_top_toolbar.c +++ b/src/window_game_top_toolbar.c @@ -166,6 +166,11 @@ static void window_game_top_toolbar_mouseup() game_do_command(0, 1, 0, 0, 2, 0, 0); break; case WIDX_FASTFORWARD: + // This is an excellent place to add in debugging statements and + // print routines, that will be triggered when you press the + // button in the game. Use "git update-index --skip-worktree + // src/window_game_top_toolbar" to avoid committing these changes to + // version control. window_cheats_open(); break; From 098fe08fdf830c82e78a017924b98ce567607572 Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Wed, 28 May 2014 10:55:35 +0200 Subject: [PATCH 13/53] New setting: landscape_smoothing --- src/config.c | 24 ++++++++++++++++++++++++ src/config.h | 1 + src/window_options.c | 2 ++ 3 files changed, 27 insertions(+) diff --git a/src/config.c b/src/config.c index f79357266f..ea93527872 100644 --- a/src/config.c +++ b/src/config.c @@ -86,6 +86,7 @@ general_configuration_t gGeneral_config_default = { 0, // construction_marker_colour 1, // edge_scrolling 0, // always_show_gridlines + 1, // landscape_smoothing }; sound_configuration_t gSound_config; @@ -148,6 +149,14 @@ void config_load() else { RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &= !CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES; } + + // landscape smoothing + if (!gGeneral_config.landscape_smoothing){ + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= CONFIG_FLAG_DISABLE_SMOOTH_LANDSCAPE; + } + else { + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &= !CONFIG_FLAG_DISABLE_SMOOTH_LANDSCAPE; + } @@ -327,6 +336,13 @@ void config_write_ini_general(FILE *fp) else { fprintf(fp, "always_show_gridlines = false\n"); } + + if (gGeneral_config.landscape_smoothing){ + fprintf(fp, "landscape_smoothing = true\n"); + } + else { + fprintf(fp, "landscape_smoothing = false\n"); + } } /** @@ -533,6 +549,14 @@ static void config_general(char *setting, char *value){ gGeneral_config.always_show_gridlines = 0; } } + else if (strcmp(setting, "landscape_smoothing") == 0){ + if (strcmp(value, "true") == 0){ + gGeneral_config.landscape_smoothing = 1; + } + else { + gGeneral_config.landscape_smoothing = 0; + } + } } /** diff --git a/src/config.h b/src/config.h index 44079612d4..9bdb7d6f4c 100644 --- a/src/config.h +++ b/src/config.h @@ -137,6 +137,7 @@ typedef struct general_configuration { sint8 construction_marker_colour; sint8 edge_scrolling; sint8 always_show_gridlines; + sint8 landscape_smoothing; } general_configuration_t; static const struct { char *key; int value; } _currencyLookupTable[] = { diff --git a/src/window_options.c b/src/window_options.c index 48175172cf..26f8d4d1d0 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -249,6 +249,8 @@ static void window_options_mouseup() break; case WIDX_TILE_SMOOTHING_CHECKBOX: RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) ^= CONFIG_FLAG_DISABLE_SMOOTH_LANDSCAPE; + gGeneral_config.landscape_smoothing = !(RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) + & CONFIG_FLAG_DISABLE_SMOOTH_LANDSCAPE); config_save(); gfx_invalidate_screen(); break; From 4ae98b18e6865d3456dee958bb98c901a2cd4d30 Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Wed, 28 May 2014 11:12:12 +0200 Subject: [PATCH 14/53] New setting: show_height_as_units --- src/config.c | 24 +++++++++++++++++++++++- src/config.h | 1 + src/window_options.c | 7 +++++-- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/config.c b/src/config.c index ea93527872..e038dc3cab 100644 --- a/src/config.c +++ b/src/config.c @@ -87,6 +87,7 @@ general_configuration_t gGeneral_config_default = { 1, // edge_scrolling 0, // always_show_gridlines 1, // landscape_smoothing + 0, // show_height_as_units }; sound_configuration_t gSound_config; @@ -158,7 +159,13 @@ void config_load() RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &= !CONFIG_FLAG_DISABLE_SMOOTH_LANDSCAPE; } - + // show height as units + if (gGeneral_config.show_height_as_units){ + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS; + } + else { + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &= !CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS; + } //sound configuration RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_QUALITY, sint8) = gSound_config.sound_quality; @@ -343,6 +350,13 @@ void config_write_ini_general(FILE *fp) else { fprintf(fp, "landscape_smoothing = false\n"); } + + if (gGeneral_config.show_height_as_units){ + fprintf(fp, "show_height_as_units = true\n"); + } + else { + fprintf(fp, "show_height_as_units = false\n"); + } } /** @@ -557,6 +571,14 @@ static void config_general(char *setting, char *value){ gGeneral_config.landscape_smoothing = 0; } } + else if (strcmp(setting, "show_height_as_units") == 0){ + if (strcmp(value, "true") == 0){ + gGeneral_config.show_height_as_units = 1; + } + else { + gGeneral_config.show_height_as_units = 0; + } + } } /** diff --git a/src/config.h b/src/config.h index 9bdb7d6f4c..be7d72c473 100644 --- a/src/config.h +++ b/src/config.h @@ -138,6 +138,7 @@ typedef struct general_configuration { sint8 edge_scrolling; sint8 always_show_gridlines; sint8 landscape_smoothing; + sint8 show_height_as_units; } general_configuration_t; static const struct { char *key; int value; } _currencyLookupTable[] = { diff --git a/src/window_options.c b/src/window_options.c index 26f8d4d1d0..9aaf38e397 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -451,9 +451,12 @@ static void window_options_dropdown() case WIDX_HEIGHT_LABELS_DROPDOWN: // reset flag and set it to 1 if height as units is selected RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &= ~CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS; + gGeneral_config.show_height_as_units = 0; - if (dropdownIndex == 0) - RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS; + if (dropdownIndex == 0) { + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS; + gGeneral_config.show_height_as_units = 1; + } window_options_update_height_markers(); break; From d8b735a1ef81af70c125a14f9fb694c8ee600e2b Mon Sep 17 00:00:00 2001 From: atmaxinger Date: Wed, 28 May 2014 11:19:49 +0200 Subject: [PATCH 15/53] New setting: save_plugin_data --- src/config.c | 24 ++++++++++++++++++++++++ src/config.h | 1 + src/window_options.c | 2 ++ 3 files changed, 27 insertions(+) diff --git a/src/config.c b/src/config.c index e038dc3cab..41551d94a5 100644 --- a/src/config.c +++ b/src/config.c @@ -88,6 +88,7 @@ general_configuration_t gGeneral_config_default = { 0, // always_show_gridlines 1, // landscape_smoothing 0, // show_height_as_units + 1, // save_plugin_data }; sound_configuration_t gSound_config; @@ -167,6 +168,14 @@ void config_load() RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &= !CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS; } + // save plugin data + if (gGeneral_config.save_plugin_data){ + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= CONFIG_FLAG_SAVE_PLUGIN_DATA; + } + else { + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &= !CONFIG_FLAG_SAVE_PLUGIN_DATA; + } + //sound configuration RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_QUALITY, sint8) = gSound_config.sound_quality; RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, sint8) = gSound_config.forced_software_buffering; @@ -357,6 +366,13 @@ void config_write_ini_general(FILE *fp) else { fprintf(fp, "show_height_as_units = false\n"); } + + if (gGeneral_config.save_plugin_data){ + fprintf(fp, "save_plugin_data = true\n"); + } + else { + fprintf(fp, "save_plugin_data = false\n"); + } } /** @@ -579,6 +595,14 @@ static void config_general(char *setting, char *value){ gGeneral_config.show_height_as_units = 0; } } + else if (strcmp(setting, "save_plugin_data") == 0){ + if (strcmp(value, "true") == 0){ + gGeneral_config.save_plugin_data = 1; + } + else { + gGeneral_config.save_plugin_data = 0; + } + } } /** diff --git a/src/config.h b/src/config.h index be7d72c473..6e43a04b4e 100644 --- a/src/config.h +++ b/src/config.h @@ -139,6 +139,7 @@ typedef struct general_configuration { sint8 always_show_gridlines; sint8 landscape_smoothing; sint8 show_height_as_units; + sint8 save_plugin_data; } general_configuration_t; static const struct { char *key; int value; } _currencyLookupTable[] = { diff --git a/src/window_options.c b/src/window_options.c index 9aaf38e397..5a0646be66 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -270,6 +270,8 @@ static void window_options_mouseup() break; case WIDX_SAVE_PLUGIN_DATA_CHECKBOX: RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) ^= CONFIG_FLAG_SAVE_PLUGIN_DATA; + gGeneral_config.save_plugin_data = !(RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) + & CONFIG_FLAG_SAVE_PLUGIN_DATA); config_save(); window_invalidate(w); break; From dee0c6c730f48e2a98910b8b6d2e289ceedf0547 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 28 May 2014 16:06:04 +0100 Subject: [PATCH 16/53] fix warnings --- src/window_options.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/window_options.c b/src/window_options.c index 5a0646be66..fa0824904e 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -474,19 +474,19 @@ static void window_options_dropdown() // TODO: no clue what this does (and if it's correct) RCT2_GLOBAL(0x009AAC75, uint8) = RCT2_GLOBAL(0x009AF601 + dropdownIndex, uint8); RCT2_GLOBAL(0x009AAC76, uint8) = RCT2_GLOBAL(0x009AF604 + dropdownIndex, uint8); - gSound_config.sound_quality = dropdownIndex; + gSound_config.sound_quality = (sint8)dropdownIndex; config_save(); window_invalidate(w); break; case WIDX_CURRENCY_DROPDOWN: RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CURRENCY, uint8) = dropdownIndex | 0xC0; - gGeneral_config.currency_format = dropdownIndex; + gGeneral_config.currency_format = (sint8)dropdownIndex; config_save(); gfx_invalidate_screen(); break; case WIDX_DISTANCE_DROPDOWN: RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, uint8) = (uint8)dropdownIndex; - gGeneral_config.measurement_format = dropdownIndex; + gGeneral_config.measurement_format = (sint8)dropdownIndex; config_save(); window_options_update_height_markers(); break; @@ -502,7 +502,7 @@ static void window_options_dropdown() case WIDX_TEMPERATURE_DROPDOWN: if (dropdownIndex != RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, uint8)) { RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, uint8) = (uint8)dropdownIndex; - gGeneral_config.temperature_format = dropdownIndex; + gGeneral_config.temperature_format = (sint8)dropdownIndex; config_save(); gfx_invalidate_screen(); } From e489b999f3fb9085ec00f27ebfa5d23223059e21 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 28 May 2014 18:11:33 +0100 Subject: [PATCH 17/53] fix picked-up staff and rain drawing --- src/addresses.h | 4 ++++ src/game.c | 41 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 6b3c87e294..fa8640de7d 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -111,6 +111,10 @@ #define RCT2_ADDRESS_CURRENT_TOOL 0x009DE545 #define RCT2_ADDRESS_TOOL_WIDGETINDEX 0x009DE546 +#define RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE 0x009DE550 +#define RCT2_ADDRESS_PICKEDUP_PEEP_X 0x009DE554 +#define RCT2_ADDRESS_PICKEDUP_PEEP_Y 0x009DE556 + #define RCT2_ADDRESS_CURSOR_OVER_WINDOWCLASS 0x009DE55C #define RCT2_ADDRESS_CURSOR_OVER_WINDOWNUMBER 0x009DE55E #define RCT2_ADDRESS_CURSOR_OVER_WIDGETINDEX 0x009DE560 diff --git a/src/game.c b/src/game.c index 07457c0bdd..ad4b94ed32 100644 --- a/src/game.c +++ b/src/game.c @@ -59,10 +59,47 @@ void game_create_windows() RCT2_CALLPROC_EBPSAFE(0x0066B905); } +/** + * + * rct2: 0x006838BD + */ +void update_water_animation() +{ + RCT2_CALLPROC_EBPSAFE(0x006838BD); +} + +/** + * + * rct2: 0x00684218 + */ +void update_rain_animation() +{ + if (RCT2_GLOBAL(0x009ABDF2, uint8) == 0) + return; + + // Draw picked-up peep + if (RCT2_GLOBAL(0x009DE550, uint32) != 0xFFFFFFFF) { + gfx_draw_sprite( + (rct_drawpixelinfo*)RCT2_ADDRESS_SCREEN_DPI, + RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, uint32), + RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_X, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_Y, sint16) + ); + } + + // Get rain draw function and draw rain + uint32 eax = RCT2_ADDRESS(0x009AC058, uint32)[RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RAIN_LEVEL, uint8)]; + if (eax != 0xFFFFFFFF && !(RCT2_GLOBAL(0x009DEA6F, uint8) & 1)) + RCT2_CALLPROC_X(0x00684266, eax, 0, 0, 0, 0, 0, 0); +} + void game_update() { int eax, tmp; + // Handles picked-up peep and rain redraw + RCT2_CALLPROC_EBPSAFE(0x006843DC); + // 0x006E3AEC // screen_game_process_mouse_input(); // RCT2_CALLPROC_EBPSAFE(0x006E3AEC); // screen_game_process_keyboard_input(); screenshot_check(); @@ -124,8 +161,8 @@ void game_update() RCT2_GLOBAL(0x0141F568, uint8) = RCT2_GLOBAL(0x0013CA740, uint8); game_handle_input(); - RCT2_CALLPROC_EBPSAFE(0x006838BD); - RCT2_CALLPROC_EBPSAFE(0x00684218); + update_water_animation(); + update_rain_animation(); if (RCT2_GLOBAL(0x009AAC73, uint8) != 255) { RCT2_GLOBAL(0x009AAC73, uint8)++; From 7dc750bd554f316c343a01f05a6804a13e31a82e Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 28 May 2014 22:22:09 +0100 Subject: [PATCH 18/53] Switched to cdecl for mouse down. --- src/game.c | 32 ++++++++++++++++++++- src/gfx.h | 2 +- src/window_banner.c | 8 +++--- src/window_footpath.c | 27 ++---------------- src/window_game_top_toolbar.c | 26 ++--------------- src/window_guest_list.c | 27 ++---------------- src/window_land.c | 26 ++--------------- src/window_map.c | 4 +-- src/window_options.c | 20 ++------------ src/window_park.c | 46 +++---------------------------- src/window_ride_list.c | 26 ++--------------- src/window_title_menu.c | 27 ++---------------- src/window_title_scenarioselect.c | 20 ++------------ 13 files changed, 58 insertions(+), 233 deletions(-) diff --git a/src/game.c b/src/game.c index ad4b94ed32..e9fea477da 100644 --- a/src/game.c +++ b/src/game.c @@ -654,6 +654,36 @@ static void input_mouseover_widget_flatbutton_invalidate() widget_invalidate(RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WINDOWCLASS, rct_windowclass), RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WINDOWNUMBER, rct_windownumber), RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WIDGETINDEX, rct_windownumber)); } +static void RCT2_CALLPROC_WE_MOUSE_DOWN(int address, int widgetIndex, rct_window*w, rct_widget* widget ) +{ +#ifdef _MSC_VER + __asm { + push address + push widget + push w + push widgetIndex + mov edi, widget + mov edx, widgetIndex + mov esi, w + call[esp + 12] + add esp, 16 + } +#else + __asm__("\ + push %[address]\n\ + mov edx, widgetIndex \n\ + mov edi, widget + mov eax, %[w] \n\ + push edx \n\ + push eax \n\ + push edi \n\ + mov esi, %[w] \n\ + call [esp+12] \n\ + add esp, 16 \n\ + " :[address] "+m" (address), [w] "+m" (w) : : "eax", "esi"); +#endif +} + /** * * rct2: 0x006E95F9 @@ -803,7 +833,7 @@ static void input_leftmousedown(int x, int y, rct_window *w, int widgetIndex) RCT2_GLOBAL(0x009DE528, uint16) = 1; widget_invalidate(windowClass, windowNumber, widgetIndex); - RCT2_CALLPROC_X(w->event_handlers[WE_MOUSE_DOWN], 0, 0, 0, widgetIndex, (int)w, (int)widget, 0); + RCT2_CALLPROC_WE_MOUSE_DOWN(w->event_handlers[WE_MOUSE_DOWN], widgetIndex, w, widget); break; } } diff --git a/src/gfx.h b/src/gfx.h index 395543b662..b266ea3dc2 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -31,7 +31,7 @@ typedef struct { short width; // 0x08 short height; // 0x0A short pitch; // 0x0C note: this is actually (pitch - width) - char pad_0E; // 0x0E + uint8 zoom_level; // 0x0E char var_0F; // 0x0F } rct_drawpixelinfo; diff --git a/src/window_banner.c b/src/window_banner.c index 10564eb994..663e42ba64 100644 --- a/src/window_banner.c +++ b/src/window_banner.c @@ -55,7 +55,7 @@ rct_widget window_banner_widgets[] = { static void window_banner_emptysub() { } static void window_banner_mouseup(); -static void window_banner_mousedown(); +static void window_banner_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_banner_dropdown(); static void window_banner_textinput(); static void window_banner_invalidate(); @@ -182,12 +182,12 @@ static void window_banner_mouseup() } } -static void window_banner_mousedown() +static void window_banner_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { - short widgetIndex; + //short widgetIndex; #ifdef _MSC_VER - __asm mov widgetIndex, dx + //__asm mov widgetIndex, dx #else __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); #endif diff --git a/src/window_footpath.c b/src/window_footpath.c index 0b764ec02f..ab2b8c979a 100644 --- a/src/window_footpath.c +++ b/src/window_footpath.c @@ -111,7 +111,7 @@ static rct_widget window_footpath_widgets[] = { static void window_footpath_emptysub() { } static void window_footpath_close(); static void window_footpath_mouseup(); -static void window_footpath_mousedown(); +static void window_footpath_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_footpath_dropdown(); static void window_footpath_update(rct_window *w); static void window_footpath_toolupdate(); @@ -307,31 +307,8 @@ static void window_footpath_mouseup() * * rct2: 0x006A7EC5 */ -static void window_footpath_mousedown() +static void window_footpath_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { - short widgetIndex; - rct_window *w; - rct_widget *widget; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - - #ifdef _MSC_VER - __asm mov widget, edi - #else - __asm__ ( "mov %[widget], edi " : [widget] "+m" (widget) ); - #endif - - switch (widgetIndex) { case WIDX_FOOTPATH_TYPE: window_footpath_show_footpath_types_dialog(w, widget, 0); diff --git a/src/window_game_top_toolbar.c b/src/window_game_top_toolbar.c index 5fd19964d2..8a78975390 100644 --- a/src/window_game_top_toolbar.c +++ b/src/window_game_top_toolbar.c @@ -78,7 +78,7 @@ static rct_widget window_game_top_toolbar_widgets[] = { static void window_game_top_toolbar_emptysub() { } static void window_game_top_toolbar_mouseup(); -static void window_game_top_toolbar_mousedown(); +static void window_game_top_toolbar_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_game_top_toolbar_dropdown(); static void window_game_top_toolbar_invalidate(); static void window_game_top_toolbar_paint(); @@ -259,32 +259,10 @@ static void window_game_top_toolbar_mouseup() * * rct2: 0x0066CA3B */ -static void window_game_top_toolbar_mousedown() +static void window_game_top_toolbar_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { - short widgetIndex; - rct_window *w; - rct_widget *widget; rct_viewport *mainViewport; - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - - #ifdef _MSC_VER - __asm mov widget, edi - #else - __asm__ ( "mov %[widget], edi " : [widget] "+m" (widget) ); - #endif - - if (widgetIndex == WIDX_FILE_MENU) { gDropdownItemsFormat[0] = 882; gDropdownItemsFormat[1] = 883; diff --git a/src/window_guest_list.c b/src/window_guest_list.c index 95284c0b88..d26c91993a 100644 --- a/src/window_guest_list.c +++ b/src/window_guest_list.c @@ -73,7 +73,7 @@ static rct_widget window_guest_list_widgets[] = { static void window_guest_list_emptysub() { } static void window_guest_list_mouseup(); static void window_guest_list_resize(); -static void window_guest_list_mousedown(); +static void window_guest_list_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_guest_list_dropdown(); static void window_guest_list_update(rct_window *w); static void window_guest_list_scrollgetsize(); @@ -241,32 +241,9 @@ static void window_guest_list_resize() * * rct2: 0x00699AC4 */ -static void window_guest_list_mousedown() +static void window_guest_list_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { int i; - short widgetIndex; - rct_window *w; - rct_widget *widget; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - - #ifdef _MSC_VER - __asm mov widget, edi - #else - __asm__ ( "mov %[widget], edi " : [widget] "+m" (widget) ); - #endif - - switch (widgetIndex) { case WIDX_TAB_1: case WIDX_TAB_2: diff --git a/src/window_land.c b/src/window_land.c index 0e092a771b..823c2f3011 100644 --- a/src/window_land.c +++ b/src/window_land.c @@ -52,7 +52,7 @@ static rct_widget window_land_widgets[] = { static void window_land_emptysub() { } static void window_land_close(); static void window_land_mouseup(); -static void window_land_mousedown(); +static void window_land_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_land_dropdown(); static void window_land_update(rct_window *w); static void window_land_invalidate(); @@ -217,31 +217,9 @@ static void window_land_mouseup() * * rct2: 0x0066407B */ -static void window_land_mousedown() +static void window_land_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { int i; - short widgetIndex; - rct_window *w; - rct_widget *widget; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - - #ifdef _MSC_VER - __asm mov widget, edi - #else - __asm__ ( "mov %[widget], edi " : [widget] "+m" (widget) ); - #endif - switch (widgetIndex) { case WIDX_FLOOR: diff --git a/src/window_map.c b/src/window_map.c index 4c14fb8dd2..84cfd99af1 100644 --- a/src/window_map.c +++ b/src/window_map.c @@ -77,7 +77,7 @@ static rct_widget window_map_widgets[] = { static void window_map_emptysub() { } static void window_map_close(); static void window_map_mouseup(); -static void window_map_mousedown(); +static void window_map_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_map_update(rct_window *w); static void window_map_scrollgetsize(); static void window_map_scrollmousedown(); @@ -228,7 +228,7 @@ static void window_map_mouseup() * * rct2: 0x0068D040 */ -static void window_map_mousedown() +static void window_map_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { RCT2_CALLPROC_EBPSAFE(0x0068D040); } diff --git a/src/window_options.c b/src/window_options.c index fa0824904e..d370b185c5 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -105,7 +105,7 @@ static rct_widget window_options_widgets[] = { static void window_options_emptysub() { } static void window_options_mouseup(); -static void window_options_mousedown(); +static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_options_dropdown(); static void window_options_update(rct_window *w); static void window_options_paint(); @@ -290,25 +290,9 @@ static void window_options_mouseup() * * rct2: 0x006BB01B */ -static void window_options_mousedown() +static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { int num_items, i; - short widgetIndex; - rct_window *w; - rct_widget *widget; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - widget = &w->widgets[widgetIndex - 1]; diff --git a/src/window_park.c b/src/window_park.c index 9899bda5bf..d47358c7fd 100644 --- a/src/window_park.c +++ b/src/window_park.c @@ -218,7 +218,7 @@ static void window_park_emptysub() { } static void window_park_entrance_close(); static void window_park_entrance_mouseup(); static void window_park_entrance_resize(); -static void window_park_entrance_mousedown(); +static void window_park_entrance_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_park_entrance_dropdown(); static void window_park_entrance_update(rct_window *w); static void window_park_entrance_toolupdate(); @@ -243,7 +243,7 @@ static void window_park_guests_paint(); static void window_park_price_mouseup(); static void window_park_price_resize(); -static void window_park_price_mousedown(); +static void window_park_price_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_park_price_update(rct_window *w); static void window_park_price_invalidate(); static void window_park_price_paint(); @@ -731,31 +731,8 @@ static void window_park_entrance_resize() * * rct2: 0x006681BF */ -static void window_park_entrance_mousedown() +static void window_park_entrance_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { - short widgetIndex; - rct_window *w; - rct_widget *widget; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - - #ifdef _MSC_VER - __asm mov widget, edi - #else - __asm__ ( "mov %[widget], edi " : [widget] "+m" (widget) ); - #endif - - if (widgetIndex == WIDX_OPEN_OR_CLOSE) { gDropdownItemsFormat[0] = 1142; gDropdownItemsFormat[1] = 1142; @@ -1617,24 +1594,9 @@ static void window_park_price_resize() * * rct2: 0x0066902C */ -static void window_park_price_mousedown() +static void window_park_price_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { int newFee; - short widgetIndex; - rct_window *w; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - switch (widgetIndex) { case WIDX_CLOSE: diff --git a/src/window_ride_list.c b/src/window_ride_list.c index 4d0f29da66..8dff8e2433 100644 --- a/src/window_ride_list.c +++ b/src/window_ride_list.c @@ -68,7 +68,7 @@ static rct_widget window_ride_list_widgets[] = { static void window_ride_list_emptysub() { } static void window_ride_list_mouseup(); static void window_ride_list_resize(); -static void window_ride_list_mousedown(); +static void window_ride_list_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_ride_list_dropdown(); static void window_ride_list_update(rct_window *w); static void window_ride_list_scrollgetsize(); @@ -248,31 +248,9 @@ static void window_ride_list_resize() * * rct2: 0x006B3532 */ -static void window_ride_list_mousedown() +static void window_ride_list_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { int numItems, i; - short widgetIndex; - rct_window *w; - rct_widget *widget; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - - #ifdef _MSC_VER - __asm mov widget, edi - #else - __asm__ ( "mov %[widget], edi " : [widget] "+m" (widget) ); - #endif - if (widgetIndex == WIDX_OPEN_CLOSE_ALL) { gDropdownItemsFormat[0] = STR_CLOSE_ALL; diff --git a/src/window_title_menu.c b/src/window_title_menu.c index 087b6cd41e..8e2e5aab45 100644 --- a/src/window_title_menu.c +++ b/src/window_title_menu.c @@ -45,7 +45,7 @@ static rct_widget window_title_menu_widgets[] = { static void window_title_menu_emptysub() { } static void window_title_menu_mouseup(); -static void window_title_menu_mousedown(); +static void window_title_menu_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_title_menu_dropdown(); static void window_title_menu_unknown17(); static void window_title_menu_paint(); @@ -122,31 +122,8 @@ static void window_title_menu_mouseup() } } -static void window_title_menu_mousedown() +static void window_title_menu_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { - short widgetIndex; - rct_window *w; - rct_widget *widget; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - - #ifdef _MSC_VER - __asm mov widget, edi - #else - __asm__ ( "mov %[widget], edi " : [widget] "+m" (widget) ); - #endif - - if (widgetIndex == WIDX_SHOW_TUTORIAL) { gDropdownItemsFormat[0] = STR_TUTORIAL_BEGINNERS; gDropdownItemsFormat[1] = STR_TUTORIAL_CUSTOM_RIDES; diff --git a/src/window_title_scenarioselect.c b/src/window_title_scenarioselect.c index caecf96013..09d185238f 100644 --- a/src/window_title_scenarioselect.c +++ b/src/window_title_scenarioselect.c @@ -59,7 +59,7 @@ static void window_scenarioselect_init_tabs(); static void window_scenarioselect_emptysub() { } static void window_scenarioselect_mouseup(); -static void window_scenarioselect_mousedown(); +static void window_scenarioselect_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); static void window_scenarioselect_scrollgetsize(); static void window_scenarioselect_scrollmousedown(); static void window_scenarioselect_scrollmouseover(); @@ -190,24 +190,8 @@ static void window_scenarioselect_mouseup() window_close(w); } -static void window_scenarioselect_mousedown() +static void window_scenarioselect_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) { - short widgetIndex; - rct_window *w; - - #ifdef _MSC_VER - __asm mov widgetIndex, dx - #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); - #endif - - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - - if (widgetIndex >= WIDX_TAB1 && widgetIndex <= WIDX_TAB5) { w->selected_tab = widgetIndex - 4; w->var_494 = 0; From 423db671482120108c733e13e2c986577631a93c Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Wed, 28 May 2014 22:53:28 +0100 Subject: [PATCH 19/53] add climate_update_sound --- src/addresses.h | 2 + src/climate.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++- src/climate.h | 1 + src/game.c | 2 +- 4 files changed, 152 insertions(+), 2 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index fa8640de7d..cfadc3fea7 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -84,6 +84,8 @@ #define RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS 0x009ABDE8 #define RCT2_ADDRESS_DIRTY_BLOCK_ROWS 0x009ABDEC +#define RCT2_ADDRESS_LIGHTNING_ACTIVE 0x009AC068 + #define RCT2_ADDRESS_RUN_INTRO_TICK_PART 0x009AC319 #define RCT2_ADDRESS_INSTALLED_OBJECT_LIST 0x009ADAE8 diff --git a/src/climate.c b/src/climate.c index 6c1d4a1fd7..37bae75fda 100644 --- a/src/climate.c +++ b/src/climate.c @@ -19,10 +19,19 @@ *****************************************************************************/ #include "addresses.h" +#include "audio.h" #include "climate.h" #include "date.h" #include "gfx.h" #include "rct2.h" +#include "scenario.h" + +enum { + THUNDER_STATUS_NULL = 0, + THUNDER_STATUS_PLAYING = 1, + + MAX_THUNDER_INSTANCES = 2 +}; typedef struct { sint8 base_temperature; @@ -32,6 +41,8 @@ typedef struct { int gClimateNextWeather; +static int _climateCurrentWeatherEffect; + static int _climateNextTemperature; static int _climateNextWeatherEffect; static int _climateNextWeatherGloom; @@ -39,8 +50,24 @@ static int _climateNextRainLevel; static const rct_weather_transition* climate_transitions[4]; +// Sound data +static int _rainVolume = 1; +static rct_sound _rainSoundInstance; +static unsigned int _lightningTimer, _thunderTimer; +static rct_sound _thunderSoundInstance[MAX_THUNDER_INSTANCES]; +static int _thunderStatus[MAX_THUNDER_INSTANCES] = { THUNDER_STATUS_NULL, THUNDER_STATUS_NULL }; +static unsigned int _thunderSoundId; +static int _thunderVolume; +static int _thunderStereoEcho = 0; + static void climate_determine_future_weather(); +static void climate_update_rain_sound(); +static void climate_update_thunder_sound(); +static void climate_update_lightning(); +static void climate_update_thunder(); +static int climate_play_thunder(int instanceIndex, int soundId, int volume, int pan); + int climate_celsius_to_fahrenheit(int celsius) { return (celsius * 29) / 16 + 32; @@ -88,7 +115,7 @@ void climate_update() if (temperature == target_temperature) { if (cur_gloom == next_gloom) { - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_EFFECT, sint8) = _climateNextWeatherEffect; + _climateCurrentWeatherEffect = _climateNextWeatherEffect; if (cur_rain == next_rain) { RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8) = gClimateNextWeather; @@ -152,7 +179,127 @@ static void climate_determine_future_weather() RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE_UPDATE_TIMER, sint16) = 1920; } +/** + * + * rct2: 0x006BCB91 + */ +void climate_update_sound() +{ + if (RCT2_GLOBAL(0x009AF280, uint32) == 0xFFFFFFFF) + return; + if (RCT2_GLOBAL(0x009AF59C, uint8) != 0) + return; + if (!(RCT2_GLOBAL(0x009AF59D, uint8) & 1)) + return; + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 1) + return; + climate_update_rain_sound(); + climate_update_thunder_sound(); +} + +static void climate_update_rain_sound() +{ + if (_climateCurrentWeatherEffect == 1 || _climateCurrentWeatherEffect == 2) { + if (_rainVolume == 1) { + // Start playing the rain sound + if (sound_prepare(SOUND_RAIN_1, &_rainSoundInstance, 1, RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, uint32))) + sound_play(&_rainSoundInstance, 1, -4000, 0, 0); + _rainVolume = -4000; + } else { + // Increase rain sound + _rainVolume = min(-1400, _rainVolume + 80); + RCT2_CALLPROC_2(0x00404F0D, rct_sound*, int, &_rainSoundInstance, _rainVolume); + } + } else if (_rainVolume != 1) { + // Decrease rain sound + _rainVolume -= 80; + if (_rainVolume > -4000) { + RCT2_CALLPROC_2(0x00404F0D, rct_sound*, int, &_rainSoundInstance, _rainVolume); + } else { + sound_stop(&_rainSoundInstance); + _rainVolume = 1; + } + } +} + +static void climate_update_thunder_sound() +{ + if (_thunderStereoEcho) { + // Play thunder on right side + _thunderStereoEcho = 0; + climate_play_thunder(1, _thunderSoundId, _thunderVolume, 10000); + } else if (_thunderTimer != 0) { + climate_update_lightning(); + climate_update_thunder(); + } else if (_climateCurrentWeatherEffect == 2) { + // Create new thunder and lightning + unsigned int randomNumber = scenario_rand(); + if ((randomNumber & 0xFFFF) <= 0x1B4) { + randomNumber >>= 16; + _thunderTimer = 43 + (randomNumber % 64); + _lightningTimer = randomNumber % 32; + } + } + + // Stop thunder sounds if they have finished + for (int i = 0; i < MAX_THUNDER_INSTANCES; i++) { + if (_thunderStatus[i] == THUNDER_STATUS_NULL) + continue; + + if (!RCT2_CALLFUNC_1(0x00404E53, int, rct_sound*, &_thunderSoundInstance[i])) { + sound_stop(&_thunderSoundInstance[i]); + _thunderStatus[i] = THUNDER_STATUS_NULL; + } + } +} + +static void climate_update_lightning() +{ + if (_lightningTimer == 0) + return; + + _lightningTimer--; + if (RCT2_GLOBAL(RCT2_ADDRESS_LIGHTNING_ACTIVE, uint16) == 0) + if ((scenario_rand() & 0xFFFF) <= 0x2000) + RCT2_GLOBAL(RCT2_ADDRESS_LIGHTNING_ACTIVE, uint16) = 1; +} + +static void climate_update_thunder() +{ + _thunderTimer--; + if (_thunderTimer != 0) + return; + + unsigned int randomNumber = scenario_rand(); + if (randomNumber & 0x10000) { + if (_thunderStatus[0] == THUNDER_STATUS_NULL && _thunderStatus[1] == THUNDER_STATUS_NULL) { + // Play thunder on left side + _thunderSoundId = (randomNumber & 0x20000) ? SOUND_THUNDER_1 : SOUND_THUNDER_2; + _thunderVolume = (-((int)((randomNumber >> 18) & 0xFF))) << 3; + climate_play_thunder(0, _thunderSoundId, _thunderVolume, -10000); + + // Let thunder play on right side + _thunderStereoEcho = 1; + } + } else { + _thunderSoundId = (randomNumber & 0x20000) ? SOUND_THUNDER_1 : SOUND_THUNDER_2; + int pan = (((randomNumber >> 18) & 0xFF) - 128) * 16; + climate_play_thunder(0, _thunderSoundId, 0, pan); + } +} + +static int climate_play_thunder(int instanceIndex, int soundId, int volume, int pan) +{ + if (sound_prepare(soundId, &_thunderSoundInstance[instanceIndex], 1, RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, uint32))) { + sound_play(&_thunderSoundInstance[instanceIndex], 0, volume, pan, 0); + + _thunderStatus[instanceIndex] = THUNDER_STATUS_PLAYING; + return 1; + } + + return 0; +} #pragma region Climate / Weather data tables diff --git a/src/climate.h b/src/climate.h index 814039f10f..376323d907 100644 --- a/src/climate.h +++ b/src/climate.h @@ -44,5 +44,6 @@ extern const rct_weather climate_weather_data[6]; int climate_celsius_to_fahrenheit(int celsius); void climate_reset(int climate); void climate_update(); +void climate_update_sound(); #endif diff --git a/src/game.c b/src/game.c index ad4b94ed32..bb6236379c 100644 --- a/src/game.c +++ b/src/game.c @@ -197,7 +197,7 @@ void game_logic_update() RCT2_CALLPROC_EBPSAFE(0x0068AFAD); RCT2_CALLPROC_EBPSAFE(0x006BBC6B); // vehicle and scream sounds peep_update_crowd_noise(); - RCT2_CALLPROC_EBPSAFE(0x006BCB91); // weather sound effects + climate_update_sound(); news_item_update_current(); RCT2_CALLPROC_EBPSAFE(0x0067009A); // scenario editor opening of windows for a phase From 2a27ea0689786dc833b15322f269a6373cea4d8f Mon Sep 17 00:00:00 2001 From: anyc Date: Thu, 29 May 2014 01:19:09 +0200 Subject: [PATCH 20/53] fix ASM for MinGW --- src/game.c | 11 ++++++----- src/window_banner.c | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/game.c b/src/game.c index 8a619de450..16de96fbcd 100644 --- a/src/game.c +++ b/src/game.c @@ -671,16 +671,17 @@ static void RCT2_CALLPROC_WE_MOUSE_DOWN(int address, int widgetIndex, rct_windo #else __asm__("\ push %[address]\n\ - mov edx, widgetIndex \n\ - mov edi, widget + mov edi, %[widget] \n\ mov eax, %[w] \n\ - push edx \n\ - push eax \n\ + mov edx, %[widgetIndex] \n\ push edi \n\ + push eax \n\ + push edx \n\ mov esi, %[w] \n\ call [esp+12] \n\ add esp, 16 \n\ - " :[address] "+m" (address), [w] "+m" (w) : : "eax", "esi"); + " :[address] "+m" (address), [w] "+m" (w), [widget] "+m" (widget), [widgetIndex] "+m" (widgetIndex): : "eax", "esi", "edx", "edi" + ); #endif } diff --git a/src/window_banner.c b/src/window_banner.c index 663e42ba64..7b27b8fbe2 100644 --- a/src/window_banner.c +++ b/src/window_banner.c @@ -189,7 +189,7 @@ static void window_banner_mousedown(int widgetIndex, rct_window*w, rct_widget* w #ifdef _MSC_VER //__asm mov widgetIndex, dx #else - __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); +// __asm__ ( "mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex) ); #endif From a6912160447fa59afc7f5332e2eee94dd8897f14 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 29 May 2014 17:22:32 +0100 Subject: [PATCH 21/53] Fixed small issue with mouse down code --- src/game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game.c b/src/game.c index 16de96fbcd..ac83922df2 100644 --- a/src/game.c +++ b/src/game.c @@ -1098,7 +1098,7 @@ void handle_shortcut_command(int shortcutIndex) RCT2_CALLPROC_EBPSAFE(0x006B3CFF); window = window_find_by_id(WC_CONSTRUCT_RIDE, 0); if (window != NULL) - window_event_helper(window, 10, WE_MOUSE_DOWN); + RCT2_CALLPROC_WE_MOUSE_DOWN(window->event_handlers[WE_MOUSE_DOWN], 10, window, NULL); } break; case SHORTCUT_SHOW_RIDES_LIST: From 64bece02468cf766e689f6ae2a8dadbf311a7582 Mon Sep 17 00:00:00 2001 From: lnz Date: Wed, 21 May 2014 14:04:08 +0200 Subject: [PATCH 22/53] Initial implementation of ride reachability checks --- src/ride.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++++ src/ride.h | 6 +- src/scenario.c | 2 +- 3 files changed, 209 insertions(+), 3 deletions(-) diff --git a/src/ride.c b/src/ride.c index 56149ba2a9..5b301cfd36 100644 --- a/src/ride.c +++ b/src/ride.c @@ -20,6 +20,9 @@ #include #include "addresses.h" +#include "map.h" +#include "news_item.h" +#include "sprite.h" #include "ride.h" #include "sprite.h" #include "peep.h" @@ -191,3 +194,204 @@ void ride_update_favourited_stat() window_invalidate_by_id(WC_RIDE_LIST, 0); } + +int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) +{ + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate / 4]; + + do { + rct_map_element_path_properties props = tile->properties.path; + uint8 path_type = props.type >> 2, path_dir = props.type & 3; + uint8 element_type = tile->type & 0x3C; + + if (!(element_type & PATH_ROAD)) + continue; + + if (path_type & 1) { + if (path_dir == face_direction) { + if (height == tile->base_height + 2) + return 1; + } + else if (path_dir ^ 2 == face_direction && height == tile->base_height) { + return 1; + } + } else { + if (height == tile->base_height) + return 1; + } + + } while (!(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) && tile++); + + return 0; +} + + + +/** + * rct2: 0x006B7C59 + * @return 1 if the coordinate is reachable or has no entrance, 0 otw + */ +int ride_is_reachable(uint16 coordinate, rct_ride* ride, int index) { + int x = ((coordinate >> 8) & 0xFF) << 5, // cx + y = (coordinate & 0xFF) << 5; // ax + uint8 station_height = ride->pad_05A[index]; // pad_05a is uint8 station_base_height[4] + int tile_idx = ((x << 8) | y) >> 3; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + + while(1) { + uint8 element_type = tile->type & 0x3C; + if (element_type == MAP_ELEMENT_TYPE_ENTRANCE && station_height == tile->base_height) { + break; + } else if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) { + return 1; + } + tile++; + } + + uint8 face_direction = tile->type & 3; + y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; + x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; + tile_idx = ((x << 8) | y) >> 3; + + return map_coord_is_connected(tile_idx, station_height, face_direction); + /* while (1) { */ + /* rct_map_element_path_properties props; */ + + /* element_type = tile->type & 0x3C; */ + /* if (!(element_type & MAP_ELEMENT_TYPE_PATH)) */ + /* goto end; */ + + /* props = tile->properties.path; */ + /* if ( props.type & PATH_ROAD) { // with roads slopes count as connected sometimes */ + /* if ((props.type & 3) == face_direction) { */ + /* if (station_height == tile->base_height + 2) */ + /* return 1; */ + /* } */ + /* else { */ + /* uint8 madness = (props.type & 3) ^ 2; */ + /* if (madness == face_direction && station_height == tile->base_height) */ + /* return 1; */ + /* } */ + /* } else { // off-road only same height counts as connected */ + /* if (station_height == tile->base_height) */ + /* return 1; */ + /* } */ + + /* end: */ + /* if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) */ + /* return 0; */ + /* tile++; */ + /* } */ +} + + +void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) +{ + for (int i = 0; i < 4; ++i) { + uint16 station_start = ride->station_starts[i], + entrance = ride->entrances[i], + exit = ride->exits[i]; + + if (station_start == -1 ) + continue; + if (entrance != -1 && !ride_is_reachable(entrance, ride, i)) { + RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; + RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; + news_item_add_to_queue(1, 0xb26, ride_idx); + ride->var_1AF = 3; + } + + if (exit != -1 && !ride_is_reachable(exit, ride, i)) { + RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; + RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; + news_item_add_to_queue(1, 0xb27, ride_idx); + ride->var_1AF = 3; + } + + } +} + + +void blue_reachable(rct_ride* ride, int ride_idx) +{ + uint16 coordinate = ride->station_starts[ride_idx]; + int x = ((coordinate >> 8) & 0xFF) << 5, // cx + y = (coordinate & 0xFF) << 5; // ax + uint16 magic = 0; + int tile_idx = ((x << 8) | y) >> 3, count = 0; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + + while (1) { + // First find the appropriate track element for our ride + uint8 element_type = tile->type & 0x3C; + if(element_type == MAP_ELEMENT_TYPE_TRACK && tile->properties.track.ride_index == ride_idx) + break; + + if(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) + return; + tile++; + } + + uint8 track_type = tile->properties.track.type; + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { + magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; + } else { + magic = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; + } + + magic = magic << (tile->type & 3); + magic = ((magic >> 12) | magic) & 0xF; + + for (int count = 0; magic != 0; ++count) { + if (!(magic & 1)) { + magic >>= 1; + continue; + } + + uint8 face_direction = count ^ 2; + y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; + x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; + tile_idx = ((x << 8) | y) >> 3; + + if (map_coord_is_connected(tile, tile->base_height, face_direction)) + return; + } + + RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; + RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; + news_item_add_to_queue(1, 0xb26, ride_idx); + ride->var_1AF = 3; +} + + + +/** + * rct2: 0x006B7A5E + **/ +void ride_check_all_reachable() +{ +/* XXX: coordinates gleich um 5 shiften und / 4 ueberall weg */ + rct_ride *ride; + + for (int i = 0; i < MAX_RIDES; i++) { + ride = GET_RIDE(i); + if (ride->type == RIDE_TYPE_NULL) + continue; + if (ride->var_1AF != 0) + ride->var_1AF--; + if (ride->status != RIDE_STATUS_OPEN || ride->var_1AF != 0) + continue; + + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) { + //lightblue + blue_reachable(ride, i); + return; + } + else { + //pink + ride_entrance_exit_connected(ride, i); + } + + } +} + diff --git a/src/ride.h b/src/ride.h index 9d53d72864..32653a3211 100644 --- a/src/ride.h +++ b/src/ride.h @@ -111,8 +111,9 @@ typedef struct { uint8 var_199; uint8 pad_19A[0x14]; uint8 var_1AE; - uint8 pad_1AF[0x05]; - money32 profit; // 0x1B4 + uint8 var_1AF; + uint32 pad_1B0; + sint32 profit; // 0x1B4 uint8 queue_time[4]; // 0x1B8 uint8 var_1BC; uint8 pad_1BD[0x10]; @@ -343,5 +344,6 @@ int ride_get_max_queue_time(rct_ride *ride); void ride_init_all(); void reset_all_ride_build_dates(); void ride_update_favourited_stat(); +void ride_check_all_reachable(); #endif diff --git a/src/scenario.c b/src/scenario.c index 7d0957031b..6dc29fa1bf 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -592,7 +592,7 @@ void scenario_update() finance_pay_interest(); marketing_update(); peep_problem_warnings_update(); - RCT2_CALLPROC_EBPSAFE(0x006B7A5E); // check ride reachability + ride_check_all_reachable(); ride_update_favourited_stat(); if (month <= 1 && RCT2_GLOBAL(0x009ADAE0, sint32) != -1 && RCT2_GLOBAL(0x009ADAE0 + 14, uint16) & 1) { From 5e104477d328bf09a8261ac2a0a737d19eb7292c Mon Sep 17 00:00:00 2001 From: lnz Date: Mon, 26 May 2014 15:22:52 +0200 Subject: [PATCH 23/53] Cleanup and refactoring of ride reachability stuff --- src/map.c | 38 +++++++++++++++++++- src/map.h | 2 ++ src/ride.c | 95 ++++++++++---------------------------------------- src/scenario.c | 1 + 4 files changed, 59 insertions(+), 77 deletions(-) diff --git a/src/map.c b/src/map.c index 935f059ee0..20d85834b6 100644 --- a/src/map.c +++ b/src/map.c @@ -328,4 +328,40 @@ void sub_68B089() } while (mapElement->base_height == 255); mapElement++; RCT2_GLOBAL(0x0140E9A4, rct_map_element*) = mapElement; -} \ No newline at end of file +} + + +/** + * Checks if the tile at coordinate at height counts as connected. + * @return 1 if connected, 0 otherwisei + */ +int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) +{ + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate]; + + do { + rct_map_element_path_properties props = tile->properties.path; + uint8 path_type = props.type >> 2, path_dir = props.type & 3; + uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; + + if (!(element_type & PATH_ROAD)) + continue; + + if (path_type & 1) { + if (path_dir == face_direction) { + if (height == tile->base_height + 2) + return 1; + } + else if (path_dir ^ 2 == face_direction && height == tile->base_height) { + return 1; + } + } else { + if (height == tile->base_height) + return 1; + } + + } while (!(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) && tile++); + + return 0; +} + diff --git a/src/map.h b/src/map.h index 355767bc81..069c0d52c9 100644 --- a/src/map.h +++ b/src/map.h @@ -195,5 +195,7 @@ void map_init(); void map_update_tile_pointers(); int map_element_height(int x, int y); void sub_68B089(); +int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction); + #endif diff --git a/src/ride.c b/src/ride.c index 5b301cfd36..32f500d1ea 100644 --- a/src/ride.c +++ b/src/ride.c @@ -195,51 +195,21 @@ void ride_update_favourited_stat() } -int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) -{ - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate / 4]; - - do { - rct_map_element_path_properties props = tile->properties.path; - uint8 path_type = props.type >> 2, path_dir = props.type & 3; - uint8 element_type = tile->type & 0x3C; - - if (!(element_type & PATH_ROAD)) - continue; - - if (path_type & 1) { - if (path_dir == face_direction) { - if (height == tile->base_height + 2) - return 1; - } - else if (path_dir ^ 2 == face_direction && height == tile->base_height) { - return 1; - } - } else { - if (height == tile->base_height) - return 1; - } - - } while (!(tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) && tile++); - - return 0; -} - /** * rct2: 0x006B7C59 * @return 1 if the coordinate is reachable or has no entrance, 0 otw */ -int ride_is_reachable(uint16 coordinate, rct_ride* ride, int index) { +int ride_entrance_exit_is_reachable(uint16 coordinate, rct_ride* ride, int index) { int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax uint8 station_height = ride->pad_05A[index]; // pad_05a is uint8 station_base_height[4] - int tile_idx = ((x << 8) | y) >> 3; - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + int tile_idx = ((x << 8) | y) >> 5; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; while(1) { - uint8 element_type = tile->type & 0x3C; + uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; if (element_type == MAP_ELEMENT_TYPE_ENTRANCE && station_height == tile->base_height) { break; } else if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) { @@ -251,37 +221,9 @@ int ride_is_reachable(uint16 coordinate, rct_ride* ride, int index) { uint8 face_direction = tile->type & 3; y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; - tile_idx = ((x << 8) | y) >> 3; + tile_idx = ((x << 8) | y) >> 5; return map_coord_is_connected(tile_idx, station_height, face_direction); - /* while (1) { */ - /* rct_map_element_path_properties props; */ - - /* element_type = tile->type & 0x3C; */ - /* if (!(element_type & MAP_ELEMENT_TYPE_PATH)) */ - /* goto end; */ - - /* props = tile->properties.path; */ - /* if ( props.type & PATH_ROAD) { // with roads slopes count as connected sometimes */ - /* if ((props.type & 3) == face_direction) { */ - /* if (station_height == tile->base_height + 2) */ - /* return 1; */ - /* } */ - /* else { */ - /* uint8 madness = (props.type & 3) ^ 2; */ - /* if (madness == face_direction && station_height == tile->base_height) */ - /* return 1; */ - /* } */ - /* } else { // off-road only same height counts as connected */ - /* if (station_height == tile->base_height) */ - /* return 1; */ - /* } */ - - /* end: */ - /* if (tile->flags & MAP_ELEMENT_FLAG_LAST_TILE) */ - /* return 0; */ - /* tile++; */ - /* } */ } @@ -294,14 +236,14 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) if (station_start == -1 ) continue; - if (entrance != -1 && !ride_is_reachable(entrance, ride, i)) { + if (entrance != -1 && !ride_entrance_exit_is_reachable(entrance, ride, i)) { RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb26, ride_idx); ride->var_1AF = 3; } - if (exit != -1 && !ride_is_reachable(exit, ride, i)) { + if (exit != -1 && !ride_entrance_exit_is_reachable(exit, ride, i)) { RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb27, ride_idx); @@ -312,18 +254,17 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) } -void blue_reachable(rct_ride* ride, int ride_idx) +void ride_is_shop_reachable(rct_ride* ride, int ride_idx) { uint16 coordinate = ride->station_starts[ride_idx]; int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax uint16 magic = 0; - int tile_idx = ((x << 8) | y) >> 3, count = 0; - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx / 4]; + int tile_idx = ((x << 8) | y) >> 5, count = 0; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; while (1) { - // First find the appropriate track element for our ride - uint8 element_type = tile->type & 0x3C; + uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; if(element_type == MAP_ELEMENT_TYPE_TRACK && tile->properties.track.ride_index == ride_idx) break; @@ -333,7 +274,8 @@ void blue_reachable(rct_ride* ride, int ride_idx) } uint8 track_type = tile->properties.track.type; - if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { + ride = GET_RIDE(tile->properties.track.ride_index); + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { // buggy but why magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; } else { magic = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; @@ -341,7 +283,9 @@ void blue_reachable(rct_ride* ride, int ride_idx) magic = magic << (tile->type & 3); magic = ((magic >> 12) | magic) & 0xF; - + if (magic == 0) + return; + for (int count = 0; magic != 0; ++count) { if (!(magic & 1)) { magic >>= 1; @@ -351,7 +295,7 @@ void blue_reachable(rct_ride* ride, int ride_idx) uint8 face_direction = count ^ 2; y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; - tile_idx = ((x << 8) | y) >> 3; + tile_idx = ((x << 8) | y) >> 5; if (map_coord_is_connected(tile, tile->base_height, face_direction)) return; @@ -370,7 +314,6 @@ void blue_reachable(rct_ride* ride, int ride_idx) **/ void ride_check_all_reachable() { -/* XXX: coordinates gleich um 5 shiften und / 4 ueberall weg */ rct_ride *ride; for (int i = 0; i < MAX_RIDES; i++) { @@ -383,8 +326,8 @@ void ride_check_all_reachable() continue; if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) { - //lightblue - blue_reachable(ride, i); + //blue + ride_is_shop_reachable(ride, i); return; } else { diff --git a/src/scenario.c b/src/scenario.c index 6dc29fa1bf..5ae95f70e1 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -574,6 +574,7 @@ void scenario_update() RCT2_CALLPROC_EBPSAFE(0x0069E79A); // daily profit update RCT2_CALLPROC_EBPSAFE(0x0069C35E); // some kind of peeps days_visited update loop get_local_time(); + ride_check_all_reachable(); RCT2_CALLPROC_EBPSAFE(0x0066A13C); // objective 6 dragging if (objective_type == 10 || objective_type == 9 || objective_type == 8 || objective_type == 6 || objective_type == 5) { From ce270dbe1960522bb329f9db61704871d8ce45cc Mon Sep 17 00:00:00 2001 From: lnz Date: Mon, 26 May 2014 17:39:18 +0200 Subject: [PATCH 24/53] Fix lots of disgusting bugs --- src/map.c | 6 +++--- src/ride.c | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/map.c b/src/map.c index 20d85834b6..d7fcfb3003 100644 --- a/src/map.c +++ b/src/map.c @@ -335,16 +335,16 @@ void sub_68B089() * Checks if the tile at coordinate at height counts as connected. * @return 1 if connected, 0 otherwisei */ -int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction) +int map_coord_is_connected(uint16 tile_idx, uint8 height, uint8 face_direction) { - rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[coordinate]; + rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; do { rct_map_element_path_properties props = tile->properties.path; uint8 path_type = props.type >> 2, path_dir = props.type & 3; uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; - if (!(element_type & PATH_ROAD)) + if (element_type != PATH_ROAD) continue; if (path_type & 1) { diff --git a/src/ride.c b/src/ride.c index 32f500d1ea..005b776d47 100644 --- a/src/ride.c +++ b/src/ride.c @@ -275,10 +275,10 @@ void ride_is_shop_reachable(rct_ride* ride, int ride_idx) uint8 track_type = tile->properties.track.type; ride = GET_RIDE(tile->properties.track.ride_index); - if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { // buggy but why - magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; - } else { + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { magic = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; + } else { + magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; } magic = magic << (tile->type & 3); @@ -286,18 +286,19 @@ void ride_is_shop_reachable(rct_ride* ride, int ride_idx) if (magic == 0) return; - for (int count = 0; magic != 0; ++count) { + for (int count = 0; magic != 0; ++count) { if (!(magic & 1)) { - magic >>= 1; + magic >>= 1; continue; } + magic >>= 1; uint8 face_direction = count ^ 2; y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; tile_idx = ((x << 8) | y) >> 5; - if (map_coord_is_connected(tile, tile->base_height, face_direction)) + if (map_coord_is_connected(tile_idx, tile->base_height, face_direction)) return; } @@ -328,7 +329,6 @@ void ride_check_all_reachable() if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) { //blue ride_is_shop_reachable(ride, i); - return; } else { //pink From 3a3694a480fb19d0f9449598530d1feb6d3d987d Mon Sep 17 00:00:00 2001 From: lnz Date: Mon, 26 May 2014 18:19:34 +0200 Subject: [PATCH 25/53] More critical bugfixes for the reachability code. --- src/ride.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ride.c b/src/ride.c index 005b776d47..261dfc752c 100644 --- a/src/ride.c +++ b/src/ride.c @@ -256,13 +256,17 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) void ride_is_shop_reachable(rct_ride* ride, int ride_idx) { - uint16 coordinate = ride->station_starts[ride_idx]; + uint16 coordinate = ride->station_starts[0]; + if (coordinate == 0xFFFF) + return; + int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax uint16 magic = 0; int tile_idx = ((x << 8) | y) >> 5, count = 0; rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; + while (1) { uint8 element_type = tile->type & MAP_ELEMENT_TYPE_MASK; if(element_type == MAP_ELEMENT_TYPE_TRACK && tile->properties.track.ride_index == ride_idx) From 6e32406e7b6c1965bb0d075cf1ec1190bcd826df Mon Sep 17 00:00:00 2001 From: lnz Date: Thu, 29 May 2014 23:04:52 +0200 Subject: [PATCH 26/53] Cleanup and documentatin of ride connected functions --- src/ride.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/ride.c b/src/ride.c index 261dfc752c..6eb7d7ca9f 100644 --- a/src/ride.c +++ b/src/ride.c @@ -237,6 +237,7 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) if (station_start == -1 ) continue; if (entrance != -1 && !ride_entrance_exit_is_reachable(entrance, ride, i)) { + // name of ride is parameter of the format string RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb26, ride_idx); @@ -244,6 +245,7 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) } if (exit != -1 && !ride_entrance_exit_is_reachable(exit, ride, i)) { + // name of ride is parameter of the format string RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb27, ride_idx); @@ -254,7 +256,7 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) } -void ride_is_shop_reachable(rct_ride* ride, int ride_idx) +void ride_shop_connected(rct_ride* ride, int ride_idx) { uint16 coordinate = ride->station_starts[0]; if (coordinate == 0xFFFF) @@ -262,7 +264,7 @@ void ride_is_shop_reachable(rct_ride* ride, int ride_idx) int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax - uint16 magic = 0; + uint16 entrance_directions = 0; int tile_idx = ((x << 8) | y) >> 5, count = 0; rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; @@ -280,24 +282,28 @@ void ride_is_shop_reachable(rct_ride* ride, int ride_idx) uint8 track_type = tile->properties.track.type; ride = GET_RIDE(tile->properties.track.ride_index); if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x80000) { - magic = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; + entrance_directions = RCT2_ADDRESS(0x0099CA64, uint8)[track_type * 16]; } else { - magic = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; + entrance_directions = RCT2_ADDRESS(0x0099BA64, uint8)[track_type * 16]; } - magic = magic << (tile->type & 3); - magic = ((magic >> 12) | magic) & 0xF; - if (magic == 0) + + uint8 tile_direction = tile->type & MAP_ELEMENT_DIRECTION_MASK; + entrance_directions <<= tile_direction; + entrance_directions = ((entrance_directions >> 12) | entrance_directions) & 0xF; + + // now each bit in entrance_directions stands for an entrance direction to check + if (entrance_directions == 0) return; - for (int count = 0; magic != 0; ++count) { - if (!(magic & 1)) { - magic >>= 1; + for (int count = 0; entrance_directions != 0; ++count) { + if (!(entrance_directions & 1)) { + entrance_directions >>= 1; continue; } - magic >>= 1; + entrance_directions >>= 1; - uint8 face_direction = count ^ 2; + uint8 face_direction = count ^ 2; // flip direction north<->south, east<->west y -= RCT2_ADDRESS(0x00993CCC, sint16)[face_direction * 2]; x -= RCT2_ADDRESS(0x00993CCE, sint16)[face_direction * 2]; tile_idx = ((x << 8) | y) >> 5; @@ -306,9 +312,11 @@ void ride_is_shop_reachable(rct_ride* ride, int ride_idx) return; } + // name of ride is parameter of the format string RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; - RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; + RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb26, ride_idx); + ride->var_1AF = 3; } @@ -330,14 +338,10 @@ void ride_check_all_reachable() if (ride->status != RIDE_STATUS_OPEN || ride->var_1AF != 0) continue; - if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) { - //blue - ride_is_shop_reachable(ride, i); - } - else { - //pink + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) + ride_shop_connected(ride, i); + else ride_entrance_exit_connected(ride, i); - } } } From 978bc39d251c3744fb16e8ca73c7d64fde0290ab Mon Sep 17 00:00:00 2001 From: lnz Date: Thu, 29 May 2014 23:42:24 +0200 Subject: [PATCH 27/53] Name various ride variables, clear a warning in map.c, add a note in scenario --- src/map.c | 2 +- src/ride.c | 14 +++++++------- src/ride.h | 5 +++-- src/scenario.c | 2 +- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/map.c b/src/map.c index d7fcfb3003..5f157b1ab7 100644 --- a/src/map.c +++ b/src/map.c @@ -352,7 +352,7 @@ int map_coord_is_connected(uint16 tile_idx, uint8 height, uint8 face_direction) if (height == tile->base_height + 2) return 1; } - else if (path_dir ^ 2 == face_direction && height == tile->base_height) { + else if ((path_dir ^ 2) == face_direction && height == tile->base_height) { return 1; } } else { diff --git a/src/ride.c b/src/ride.c index 6eb7d7ca9f..a709606d4d 100644 --- a/src/ride.c +++ b/src/ride.c @@ -204,7 +204,7 @@ void ride_update_favourited_stat() int ride_entrance_exit_is_reachable(uint16 coordinate, rct_ride* ride, int index) { int x = ((coordinate >> 8) & 0xFF) << 5, // cx y = (coordinate & 0xFF) << 5; // ax - uint8 station_height = ride->pad_05A[index]; // pad_05a is uint8 station_base_height[4] + uint8 station_height = ride->station_heights[index]; int tile_idx = ((x << 8) | y) >> 5; rct_map_element* tile = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; @@ -241,7 +241,7 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb26, ride_idx); - ride->var_1AF = 3; + ride->connected_message_throttle = 3; } if (exit != -1 && !ride_entrance_exit_is_reachable(exit, ride, i)) { @@ -249,7 +249,7 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb27, ride_idx); - ride->var_1AF = 3; + ride->connected_message_throttle = 3; } } @@ -317,7 +317,7 @@ void ride_shop_connected(rct_ride* ride, int ride_idx) RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; news_item_add_to_queue(1, 0xb26, ride_idx); - ride->var_1AF = 3; + ride->connected_message_throttle = 3; } @@ -333,9 +333,9 @@ void ride_check_all_reachable() ride = GET_RIDE(i); if (ride->type == RIDE_TYPE_NULL) continue; - if (ride->var_1AF != 0) - ride->var_1AF--; - if (ride->status != RIDE_STATUS_OPEN || ride->var_1AF != 0) + if (ride->connected_message_throttle != 0) + ride->connected_message_throttle--; + if (ride->status != RIDE_STATUS_OPEN || ride->connected_message_throttle != 0) continue; if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride->type * 8, uint32) & 0x20000) diff --git a/src/ride.h b/src/ride.h index 32653a3211..9f593c1ec5 100644 --- a/src/ride.h +++ b/src/ride.h @@ -56,7 +56,8 @@ typedef struct { uint32 var_04C; uint16 overall_view; // 0x050 uint16 station_starts[4]; // 0x052 - uint8 pad_05A[0x10]; + uint16 station_heights[4]; // 0x05A + uint8 pad_062[8]; uint16 entrances[4]; // 0x06A uint16 exits[4]; // 0x072 uint8 pad_07A[0x0C]; @@ -111,7 +112,7 @@ typedef struct { uint8 var_199; uint8 pad_19A[0x14]; uint8 var_1AE; - uint8 var_1AF; + uint8 connected_message_throttle; uint32 pad_1B0; sint32 profit; // 0x1B4 uint8 queue_time[4]; // 0x1B8 diff --git a/src/scenario.c b/src/scenario.c index 5ae95f70e1..cda9235f13 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -574,7 +574,7 @@ void scenario_update() RCT2_CALLPROC_EBPSAFE(0x0069E79A); // daily profit update RCT2_CALLPROC_EBPSAFE(0x0069C35E); // some kind of peeps days_visited update loop get_local_time(); - ride_check_all_reachable(); + ride_check_all_reachable(); // XXX remove after debugging done RCT2_CALLPROC_EBPSAFE(0x0066A13C); // objective 6 dragging if (objective_type == 10 || objective_type == 9 || objective_type == 8 || objective_type == 6 || objective_type == 5) { From bad9e8b7bdc7c4a58977cb4ec4c8e22291e71e33 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Thu, 29 May 2014 23:05:55 +0100 Subject: [PATCH 28/53] fix bug in format string --- src/string_ids.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/string_ids.c b/src/string_ids.c index e18f7e6bc8..28c70e4a1a 100644 --- a/src/string_ids.c +++ b/src/string_ids.c @@ -1525,6 +1525,7 @@ void format_string_part(char **dest, rct_string_id format, char **args) // args += (format & 0xC00) >> 9; format &= ~0xC00; strcpy(*dest, RCT2_ADDRESS(0x135A8F4 + (format * 32), char)); + *dest = strchr(*dest, 0); } else if (format < 0xE000) { // Real name format -= -0xA000; @@ -1532,6 +1533,7 @@ void format_string_part(char **dest, rct_string_id format, char **args) real_names[format % countof(real_names)], real_name_initials[(format >> 10) % countof(real_name_initials)] ); + *dest = strchr(*dest, 0); } else { // ? RCT2_CALLPROC_EBPSAFE(RCT2_ADDRESS(0x0095AFB8, uint32)[format]); From 35b38f3c16e78fc20009df0f7112131bc7417eb0 Mon Sep 17 00:00:00 2001 From: lnz Date: Fri, 30 May 2014 00:12:29 +0200 Subject: [PATCH 29/53] Remove debug statements and add string_ids for ride connected functions. --- src/ride.c | 6 +++--- src/scenario.c | 1 - src/string_ids.h | 3 +++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ride.c b/src/ride.c index a709606d4d..840d12abf9 100644 --- a/src/ride.c +++ b/src/ride.c @@ -240,7 +240,7 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) // name of ride is parameter of the format string RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; - news_item_add_to_queue(1, 0xb26, ride_idx); + news_item_add_to_queue(1, STR_ENTRANCE_NOT_CONNECTED, ride_idx); ride->connected_message_throttle = 3; } @@ -248,7 +248,7 @@ void ride_entrance_exit_connected(rct_ride* ride, int ride_idx) // name of ride is parameter of the format string RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; - news_item_add_to_queue(1, 0xb27, ride_idx); + news_item_add_to_queue(1, STR_EXIT_NOT_CONNECTED, ride_idx); ride->connected_message_throttle = 3; } @@ -315,7 +315,7 @@ void ride_shop_connected(rct_ride* ride, int ride_idx) // name of ride is parameter of the format string RCT2_GLOBAL(0x013CE952, uint16) = ride->var_04A; RCT2_GLOBAL(0x013CE954, uint32) = ride->var_04C; - news_item_add_to_queue(1, 0xb26, ride_idx); + news_item_add_to_queue(1, STR_ENTRANCE_NOT_CONNECTED, ride_idx); ride->connected_message_throttle = 3; } diff --git a/src/scenario.c b/src/scenario.c index cda9235f13..6dc29fa1bf 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -574,7 +574,6 @@ void scenario_update() RCT2_CALLPROC_EBPSAFE(0x0069E79A); // daily profit update RCT2_CALLPROC_EBPSAFE(0x0069C35E); // some kind of peeps days_visited update loop get_local_time(); - ride_check_all_reachable(); // XXX remove after debugging done RCT2_CALLPROC_EBPSAFE(0x0066A13C); // objective 6 dragging if (objective_type == 10 || objective_type == 9 || objective_type == 8 || objective_type == 6 || objective_type == 5) { diff --git a/src/string_ids.h b/src/string_ids.h index 6812f33eeb..5db27533b3 100644 --- a/src/string_ids.h +++ b/src/string_ids.h @@ -567,6 +567,9 @@ enum { STR_NO_RECENT_AWARDS = 2848, + STR_ENTRANCE_NOT_CONNECTED = 2854, + STR_EXIT_NOT_CONNECTED = 2855, + STR_TUTORIAL = 2856, STR_PRESS_KEY_OR_MOUSE_BUTTON_FOR_CONTROL = 2857, From d5f374d38c931395dc5786e6261a391790867ecb Mon Sep 17 00:00:00 2001 From: lnz Date: Fri, 30 May 2014 00:24:44 +0200 Subject: [PATCH 30/53] Fix station_heights bug and use FOR_ALL_RIDES in ride_check_all_reachable --- src/ride.c | 9 +++------ src/ride.h | 4 ++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/ride.c b/src/ride.c index 840d12abf9..c7746e91f9 100644 --- a/src/ride.c +++ b/src/ride.c @@ -328,11 +328,9 @@ void ride_shop_connected(rct_ride* ride, int ride_idx) void ride_check_all_reachable() { rct_ride *ride; - - for (int i = 0; i < MAX_RIDES; i++) { - ride = GET_RIDE(i); - if (ride->type == RIDE_TYPE_NULL) - continue; + int i; + + FOR_ALL_RIDES(i, ride) { if (ride->connected_message_throttle != 0) ride->connected_message_throttle--; if (ride->status != RIDE_STATUS_OPEN || ride->connected_message_throttle != 0) @@ -342,7 +340,6 @@ void ride_check_all_reachable() ride_shop_connected(ride, i); else ride_entrance_exit_connected(ride, i); - } } diff --git a/src/ride.h b/src/ride.h index 9f593c1ec5..bcbc0c86dd 100644 --- a/src/ride.h +++ b/src/ride.h @@ -56,8 +56,8 @@ typedef struct { uint32 var_04C; uint16 overall_view; // 0x050 uint16 station_starts[4]; // 0x052 - uint16 station_heights[4]; // 0x05A - uint8 pad_062[8]; + uint8 station_heights[4]; // 0x05A + uint8 pad_05E[0xC]; uint16 entrances[4]; // 0x06A uint16 exits[4]; // 0x072 uint8 pad_07A[0x0C]; From 6a1c5fa6ebff5e49755f18a31fdecb6c541eb418 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Fri, 30 May 2014 23:27:11 +0100 Subject: [PATCH 31/53] add initial start to peep update --- src/award.c | 16 ++++---- src/peep.c | 85 +++++++++++++++++++++++++++++++++++++++-- src/peep.h | 10 +++-- src/window_guest_list.c | 6 +-- 4 files changed, 99 insertions(+), 18 deletions(-) diff --git a/src/award.c b/src/award.c index 25c843ddd9..3f76984ebf 100644 --- a/src/award.c +++ b/src/award.c @@ -76,7 +76,7 @@ static int award_is_deserved_most_untidy(int awardType, int activeAwardTypes) if (peep->var_2A != 0) continue; - if (peep->thoughts[0].pad_3 > 5) + if (peep->thoughts[0].var_2 > 5) continue; if (peep->thoughts[0].type == PEEP_THOUGHT_TYPE_BAD_LITTER || @@ -109,7 +109,7 @@ static int award_is_deserved_most_tidy(int awardType, int activeAwardTypes) if (peep->var_2A != 0) continue; - if (peep->thoughts[0].pad_3 > 5) + if (peep->thoughts[0].var_2 > 5) continue; if (peep->thoughts[0].type == PEEP_THOUGHT_VERY_CLEAN) @@ -183,7 +183,7 @@ static int award_is_deserved_most_beautiful(int awardType, int activeAwardTypes) if (peep->var_2A != 0) continue; - if (peep->thoughts[0].pad_3 > 5) + if (peep->thoughts[0].var_2 > 5) continue; if (peep->thoughts[0].type == PEEP_THOUGHT_TYPE_SCENERY) @@ -226,7 +226,7 @@ static int award_is_deserved_safest(int awardType, int activeAwardTypes) FOR_ALL_GUESTS(spriteIndex, peep) { if (peep->var_2A != 0) continue; - if (peep->thoughts[0].pad_3 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_VANDALISM) + if (peep->thoughts[0].var_2 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_VANDALISM) peepsWhoDislikeVandalism++; } @@ -307,7 +307,7 @@ static int award_is_deserved_best_food(int awardType, int activeAwardTypes) if (peep->var_2A != 0) continue; - if (peep->thoughts[0].pad_3 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_HUNGRY) + if (peep->thoughts[0].var_2 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_HUNGRY) hungryPeeps++; } @@ -353,7 +353,7 @@ static int award_is_deserved_worst_food(int awardType, int activeAwardTypes) if (peep->var_2A != 0) continue; - if (peep->thoughts[0].pad_3 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_HUNGRY) + if (peep->thoughts[0].var_2 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_HUNGRY) hungryPeeps++; } @@ -388,7 +388,7 @@ static int award_is_deserved_best_restrooms(int awardType, int activeAwardTypes) if (peep->var_2A != 0) continue; - if (peep->thoughts[0].pad_3 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_BATHROOM) + if (peep->thoughts[0].var_2 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_BATHROOM) guestsWhoNeedRestroom++; } @@ -510,7 +510,7 @@ static int award_is_deserved_most_confusing_layout(int awardType, int activeAwar continue; peepsCounted++; - if (peep->thoughts[0].pad_3 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_LOST || peep->thoughts[0].type == PEEP_THOUGHT_TYPE_CANT_FIND) + if (peep->thoughts[0].var_2 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_LOST || peep->thoughts[0].type == PEEP_THOUGHT_TYPE_CANT_FIND) peepsLost++; } diff --git a/src/peep.c b/src/peep.c index cde8015f4e..7042c04c5d 100644 --- a/src/peep.c +++ b/src/peep.c @@ -28,6 +28,8 @@ #include "sprite.h" #include "window.h" +static void peep_update(rct_peep *peep); + int peep_get_staff_count() { uint16 spriteIndex; @@ -60,17 +62,94 @@ void peep_update_all() spriteIndex = peep->next; if ((i & 0x7F) != (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 0x7F)) { - RCT2_CALLPROC_X(0x0068FC1E, 0, 0, 0, 0, (int)peep, 0, 0); + peep_update(peep); } else { RCT2_CALLPROC_X(0x0068F41A, 0, 0, 0, i, (int)peep, 0, 0); if (peep->var_08 == 4) - RCT2_CALLPROC_X(0x0068FC1E, 0, 0, 0, 0, (int)peep, 0, 0); + peep_update(peep); } i++; } } +/** + * + * rct2: 0x0068FC1E + */ +static void peep_update(rct_peep *peep) +{ + // RCT2_CALLPROC_X(0x0068FC1E, 0, 0, 0, 0, (int)peep, 0, 0); return; + + int i, j; + + if (peep->type == PEEP_TYPE_GUEST) { + if (peep->var_AD != 255) + if (++peep->var_AE < 720) + peep->var_AD = 255; + + // Update thoughts + i = 0; + int ebp = 0; + int edi = -1; + for (i = 0; i < PEEP_MAX_THOUGHTS; i++) { + if (peep->thoughts[i].type == PEEP_THOUGHT_TYPE_NONE) + break; + + if (peep->thoughts[i].var_2 == 1) { + ebp++; + if (++peep->thoughts[i].var_3 >= 220) { + peep->thoughts[i].var_3 = 0; + peep->thoughts[i].var_2++; + ebp--; + } + } else if (peep->thoughts[i].var_2 >= 0) { + if (++peep->thoughts[i].var_3 > 255) { + if (++peep->thoughts[i].var_3 >= 28) { + peep->var_45 |= 1; + + // Clear top thought, push others up + for (j = i; j < PEEP_MAX_THOUGHTS - 1; j++) + peep->thoughts[j].type = peep->thoughts[j + 1].type; + peep->thoughts[PEEP_MAX_THOUGHTS - 1].type = PEEP_THOUGHT_TYPE_NONE; + } + } + } else { + edi = i; + } + } + if (ebp == 0 && edi != -1) { + peep->thoughts[edi].var_2 = 1; + peep->var_45 |= 1; + } + } + + // Walking speed logic + unsigned int stepsToTake = peep->energy; + if (stepsToTake < 95 && peep->state == PEEP_STATE_QUEUING) + stepsToTake = 95; + if ((peep->flags & PEEP_FLAGS_SLOW_WALK) && peep->state != PEEP_STATE_QUEUING) + stepsToTake /= 2; + if (peep->var_71 == 255 && (RCT2_GLOBAL((int)peep + 0x29, uint8) & 4)) { + stepsToTake /= 2; + if (peep->state == PEEP_STATE_QUEUING) + stepsToTake += stepsToTake / 2; + } + + unsigned int carryCheck = peep->var_73 + stepsToTake; + peep->var_73 = carryCheck; + if (carryCheck <= 255) { + // loc_68FD3A + RCT2_CALLPROC_X(0x0068FD3A, 0, 0, 0, 0, (int)peep, 0, 0); + } else { + // loc_68FD2F + RCT2_CALLPROC_X(0x0068FD2F, 0, 0, 0, 0, (int)peep, 0, 0); + switch (peep->state) { + + } + } +} + /** * @@ -89,7 +168,7 @@ void peep_problem_warnings_update() RCT2_GLOBAL(RCT2_ADDRESS_RIDE_COUNT, sint16) = ride_get_count(); // refactor this to somewhere else FOR_ALL_GUESTS(spriteIndex, peep) { - if (peep->var_2A != 0 || peep->thoughts[0].pad_3 > 5) + if (peep->var_2A != 0 || peep->thoughts[0].var_2 > 5) continue; switch (peep->thoughts[0].type) { diff --git a/src/peep.h b/src/peep.h index 2bac8ed735..74dfd3f6b8 100644 --- a/src/peep.h +++ b/src/peep.h @@ -307,8 +307,8 @@ enum PEEP_ITEM { typedef struct { uint8 type; uint8 item; - uint8 pad_3; - uint8 pad_4; + uint8 var_2; + uint8 var_3; } rct_peep_thought; typedef struct { @@ -376,7 +376,8 @@ typedef struct { uint8 var_70; uint8 var_71; uint8 var_72; - uint8 pad_73[3]; + uint8 var_73; + uint16 pad_74; uint8 var_76; uint8 pad_77; uint8 var_78; @@ -387,7 +388,8 @@ typedef struct { money32 cash_spent; // 0xA4 uint8 pad_A8; sint32 time_in_park; // 0xA9 - uint8 pad_AD[0x3]; + uint8 var_AD; + uint16 var_AE; rct_peep_thought thoughts[PEEP_MAX_THOUGHTS]; // 0xB0 uint8 pad_C4; uint8 var_C5; diff --git a/src/window_guest_list.c b/src/window_guest_list.c index d26c91993a..14fe8d13a7 100644 --- a/src/window_guest_list.c +++ b/src/window_guest_list.c @@ -731,9 +731,9 @@ static void window_guest_list_scrollpaint() thought = &peep->thoughts[j]; if (thought->type == PEEP_THOUGHT_TYPE_NONE) break; - if (thought->pad_3 == 0) + if (thought->var_2 == 0) continue; - if (thought->pad_3 > 5) + if (thought->var_2 > 5) break; ebx = thought->type; @@ -837,7 +837,7 @@ static int sub_69B7EA(rct_peep *peep, int *outEAX) *outEAX = eax; return ebx & 0xFFFF; case VIEW_THOUGHTS: - if (peep->thoughts[0].pad_3 <= 5) { + if (peep->thoughts[0].var_2 <= 5) { eax = peep->thoughts[0].item; ebx = peep->thoughts[0].type; if (peep->thoughts[0].type != PEEP_THOUGHT_TYPE_NONE) { From b1e9c5c786b4d2050a9dd9f0e10fc6d65d15a211 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 31 May 2014 14:43:29 +0100 Subject: [PATCH 32/53] fix format string bugs --- src/string_ids.c | 79 ++++++++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/src/string_ids.c b/src/string_ids.c index 28c70e4a1a..11a5703f12 100644 --- a/src/string_ids.c +++ b/src/string_ids.c @@ -1085,12 +1085,16 @@ void format_integer(char **dest, int value) *dest = dst; - // Right to left - while (value > 0) { - digit = value % 10; - value /= 10; + if (value == 0) { + *dst++ = '0'; + } else { + // Right to left + while (value > 0) { + digit = value % 10; + value /= 10; - *dst++ = '0' + digit; + *dst++ = '0' + digit; + } } finish = dst; @@ -1121,20 +1125,24 @@ void format_comma_separated_integer(char **dest, int value) *dest = dst; - // Groups of three digits, right to left - groupIndex = 0; - while (value > 0) { - // Append group seperator - if (groupIndex == 3) { - groupIndex = 0; - *dst++ = ','; + if (value == 0) { + *dst++ = '0'; + } else { + // Groups of three digits, right to left + groupIndex = 0; + while (value > 0) { + // Append group seperator + if (groupIndex == 3) { + groupIndex = 0; + *dst++ = ','; + } + + digit = value % 10; + value /= 10; + + *dst++ = '0' + digit; + groupIndex++; } - - digit = value % 10; - value /= 10; - - *dst++ = '0' + digit; - groupIndex++; } finish = dst; @@ -1225,20 +1233,24 @@ void format_currency(char **dest, int value) *dest = dst; - // Groups of three digits, right to left - groupIndex = 0; - while (value > 0) { - // Append group seperator - if (groupIndex == 3) { - groupIndex = 0; - *dst++ = ','; + if (value == 0) { + *dst++ = '0'; + } else { + // Groups of three digits, right to left + groupIndex = 0; + while (value > 0) { + // Append group seperator + if (groupIndex == 3) { + groupIndex = 0; + *dst++ = ','; + } + + digit = value % 10; + value /= 10; + + *dst++ = '0' + digit; + groupIndex++; } - - digit = value % 10; - value /= 10; - - *dst++ = '0' + digit; - groupIndex++; } finish = dst; @@ -1389,11 +1401,12 @@ void format_string_code(unsigned char format_code, char **dest, char **args) value = *((uint16*)*args); *args += 2; - uint16 dateArgs[] = { date_get_year(value), date_get_month(value) }; + uint16 dateArgs[] = { date_get_month(value), date_get_year(value) + 1 }; + uint16 *dateArgs2 = dateArgs; char formatString[] = "?, Year ?"; formatString[0] = FORMAT_MONTH; formatString[8] = FORMAT_COMMA16; - format_string_part_from_raw(dest, formatString, (char**)&dateArgs); + format_string_part_from_raw(dest, formatString, (char**)&dateArgs2); break; case FORMAT_MONTH: // Pop argument From 34a9f94ac170c65a637536918ac35876da743f61 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sat, 17 May 2014 09:34:58 +0200 Subject: [PATCH 33/53] Add gfx_get_string_width() --- src/gfx.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 929998071e..c3f5f09a8d 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1041,18 +1041,70 @@ void gfx_redraw_screen_rect(short left, short top, short right, short bottom) } /** - * + * * rct2: 0x006C2321 * buffer (esi) */ int gfx_get_string_width(char *buffer) { - int eax, ebx, ecx, edx, esi, edi, ebp; + int base; + int width; - esi = (int)buffer; - RCT2_CALLFUNC_X(0x006C2321, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + char curr_char; - return ecx & 0xFFFF; + curr_char = 0; + base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + width = 0; + + for (curr_char = *buffer; curr_char > 0; buffer++, curr_char = *buffer) { + + if (curr_char >= 0x20) { + width += RCT2_ADDRESS(0x0141E9E8, uint8)[base + (curr_char-0x20)]; + continue; + } + switch(curr_char) { + case 1: + width = *buffer; + buffer++; + break; + case 2: + case 3: + case 4: + buffer++; + break; + case 7: + base = 0x1C0; + break; + case 8: + base = 0x2A0; + break; + case 9: + base = 0x0E0; + break; + case 0x0A: + base = 0; + break; + case 0x17: + curr_char = *buffer; + curr_char &= 0x7FFFF; + buffer += 4; + curr_char <<= 4; + width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[curr_char]; + curr_char = 0; + break; + default: + if (curr_char <= 0x10) { + continue; + } + buffer += 2; + if (curr_char <= 0x16) { + continue; + } + buffer += 2; + break; + } + } + return width; } /** From 6e778006a5f17445189d16a6867e570f2c89358c Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sat, 17 May 2014 22:37:37 +0200 Subject: [PATCH 34/53] First pass for gfx_draw_string() --- src/addresses.h | 1 + src/gfx.c | 330 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 331 insertions(+) diff --git a/src/addresses.h b/src/addresses.h index 3a36125e05..912461a9b3 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -249,6 +249,7 @@ #define RCT2_ADDRESS_NEWS_ITEM_LIST 0x013CA754 #define RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE 0x013CE950 +#define RCT2_ADDRESS_CURRENT_FONT_FLAGS 0x013CE9A2 #define RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS 0x013CE9A4 #define RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT 0x0141E9AC diff --git a/src/gfx.c b/src/gfx.c index c3f5f09a8d..ced773d864 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1285,4 +1285,334 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, in gLastDrawStringX = ecx; gLastDrawStringY = edx; + + + RCT2_GLOBAL(0x00EDF840, uint16) = x; + RCT2_GLOBAL(0x00EDF842, uint16) = y; + + if (colour & 0xFE) { + // jz loc_682853 + } + + if ((x >= dpi->x + dpi->width) || (x <= dpi->x) || + (y >= dpi->y + dpi->height) || (y <= dpi->y)) { + return; + } + if (colour == 0xFF) { + // jz loc_682853 + } + + uint16* current_font_flags = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16); + uint16* current_font_sprite_base = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + + // switch_colour: + *current_font_flags = 0; + if (*current_font_sprite_base < 0) { + *current_font_flags |= 4; + if (*current_font_sprite_base != 0xFFFF) { + *current_font_flags |= 8; + } + *current_font_sprite_base = 0xE0; + } + // loc_6827A5 + if (!(ax & (1 << 5))) { + *current_font_flags |= 2; + } + + // loc_6827B4 + if (!(colour & 0x40)) { + ebp = al; + // jmp short loc_682AC7 + } + + *current_font_flags |= 1; + colour &= 0x1F; + + ebp = colour; + + if (*current_font_flags & 4) { + if (*current_font_flags & 8) { + // loc_682805 + eax = RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC46, uint8)[ebp * 8]; + } else { + // loc_6827E7 + eax = RCT2_ADDRESS(0x0141FC49, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC47, uint8)[ebp * 8]; + } + } else { + eax = RCT2_ADDRESS(0x0141FC4A, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + } + // jmp short loc_682842 + + + // ; --------------------------------------------------------------------------- + + + // ; --------------------------------------------------------------------------- + // loc_682842 + RCT2_GLOBAL(0x009ABE05, uint32) = eax; + RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; + eax = 0; + + // loc_682853 + if (y + 0x13 <= dpi->y) { + skip_char; + } + if (dpi->y + dpi->height <= y) { + skip_char; + } + + // loc_682875 + al = *format; + format++; + + // skip_cont + if (al == 0) { + return; + } + if (al >= 0x9C) { + // jnb short loc_682888 + } + if (al >= 0x8E) { + // jnb colour_char + } + + // loc_682888 + al -= 0x20; + if (al < 0) { + // jb short loc_6828F5 + } + bx = dpi->x + dpi->width; + if (x >= bx) { + // jge skip_char + } + bx = x + 0x1A; + if (bx < dpi->x) { + // jl short loc_6828E0 + } + ebx = al + *current_font_sprite_base; + cl = cl + (RCT2_ADDRESS(0x0141E9E8, uint32)[ebx] & 0xFF) + // push dword_141E9E8[ebx] + // push ecx + // push edx + // push edi + // push esi + + eax = (int)al; + ebx += 0xF15; + esi = (int)format; + edi = (int)dpi; + + RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; + + RCT2_CALLPROC_X(0x067A46E, eax, ebx, ecx, edx, esi, edi, ebp); + + // pop esi + // pop edi + // pop edx + // pop ecx + // pop eax + + // jmp short loc_682875 + + // loc_6828E0 + ebx = al; + ebx += *current_font_sprite_base; + cl = cl + (RCT2_ADDRESS(0x0141E9E8, uint32)[ebx] & 0xFF); + // jmp short loc_682875 + + // loc_6828F5 + switch (al) { + case 0x0E5: + // jz loc_6829E3 + cx = RCT2_GLOBAL(0x0EDF840, uint16); + dx += 0x0A; + if (*current_font_sprite_base <= 0x0E) { + // jbe loc_682875 + } + dx -= 4; + if (*current_font_sprite_base == 0x1C0) { + // jz loc_682875 + } + dx -= 0xFFF4; + // jmp loc_682875 + case 0x0E6: + // jz loc_6829AD + cx = RCT2_GLOBAL(0x0EDF840, uint16); + dx += 5; + if (*current_font_sprite_base <= 0x0E) { + // jbe loc_682875 + } + dx -= 2; + if (*current_font_sprite_base == 0x1C0) { + // jz loc_682875 + } + dx -= 0xFFFA; + // jmp loc_682875 + case 0x0E1: + // jz loc_682A19 + al = *buffer; + buffer++; + cx = RCT2_GLOBAL(0x0EDF840, uint16); + cx += al; + // jmp loc_682875 + + case 0x0F1: + // jz loc_682A34 + ax = *buffer; + buffer += 2; + cx = RCT2_GLOBAL(0x0EDF840, uint16); + cx += (ax & 0xFF); + dx = RCT2_GLOBAL(0x0EDF842, uint16); + dx += (ax & 0xFF00) >> 8; + // jmp loc_682875 + + + case 0x0E7: + // jz loc_682A57 + *current_font_sprite_base = 0x1C0; + // jmp loc_682875 + + case 0x0E8: + // jz loc_682A65 + *current_font_sprite_base = 0x2A0; + // jmp loc_682875 + + case 0x0E9: + // jz loc_682A81 + *current_font_sprite_base = 0xE0; + // jmp loc_682875 + + case 0x0EA: + // jz loc_682A73 + *current_font_sprite_base = 0; + // jmp loc_682875 + + case 0x0EB: + // jz loc_682A8F + *current_font_flags |= 2; + // jmp loc_682875 + + case 0x0EC: + // jz loc_682A9C + *current_font_flags &= 0x0FFFD; + // jmp loc_682875 + + case 0x0ED: + // jz loc_682AAE + ebp = RCT2_GLOBAL(0x0141F740, uint8); + + // jmp short loc_682AC7 + + case 0x0EE: + // jz loc_682AC0 + ebp = RCT2_GLOBAL(0x0141F741, uint8); + + // jmp short loc_682AC7 + + case 0x0EF: + // jz loc_682AB7 + ebp = RCT2_GLOBAL(0x0141F742, uint8); + + // jmp short loc_682AC7 + + case 0x0E2: + // jz loc_682AF7 + eax = *buffer; + buffer++; + if (*current_font_flags & 1) { + // jnz loc_682853 + } + + // push ebx + // mov eax, ds:dword_97FCBC[eax*4] + // shl eax, 4 + // mov eax, g1_elements[eax] + // mov bl, [eax+0F9h] + // mov bh, 1 + + eax = RCT2_ADDRESS(0x097FCBC, uint32)[eax*4]; + rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); + // What on earth is going on here? + bx = *(g1_element + 0xF9) + (1 << 8); + + if (!(*current_font_flags & 2)) { + bx = bx & 0xFF; + } + RCT2_GLOBAL(0x09ABE05, uint16) = bx; + bx = *(g1_element + 0xF7); + RCT2_GLOBAL(0x09ABE07, uint16) = bx; + bx = *(g1_element + 0xFA); + RCT2_GLOBAL(0x09ABE09, uint16) = bx; + + // pop ebx + RCT2_GLOBAL(0x09ABDA4, uint32) = RCT2_GLOBAL(0x09ABE04, uint32); + + // jmp loc_682853 + + case 0x0F7: + // jz short loc_68296E + buffer += 4; + if (cx >= dpi->x + dpi->width) { + skip_char; + } + ebx = *(format - 4); + eax = ebx & 0x7FFFF; + rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, rct_g1_element)[eax]); + + gfx_draw_sprite(dpi, ebx, cx, dx); + + cx += g1_element->offset; + // jmp loc_682875 + + } + // jmp loc_682875 + + // colour_char + al -= 0x8E; + if (*current_font_flags == 1) { + // jnz short loc_682853 + } + eax = eax & 0xFF; + // mov ebp, g1_elements+13320h + ebp = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 0x13320, uint32)); + // mov eax, [ebp+eax*4+0] + eax = *(ebp + eax*4); + + if (!(*current_font_flags & 2)) { + eax = eax & 0x0FF0000FF; + } + // jump 6842 + + + // loc_682AC7 + if (*current_font_flags & 1) { + // jnz loc_682853 + } + eax = RCT2_ADDRESS(0x0141FD45, uint8)[ebp * 8]; + if (*current_font_flags & 2) { + eax |= 0x0A0A00; + } + // jmp loc_682842 + + // skip_char + al = *buffer; + buffer++; + if (al < 0x20) { + // jb skip_cont + } + if (al >= 0x9C) { + // jnb short skip_char + } + if (al >= 0x8E) { + // jnb colour_char + } + // jmp short skip_char + + } From 99c7b23452077048aa9c248433530844a0256d6e Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sun, 18 May 2014 16:02:02 +0200 Subject: [PATCH 35/53] Second pass of gfx_draw_string. Still buggy --- src/gfx.c | 683 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 384 insertions(+), 299 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index ced773d864..9a5b968f5e 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1261,358 +1261,443 @@ void gfx_draw_string_left(rct_drawpixelinfo *dpi, int format, void *args, int co gfx_draw_string(dpi, buffer, colour, x, y); } + +void colour_char(int al, uint16* current_font_flags) { + + int eax; + uint32* ebp; + + // colour_char + eax = al & 0xFF; + // mov ebp, g1_elements+13320h + ebp = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 0x13320, uint32); + // mov eax, [ebp+eax*4+0] + eax = ebp[eax*4]; + + if (!(*current_font_flags & 2)) { + eax = eax & 0x0FF0000FF; + } + // Store current colour? + RCT2_GLOBAL(0x009ABE05, uint32) = eax; + RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; + +} + + +void sub_682AC7(int ebp, int* eax, uint16* current_font_flags) { + + // loc_682AC7 + *eax = RCT2_ADDRESS(0x0141FD45, uint8)[ebp * 8]; + if (*current_font_flags & 2) { + *eax |= 0x0A0A00; + } + // Store current colour? + RCT2_GLOBAL(0x009ABE05, uint32) = *eax; + RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; + *eax = 0; + // jmp loc_682842 + +} + + /** * * rct2: 0x00682702 * dpi (edi) - * format (esi) + * buffer (esi) * colour (al) * x (cx) * y (dx) */ -void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, int y) +void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, int y) { int eax, ebx, ecx, edx, esi, edi, ebp; - eax = colour; - ebx = 0; - ecx = x; - edx = y; - esi = (int)format; - edi = (int)dpi; - ebp = 0; - RCT2_CALLFUNC_X(0x00682702, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - - gLastDrawStringX = ecx; - gLastDrawStringY = edx; + // eax = colour; + // ebx = 0; + // ecx = x; + // edx = y; + // esi = (int)buffer; + // edi = (int)dpi; + // ebp = 0; + // RCT2_CALLFUNC_X(0x00682702, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + int max_x = x; + int max_y = y; RCT2_GLOBAL(0x00EDF840, uint16) = x; RCT2_GLOBAL(0x00EDF842, uint16) = y; if (colour & 0xFE) { - // jz loc_682853 + // jz loc_682853 } if ((x >= dpi->x + dpi->width) || (x <= dpi->x) || (y >= dpi->y + dpi->height) || (y <= dpi->y)) { return; } - if (colour == 0xFF) { - // jz loc_682853 - } - uint16* current_font_flags = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16); uint16* current_font_sprite_base = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); - // switch_colour: - *current_font_flags = 0; - if (*current_font_sprite_base < 0) { - *current_font_flags |= 4; - if (*current_font_sprite_base != 0xFFFF) { - *current_font_flags |= 8; + if (!(colour == 0xFF)) { + + // switch_colour: + *current_font_flags = 0; + if (*current_font_sprite_base < 0) { + *current_font_flags |= 4; + if (*current_font_sprite_base != 0xFFFF) { + *current_font_flags |= 8; + } + *current_font_sprite_base = 0xE0; + } + // loc_6827A5 + if (!(colour & (1 << 5))) { + *current_font_flags |= 2; } - *current_font_sprite_base = 0xE0; - } - // loc_6827A5 - if (!(ax & (1 << 5))) { - *current_font_flags |= 2; - } - // loc_6827B4 - if (!(colour & 0x40)) { - ebp = al; - // jmp short loc_682AC7 - } - - *current_font_flags |= 1; - colour &= 0x1F; - - ebp = colour; - - if (*current_font_flags & 4) { - if (*current_font_flags & 8) { - // loc_682805 - eax = RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; - eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC46, uint8)[ebp * 8]; + // loc_6827B4 + if (!(colour & 0x40)) { + ebp = colour; + sub_682AC7(ebp, &colour, current_font_flags); + // jmp short loc_682AC7 } else { - // loc_6827E7 - eax = RCT2_ADDRESS(0x0141FC49, uint8)[ebp * 8]; - eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC47, uint8)[ebp * 8]; + *current_font_flags |= 1; + colour &= 0x1F; + + ebp = colour; + + if (*current_font_flags & 4) { + if (*current_font_flags & 8) { + // loc_682805 + eax = RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC46, uint8)[ebp * 8]; + } else { + // loc_6827E7 + eax = RCT2_ADDRESS(0x0141FC49, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC47, uint8)[ebp * 8]; + } + } else { + eax = RCT2_ADDRESS(0x0141FC4A, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + } + // loc_682842 + // Store current colour? ; + RCT2_GLOBAL(0x009ABE05, uint32) = eax; + RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; + eax = 0; + } - } else { - eax = RCT2_ADDRESS(0x0141FC4A, uint8)[ebp * 8]; - eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; - } - // jmp short loc_682842 - - - // ; --------------------------------------------------------------------------- - - - // ; --------------------------------------------------------------------------- - // loc_682842 - RCT2_GLOBAL(0x009ABE05, uint32) = eax; - RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; - eax = 0; - - // loc_682853 - if (y + 0x13 <= dpi->y) { - skip_char; - } - if (dpi->y + dpi->height <= y) { - skip_char; + // jmp short loc_682842 + // jz loc_682853 } - // loc_682875 - al = *format; - format++; + int skip_char = 0; - // skip_cont - if (al == 0) { - return; - } - if (al >= 0x9C) { - // jnb short loc_682888 - } - if (al >= 0x8E) { - // jnb colour_char + // loc_682853 + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; } - // loc_682888 - al -= 0x20; - if (al < 0) { - // jb short loc_6828F5 - } - bx = dpi->x + dpi->width; - if (x >= bx) { - // jge skip_char - } - bx = x + 0x1A; - if (bx < dpi->x) { - // jl short loc_6828E0 - } - ebx = al + *current_font_sprite_base; - cl = cl + (RCT2_ADDRESS(0x0141E9E8, uint32)[ebx] & 0xFF) - // push dword_141E9E8[ebx] - // push ecx - // push edx - // push edi - // push esi + // loc_682875 + // al = *buffer; + // buffer++; - eax = (int)al; - ebx += 0xF15; - esi = (int)format; - edi = (int)dpi; - - RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; + for (uint8 al = *buffer; al > 0; al= *buffer, ++buffer) { + // skip_char + // al = *buffer; + // buffer++; + if (skip_char) { + if (al < 0x20) { + skip_char = 0; + // jb skip_cont + } else if (al >= 0x9C) { + continue; + // jnb short skip_char + } else if (al >= 0x8E) { + al -= 0x8E; + if (*current_font_flags == 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } else { + skip_char = 0; + } + continue; + // jnz short loc_682853 + } + colour_char(al, current_font_flags); + continue; + // jnb colour_char + } else { + continue; + // jmp short skip_char + } + } - RCT2_CALLPROC_X(0x067A46E, eax, ebx, ecx, edx, esi, edi, ebp); + // skip_cont + if (al >= 0x9C) { + // jnb short loc_682888 + // loc_682888 + al -= 0x20; + if (al < 0) { + // jb short loc_6828F5 + // loc_6828F5 + switch (al) { + case 0x0E5: + // jz loc_6829E3 + max_x = RCT2_GLOBAL(0x0EDF840, uint16); + max_y += 0x0A; + if (*current_font_sprite_base <= 0x0E) { + // jbe loc_682875 + break; + } + max_y -= 4; + if (*current_font_sprite_base == 0x1C0) { + // jz loc_682875 + break; + } + max_y -= 0xFFF4; + // jmp loc_682875 + break; + case 0x0E6: + // jz loc_6829AD + max_x = RCT2_GLOBAL(0x0EDF840, uint16); + max_y += 5; + if (*current_font_sprite_base <= 0x0E) { + // jbe loc_682875 + break; + } + max_y -= 2; + if (*current_font_sprite_base == 0x1C0) { + // jz loc_682875 + break; + } + max_y -= 0xFFFA; + // jmp loc_682875 + break; + case 0x0E1: + // jz loc_682A19 + al = *buffer; + buffer++; + max_x = RCT2_GLOBAL(0x0EDF840, uint16); + max_x += al; + // jmp loc_682875 + break; - // pop esi - // pop edi - // pop edx - // pop ecx - // pop eax - - // jmp short loc_682875 - - // loc_6828E0 - ebx = al; - ebx += *current_font_sprite_base; - cl = cl + (RCT2_ADDRESS(0x0141E9E8, uint32)[ebx] & 0xFF); - // jmp short loc_682875 - - // loc_6828F5 - switch (al) { - case 0x0E5: - // jz loc_6829E3 - cx = RCT2_GLOBAL(0x0EDF840, uint16); - dx += 0x0A; - if (*current_font_sprite_base <= 0x0E) { - // jbe loc_682875 - } - dx -= 4; - if (*current_font_sprite_base == 0x1C0) { - // jz loc_682875 - } - dx -= 0xFFF4; - // jmp loc_682875 - case 0x0E6: - // jz loc_6829AD - cx = RCT2_GLOBAL(0x0EDF840, uint16); - dx += 5; - if (*current_font_sprite_base <= 0x0E) { - // jbe loc_682875 - } - dx -= 2; - if (*current_font_sprite_base == 0x1C0) { - // jz loc_682875 - } - dx -= 0xFFFA; - // jmp loc_682875 - case 0x0E1: - // jz loc_682A19 - al = *buffer; - buffer++; - cx = RCT2_GLOBAL(0x0EDF840, uint16); - cx += al; - // jmp loc_682875 - - case 0x0F1: - // jz loc_682A34 - ax = *buffer; - buffer += 2; - cx = RCT2_GLOBAL(0x0EDF840, uint16); - cx += (ax & 0xFF); - dx = RCT2_GLOBAL(0x0EDF842, uint16); - dx += (ax & 0xFF00) >> 8; - // jmp loc_682875 + case 0x0F1: + // jz loc_682A34 + eax = *((uint16*)buffer); + buffer += 2; + max_x = RCT2_GLOBAL(0x0EDF840, uint16); + max_x += (eax & 0xFF); + max_y = RCT2_GLOBAL(0x0EDF842, uint16); + max_y += (eax & 0xFF00) >> 8; + // jmp loc_682875 + break; - case 0x0E7: - // jz loc_682A57 - *current_font_sprite_base = 0x1C0; - // jmp loc_682875 + case 0x0E7: + // jz loc_682A57 + *current_font_sprite_base = 0x1C0; + // jmp loc_682875 + break; - case 0x0E8: - // jz loc_682A65 - *current_font_sprite_base = 0x2A0; - // jmp loc_682875 + case 0x0E8: + // jz loc_682A65 + *current_font_sprite_base = 0x2A0; + // jmp loc_682875 + break; - case 0x0E9: - // jz loc_682A81 - *current_font_sprite_base = 0xE0; - // jmp loc_682875 + case 0x0E9: + // jz loc_682A81 + *current_font_sprite_base = 0xE0; + // jmp loc_682875 + break; - case 0x0EA: - // jz loc_682A73 - *current_font_sprite_base = 0; - // jmp loc_682875 + case 0x0EA: + // jz loc_682A73 + *current_font_sprite_base = 0; + // jmp loc_682875 + break; - case 0x0EB: - // jz loc_682A8F - *current_font_flags |= 2; - // jmp loc_682875 + case 0x0EB: + // jz loc_682A8F + *current_font_flags |= 2; + // jmp loc_682875 + break; - case 0x0EC: - // jz loc_682A9C - *current_font_flags &= 0x0FFFD; - // jmp loc_682875 + case 0x0EC: + // jz loc_682A9C + *current_font_flags &= 0x0FFFD; + // jmp loc_682875 + break; - case 0x0ED: - // jz loc_682AAE - ebp = RCT2_GLOBAL(0x0141F740, uint8); - - // jmp short loc_682AC7 - - case 0x0EE: - // jz loc_682AC0 - ebp = RCT2_GLOBAL(0x0141F741, uint8); + case 0x0ED: + // jz loc_682AAE + ebp = RCT2_GLOBAL(0x0141F740, uint8); + if (*current_font_flags & 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } else { + skip_char = 0; + } + continue; + // jnz loc_682853 + } + sub_682AC7(ebp, &al, current_font_flags); + // jmp short loc_682AC7 + break; + case 0x0EE: + // jz loc_682AC0 + ebp = RCT2_GLOBAL(0x0141F741, uint8); + if (*current_font_flags & 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } else { + skip_char = 0; + } + continue; + // jnz loc_682853 + } + sub_682AC7(ebp, &al, current_font_flags); + // jmp short loc_682AC7 + break; + case 0x0EF: + // jz loc_682AB7 + ebp = RCT2_GLOBAL(0x0141F742, uint8); + if (*current_font_flags & 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } else { + skip_char = 0; + } + continue; + // jnz loc_682853 + } + sub_682AC7(ebp, &al, current_font_flags); + // jmp short loc_682AC7 + break; + case 0x0E2: + // jz loc_682AF7 + eax = *buffer; + buffer++; + if (*current_font_flags & 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + break; + } + } - // jmp short loc_682AC7 + // push ebx + // mov eax, ds:dword_97FCBC[eax*4] + // shl eax, 4 + // mov eax, g1_elements[eax] + // mov bl, [eax+0F9h] + // mov bh, 1 - case 0x0EF: - // jz loc_682AB7 - ebp = RCT2_GLOBAL(0x0141F742, uint8); + eax = RCT2_ADDRESS(0x097FCBC, uint32)[eax*4]; + uint32* g1_element_poss = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, uint32)[eax*16]); + // What on earth is going on here? + g1_element_poss += 0xF9; + ebx = *g1_element_poss + (1 << 8); - // jmp short loc_682AC7 - - case 0x0E2: - // jz loc_682AF7 - eax = *buffer; - buffer++; - if (*current_font_flags & 1) { - // jnz loc_682853 - } + if (!(*current_font_flags & 2)) { + ebx = ebx & 0xFF; + } + RCT2_GLOBAL(0x09ABE05, uint16) = ebx; + ebx = *(g1_element_poss + 0xF7); + RCT2_GLOBAL(0x09ABE07, uint16) = ebx; + ebx = *(g1_element_poss + 0xFA); + RCT2_GLOBAL(0x09ABE09, uint16) = ebx; + + // pop ebx + RCT2_GLOBAL(0x09ABDA4, uint32) = RCT2_GLOBAL(0x09ABE04, uint32); + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } + break; + // jmp loc_682853 + + case 0x0F7: + // jz short loc_68296E + buffer += 4; + if (max_x >= dpi->x + dpi->width) { + skip_char = 1; + break; + } + ebx = *(buffer - 4); + eax = ebx & 0x7FFFF; + rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, rct_g1_element)[eax]); - // push ebx - // mov eax, ds:dword_97FCBC[eax*4] - // shl eax, 4 - // mov eax, g1_elements[eax] - // mov bl, [eax+0F9h] - // mov bh, 1 + gfx_draw_sprite(dpi, ebx, max_x, max_y); - eax = RCT2_ADDRESS(0x097FCBC, uint32)[eax*4]; - rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); - // What on earth is going on here? - bx = *(g1_element + 0xF9) + (1 << 8); + max_x = max_x + g1_element->offset; + // jmp loc_682875 + break; + } - if (!(*current_font_flags & 2)) { - bx = bx & 0xFF; - } - RCT2_GLOBAL(0x09ABE05, uint16) = bx; - bx = *(g1_element + 0xF7); - RCT2_GLOBAL(0x09ABE07, uint16) = bx; - bx = *(g1_element + 0xFA); - RCT2_GLOBAL(0x09ABE09, uint16) = bx; + } + if (x >= dpi->x + dpi->width) { + skip_char = 1; + } + if (x + 0x1A < dpi->x) { + // jl short loc_6828E0 + // loc_6828E0 + ebx = al; + ebx += *current_font_sprite_base; + max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); + continue; + // jmp short loc_682875 + } + ebx = al + *current_font_sprite_base; + max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint32)[ebx] & 0xFF); + // push dword_141E9E8[ebx] + // push ecx + // push edx + // push edi + // push esi - // pop ebx - RCT2_GLOBAL(0x09ABDA4, uint32) = RCT2_GLOBAL(0x09ABE04, uint32); - - // jmp loc_682853 - - case 0x0F7: - // jz short loc_68296E - buffer += 4; - if (cx >= dpi->x + dpi->width) { - skip_char; - } - ebx = *(format - 4); - eax = ebx & 0x7FFFF; - rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, rct_g1_element)[eax]); - - gfx_draw_sprite(dpi, ebx, cx, dx); - - cx += g1_element->offset; - // jmp loc_682875 - - } - // jmp loc_682875 - - // colour_char - al -= 0x8E; - if (*current_font_flags == 1) { - // jnz short loc_682853 - } - eax = eax & 0xFF; - // mov ebp, g1_elements+13320h - ebp = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 0x13320, uint32)); - // mov eax, [ebp+eax*4+0] - eax = *(ebp + eax*4); - - if (!(*current_font_flags & 2)) { - eax = eax & 0x0FF0000FF; - } - // jump 6842 - - - // loc_682AC7 - if (*current_font_flags & 1) { - // jnz loc_682853 - } - eax = RCT2_ADDRESS(0x0141FD45, uint8)[ebp * 8]; - if (*current_font_flags & 2) { - eax |= 0x0A0A00; - } - // jmp loc_682842 - - // skip_char - al = *buffer; - buffer++; - if (al < 0x20) { - // jb skip_cont - } - if (al >= 0x9C) { - // jnb short skip_char - } - if (al >= 0x8E) { - // jnb colour_char - } - // jmp short skip_char + eax = (int)al; + ebx += 0xF15; + ecx = max_x; + edx = max_y; + esi = (int)buffer; + edi = (int)dpi; + RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; + RCT2_CALLPROC_X(0x067A46E, eax, ebx, ecx, edx, esi, edi, ebp); + + // pop esi + // pop edi + // pop edx + // pop ecx + // pop eax + + continue; + // jmp short loc_682875 + + } else if (al >= 0x8E) { + al -= 0x8E; + if (*current_font_flags == 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } else { + skip_char = 0; + } + continue; + // jnz short loc_682853 + } + colour_char(al, current_font_flags); + continue; + // jnb colour_char + } + + } + + gLastDrawStringX = max_x; + gLastDrawStringY = max_y; + } From 702a97b185d5a952c03577f5609daf84d69fc9f0 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sun, 18 May 2014 22:06:08 +0200 Subject: [PATCH 36/53] Fix some bugs, tidy up Still buggy... --- src/gfx.c | 290 ++++++++++++++++++++---------------------------------- 1 file changed, 109 insertions(+), 181 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 9a5b968f5e..35cd38f30f 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1265,14 +1265,9 @@ void gfx_draw_string_left(rct_drawpixelinfo *dpi, int format, void *args, int co void colour_char(int al, uint16* current_font_flags) { int eax; - uint32* ebp; - // colour_char - eax = al & 0xFF; - // mov ebp, g1_elements+13320h - ebp = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 0x13320, uint32); - // mov eax, [ebp+eax*4+0] - eax = ebp[eax*4]; + rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[0x1332]); + eax = g1_element->offset[(al & 0xFF) * 4]; if (!(*current_font_flags & 2)) { eax = eax & 0x0FF0000FF; @@ -1280,7 +1275,6 @@ void colour_char(int al, uint16* current_font_flags) { // Store current colour? RCT2_GLOBAL(0x009ABE05, uint32) = eax; RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; - } @@ -1328,72 +1322,69 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in RCT2_GLOBAL(0x00EDF840, uint16) = x; RCT2_GLOBAL(0x00EDF842, uint16) = y; - if (colour & 0xFE) { - // jz loc_682853 - } - - if ((x >= dpi->x + dpi->width) || (x <= dpi->x) || - (y >= dpi->y + dpi->height) || (y <= dpi->y)) { - return; - } uint16* current_font_flags = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16); uint16* current_font_sprite_base = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); - if (!(colour == 0xFF)) { + if (colour != 0xFE) { - // switch_colour: - *current_font_flags = 0; - if (*current_font_sprite_base < 0) { - *current_font_flags |= 4; - if (*current_font_sprite_base != 0xFFFF) { - *current_font_flags |= 8; - } - *current_font_sprite_base = 0xE0; - } - // loc_6827A5 - if (!(colour & (1 << 5))) { - *current_font_flags |= 2; + if ((x >= dpi->x + dpi->width) || (x <= dpi->x) || + (y >= dpi->y + dpi->height) || (y <= dpi->y)) { + return; } - // loc_6827B4 - if (!(colour & 0x40)) { - ebp = colour; - sub_682AC7(ebp, &colour, current_font_flags); - // jmp short loc_682AC7 - } else { - *current_font_flags |= 1; - colour &= 0x1F; + if (colour != 0xFF) { - ebp = colour; - - if (*current_font_flags & 4) { - if (*current_font_flags & 8) { - // loc_682805 - eax = RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; - eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC46, uint8)[ebp * 8]; - } else { - // loc_6827E7 - eax = RCT2_ADDRESS(0x0141FC49, uint8)[ebp * 8]; - eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC47, uint8)[ebp * 8]; + // switch_colour: + *current_font_flags = 0; + if (*current_font_sprite_base < 0) { + *current_font_flags |= 4; + if (*current_font_sprite_base != 0xFFFF) { + *current_font_flags |= 8; } - } else { - eax = RCT2_ADDRESS(0x0141FC4A, uint8)[ebp * 8]; - eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + *current_font_sprite_base = 0xE0; + } + // loc_6827A5 + if (!(colour & (1 << 5))) { + *current_font_flags |= 2; } - // loc_682842 - // Store current colour? ; - RCT2_GLOBAL(0x009ABE05, uint32) = eax; - RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; - eax = 0; + // loc_6827B4 + if (!(colour & 0x40)) { + ebp = colour; + sub_682AC7(ebp, &colour, current_font_flags); + // jmp short loc_682AC7 + } else { + *current_font_flags |= 1; + colour &= 0x1F; + + ebp = colour; + + if (*current_font_flags & 4) { + if (*current_font_flags & 8) { + // loc_682805 + eax = RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC46, uint8)[ebp * 8]; + } else { + // loc_6827E7 + eax = RCT2_ADDRESS(0x0141FC49, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC47, uint8)[ebp * 8]; + } + } else { + eax = RCT2_ADDRESS(0x0141FC4A, uint8)[ebp * 8]; + eax = eax << 10; + eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + } + // loc_682842 + // Store current colour? ; + RCT2_GLOBAL(0x009ABE05, uint32) = eax; + RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; + eax = 0; + + } } - // jmp short loc_682842 - // jz loc_682853 } - int skip_char = 0; // loc_682853 @@ -1402,20 +1393,15 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } // loc_682875 - // al = *buffer; - // buffer++; - - for (uint8 al = *buffer; al > 0; al= *buffer, ++buffer) { + for (uint8 al = *buffer; al > 0; ++buffer, al = *buffer) { // skip_char // al = *buffer; // buffer++; if (skip_char) { if (al < 0x20) { skip_char = 0; - // jb skip_cont } else if (al >= 0x9C) { continue; - // jnb short skip_char } else if (al >= 0x8E) { al -= 0x8E; if (*current_font_flags == 1) { @@ -1425,117 +1411,89 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in skip_char = 0; } continue; - // jnz short loc_682853 } colour_char(al, current_font_flags); continue; - // jnb colour_char } else { continue; - // jmp short skip_char } } // skip_cont - if (al >= 0x9C) { - // jnb short loc_682888 + if ((al >= 0x8E) && (al < 0x9C)){ + al -= 0x8E; + if (*current_font_flags == 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } else { + skip_char = 0; + } + continue; + } + colour_char(al, current_font_flags); + continue; + } else { // loc_682888 - al -= 0x20; - if (al < 0) { - // jb short loc_6828F5 - // loc_6828F5 + if (al < 0x20) { + al -= 0x20; switch (al) { case 0x0E5: - // jz loc_6829E3 max_x = RCT2_GLOBAL(0x0EDF840, uint16); max_y += 0x0A; if (*current_font_sprite_base <= 0x0E) { - // jbe loc_682875 break; } max_y -= 4; if (*current_font_sprite_base == 0x1C0) { - // jz loc_682875 break; } max_y -= 0xFFF4; - // jmp loc_682875 break; case 0x0E6: - // jz loc_6829AD max_x = RCT2_GLOBAL(0x0EDF840, uint16); max_y += 5; if (*current_font_sprite_base <= 0x0E) { - // jbe loc_682875 break; } max_y -= 2; if (*current_font_sprite_base == 0x1C0) { - // jz loc_682875 break; } max_y -= 0xFFFA; - // jmp loc_682875 break; case 0x0E1: - // jz loc_682A19 al = *buffer; buffer++; max_x = RCT2_GLOBAL(0x0EDF840, uint16); max_x += al; - // jmp loc_682875 break; - case 0x0F1: - // jz loc_682A34 eax = *((uint16*)buffer); buffer += 2; max_x = RCT2_GLOBAL(0x0EDF840, uint16); max_x += (eax & 0xFF); max_y = RCT2_GLOBAL(0x0EDF842, uint16); max_y += (eax & 0xFF00) >> 8; - // jmp loc_682875 break; - - case 0x0E7: - // jz loc_682A57 *current_font_sprite_base = 0x1C0; - // jmp loc_682875 break; - case 0x0E8: - // jz loc_682A65 *current_font_sprite_base = 0x2A0; - // jmp loc_682875 break; - case 0x0E9: - // jz loc_682A81 *current_font_sprite_base = 0xE0; - // jmp loc_682875 break; - case 0x0EA: - // jz loc_682A73 *current_font_sprite_base = 0; - // jmp loc_682875 break; - case 0x0EB: - // jz loc_682A8F *current_font_flags |= 2; - // jmp loc_682875 break; - case 0x0EC: - // jz loc_682A9C *current_font_flags &= 0x0FFFD; - // jmp loc_682875 break; - case 0x0ED: - // jz loc_682AAE ebp = RCT2_GLOBAL(0x0141F740, uint8); if (*current_font_flags & 1) { if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { @@ -1543,14 +1501,11 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } else { skip_char = 0; } - continue; - // jnz loc_682853 + break; } sub_682AC7(ebp, &al, current_font_flags); - // jmp short loc_682AC7 break; case 0x0EE: - // jz loc_682AC0 ebp = RCT2_GLOBAL(0x0141F741, uint8); if (*current_font_flags & 1) { if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { @@ -1558,14 +1513,11 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } else { skip_char = 0; } - continue; - // jnz loc_682853 + break; } sub_682AC7(ebp, &al, current_font_flags); - // jmp short loc_682AC7 break; case 0x0EF: - // jz loc_682AB7 ebp = RCT2_GLOBAL(0x0141F742, uint8); if (*current_font_flags & 1) { if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { @@ -1573,14 +1525,11 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } else { skip_char = 0; } - continue; - // jnz loc_682853 + break; } sub_682AC7(ebp, &al, current_font_flags); - // jmp short loc_682AC7 break; case 0x0E2: - // jz loc_682AF7 eax = *buffer; buffer++; if (*current_font_flags & 1) { @@ -1618,10 +1567,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in skip_char = 1; } break; - // jmp loc_682853 - case 0x0F7: - // jz short loc_68296E buffer += 4; if (max_x >= dpi->x + dpi->width) { skip_char = 1; @@ -1634,67 +1580,49 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in gfx_draw_sprite(dpi, ebx, max_x, max_y); max_x = max_x + g1_element->offset; - // jmp loc_682875 break; } - } - if (x >= dpi->x + dpi->width) { - skip_char = 1; - } - if (x + 0x1A < dpi->x) { - // jl short loc_6828E0 - // loc_6828E0 - ebx = al; - ebx += *current_font_sprite_base; - max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); - continue; - // jmp short loc_682875 - } - ebx = al + *current_font_sprite_base; - max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint32)[ebx] & 0xFF); - // push dword_141E9E8[ebx] - // push ecx - // push edx - // push edi - // push esi - - eax = (int)al; - ebx += 0xF15; - ecx = max_x; - edx = max_y; - esi = (int)buffer; - edi = (int)dpi; - - RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; - - RCT2_CALLPROC_X(0x067A46E, eax, ebx, ecx, edx, esi, edi, ebp); - - // pop esi - // pop edi - // pop edx - // pop ecx - // pop eax - - continue; - // jmp short loc_682875 - - } else if (al >= 0x8E) { - al -= 0x8E; - if (*current_font_flags == 1) { - if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + } else { + al -= 0x20; + if (max_x >= dpi->x + dpi->width) { skip_char = 1; - } else { - skip_char = 0; } - continue; - // jnz short loc_682853 - } - colour_char(al, current_font_flags); - continue; - // jnb colour_char - } + if (max_x + 0x1A < dpi->x) { + ebx = al; + ebx += *current_font_sprite_base; + max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); + continue; + } + ebx = al + *current_font_sprite_base; + max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); + // push dword_141E9E8[ebx] + // push ecx + // push edx + // push edi + // push esi + eax = (int)al; + ebx += 0xF15; + ecx = max_x; + edx = max_y; + esi = (int)buffer; + edi = (int)dpi; + ebp = 0; + + RCT2_GLOBAL(0x00EDF81C, uint32) = 0x20000000; + + RCT2_CALLPROC_X(0x067A46E, eax, ebx, ecx, edx, esi, edi, ebp); + + // pop esi + // pop edi + // pop edx + // pop ecx + // pop eax + + continue; + } + } } gLastDrawStringX = max_x; From c3ea45062b7a377a28c74c1c28f3aea94c93554f Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 22 May 2014 22:01:37 +0200 Subject: [PATCH 37/53] gfx_draw_string complete. Needs tidying --- src/gfx.c | 55 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 35cd38f30f..297c0564d9 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1278,17 +1278,19 @@ void colour_char(int al, uint16* current_font_flags) { } -void sub_682AC7(int ebp, int* eax, uint16* current_font_flags) { +void sub_682AC7(int ebp, uint16* current_font_flags) { + + int eax; // loc_682AC7 - *eax = RCT2_ADDRESS(0x0141FD45, uint8)[ebp * 8]; + eax = RCT2_ADDRESS(0x0141FD45, uint8)[ebp * 8]; if (*current_font_flags & 2) { - *eax |= 0x0A0A00; + eax |= 0x0A0A00; } - // Store current colour? - RCT2_GLOBAL(0x009ABE05, uint32) = *eax; + //Store current colour? + RCT2_GLOBAL(0x009ABE05, uint32) = eax; RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; - *eax = 0; + eax = 0; // jmp loc_682842 } @@ -1325,10 +1327,20 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in uint16* current_font_flags = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16); uint16* current_font_sprite_base = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + int skip_char = 0; + if (colour != 0xFE) { - if ((x >= dpi->x + dpi->width) || (x <= dpi->x) || - (y >= dpi->y + dpi->height) || (y <= dpi->y)) { + if (x >= dpi->x + dpi->width) + return; + + if (x + 0x280 <= dpi->x) + return; + + if (y >= dpi->y + dpi->height) + return; + + if (y + 0x5A <= dpi->y) { return; } @@ -1344,14 +1356,25 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in *current_font_sprite_base = 0xE0; } // loc_6827A5 - if (!(colour & (1 << 5))) { + // also reset bit 5 + if (colour & (1 << 5)) { *current_font_flags |= 2; } + colour &= ~(1 << 5); // loc_6827B4 if (!(colour & 0x40)) { ebp = colour; - sub_682AC7(ebp, &colour, current_font_flags); + if (*current_font_flags & 1) { + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { + skip_char = 1; + } + else { + skip_char = 0; + } + } else { + sub_682AC7(ebp, current_font_flags); + } // jmp short loc_682AC7 } else { *current_font_flags |= 1; @@ -1385,7 +1408,6 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } } } - int skip_char = 0; // loc_682853 if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { @@ -1503,7 +1525,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } break; } - sub_682AC7(ebp, &al, current_font_flags); + sub_682AC7(ebp, current_font_flags); break; case 0x0EE: ebp = RCT2_GLOBAL(0x0141F741, uint8); @@ -1515,7 +1537,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } break; } - sub_682AC7(ebp, &al, current_font_flags); + sub_682AC7(ebp, current_font_flags); break; case 0x0EF: ebp = RCT2_GLOBAL(0x0141F742, uint8); @@ -1527,7 +1549,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } break; } - sub_682AC7(ebp, &al, current_font_flags); + sub_682AC7(ebp, current_font_flags); break; case 0x0E2: eax = *buffer; @@ -1595,6 +1617,9 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in continue; } ebx = al + *current_font_sprite_base; + + ecx = max_x; + max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); // push dword_141E9E8[ebx] // push ecx @@ -1604,7 +1629,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in eax = (int)al; ebx += 0xF15; - ecx = max_x; + edx = max_y; esi = (int)buffer; edi = (int)dpi; From 67b7ca8d1eeb605c6236543bc83ce7d7f428ae0d Mon Sep 17 00:00:00 2001 From: ZedThree Date: Tue, 27 May 2014 19:16:05 +0200 Subject: [PATCH 38/53] Fix use of g1_elements and tidy comments --- src/gfx.c | 95 ++++++++++++++++--------------------------------------- 1 file changed, 28 insertions(+), 67 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 297c0564d9..916b1eecf4 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1308,25 +1308,21 @@ void sub_682AC7(int ebp, uint16* current_font_flags) { void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, int y) { int eax, ebx, ecx, edx, esi, edi, ebp; + rct_g1_element* g1_element; - // eax = colour; - // ebx = 0; - // ecx = x; - // edx = y; - // esi = (int)buffer; - // edi = (int)dpi; - // ebp = 0; - // RCT2_CALLFUNC_X(0x00682702, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - + // Maximum length/height of string int max_x = x; int max_y = y; + // Store original x, y RCT2_GLOBAL(0x00EDF840, uint16) = x; RCT2_GLOBAL(0x00EDF842, uint16) = y; + // uint16* current_font_flags = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16); uint16* current_font_sprite_base = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + // Flag for skipping non-printing characters int skip_char = 0; if (colour != 0xFE) { @@ -1355,76 +1351,62 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } *current_font_sprite_base = 0xE0; } - // loc_6827A5 - // also reset bit 5 if (colour & (1 << 5)) { *current_font_flags |= 2; } colour &= ~(1 << 5); - // loc_6827B4 if (!(colour & 0x40)) { ebp = colour; if (*current_font_flags & 1) { if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { skip_char = 1; - } - else { + } else { skip_char = 0; } } else { sub_682AC7(ebp, current_font_flags); } - // jmp short loc_682AC7 } else { *current_font_flags |= 1; colour &= 0x1F; - ebp = colour; - if (*current_font_flags & 4) { if (*current_font_flags & 8) { - // loc_682805 - eax = RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + eax = RCT2_ADDRESS(0x0141FC48, uint8)[colour * 8]; eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC46, uint8)[ebp * 8]; + eax = eax | RCT2_ADDRESS(0x0141FC46, uint8)[colour * 8]; } else { - // loc_6827E7 - eax = RCT2_ADDRESS(0x0141FC49, uint8)[ebp * 8]; + eax = RCT2_ADDRESS(0x0141FC49, uint8)[colour * 8]; eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC47, uint8)[ebp * 8]; + eax = eax | RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]; } } else { - eax = RCT2_ADDRESS(0x0141FC4A, uint8)[ebp * 8]; + eax = RCT2_ADDRESS(0x0141FC4A, uint8)[colour * 8]; eax = eax << 10; - eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[ebp * 8]; + eax = eax | RCT2_ADDRESS(0x0141FC48, uint8)[colour * 8]; } - // loc_682842 // Store current colour? ; RCT2_GLOBAL(0x009ABE05, uint32) = eax; RCT2_GLOBAL(0x009ABDA4, uint32) = 0x009ABE04; eax = 0; - } } } - - // loc_682853 + if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { skip_char = 1; } - // loc_682875 for (uint8 al = *buffer; al > 0; ++buffer, al = *buffer) { - // skip_char - // al = *buffer; - // buffer++; + + // Skip to the next printing character if (skip_char) { if (al < 0x20) { + // Control codes skip_char = 0; - } else if (al >= 0x9C) { - continue; - } else if (al >= 0x8E) { + } else if (al >= 0x8E && al < 0x9C) { + // Colour codes al -= 0x8E; if (*current_font_flags == 1) { if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { @@ -1440,9 +1422,9 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in continue; } } - - // skip_cont + if ((al >= 0x8E) && (al < 0x9C)){ + // Colour codes al -= 0x8E; if (*current_font_flags == 1) { if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { @@ -1455,8 +1437,8 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in colour_char(al, current_font_flags); continue; } else { - // loc_682888 if (al < 0x20) { + // Control codes al -= 0x20; switch (al) { case 0x0E5: @@ -1552,7 +1534,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in sub_682AC7(ebp, current_font_flags); break; case 0x0E2: - eax = *buffer; + al = *buffer; buffer++; if (*current_font_flags & 1) { if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { @@ -1561,29 +1543,19 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } } - // push ebx - // mov eax, ds:dword_97FCBC[eax*4] - // shl eax, 4 - // mov eax, g1_elements[eax] - // mov bl, [eax+0F9h] - // mov bh, 1 - - eax = RCT2_ADDRESS(0x097FCBC, uint32)[eax*4]; - uint32* g1_element_poss = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, uint32)[eax*16]); - // What on earth is going on here? - g1_element_poss += 0xF9; - ebx = *g1_element_poss + (1 << 8); + eax = RCT2_ADDRESS(0x097FCBC, uint32)[al*4]; + g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); + ebx = g1_element->offset[0xF9] + (1 << 8); if (!(*current_font_flags & 2)) { ebx = ebx & 0xFF; } RCT2_GLOBAL(0x09ABE05, uint16) = ebx; - ebx = *(g1_element_poss + 0xF7); + ebx = g1_element->offset[0xF7]; RCT2_GLOBAL(0x09ABE07, uint16) = ebx; - ebx = *(g1_element_poss + 0xFA); + ebx = g1_element->offset[0xFA]; RCT2_GLOBAL(0x09ABE09, uint16) = ebx; - // pop ebx RCT2_GLOBAL(0x09ABDA4, uint32) = RCT2_GLOBAL(0x09ABE04, uint32); if ((y + 0x13 <= dpi->y) || (dpi->y + dpi->height <= y)) { skip_char = 1; @@ -1597,7 +1569,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } ebx = *(buffer - 4); eax = ebx & 0x7FFFF; - rct_g1_element* g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, rct_g1_element)[eax]); + g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, rct_g1_element)[eax]); gfx_draw_sprite(dpi, ebx, max_x, max_y); @@ -1621,11 +1593,6 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in ecx = max_x; max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); - // push dword_141E9E8[ebx] - // push ecx - // push edx - // push edi - // push esi eax = (int)al; ebx += 0xF15; @@ -1639,12 +1606,6 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in RCT2_CALLPROC_X(0x067A46E, eax, ebx, ecx, edx, esi, edi, ebp); - // pop esi - // pop edi - // pop edx - // pop ecx - // pop eax - continue; } } From 504ce150ea2485cc24c2a3da348ed30b8f6b7cf3 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Tue, 27 May 2014 19:58:31 +0200 Subject: [PATCH 39/53] Fix bug in gfx_get_string_width --- src/gfx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 916b1eecf4..456f788442 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1041,6 +1041,7 @@ void gfx_redraw_screen_rect(short left, short top, short right, short bottom) } /** + * Return the width of the string in buffer * * rct2: 0x006C2321 * buffer (esi) @@ -1050,9 +1051,8 @@ int gfx_get_string_width(char *buffer) int base; int width; - char curr_char; + uint8 curr_char; - curr_char = 0; base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); width = 0; From 55183d05897368315fcbf71ec6004c4c3bb2f097 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Tue, 27 May 2014 20:00:44 +0200 Subject: [PATCH 40/53] draw_string_centred --- src/gfx.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/gfx.c b/src/gfx.c index 456f788442..5b45d2b781 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -900,7 +900,18 @@ void gfx_transpose_palette(int pal, unsigned char product) */ void gfx_draw_string_centred(rct_drawpixelinfo *dpi, int format, int x, int y, int colour, void *args) { - RCT2_CALLPROC_X(0x006C1D6C, colour, format, x, y, (int)args, (int)dpi, 0); + char* buffer; + buffer = (char*)0x0141ED68; + format_string(buffer, format, args); + + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; + + int width = gfx_get_string_width(buffer); + + if (width <= 0xFFF) { + x -= width / 2; + gfx_draw_string(dpi, buffer, colour, x, y); + } } /** From 4fdba86b0168696dbc6511d12d0aafa3145e1adb Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 29 May 2014 15:43:38 +0200 Subject: [PATCH 41/53] Add address for common string format buffer --- src/addresses.h | 2 ++ src/gfx.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 912461a9b3..974a9c7507 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -258,6 +258,8 @@ #define RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID 0x0141E9AE #define RCT2_ADDRESS_CURRENT_ROTATION 0x0141E9E0 +#define RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER 0x0141ED68 + #define RCT2_ADDRESS_WATER_RAISE_COST 0x0141F738 #define RCT2_ADDRESS_WATER_LOWER_COST 0x0141F73C diff --git a/src/gfx.c b/src/gfx.c index 5b45d2b781..c19b433554 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1188,7 +1188,7 @@ void gfx_draw_string_right(rct_drawpixelinfo* dpi, int format, void* args, int c char* buffer; short text_width; - buffer = (char*)0x0141ED68; + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); format_string(buffer, format, args); // Measure text width @@ -1267,7 +1267,7 @@ void gfx_draw_string_left(rct_drawpixelinfo *dpi, int format, void *args, int co { char* buffer; - buffer = (char*)0x0141ED68; + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); format_string(buffer, format, args); gfx_draw_string(dpi, buffer, colour, x, y); } From 130796052f66d7a68e1675f56f0cffd1860dcb7d Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 29 May 2014 15:44:33 +0200 Subject: [PATCH 42/53] More string functions --- src/gfx.c | 55 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index c19b433554..e1c3c1bcc9 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -901,15 +901,19 @@ void gfx_transpose_palette(int pal, unsigned char product) void gfx_draw_string_centred(rct_drawpixelinfo *dpi, int format, int x, int y, int colour, void *args) { char* buffer; - buffer = (char*)0x0141ED68; + short text_width; + + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); format_string(buffer, format, args); RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; - int width = gfx_get_string_width(buffer); + // Measure text width + text_width = gfx_get_string_width(buffer); - if (width <= 0xFFF) { - x -= width / 2; + // Draw the text centred + if (text_width <= 0xFFF) { + x -= text_width / 2; gfx_draw_string(dpi, buffer, colour, x, y); } } @@ -1132,15 +1136,19 @@ int gfx_get_string_width(char *buffer) */ void gfx_draw_string_left_clipped(rct_drawpixelinfo* dpi, int format, void* args, int colour, int x, int y, int width) { - RCT2_CALLPROC_X(0x006C1B83, colour, format, x, y, (int)args, (int)dpi, width); + // RCT2_CALLPROC_X(0x006C1B83, colour, format, x, y, (int)args, (int)dpi, width); - //char* buffer; + char* buffer; - //buffer = (char*)0x0141ED68; - //format_string(buffer, format, args); - //rctmem->current_font_sprite_base = 224; - //clip_text(buffer, width); - //gfx_draw_string(dpi, buffer, colour, x, y); + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + format_string(buffer, format, args); + + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; + + // Clip text + RCT2_CALLPROC_X(0x006C2460, 0, 0, 0, 0, (int)buffer, width, 0); + + gfx_draw_string(dpi, buffer, colour, x, y); } /** @@ -1157,19 +1165,24 @@ void gfx_draw_string_left_clipped(rct_drawpixelinfo* dpi, int format, void* args */ void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y, int width) { - RCT2_CALLPROC_X(0x006C1BBA, colour, format, x, y, (int)args, (int)dpi, width); + char* buffer; + short text_width; - //char* buffer; - //short text_width; + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + format_string(buffer, format, args); - //buffer = (char*)0x0141ED68; - //format_string(buffer, format, args); - //rctmem->current_font_sprite_base = 224; - //text_width = clip_text(buffer, width); + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; - //// Draw the text centred - //x -= (text_width - 1) / 2; - //gfx_draw_string(dpi, buffer, colour, x, y); + // Clip text + RCT2_CALLPROC_X(0x006C2460, 0, 0, 0, 0, (int)buffer, width, 0); + // // Measure text width + // text_width = gfx_get_string_width(buffer); + + // Draw the text centred + if (text_width <= 0xFFF) { + x -= text_width / 2; + gfx_draw_string(dpi, buffer, colour, x, y); + } } From b5d11159b38d9e1153ea39b5270fd2d231ade9a1 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 29 May 2014 15:44:47 +0200 Subject: [PATCH 43/53] Start of clip_text --- src/gfx.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/src/gfx.c b/src/gfx.c index e1c3c1bcc9..d35357875b 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1122,6 +1122,116 @@ int gfx_get_string_width(char *buffer) return width; } +/** + * Clip the text in buffer to width and return the new width of the clipped string + * + * rct2: 0x006C2460 + * buffer (esi) + * width (edi) + */ +int gfx_clip_string(char *buffer, int width) +{ + uint16 base; + + if (width < 6) { + *buffer = 0; + return 0; + } + + base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + edx = rct2_address(0x141E9F6, uint32)[base]; + + edx = &(edx + edx*2); + // lea edx, [edx+edx*2] + dx = -(edx & 0xFFFF); + dx += width; + eax = 0; + cx = 0; + max_x = 0; + ebp = buffer; + + + // loc_6C2485: ; CODE XREF: clip_text+42j + for (uint32 al = *buffer; al > 0; buffer++, al = *buffer) { + + if (al < 0x20) { + switch(curr_char) { + case 1: + width = *buffer; + buffer++; + continue; + case 2: + case 3: + case 4: + buffer++; + continue; + case 7: + base = 0x1C0; + // jmp short loc_6C2523 + break; + case 8: + base = 0x2A0; + // jmp short loc_6C2523 + break; + case 9: + base = 0x0E0; + // jmp short loc_6C2523 + break; + case 0x0A: + base = 0; + // jmp short loc_6C2523 + break; + case 0x17: + curr_char = *buffer; + curr_char &= 0x7FFFF; + buffer += 4; + curr_char <<= 4; + width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[curr_char]; + curr_char = 0; + break; + default: + if (curr_char <= 0x10) { + continue; + } + buffer += 2; + if (curr_char <= 0x16) { + continue; + } + buffer += 2; + break; + } + + + // loc_6C2523: ; CODE XREF: clip_text+AEj + // ; clip_text+B5j ... + // movzx edx, byte_141E9F6[ebx] + // lea edx, [edx+edx*2] + // neg dx + // add dx, di + // jmp loc_6C2485 + + } else { + + max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); + + // loc_6C249A: ; CODE XREF: clip_text+AAj + if (max_x > width) { + rct2_global(ebp + 0, uint32) = 0x2E2E2E; + max_x = width; + // pop esi + return; + } + if (max_x > dx) { + continue; + // ja short loc_6C2485 + } + ebp = buffer; + continue; + } + } +} + + /** * Draws i formatted text string left aligned at i specified position but clips * the text with an elipsis if the text width exceeds the specified width. From 9fecf42e518e665aaa4289c3e25832be4d01f158 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 29 May 2014 15:52:42 +0200 Subject: [PATCH 44/53] Tidy up loop on pointer --- src/gfx.c | 241 ++++++++++++++++++++++++++---------------------------- 1 file changed, 118 insertions(+), 123 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index d35357875b..7c14ab2ec6 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1066,26 +1066,24 @@ int gfx_get_string_width(char *buffer) int base; int width; - uint8 curr_char; - base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); width = 0; - for (curr_char = *buffer; curr_char > 0; buffer++, curr_char = *buffer) { + for (uint8* curr_char = buffer; *curr_char > 0; curr_char++) { - if (curr_char >= 0x20) { - width += RCT2_ADDRESS(0x0141E9E8, uint8)[base + (curr_char-0x20)]; + if (*curr_char >= 0x20) { + width += RCT2_ADDRESS(0x0141E9E8, uint8)[base + (*curr_char-0x20)]; continue; } - switch(curr_char) { + switch(*curr_char) { case 1: - width = *buffer; - buffer++; + width = *curr_char; + curr_char++; break; case 2: case 3: case 4: - buffer++; + curr_char++; break; case 7: base = 0x1C0; @@ -1100,22 +1098,19 @@ int gfx_get_string_width(char *buffer) base = 0; break; case 0x17: - curr_char = *buffer; - curr_char &= 0x7FFFF; - buffer += 4; - curr_char <<= 4; - width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[curr_char]; - curr_char = 0; + width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; + curr_char += 4; + *curr_char = 0; break; default: - if (curr_char <= 0x10) { + if (*curr_char <= 0x10) { continue; } - buffer += 2; - if (curr_char <= 0x16) { + curr_char += 2; + if (*curr_char <= 0x16) { continue; } - buffer += 2; + curr_char += 2; break; } } @@ -1129,107 +1124,107 @@ int gfx_get_string_width(char *buffer) * buffer (esi) * width (edi) */ -int gfx_clip_string(char *buffer, int width) -{ - uint16 base; +// int gfx_clip_string(char *buffer, int width) +// { +// uint16 base; - if (width < 6) { - *buffer = 0; - return 0; - } +// if (width < 6) { +// *buffer = 0; +// return 0; +// } - base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); - edx = rct2_address(0x141E9F6, uint32)[base]; +// base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); +// edx = rct2_address(0x141E9F6, uint32)[base]; - edx = &(edx + edx*2); - // lea edx, [edx+edx*2] - dx = -(edx & 0xFFFF); - dx += width; - eax = 0; - cx = 0; - max_x = 0; - ebp = buffer; +// edx = &(edx + edx*2); +// // lea edx, [edx+edx*2] +// dx = -(edx & 0xFFFF); +// dx += width; +// eax = 0; +// cx = 0; +// max_x = 0; +// ebp = buffer; - // loc_6C2485: ; CODE XREF: clip_text+42j - for (uint32 al = *buffer; al > 0; buffer++, al = *buffer) { +// // loc_6C2485: ; CODE XREF: clip_text+42j +// for (uint32 al = *buffer; al > 0; buffer++, al = *buffer) { - if (al < 0x20) { - switch(curr_char) { - case 1: - width = *buffer; - buffer++; - continue; - case 2: - case 3: - case 4: - buffer++; - continue; - case 7: - base = 0x1C0; - // jmp short loc_6C2523 - break; - case 8: - base = 0x2A0; - // jmp short loc_6C2523 - break; - case 9: - base = 0x0E0; - // jmp short loc_6C2523 - break; - case 0x0A: - base = 0; - // jmp short loc_6C2523 - break; - case 0x17: - curr_char = *buffer; - curr_char &= 0x7FFFF; - buffer += 4; - curr_char <<= 4; - width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[curr_char]; - curr_char = 0; - break; - default: - if (curr_char <= 0x10) { - continue; - } - buffer += 2; - if (curr_char <= 0x16) { - continue; - } - buffer += 2; - break; - } +// if (al < 0x20) { +// switch(curr_char) { +// case 1: +// width = *buffer; +// buffer++; +// continue; +// case 2: +// case 3: +// case 4: +// buffer++; +// continue; +// case 7: +// base = 0x1C0; +// // jmp short loc_6C2523 +// break; +// case 8: +// base = 0x2A0; +// // jmp short loc_6C2523 +// break; +// case 9: +// base = 0x0E0; +// // jmp short loc_6C2523 +// break; +// case 0x0A: +// base = 0; +// // jmp short loc_6C2523 +// break; +// case 0x17: +// curr_char = *buffer; +// curr_char &= 0x7FFFF; +// buffer += 4; +// curr_char <<= 4; +// width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[curr_char]; +// curr_char = 0; +// break; +// default: +// if (curr_char <= 0x10) { +// continue; +// } +// buffer += 2; +// if (curr_char <= 0x16) { +// continue; +// } +// buffer += 2; +// break; +// } - // loc_6C2523: ; CODE XREF: clip_text+AEj - // ; clip_text+B5j ... - // movzx edx, byte_141E9F6[ebx] - // lea edx, [edx+edx*2] - // neg dx - // add dx, di - // jmp loc_6C2485 +// // loc_6C2523: ; CODE XREF: clip_text+AEj +// // ; clip_text+B5j ... +// // movzx edx, byte_141E9F6[ebx] +// // lea edx, [edx+edx*2] +// // neg dx +// // add dx, di +// // jmp loc_6C2485 - } else { +// } else { - max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); +// max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); - // loc_6C249A: ; CODE XREF: clip_text+AAj - if (max_x > width) { - rct2_global(ebp + 0, uint32) = 0x2E2E2E; - max_x = width; - // pop esi - return; - } - if (max_x > dx) { - continue; - // ja short loc_6C2485 - } - ebp = buffer; - continue; - } - } -} +// // loc_6C249A: ; CODE XREF: clip_text+AAj +// if (max_x > width) { +// rct2_global(ebp + 0, uint32) = 0x2E2E2E; +// max_x = width; +// // pop esi +// return; +// } +// if (max_x > dx) { +// continue; +// // ja short loc_6C2485 +// } +// ebp = buffer; +// continue; +// } +// } +// } /** @@ -1275,24 +1270,24 @@ void gfx_draw_string_left_clipped(rct_drawpixelinfo* dpi, int format, void* args */ void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y, int width) { - char* buffer; - short text_width; + // char* buffer; + // short text_width; - buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); - format_string(buffer, format, args); + // buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + // format_string(buffer, format, args); - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; + // RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; - // Clip text - RCT2_CALLPROC_X(0x006C2460, 0, 0, 0, 0, (int)buffer, width, 0); - // // Measure text width - // text_width = gfx_get_string_width(buffer); + // // Clip text + // RCT2_CALLPROC_X(0x006C2460, 0, 0, 0, 0, (int)buffer, width, 0); + // // // Measure text width + // // text_width = gfx_get_string_width(buffer); - // Draw the text centred - if (text_width <= 0xFFF) { - x -= text_width / 2; - gfx_draw_string(dpi, buffer, colour, x, y); - } + // // Draw the text centred + // if (text_width <= 0xFFF) { + // x -= text_width / 2; + // gfx_draw_string(dpi, buffer, colour, x, y); + // } } From 9c9ece2d7bd7310917ad21a1f02fbbf8e0abfd15 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 29 May 2014 21:21:01 +0200 Subject: [PATCH 45/53] clip text mostly working --- src/gfx.c | 188 +++++++++++++++++++++++------------------------------- 1 file changed, 80 insertions(+), 108 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 7c14ab2ec6..c9b2e5ab1e 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1124,107 +1124,81 @@ int gfx_get_string_width(char *buffer) * buffer (esi) * width (edi) */ -// int gfx_clip_string(char *buffer, int width) -// { -// uint16 base; +int gfx_clip_string(char *buffer, int width) +{ + uint16 base; + int edx, ebp; + int max_x; -// if (width < 6) { -// *buffer = 0; -// return 0; -// } + if (width < 6) { + *buffer = 0; + return 0; + } -// base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); -// edx = rct2_address(0x141E9F6, uint32)[base]; + base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + edx = width - (3 * RCT2_ADDRESS(0x141E9F6, uint32)[base]); -// edx = &(edx + edx*2); -// // lea edx, [edx+edx*2] -// dx = -(edx & 0xFFFF); -// dx += width; -// eax = 0; -// cx = 0; -// max_x = 0; -// ebp = buffer; + max_x = 0; + ebp = buffer; + for (uint8* curr_char = buffer; *curr_char > 0; curr_char++) { + if (*curr_char < 0x20) { + switch(*curr_char) { + case 1: + width = *curr_char; + curr_char++; + continue; + case 2: + case 3: + case 4: + curr_char++; + continue; + case 7: + base = 0x1C0; + break; + case 8: + base = 0x2A0; + break; + case 9: + base = 0x0E0; + break; + case 0x0A: + base = 0; + break; + case 0x17: + max_x = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; + curr_char += 4; + *curr_char = 0; + continue; + default: + if (*curr_char <= 0x10) { + continue; + } + curr_char += 2; + if (*curr_char <= 0x16) { + continue; + } + curr_char += 2; + continue; + } -// // loc_6C2485: ; CODE XREF: clip_text+42j -// for (uint32 al = *buffer; al > 0; buffer++, al = *buffer) { + edx = RCT2_ADDRESS(0x141E9F6, uint32)[base]; + edx = width - (3 * RCT2_ADDRESS(0x141E9F6, uint32)[base]); + } -// if (al < 0x20) { -// switch(curr_char) { -// case 1: -// width = *buffer; -// buffer++; -// continue; -// case 2: -// case 3: -// case 4: -// buffer++; -// continue; -// case 7: -// base = 0x1C0; -// // jmp short loc_6C2523 -// break; -// case 8: -// base = 0x2A0; -// // jmp short loc_6C2523 -// break; -// case 9: -// base = 0x0E0; -// // jmp short loc_6C2523 -// break; -// case 0x0A: -// base = 0; -// // jmp short loc_6C2523 -// break; -// case 0x17: -// curr_char = *buffer; -// curr_char &= 0x7FFFF; -// buffer += 4; -// curr_char <<= 4; -// width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[curr_char]; -// curr_char = 0; -// break; -// default: -// if (curr_char <= 0x10) { -// continue; -// } -// buffer += 2; -// if (curr_char <= 0x16) { -// continue; -// } -// buffer += 2; -// break; -// } + max_x += (RCT2_ADDRESS(0x0141E9E8, uint8)[base] & 0xFF); - -// // loc_6C2523: ; CODE XREF: clip_text+AEj -// // ; clip_text+B5j ... -// // movzx edx, byte_141E9F6[ebx] -// // lea edx, [edx+edx*2] -// // neg dx -// // add dx, di -// // jmp loc_6C2485 - -// } else { - -// max_x = max_x + (RCT2_ADDRESS(0x0141E9E8, uint8)[ebx] & 0xFF); - -// // loc_6C249A: ; CODE XREF: clip_text+AAj -// if (max_x > width) { -// rct2_global(ebp + 0, uint32) = 0x2E2E2E; -// max_x = width; -// // pop esi -// return; -// } -// if (max_x > dx) { -// continue; -// // ja short loc_6C2485 -// } -// ebp = buffer; -// continue; -// } -// } -// } + if (max_x > width) { + RCT2_GLOBAL(ebp + 0, uint32) = 0x2E2E2E; + max_x = width; + return; + } + if (max_x <= edx) { + ebp = curr_char; + } + } + return max_x; +} /** @@ -1270,24 +1244,22 @@ void gfx_draw_string_left_clipped(rct_drawpixelinfo* dpi, int format, void* args */ void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y, int width) { - // char* buffer; - // short text_width; + char* buffer; + short text_width; - // buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); - // format_string(buffer, format, args); + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + format_string(buffer, format, args); - // RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; - // // Clip text - // RCT2_CALLPROC_X(0x006C2460, 0, 0, 0, 0, (int)buffer, width, 0); - // // // Measure text width - // // text_width = gfx_get_string_width(buffer); + // Clip text + text_width = gfx_clip_string(buffer, width); - // // Draw the text centred - // if (text_width <= 0xFFF) { - // x -= text_width / 2; - // gfx_draw_string(dpi, buffer, colour, x, y); - // } + // Draw the text centred + if (text_width <= 0xFFF) { + x -= (text_width - 1) / 2; + gfx_draw_string(dpi, buffer, colour, x, y); + } } From 1dc794b038c2c6c1c5f445cbc05e82f1a6594912 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 29 May 2014 23:30:05 +0200 Subject: [PATCH 46/53] Finish clip string --- src/gfx.c | 60 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index c9b2e5ab1e..a546ac8231 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1118,30 +1118,35 @@ int gfx_get_string_width(char *buffer) } /** - * Clip the text in buffer to width and return the new width of the clipped string + * Clip the text in buffer to width, add ellipsis and return the new width of the clipped string * * rct2: 0x006C2460 * buffer (esi) * width (edi) */ -int gfx_clip_string(char *buffer, int width) +int gfx_clip_string(char* buffer, int width) { - uint16 base; - int edx, ebp; - int max_x; + // Location of font sprites + uint16 current_font_sprite_base; + // Width the string has to fit into + int max_width; + // Character to change to ellipsis + char* last_char; + // Width of the string, including ellipsis + int clipped_width; if (width < 6) { *buffer = 0; return 0; } - base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); - edx = width - (3 * RCT2_ADDRESS(0x141E9F6, uint32)[base]); + current_font_sprite_base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]); - max_x = 0; - ebp = buffer; + clipped_width = 0; + last_char = buffer; - for (uint8* curr_char = buffer; *curr_char > 0; curr_char++) { + for (char* curr_char = buffer; *curr_char > 0; curr_char++) { if (*curr_char < 0x20) { switch(*curr_char) { case 1: @@ -1154,19 +1159,19 @@ int gfx_clip_string(char *buffer, int width) curr_char++; continue; case 7: - base = 0x1C0; + current_font_sprite_base = 0x1C0; break; case 8: - base = 0x2A0; + current_font_sprite_base = 0x2A0; break; case 9: - base = 0x0E0; + current_font_sprite_base = 0x0E0; break; case 0x0A: - base = 0; + current_font_sprite_base = 0; break; case 0x17: - max_x = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; + clipped_width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; curr_char += 4; *curr_char = 0; continue; @@ -1181,26 +1186,23 @@ int gfx_clip_string(char *buffer, int width) curr_char += 2; continue; } - - edx = RCT2_ADDRESS(0x141E9F6, uint32)[base]; - edx = width - (3 * RCT2_ADDRESS(0x141E9F6, uint32)[base]); + max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]); } - max_x += (RCT2_ADDRESS(0x0141E9E8, uint8)[base] & 0xFF); + clipped_width += RCT2_ADDRESS(0x0141E9E8, uint8)[current_font_sprite_base + (*curr_char-0x20)]; - if (max_x > width) { - RCT2_GLOBAL(ebp + 0, uint32) = 0x2E2E2E; - max_x = width; - return; + if (clipped_width >= width) { + RCT2_GLOBAL(last_char, uint32) = 0x2E2E2E; + clipped_width = width; + return clipped_width; } - if (max_x <= edx) { - ebp = curr_char; + if (clipped_width <= max_width) { + last_char = curr_char; } } - return max_x; + return clipped_width; } - /** * Draws i formatted text string left aligned at i specified position but clips * the text with an elipsis if the text width exceeds the specified width. @@ -1224,8 +1226,8 @@ void gfx_draw_string_left_clipped(rct_drawpixelinfo* dpi, int format, void* args RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 0xE0; - // Clip text - RCT2_CALLPROC_X(0x006C2460, 0, 0, 0, 0, (int)buffer, width, 0); + // Clip text - return value is not needed + gfx_clip_string(buffer, width); gfx_draw_string(dpi, buffer, colour, x, y); } From 5b41528e2e726445cadeb4de407a2be74c5967bb Mon Sep 17 00:00:00 2001 From: ZedThree Date: Thu, 29 May 2014 23:30:20 +0200 Subject: [PATCH 47/53] Rename variables in get_width to align with clip_string --- src/gfx.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index a546ac8231..ce3c8cdac8 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1061,18 +1061,20 @@ void gfx_redraw_screen_rect(short left, short top, short right, short bottom) * rct2: 0x006C2321 * buffer (esi) */ -int gfx_get_string_width(char *buffer) +int gfx_get_string_width(char* buffer) { - int base; + // Current font sprites + uint16 current_font_sprite_base; + // Width of string int width; - base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + current_font_sprite_base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); width = 0; - for (uint8* curr_char = buffer; *curr_char > 0; curr_char++) { + for (char* curr_char = buffer; *curr_char > 0; curr_char++) { if (*curr_char >= 0x20) { - width += RCT2_ADDRESS(0x0141E9E8, uint8)[base + (*curr_char-0x20)]; + width += RCT2_ADDRESS(0x0141E9E8, uint8)[current_font_sprite_base + (*curr_char-0x20)]; continue; } switch(*curr_char) { @@ -1086,16 +1088,16 @@ int gfx_get_string_width(char *buffer) curr_char++; break; case 7: - base = 0x1C0; + current_font_sprite_base = 0x1C0; break; case 8: - base = 0x2A0; + current_font_sprite_base = 0x2A0; break; case 9: - base = 0x0E0; + current_font_sprite_base = 0x0E0; break; case 0x0A: - base = 0; + current_font_sprite_base = 0; break; case 0x17: width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; From 583fbaa2a4357419632109cf9b37e38881b60454 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Fri, 30 May 2014 14:10:27 +0200 Subject: [PATCH 48/53] Fix some pointer issues --- src/gfx.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index ce3c8cdac8..c2ec96794f 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1064,17 +1064,17 @@ void gfx_redraw_screen_rect(short left, short top, short right, short bottom) int gfx_get_string_width(char* buffer) { // Current font sprites - uint16 current_font_sprite_base; + uint16* current_font_sprite_base; // Width of string int width; - current_font_sprite_base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); width = 0; - for (char* curr_char = buffer; *curr_char > 0; curr_char++) { + for (char* curr_char = buffer; *curr_char != NULL; curr_char++) { if (*curr_char >= 0x20) { - width += RCT2_ADDRESS(0x0141E9E8, uint8)[current_font_sprite_base + (*curr_char-0x20)]; + width += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)]; continue; } switch(*curr_char) { @@ -1088,16 +1088,16 @@ int gfx_get_string_width(char* buffer) curr_char++; break; case 7: - current_font_sprite_base = 0x1C0; + *current_font_sprite_base = 0x1C0; break; case 8: - current_font_sprite_base = 0x2A0; + *current_font_sprite_base = 0x2A0; break; case 9: - current_font_sprite_base = 0x0E0; + *current_font_sprite_base = 0x0E0; break; case 0x0A: - current_font_sprite_base = 0; + *current_font_sprite_base = 0; break; case 0x17: width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; @@ -1129,7 +1129,7 @@ int gfx_get_string_width(char* buffer) int gfx_clip_string(char* buffer, int width) { // Location of font sprites - uint16 current_font_sprite_base; + uint16* current_font_sprite_base; // Width the string has to fit into int max_width; // Character to change to ellipsis @@ -1142,13 +1142,13 @@ int gfx_clip_string(char* buffer, int width) return 0; } - current_font_sprite_base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); - max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]); + current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[*current_font_sprite_base]); clipped_width = 0; last_char = buffer; - for (char* curr_char = buffer; *curr_char > 0; curr_char++) { + for (char* curr_char = buffer; *curr_char != NULL; curr_char++) { if (*curr_char < 0x20) { switch(*curr_char) { case 1: @@ -1161,16 +1161,16 @@ int gfx_clip_string(char* buffer, int width) curr_char++; continue; case 7: - current_font_sprite_base = 0x1C0; + *current_font_sprite_base = 0x1C0; break; case 8: - current_font_sprite_base = 0x2A0; + *current_font_sprite_base = 0x2A0; break; case 9: - current_font_sprite_base = 0x0E0; + *current_font_sprite_base = 0x0E0; break; case 0x0A: - current_font_sprite_base = 0; + *current_font_sprite_base = 0; break; case 0x17: clipped_width = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS + 4, uint16)[(*curr_char & 0x7FFFF) << 4]; @@ -1188,10 +1188,10 @@ int gfx_clip_string(char* buffer, int width) curr_char += 2; continue; } - max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[current_font_sprite_base]); + max_width = width - (3 * RCT2_ADDRESS(0x141E9F6, uint8)[*current_font_sprite_base]); } - clipped_width += RCT2_ADDRESS(0x0141E9E8, uint8)[current_font_sprite_base + (*curr_char-0x20)]; + clipped_width += RCT2_ADDRESS(0x0141E9E8, uint8)[*current_font_sprite_base + (*curr_char-0x20)]; if (clipped_width >= width) { RCT2_GLOBAL(last_char, uint32) = 0x2E2E2E; @@ -1424,8 +1424,8 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in RCT2_GLOBAL(0x00EDF842, uint16) = y; // - uint16* current_font_flags = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16); - uint16* current_font_sprite_base = &RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + uint16* current_font_flags = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16); + uint16* current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); // Flag for skipping non-printing characters int skip_char = 0; From a06f6ade8b42bbe491c84c9d5f5e7a53b62692b5 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sat, 31 May 2014 16:39:40 +0200 Subject: [PATCH 49/53] String functions for wrapped text --- src/gfx.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 124 insertions(+), 16 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index c2ec96794f..2a80c2e1f5 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -1307,15 +1307,62 @@ void gfx_draw_string_right(rct_drawpixelinfo* dpi, int format, void* args, int c int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour) { int eax, ebx, ecx, edx, esi, edi, ebp; + // Location of font sprites + uint16* current_font_sprite_base; + // Location of font flags + uint16 current_font_flags; - eax = colour; - ebx = format; - ecx = x; - edx = y; - esi = (int)args; - edi = (int)dpi; - ebp = width; - RCT2_CALLFUNC_X(0x006C1E53, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + *current_font_sprite_base = 0xE0; + + char* buffer = RCT2_ADDRESS(0x009C383D, char); + + gfx_draw_string(dpi, buffer, colour, dpi->x, dpi->y); + + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + + format_string(buffer, format, args); + + *current_font_sprite_base = 0xE0; + + esi = buffer; + edi = width; + RCT2_CALLFUNC_X(0x006C21E2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + ecx &= 0xFFFF; + edi &= 0xFFFF; + + RCT2_GLOBAL(0x00F43938, uint16) = 0x0A; + + if (ebx > 0xE0) { + RCT2_GLOBAL(0x00F43938, uint16) = 6; + if (ebx != 0x1C0) { + RCT2_GLOBAL(0x00F43938, uint16) = 0x12; + } + } + + if (*buffer == 0x0B) { + RCT2_GLOBAL(0x00F43938, uint16) = RCT2_GLOBAL(0x00F43938, uint16) + 1; + } + + ebx = (RCT2_GLOBAL(0x00F43938, uint16) / 2) * edi; + edx = y - ebx; + + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16) = 0; + + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + + do { + int new_width = gfx_get_string_width(buffer); + new_width /= 2; + gfx_draw_string(dpi, buffer, 0xFE, x - new_width, edx); + + buffer += strlen(buffer) + 1; + + edx += RCT2_GLOBAL(0x00F43938, uint16); + eax = (RCT2_GLOBAL(0x00F43938, uint16) / 2) * edi; + ebx -= eax; + + } while (ebx > 0); return (sint16)(edx & 0xFFFF) - y; } @@ -1334,17 +1381,78 @@ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, i int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int y, int width, int format, int colour) { int eax, ebx, ecx, edx, esi, edi, ebp; + + // eax = colour; + // ebx = format; + // ecx = x; + // edx = y; + // esi = (int)args; + // edi = (int)dpi; + // ebp = width; + // RCT2_CALLFUNC_X(0x006C2105, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + // return (sint16)(edx & 0xFFFF) - y; - eax = colour; - ebx = format; - ecx = x; - edx = y; - esi = (int)args; - edi = (int)dpi; - ebp = width; - RCT2_CALLFUNC_X(0x006C2105, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + // Location of font sprites + uint16* current_font_sprite_base; + // Location of font flags + uint16 current_font_flags; + + current_font_sprite_base = RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16); + *current_font_sprite_base = 0xE0; + + char* buffer = RCT2_ADDRESS(0x009C383D, char); + + gfx_draw_string(dpi, buffer, colour, dpi->x, dpi->y); + + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + + format_string(buffer, format, args); + + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + + *current_font_sprite_base = 0xE0; + + // Add line breaks? Adds \0 rather than \n + // not working for strings with colour code? + esi = buffer; + edi = width; + RCT2_CALLFUNC_X(0x006C21E2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + ecx &= 0xFFFF; + edi &= 0xFFFF; + + // Font height? + RCT2_GLOBAL(0x00F43938, uint16) = 0x0A; + + if (ebx > 0xE0) { + RCT2_GLOBAL(0x00F43938, uint16) = 6; + if (ebx != 0x1C0) { + RCT2_GLOBAL(0x00F43938, uint16) = 0x12; + } + } + + // Number of lines? + ebx = (RCT2_GLOBAL(0x00F43938, uint16) / 2) * edi; + + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16) = 0; + + buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); + esi = buffer; + + edx = y; + + do { + gfx_draw_string(dpi, buffer, 0xFE, x, edx); + + buffer += strlen(buffer) + 1; + + edx += RCT2_GLOBAL(0x00F43938, uint16); + eax = (RCT2_GLOBAL(0x00F43938, uint16) / 2); + ebx -= eax; + + } while (ebx >= 0); return (sint16)(edx & 0xFFFF) - y; + } /** From 8b1c76b1b608fed23139629fa4a164153edd2ea2 Mon Sep 17 00:00:00 2001 From: ZedThree Date: Sat, 31 May 2014 16:43:39 +0200 Subject: [PATCH 50/53] Replace pad_0E with zoom_level --- src/gfx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 2a80c2e1f5..8bdd35d596 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -354,7 +354,7 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot } else { // 00678B7E 00678C83 - if (dpi->pad_0E < 1) { + if (dpi->zoom_level < 1) { // Location in screen buffer? uint8* pixel = top_ * (dpi->width + dpi->pitch) + left_ + dpi->bits; @@ -372,10 +372,10 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot } pixel += length; } - } else if (dpi->pad_0E > 1) { + } else if (dpi->zoom_level > 1) { // 00678C8A 00678D57 right_ = right; - } else if (dpi->pad_0E == 1) { + } else if (dpi->zoom_level == 1) { // 00678C88 00678CEE right = right; } @@ -750,12 +750,12 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y) ebx &= 0x7FFFF; ebx <<= 4; ebx += RCT2_ADDRESS_G1_ELEMENTS; - if (dpi->pad_0E >= 1){ - if (dpi->pad_0E == 1){ + if (dpi->zoom_level >= 1){ + if (dpi->zoom_level == 1){ return; //jump into 0x67bd81 } - if (dpi->pad_0E >= 3){ + if (dpi->zoom_level >= 3){ return;//jump into 0x67FAAE } //jump into 0x67DADA From b5575d31eb7c0e59c0ecb2fcf7617c055719a59c Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 31 May 2014 16:47:30 +0100 Subject: [PATCH 51/53] fix more format string bugs --- src/string_ids.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/string_ids.c b/src/string_ids.c index 11a5703f12..c67eba118f 100644 --- a/src/string_ids.c +++ b/src/string_ids.c @@ -1387,6 +1387,7 @@ void format_string_code(unsigned char format_code, char **dest, char **args) *args += 2; format_string_part(dest, value, args); + (*dest)--; break; case FORMAT_STRING: // Pop argument @@ -1538,7 +1539,7 @@ void format_string_part(char **dest, rct_string_id format, char **args) // args += (format & 0xC00) >> 9; format &= ~0xC00; strcpy(*dest, RCT2_ADDRESS(0x135A8F4 + (format * 32), char)); - *dest = strchr(*dest, 0); + *dest = strchr(*dest, 0) + 1; } else if (format < 0xE000) { // Real name format -= -0xA000; @@ -1546,7 +1547,7 @@ void format_string_part(char **dest, rct_string_id format, char **args) real_names[format % countof(real_names)], real_name_initials[(format >> 10) % countof(real_name_initials)] ); - *dest = strchr(*dest, 0); + *dest = strchr(*dest, 0) + 1; } else { // ? RCT2_CALLPROC_EBPSAFE(RCT2_ADDRESS(0x0095AFB8, uint32)[format]); From 7ae52df001cc0c0e02938d7a01867a60450b770e Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 31 May 2014 16:57:00 +0100 Subject: [PATCH 52/53] fix format_string currency 2dp --- src/string_ids.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/string_ids.c b/src/string_ids.c index c67eba118f..c6d5c7e196 100644 --- a/src/string_ids.c +++ b/src/string_ids.c @@ -1285,9 +1285,7 @@ void format_currency_2dp(char **dest, int value) *dest = dst; // Two decimal places - digit = value % 10; - value /= 10; - *dst++ = '0' + digit; + *dst++ = '0'; digit = value % 10; value /= 10; *dst++ = '0' + digit; From b701eb82220cc1f947d9948042eee85c44dabe66 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 31 May 2014 17:11:26 +0100 Subject: [PATCH 53/53] fix format_string currency --- src/string_ids.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/string_ids.c b/src/string_ids.c index c6d5c7e196..2ce1f8085e 100644 --- a/src/string_ids.c +++ b/src/string_ids.c @@ -1233,6 +1233,7 @@ void format_currency(char **dest, int value) *dest = dst; + value /= 10; if (value == 0) { *dst++ = '0'; } else {