implement import of rct1 scenarios, part 1

This commit is contained in:
IntelOrca 2015-07-14 18:14:43 +01:00 committed by Ted John
parent b2566a7223
commit f0382b9ab2
4 changed files with 327 additions and 4 deletions

View File

@ -14,8 +14,7 @@
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommand>$(TargetDir)\openrct2.exe</LocalDebuggerCommand>
<LocalDebuggerCommandArguments>
</LocalDebuggerCommandArguments>
<LocalDebuggerCommandArguments>C:\Users\Ted\Desktop\rct1ll\Scenarios\sc1.sc4</LocalDebuggerCommandArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release XP|Win32'">
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>

View File

@ -1828,3 +1828,322 @@ bool rideTypeShouldLoseSeparateFlag(rct_ride_entry *ride)
}
#pragma endregion
#pragma region RCT1 Scenario / Saved Game Import
#include "audio/audio.h"
#include "localisation/date.h"
#include "peep/staff.h"
static void rct1_import_s4_properly(rct1_s4 *s4);
static const uint8 RCT1RideTypeConversionTable[] = {
RIDE_TYPE_WOODEN_ROLLER_COASTER,
RIDE_TYPE_STAND_UP_ROLLER_COASTER,
RIDE_TYPE_SUSPENDED_SWINGING_COASTER,
RIDE_TYPE_INVERTED_ROLLER_COASTER,
RIDE_TYPE_JUNIOR_ROLLER_COASTER,
RIDE_TYPE_MINIATURE_RAILWAY,
RIDE_TYPE_MONORAIL,
RIDE_TYPE_MINI_SUSPENDED_COASTER,
RIDE_TYPE_BOAT_RIDE,
RIDE_TYPE_WOODEN_WILD_MOUSE,
RIDE_TYPE_STEEPLECHASE,
RIDE_TYPE_CAR_RIDE,
RIDE_TYPE_LAUNCHED_FREEFALL,
RIDE_TYPE_BOBSLEIGH_COASTER,
RIDE_TYPE_OBSERVATION_TOWER,
RIDE_TYPE_LOOPING_ROLLER_COASTER,
RIDE_TYPE_DINGHY_SLIDE,
RIDE_TYPE_MINE_TRAIN_COASTER,
RIDE_TYPE_CHAIRLIFT,
RIDE_TYPE_CORKSCREW_ROLLER_COASTER,
RIDE_TYPE_MAZE,
RIDE_TYPE_SPIRAL_ROLLER_COASTER,
RIDE_TYPE_GO_KARTS,
RIDE_TYPE_LOG_FLUME,
RIDE_TYPE_RIVER_RAPIDS,
RIDE_TYPE_DODGEMS,
RIDE_TYPE_PIRATE_SHIP,
RIDE_TYPE_SWINGING_INVERTER_SHIP,
RIDE_TYPE_FOOD_STALL,
RIDE_TYPE_FOOD_STALL,
RIDE_TYPE_DRINK_STALL,
RIDE_TYPE_FOOD_STALL,
RIDE_TYPE_SHOP,
RIDE_TYPE_MERRY_GO_ROUND,
RIDE_TYPE_SHOP,
RIDE_TYPE_INFORMATION_KIOSK,
RIDE_TYPE_TOILETS,
RIDE_TYPE_FERRIS_WHEEL,
RIDE_TYPE_MOTION_SIMULATOR,
RIDE_TYPE_3D_CINEMA,
RIDE_TYPE_TOP_SPIN,
RIDE_TYPE_SPACE_RINGS,
RIDE_TYPE_REVERSE_FREEFALL_COASTER,
RIDE_TYPE_SHOP,
RIDE_TYPE_VERTICAL_DROP_ROLLER_COASTER,
RIDE_TYPE_FOOD_STALL,
RIDE_TYPE_TWIST,
RIDE_TYPE_HAUNTED_HOUSE,
RIDE_TYPE_FOOD_STALL,
RIDE_TYPE_CIRCUS_SHOW,
RIDE_TYPE_GHOST_TRAIN,
RIDE_TYPE_TWISTER_ROLLER_COASTER,
RIDE_TYPE_WOODEN_ROLLER_COASTER,
RIDE_TYPE_SIDE_FRICTION_ROLLER_COASTER,
RIDE_TYPE_WILD_MOUSE,
RIDE_TYPE_FOOD_STALL,
RIDE_TYPE_FOOD_STALL,
RIDE_TYPE_SHOP,
RIDE_TYPE_FOOD_STALL,
RIDE_TYPE_VIRGINIA_REEL,
RIDE_TYPE_SPLASH_BOATS,
RIDE_TYPE_MINI_HELICOPTERS,
RIDE_TYPE_LAY_DOWN_ROLLER_COASTER,
RIDE_TYPE_SUSPENDED_MONORAIL,
RIDE_TYPE_NULL,
RIDE_TYPE_REVERSER_ROLLER_COASTER,
RIDE_TYPE_HEARTLINE_TWISTER_COASTER,
RIDE_TYPE_MINI_GOLF,
RIDE_TYPE_NULL,
RIDE_TYPE_ROTO_DROP,
RIDE_TYPE_FLYING_SAUCERS,
RIDE_TYPE_CROOKED_HOUSE,
RIDE_TYPE_MONORAIL_CYCLES,
RIDE_TYPE_COMPACT_INVERTED_COASTER,
RIDE_TYPE_WATER_COASTER,
RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER,
RIDE_TYPE_INVERTED_HAIRPIN_COASTER,
RIDE_TYPE_BOAT_RIDE,
RIDE_TYPE_SHOP,
RIDE_TYPE_RIVER_RAFTS,
RIDE_TYPE_FOOD_STALL,
RIDE_TYPE_ENTERPRISE,
RIDE_TYPE_DRINK_STALL,
RIDE_TYPE_FOOD_STALL,
RIDE_TYPE_DRINK_STALL
};
// rct2: 0x0097F0BC
static const uint8 RCT1ColourConversionTable[] = {
0, 1, 2, 4, 5, 6, 7, 9,
11, 12, 13, 14, 15, 16, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27,
28, 30, 31, 29, 3, 10, 17, 8
};
bool rct1_load_saved_game(const char *path)
{
rct1_s4 *s4;
s4 = malloc(sizeof(rct1_s4));
if (!rct1_read_sv4(path, s4)) {
free(s4);
return false;
}
rct1_import_s4_properly(s4);
free(s4);
return true;
}
bool rct1_load_scenario(const char *path)
{
rct1_s4 *s4;
s4 = malloc(sizeof(rct1_s4));
if (!rct1_read_sc4(path, s4)) {
free(s4);
return false;
}
rct1_import_s4_properly(s4);
free(s4);
scenario_begin();
return true;
}
static void rct1_import_map_elements(rct1_s4 *s4)
{
memcpy(gMapElements, s4->map_elements, 0xC000 * sizeof(rct_map_element));
rct1_clear_extra_tile_entries();
// sub_69F143();
rct1_fix_z();
sub_69F3AB();
sub_6A2730();
rct1_fix_scenery();
rct1_fix_terrain();
rct1_fix_entrance_positions();
rct_map_element *mapElement;
for (int y = 0; y < 256; y++) {
for (int x = 0; x < 256; x++) {
restartTile:
mapElement = map_get_first_element_at(x, y);
do {
switch (map_element_get_type(mapElement)) {
case MAP_ELEMENT_TYPE_TRACK:
x = x;
// map_element_remove(mapElement);
// goto restartTile;
break;
case MAP_ELEMENT_TYPE_ENTRANCE:
// if (mapElement->properties.entrance.type != ENTRANCE_TYPE_PARK_ENTRANCE) {
// map_element_remove(mapElement);
// goto restartTile;
// }
break;
}
} while (!map_element_is_last_for_tile(mapElement++));
}
}
}
static void rct1_import_ride(rct1_s4 *s4, rct_ride *dst, rct1_ride *src)
{
memset(dst, 0, sizeof(rct_ride));
dst->type = RCT1RideTypeConversionTable[src->type];
dst->subtype = src->type;
// Ride name
dst->name = 0;
if (is_user_string_id(src->name)) {
const char *rideName = s4->string_table[(src->name - 0x8000) % 1024];
if (rideName[0] != 0) {
rct_string_id rideNameStringId = user_string_allocate(4, rideName);
if (rideNameStringId != 0) {
dst->name = rideNameStringId;
}
}
}
if (dst->name == 0) {
dst->name = 1;
uint16 *args = (uint16*)&dst->name_arguments;
args[0] = 2 + dst->type;
args[1] = src->name_argument_number;
}
//
dst->status = RIDE_STATUS_CLOSED;
// Station
dst->overall_view = src->overall_view;
for (int i = 0; i < 4; i++) {
dst->station_starts[i] = src->station_starts[i];
dst->station_heights[i] = src->station_height[i];
dst->station_length[i] = src->station_length[i];
dst->station_depart[i] = src->station_depart[i];
dst->entrances[i] = src->entrance[i];
dst->exits[i] = src->exit[i];
}
// Operation
dst->mode = src->operating_mode;
dst->depart_flags = src->depart_flags;
dst->min_waiting_time = src->min_waiting_time;
dst->max_waiting_time = src->max_waiting_time;
dst->operation_option = src->operation_option;
dst->music = src->music;
// Colours
dst->colour_scheme_type = src->colour_scheme;
if (s4->game_version == 108166) {
dst->track_colour_main[0] = RCT1ColourConversionTable[src->track_primary_colour];
dst->track_colour_additional[0] = RCT1ColourConversionTable[src->track_secondary_colour];
dst->track_colour_supports[0] = RCT1ColourConversionTable[src->track_support_colour];
} else {
for (int i = 0; i < 4; i++) {
dst->track_colour_main[i] = RCT1ColourConversionTable[src->track_colour_main[i]];
dst->track_colour_additional[i] = RCT1ColourConversionTable[src->track_colour_additional[i]];
dst->track_colour_supports[i] = RCT1ColourConversionTable[src->track_colour_supports[i]];
}
}
// Maintenance
dst->inspection_interval = src->inspection_interval;
dst->last_inspection = src->last_inspection;
dst->reliability = src->reliability;
dst->unreliability_factor = src->unreliability_factor;
dst->breakdown_reason = src->breakdown_reason;
// Finance
dst->price = src->price;
}
static void rct1_import_s4_properly(rct1_s4 *s4)
{
int mapSize = s4->map_size == 0 ? 128 : s4->map_size;
pause_sounds();
unpause_sounds();
object_unload_all();
map_init(mapSize);
banner_init();
reset_park_entrances();
user_string_clear_all();
reset_sprite_list();
ride_init_all();
window_guest_list_init_vars_a();
staff_reset_modes();
park_init();
finance_init();
date_reset();
window_guest_list_init_vars_b();
window_staff_list_init_vars();
RCT2_GLOBAL(0x0141F570, uint8) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_SHOW_REAL_GUEST_NAMES;
window_new_ride_init_vars();
RCT2_GLOBAL(0x0141F571, uint8) = 4;
news_item_init_queue();
rct_string_id stringId;
rct1_load_default_objects();
reset_loaded_objects();
for (int i = 0; i < MAX_RIDES; i++) {
if (s4->rides[i].type != RIDE_TYPE_NULL) {
rct1_import_ride(s4, GET_RIDE(i), &s4->rides[i]);
}
}
// Map elements
rct1_import_map_elements(s4);
// Finance
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, uint32) = ENCRYPT_MONEY(s4->cash);
RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) = s4->park_entrance_fee;
// Park name
const char *parkName = s4->scenario_name;
if (is_user_string_id((rct_string_id)s4->park_name_string_index)) {
const char *userString = s4->string_table[(s4->park_name_string_index - 0x8000) % 1024];
if (userString[0] != 0) {
parkName = userString;
}
}
stringId = user_string_allocate(4, parkName);
if (stringId != 0) {
RCT2_GLOBAL(RCT2_ADDRESS_PARK_NAME, rct_string_id) = stringId;
RCT2_GLOBAL(RCT2_ADDRESS_PARK_NAME_ARGS, uint32) = 0;
}
// Scenario name
strcpy((char*)RCT2_ADDRESS_SCENARIO_NAME, s4->scenario_name);
// Scenario objective
RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8) = s4->scenario_objective_type;
RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_YEAR, uint8) = s4->scenario_objective_years;
RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_CURRENCY, uint32) = s4->scenario_objective_currency;
RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_NUM_GUESTS, uint16) = s4->scenario_objective_num_guests;
// Restore view
RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_X, uint16) = s4->view_x;
RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_Y, uint16) = s4->view_y;
RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_ZOOM_AND_ROTATION, uint8) = s4->view_zoom;
RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_ZOOM_AND_ROTATION + 1, uint8) = s4->view_rotation;
}
#pragma endregion

View File

@ -511,4 +511,7 @@ void rct1_fix_landscape();
bool vehicleIsHigherInHierarchy(int track_type, char *currentVehicleName, char *comparedVehicleName);
bool rideTypeShouldLoseSeparateFlag(rct_ride_entry *ride);
bool rct1_load_saved_game(const char *path);
bool rct1_load_scenario(const char *path);
#endif

View File

@ -365,10 +365,12 @@ bool rct2_open_file(const char *path)
scenario_load_and_play_from_path(scenarioBasic.path);
return true;
} else if (_stricmp(extension, "td6") == 0 || _stricmp(extension, "td4") == 0) {
return true;
} else if (!_stricmp(extension, "td6") || !_stricmp(extension, "td4")) {
// TODO track design install
return true;
} else if (_stricmp(extension, "sv4") == 0) {
rct1_load_saved_game(path);
} else if (_stricmp(extension, "sc4") == 0) {
rct1_load_scenario(path);
}
return false;