2014-04-02 01:31:55 +02:00
|
|
|
/*****************************************************************************
|
2014-04-27 21:21:55 +02:00
|
|
|
* Copyright (c) 2014 Ted John, Matthias Lanzinger
|
2014-04-02 01:31:55 +02:00
|
|
|
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2014-04-02 01:31:55 +02:00
|
|
|
* This file is part of OpenRCT2.
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2014-04-02 01:31:55 +02:00
|
|
|
* OpenRCT2 is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*****************************************************************************/
|
2014-05-12 02:45:45 +02:00
|
|
|
|
|
|
|
#pragma warning(disable : 4996) // GetVersionExA deprecated
|
2014-04-02 01:31:55 +02:00
|
|
|
|
2015-07-03 12:06:53 +02:00
|
|
|
#include <time.h>
|
2014-04-02 01:31:55 +02:00
|
|
|
#include "addresses.h"
|
2014-10-06 18:36:58 +02:00
|
|
|
#include "audio/audio.h"
|
|
|
|
#include "audio/mixer.h"
|
2014-04-08 01:05:05 +02:00
|
|
|
#include "config.h"
|
2014-10-06 18:36:58 +02:00
|
|
|
#include "drawing/drawing.h"
|
2014-06-21 17:04:13 +02:00
|
|
|
#include "editor.h"
|
2014-04-02 01:31:55 +02:00
|
|
|
#include "game.h"
|
2016-01-05 23:33:47 +01:00
|
|
|
#include "input.h"
|
2015-07-19 01:57:42 +02:00
|
|
|
#include "interface/chat.h"
|
2015-05-19 04:53:37 +02:00
|
|
|
#include "interface/console.h"
|
2014-10-06 18:36:58 +02:00
|
|
|
#include "interface/viewport.h"
|
2014-04-02 17:46:58 +02:00
|
|
|
#include "intro.h"
|
2014-10-06 18:36:58 +02:00
|
|
|
#include "localisation/date.h"
|
|
|
|
#include "localisation/localisation.h"
|
|
|
|
#include "management/news_item.h"
|
2015-08-16 00:19:15 +02:00
|
|
|
#include "network/network.h"
|
2015-05-25 21:36:40 +02:00
|
|
|
#include "network/twitch.h"
|
2014-04-10 19:41:35 +02:00
|
|
|
#include "object.h"
|
2014-10-09 15:31:51 +02:00
|
|
|
#include "openrct2.h"
|
2015-07-14 19:18:10 +02:00
|
|
|
#include "peep/staff.h"
|
2014-10-09 15:03:54 +02:00
|
|
|
#include "platform/platform.h"
|
2015-07-14 19:18:10 +02:00
|
|
|
#include "rct1.h"
|
2014-10-06 18:36:58 +02:00
|
|
|
#include "ride/ride.h"
|
|
|
|
#include "ride/track.h"
|
2014-04-06 18:45:09 +02:00
|
|
|
#include "scenario.h"
|
2014-04-02 01:31:55 +02:00
|
|
|
#include "title.h"
|
2015-11-20 20:41:27 +01:00
|
|
|
#include "util/util.h"
|
2014-10-06 18:36:58 +02:00
|
|
|
#include "world/map.h"
|
|
|
|
#include "world/park.h"
|
|
|
|
#include "world/climate.h"
|
2015-03-29 03:29:07 +02:00
|
|
|
#include "world/scenery.h"
|
2014-10-06 18:36:58 +02:00
|
|
|
#include "world/sprite.h"
|
2014-04-02 01:31:55 +02:00
|
|
|
|
2016-01-09 01:34:34 +01:00
|
|
|
// rct2: 0x0097F67C
|
|
|
|
const char * const RCT2FilePaths[PATH_ID_END] = {
|
|
|
|
"Data\\g1.dat",
|
|
|
|
"Data\\plugin.dat",
|
|
|
|
"Data\\css1.dat",
|
|
|
|
"Data\\css2.dat",
|
|
|
|
"Data\\css4.dat",
|
|
|
|
"Data\\css5.dat",
|
|
|
|
"Data\\css6.dat",
|
|
|
|
"Data\\css7.dat",
|
|
|
|
"Data\\css8.dat",
|
|
|
|
"Data\\css9.dat",
|
|
|
|
"Data\\css11.dat",
|
|
|
|
"Data\\css12.dat",
|
|
|
|
"Data\\css13.dat",
|
|
|
|
"Data\\css14.dat",
|
|
|
|
"Data\\css15.dat",
|
|
|
|
"Data\\css3.dat",
|
|
|
|
"Data\\css17.dat",
|
|
|
|
"Data\\css18.dat",
|
|
|
|
"Data\\css19.dat",
|
|
|
|
"Data\\css20.dat",
|
|
|
|
"Data\\css21.dat",
|
|
|
|
"Data\\css22.dat",
|
|
|
|
"Saved Games\\scores.dat",
|
|
|
|
"Data\\css23.dat",
|
|
|
|
"Data\\css24.dat",
|
|
|
|
"Data\\css25.dat",
|
|
|
|
"Data\\css26.dat",
|
|
|
|
"Data\\css27.dat",
|
|
|
|
"Data\\css28.dat",
|
|
|
|
"Data\\css29.dat",
|
|
|
|
"Data\\css30.dat",
|
|
|
|
"Data\\css31.dat",
|
|
|
|
"Data\\css32.dat",
|
|
|
|
"Data\\css33.dat",
|
|
|
|
"Data\\css34.dat",
|
|
|
|
"Data\\css35.dat",
|
|
|
|
"Data\\css36.dat",
|
|
|
|
"Data\\css37.dat",
|
|
|
|
"Data\\css38.dat",
|
|
|
|
"Data\\CUSTOM1.WAV",
|
|
|
|
"Data\\CUSTOM2.WAV",
|
|
|
|
"Data\\css39.dat",
|
|
|
|
"Data\\css40.dat",
|
|
|
|
"Data\\css41.dat",
|
|
|
|
"Scenarios\\Six Flags Magic Mountain.SC6",
|
|
|
|
"Data\\css42.dat",
|
|
|
|
"Data\\css43.dat",
|
|
|
|
"Data\\css44.dat",
|
|
|
|
"Data\\css45.dat",
|
|
|
|
"Data\\css46.dat",
|
|
|
|
"Data\\css50.dat"
|
|
|
|
};
|
|
|
|
|
2015-07-29 04:06:51 +02:00
|
|
|
uint32 gCurrentDrawCount = 0;
|
|
|
|
|
2016-04-23 12:16:46 +02:00
|
|
|
uint8 gScreenFlags;
|
|
|
|
uint32 gScreenAge;
|
|
|
|
uint8 gSavePromptMode;
|
2016-04-24 01:36:39 +02:00
|
|
|
sint32 gScreenWidth;
|
|
|
|
sint32 gScreenHeight;
|
2016-04-23 12:16:46 +02:00
|
|
|
|
2014-05-23 13:15:08 +02:00
|
|
|
typedef struct tm tm_t;
|
|
|
|
|
2014-05-23 01:53:52 +02:00
|
|
|
void print_launch_information();
|
2014-04-15 01:50:20 +02:00
|
|
|
|
2014-11-23 00:30:03 +01:00
|
|
|
int rct2_init_directories();
|
|
|
|
int rct2_startup_checks();
|
2014-04-02 01:31:55 +02:00
|
|
|
|
2015-12-09 22:42:46 +01:00
|
|
|
static void rct2_draw_fps();
|
2014-04-02 01:31:55 +02:00
|
|
|
|
2015-05-21 04:11:53 +02:00
|
|
|
void rct2_quit()
|
|
|
|
{
|
2016-04-23 12:16:46 +02:00
|
|
|
gSavePromptMode = PM_QUIT;
|
2015-05-21 04:11:53 +02:00
|
|
|
window_save_prompt_open();
|
2016-01-15 16:23:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void rct2_dispose()
|
|
|
|
{
|
2016-01-15 19:18:31 +01:00
|
|
|
gfx_unload_g2();
|
|
|
|
gfx_unload_g1();
|
2016-01-15 16:23:53 +01:00
|
|
|
object_unload_all();
|
2014-05-24 01:00:58 +02:00
|
|
|
}
|
|
|
|
|
2014-11-23 00:30:03 +01:00
|
|
|
int rct2_init()
|
2014-04-02 01:31:55 +02:00
|
|
|
{
|
2014-11-21 19:39:56 +01:00
|
|
|
log_verbose("initialising game");
|
|
|
|
|
2015-07-05 17:19:01 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, uint32) = 0;
|
2014-04-02 01:31:55 +02:00
|
|
|
RCT2_GLOBAL(0x009AC310, char*) = RCT2_GLOBAL(RCT2_ADDRESS_CMDLINE, char*);
|
2015-11-20 20:41:27 +01:00
|
|
|
util_srand((unsigned int)time(0));
|
2014-11-23 00:30:03 +01:00
|
|
|
if (!rct2_init_directories())
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!rct2_startup_checks())
|
|
|
|
return 0;
|
|
|
|
|
2014-04-26 02:16:32 +02:00
|
|
|
config_reset_shortcut_keys();
|
2015-02-27 18:28:45 +01:00
|
|
|
config_shortcut_keys_load();
|
2016-01-05 23:33:47 +01:00
|
|
|
gInputPlaceObjectModifier = PLACE_OBJECT_MODIFIER_NONE;
|
2014-10-09 16:55:47 +02:00
|
|
|
// config_load();
|
2014-12-07 22:58:19 +01:00
|
|
|
|
2016-04-28 13:40:12 +02:00
|
|
|
gfx_load_g1();
|
|
|
|
gfx_load_g2();
|
|
|
|
|
2014-05-24 02:34:17 +02:00
|
|
|
object_list_load();
|
2014-04-06 18:45:09 +02:00
|
|
|
scenario_load_list();
|
2014-09-27 01:41:24 +02:00
|
|
|
|
|
|
|
ride_list_item item = { 253, 0 };
|
|
|
|
track_load_list(item);
|
|
|
|
|
2015-07-29 15:36:21 +02:00
|
|
|
font_sprite_initialise_characters();
|
2015-05-29 21:45:21 +02:00
|
|
|
if (!gOpenRCT2Headless) {
|
|
|
|
platform_init();
|
2015-11-17 01:42:23 +01:00
|
|
|
audio_init_ride_sounds_and_info();
|
2015-05-29 21:45:21 +02:00
|
|
|
}
|
2014-04-08 18:52:39 +02:00
|
|
|
viewport_init_all();
|
2014-04-04 22:46:26 +02:00
|
|
|
news_item_init_queue();
|
2014-05-06 23:04:09 +02:00
|
|
|
reset_park_entrances();
|
2014-11-24 03:58:48 +01:00
|
|
|
user_string_clear_all();
|
2014-06-20 16:31:28 +02:00
|
|
|
reset_sprite_list();
|
2014-04-09 03:39:28 +02:00
|
|
|
ride_init_all();
|
2014-05-06 23:04:09 +02:00
|
|
|
window_guest_list_init_vars_a();
|
2015-07-14 19:18:10 +02:00
|
|
|
staff_reset_modes();
|
2015-02-09 19:32:58 +01:00
|
|
|
map_init(150);
|
2014-04-10 01:22:57 +02:00
|
|
|
park_init();
|
2015-05-29 21:45:21 +02:00
|
|
|
if (!gOpenRCT2Headless)
|
|
|
|
window_title_menu_open();
|
2014-04-10 01:22:57 +02:00
|
|
|
date_reset();
|
|
|
|
climate_reset(CLIMATE_COOL_AND_WET);
|
2015-03-29 03:29:07 +02:00
|
|
|
scenery_set_default_placement_configuration();
|
2014-05-10 00:11:51 +02:00
|
|
|
window_new_ride_init_vars();
|
2014-05-06 23:04:09 +02:00
|
|
|
window_guest_list_init_vars_b();
|
2014-10-07 20:39:52 +02:00
|
|
|
window_staff_list_init_vars();
|
2014-04-02 01:31:55 +02:00
|
|
|
|
2015-05-29 21:45:21 +02:00
|
|
|
if (!gOpenRCT2Headless) {
|
|
|
|
title_load();
|
2014-04-02 01:31:55 +02:00
|
|
|
|
2016-04-24 01:36:39 +02:00
|
|
|
gfx_clear(&gScreenDPI, 10);
|
2015-05-29 21:45:21 +02:00
|
|
|
}
|
2014-11-23 00:30:03 +01:00
|
|
|
|
2015-02-04 18:44:39 +01:00
|
|
|
log_verbose("initialising game finished");
|
2014-11-23 00:30:03 +01:00
|
|
|
return 1;
|
2014-04-02 01:31:55 +02:00
|
|
|
}
|
|
|
|
|
2014-11-23 00:30:03 +01:00
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2014-11-23 00:30:03 +01:00
|
|
|
* rct2: 0x00683499
|
|
|
|
*/
|
|
|
|
int rct2_init_directories()
|
2014-04-02 01:31:55 +02:00
|
|
|
{
|
2015-02-11 23:17:49 +01:00
|
|
|
// windows_get_registry_install_info((rct2_install_info*)0x009AA10C, "RollerCoaster Tycoon 2 Setup", "MS Sans Serif", 0);
|
|
|
|
|
2014-05-03 15:04:40 +02:00
|
|
|
// check install directory
|
2015-06-24 16:36:42 +02:00
|
|
|
if (!platform_original_game_data_exists(gConfigGeneral.game_path)) {
|
|
|
|
log_verbose("install directory does not exist or invalid directory selected, %s", gConfigGeneral.game_path);
|
2014-11-23 00:30:03 +01:00
|
|
|
if (!config_find_or_browse_install_directory()) {
|
2016-01-11 22:59:05 +01:00
|
|
|
utf8 path[MAX_PATH];
|
|
|
|
config_get_default_path(path);
|
|
|
|
log_fatal("Invalid RCT2 installation path. Please correct \"game_path\" in %s.", path);
|
2014-11-23 00:30:03 +01:00
|
|
|
return 0;
|
2015-02-08 04:05:07 +01:00
|
|
|
}
|
2014-05-03 15:04:40 +02:00
|
|
|
}
|
|
|
|
|
2015-09-19 09:29:39 +02:00
|
|
|
char separator[] = {platform_get_path_separator(), 0};
|
|
|
|
|
2015-02-16 23:47:11 +01:00
|
|
|
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char), gConfigGeneral.game_path);
|
2014-04-02 01:31:55 +02:00
|
|
|
|
|
|
|
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH_SLASH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char));
|
2015-09-19 09:29:39 +02:00
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH_SLASH, char), separator);
|
2014-04-02 01:31:55 +02:00
|
|
|
|
|
|
|
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char));
|
2015-09-19 09:29:39 +02:00
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH, char), separator);
|
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH, char), "Saved Games");
|
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH, char), separator);
|
2014-04-02 01:31:55 +02:00
|
|
|
|
|
|
|
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char));
|
2015-09-19 09:29:39 +02:00
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), separator);
|
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), "Scenarios");
|
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), separator);
|
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), "*.SC6");
|
2014-04-02 01:31:55 +02:00
|
|
|
|
|
|
|
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_LANDSCAPES_PATH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char));
|
2015-09-19 09:29:39 +02:00
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_LANDSCAPES_PATH, char), separator);
|
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_LANDSCAPES_PATH, char), "Landscapes");
|
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_LANDSCAPES_PATH, char), separator);
|
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_LANDSCAPES_PATH, char), "*.SC6");
|
2014-04-02 01:31:55 +02:00
|
|
|
|
|
|
|
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char));
|
2015-09-19 09:29:39 +02:00
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), separator);
|
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), "ObjData");
|
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), separator);
|
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), "*.DAT");
|
2014-04-02 01:31:55 +02:00
|
|
|
|
|
|
|
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char));
|
2015-09-19 09:29:39 +02:00
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), separator);
|
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), "Tracks");
|
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), separator);
|
|
|
|
strcat(RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), "*.TD?");
|
2014-04-02 01:31:55 +02:00
|
|
|
|
|
|
|
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH_2, char), RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH, char));
|
2014-11-23 00:30:03 +01:00
|
|
|
return 1;
|
2014-04-02 01:31:55 +02:00
|
|
|
}
|
|
|
|
|
2015-12-22 16:31:51 +01:00
|
|
|
void substitute_path(char *dest, const char *path, const char *filename)
|
2014-05-24 00:52:13 +02:00
|
|
|
{
|
|
|
|
while (*path != '*') {
|
|
|
|
*dest++ = *path++;
|
|
|
|
}
|
|
|
|
strcpy(dest, filename);
|
|
|
|
}
|
|
|
|
|
2014-11-23 00:30:03 +01:00
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2014-11-23 00:30:03 +01:00
|
|
|
* rct2: 0x00674B42
|
|
|
|
*/
|
|
|
|
int rct2_startup_checks()
|
2014-04-02 01:31:55 +02:00
|
|
|
{
|
2014-11-23 00:30:03 +01:00
|
|
|
if (!check_file_paths())
|
|
|
|
return 0;
|
2014-04-02 01:31:55 +02:00
|
|
|
|
2014-11-23 00:30:03 +01:00
|
|
|
return 1;
|
2014-04-02 01:31:55 +02:00
|
|
|
}
|
|
|
|
|
2015-07-04 21:00:32 +02:00
|
|
|
void rct2_draw()
|
|
|
|
{
|
2015-07-11 05:01:58 +02:00
|
|
|
redraw_rain();
|
2015-07-11 04:13:19 +02:00
|
|
|
window_update_all();
|
2015-07-13 04:23:58 +02:00
|
|
|
gfx_invalidate_pickedup_peep();
|
|
|
|
gfx_draw_pickedup_peep();
|
2015-07-11 04:13:19 +02:00
|
|
|
update_rain_animation();
|
|
|
|
update_palette_effects();
|
2015-07-04 21:00:32 +02:00
|
|
|
|
2015-07-19 01:57:42 +02:00
|
|
|
chat_draw();
|
2016-04-24 01:36:39 +02:00
|
|
|
console_draw(&gScreenDPI);
|
2015-07-04 21:00:32 +02:00
|
|
|
|
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) != 0) {
|
|
|
|
//intro
|
2016-04-23 12:16:46 +02:00
|
|
|
} else if (gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) {
|
2015-07-04 21:00:32 +02:00
|
|
|
//title
|
2016-04-24 01:36:39 +02:00
|
|
|
DrawOpenRCT2(0, gScreenHeight - 20);
|
2015-07-04 21:00:32 +02:00
|
|
|
} else {
|
|
|
|
//game
|
|
|
|
}
|
2015-10-20 20:16:30 +02:00
|
|
|
|
2015-12-09 22:42:46 +01:00
|
|
|
if (gConfigGeneral.show_fps) {
|
|
|
|
rct2_draw_fps();
|
|
|
|
}
|
|
|
|
|
2015-07-29 04:06:51 +02:00
|
|
|
gCurrentDrawCount++;
|
2015-07-04 21:00:32 +02:00
|
|
|
}
|
|
|
|
|
2015-12-09 22:42:46 +01:00
|
|
|
static uint32 _lastFPSUpdateTicks;
|
|
|
|
static uint32 _lastFPSTicks;
|
|
|
|
static float _currentFPS;
|
|
|
|
|
|
|
|
static float rct2_measure_fps()
|
|
|
|
{
|
|
|
|
uint32 currentTicks = SDL_GetTicks();
|
|
|
|
if (currentTicks - _lastFPSUpdateTicks > 500) {
|
|
|
|
_lastFPSUpdateTicks = currentTicks;
|
|
|
|
|
|
|
|
uint32 frameDelta = currentTicks - _lastFPSTicks;
|
|
|
|
_currentFPS = 1000.0f / frameDelta;
|
|
|
|
}
|
|
|
|
_lastFPSTicks = currentTicks;
|
|
|
|
return _currentFPS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rct2_draw_fps()
|
|
|
|
{
|
2016-04-24 01:36:39 +02:00
|
|
|
rct_drawpixelinfo *dpi = &gScreenDPI;
|
|
|
|
int x = gScreenWidth / 2;
|
2015-12-09 22:42:46 +01:00
|
|
|
int y = 2;
|
|
|
|
|
|
|
|
// Measure FPS
|
|
|
|
float fps = rct2_measure_fps();
|
|
|
|
|
|
|
|
// Format string
|
|
|
|
utf8 buffer[64];
|
|
|
|
utf8 *ch = buffer;
|
|
|
|
ch = utf8_write_codepoint(ch, FORMAT_MEDIUMFONT);
|
|
|
|
ch = utf8_write_codepoint(ch, FORMAT_OUTLINE);
|
|
|
|
ch = utf8_write_codepoint(ch, FORMAT_WHITE);
|
|
|
|
|
|
|
|
const char *formatString = (_currentFPS >= 100.0f ? "%.0f" : "%.1f");
|
|
|
|
sprintf(ch, formatString, _currentFPS);
|
|
|
|
|
|
|
|
// Draw Text
|
|
|
|
int stringWidth = gfx_get_string_width(buffer);
|
|
|
|
x = x - (stringWidth / 2);
|
|
|
|
gfx_draw_string(dpi, buffer, 0, x, y);
|
|
|
|
|
|
|
|
// Make area dirty so the text doesn't get drawn over the last
|
|
|
|
gfx_set_dirty_blocks(x - 16, y - 4, gLastDrawStringX + 16, 16);
|
|
|
|
}
|
|
|
|
|
2016-03-05 13:20:02 +01:00
|
|
|
bool rct2_open_file(const char *path)
|
2014-05-02 14:32:44 +02:00
|
|
|
{
|
2014-09-10 20:36:11 +02:00
|
|
|
char *extension = strrchr(path, '.');
|
2016-03-05 13:20:02 +01:00
|
|
|
if (extension == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
2014-09-10 20:36:11 +02:00
|
|
|
extension++;
|
|
|
|
|
2014-10-09 02:36:59 +02:00
|
|
|
if (_stricmp(extension, "sv6") == 0) {
|
2014-11-26 17:27:21 +01:00
|
|
|
strcpy((char*)RCT2_ADDRESS_SAVED_GAMES_PATH_2, path);
|
2014-09-10 20:36:11 +02:00
|
|
|
game_load_save(path);
|
2016-04-15 22:52:15 +02:00
|
|
|
gFirstTimeSave = 0;
|
2016-03-05 13:20:02 +01:00
|
|
|
return true;
|
2014-10-09 02:36:59 +02:00
|
|
|
} else if (_stricmp(extension, "sc6") == 0) {
|
2014-09-10 20:36:11 +02:00
|
|
|
// TODO scenario install
|
|
|
|
rct_scenario_basic scenarioBasic;
|
|
|
|
strcpy(scenarioBasic.path, path);
|
|
|
|
scenario_load_and_play_from_path(scenarioBasic.path);
|
2016-03-05 13:20:02 +01:00
|
|
|
return true;
|
2014-10-09 02:36:59 +02:00
|
|
|
} else if (_stricmp(extension, "td6") == 0 || _stricmp(extension, "td4") == 0) {
|
2014-09-10 20:36:11 +02:00
|
|
|
// TODO track design install
|
2016-03-05 13:20:02 +01:00
|
|
|
return true;
|
2015-07-14 19:14:43 +02:00
|
|
|
} else if (_stricmp(extension, "sv4") == 0) {
|
2016-04-22 20:26:15 +02:00
|
|
|
if (rct1_load_saved_game(path)) {
|
|
|
|
game_load_init();
|
|
|
|
}
|
2015-07-14 19:14:43 +02:00
|
|
|
} else if (_stricmp(extension, "sc4") == 0) {
|
2016-04-22 20:26:15 +02:00
|
|
|
if (rct1_load_scenario(path)) {
|
|
|
|
scenario_begin();
|
|
|
|
}
|
2014-09-10 20:36:11 +02:00
|
|
|
}
|
2014-09-25 03:39:17 +02:00
|
|
|
|
2016-03-05 13:20:02 +01:00
|
|
|
return false;
|
2014-09-10 20:36:11 +02:00
|
|
|
}
|
2014-05-02 14:32:44 +02:00
|
|
|
|
2014-11-23 00:30:03 +01:00
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2014-11-23 00:30:03 +01:00
|
|
|
* rct2: 0x00674C95
|
|
|
|
*/
|
|
|
|
int check_file_paths()
|
2016-01-09 01:34:34 +01:00
|
|
|
{
|
|
|
|
for (int pathId = 0; pathId < PATH_ID_END; pathId++) {
|
|
|
|
if (!check_file_path(pathId)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2014-11-23 00:30:03 +01:00
|
|
|
return 1;
|
2014-06-28 20:45:25 +02:00
|
|
|
}
|
|
|
|
|
2014-11-23 00:30:03 +01:00
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2014-11-23 00:30:03 +01:00
|
|
|
* rct2: 0x00674CA5
|
|
|
|
*/
|
|
|
|
int check_file_path(int pathId)
|
2014-06-28 20:45:25 +02:00
|
|
|
{
|
2015-08-29 14:12:52 +02:00
|
|
|
const utf8* path = get_file_path(pathId);
|
|
|
|
SDL_RWops *file = SDL_RWFromFile(path, "rb");
|
2014-06-28 20:45:25 +02:00
|
|
|
|
2014-11-23 00:30:03 +01:00
|
|
|
switch (pathId) {
|
2015-02-07 00:15:11 +01:00
|
|
|
case PATH_ID_G1:
|
2015-08-29 14:12:52 +02:00
|
|
|
if (file == NULL) {
|
2014-11-23 00:30:03 +01:00
|
|
|
log_fatal("Could not find file %s", path);
|
|
|
|
return 0;
|
2014-06-28 20:45:25 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PATH_ID_CUSTOM1:
|
2016-01-09 01:34:34 +01:00
|
|
|
if (file != NULL) {
|
|
|
|
// Store file size in music_custom1_size @ 0x009AF164
|
|
|
|
gRideMusicInfoList[36]->length = (uint32)SDL_RWsize(file);
|
|
|
|
}
|
2014-06-28 20:45:25 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PATH_ID_CUSTOM2:
|
2016-01-09 01:34:34 +01:00
|
|
|
if (file != NULL) {
|
|
|
|
// Store file size in music_custom2_size @ 0x009AF16E
|
|
|
|
gRideMusicInfoList[37]->length = (uint32)SDL_RWsize(file);
|
|
|
|
}
|
2014-06-28 20:45:25 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-01-09 01:34:34 +01:00
|
|
|
if (file != NULL) {
|
2015-08-29 14:12:52 +02:00
|
|
|
SDL_RWclose(file);
|
2014-06-19 13:52:34 +02:00
|
|
|
}
|
2014-11-23 00:30:03 +01:00
|
|
|
|
|
|
|
return 1;
|
2014-06-19 13:52:34 +02:00
|
|
|
}
|
|
|
|
|
2016-01-09 01:25:09 +01:00
|
|
|
void rct2_update()
|
2014-04-02 01:31:55 +02:00
|
|
|
{
|
|
|
|
int tick, tick2;
|
|
|
|
|
2015-08-29 03:04:54 +02:00
|
|
|
tick = SDL_GetTicks();
|
2014-04-02 01:31:55 +02:00
|
|
|
|
2015-10-03 20:00:29 +02:00
|
|
|
tick2 = tick - RCT2_GLOBAL(RCT2_ADDRESS_LAST_TICK_COUNT, sint32);
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TICKS_SINCE_LAST_UPDATE, sint16) = tick2 = min(tick2, 500);
|
2014-04-02 01:31:55 +02:00
|
|
|
|
2015-10-03 20:00:29 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_LAST_TICK_COUNT, sint32) = tick;
|
2016-04-24 03:02:56 +02:00
|
|
|
if (game_is_not_paused()) {
|
|
|
|
gPaletteEffectFrame += tick2;
|
|
|
|
}
|
2014-04-02 01:31:55 +02:00
|
|
|
|
|
|
|
// TODO: screenshot countdown process
|
|
|
|
|
2015-08-16 00:19:15 +02:00
|
|
|
network_update();
|
|
|
|
|
2014-10-09 01:30:22 +02:00
|
|
|
// check_cmdline_arg();
|
2014-04-02 01:31:55 +02:00
|
|
|
// Screens
|
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) != 0)
|
|
|
|
intro_update();
|
2016-04-23 12:16:46 +02:00
|
|
|
else if ((gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) && !gOpenRCT2Headless)
|
2014-04-02 01:31:55 +02:00
|
|
|
title_update();
|
|
|
|
else
|
|
|
|
game_update();
|
2015-05-19 04:53:37 +02:00
|
|
|
|
2015-09-23 10:39:45 +02:00
|
|
|
//stop_completed_sounds(); // removes other sounds that are no longer playing in directsound
|
2015-07-04 21:00:32 +02:00
|
|
|
|
2015-05-25 21:36:40 +02:00
|
|
|
twitch_update();
|
2015-07-19 01:57:42 +02:00
|
|
|
chat_update();
|
2015-05-19 04:53:37 +02:00
|
|
|
console_update();
|
2014-04-04 20:59:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2014-04-04 20:59:32 +02:00
|
|
|
* rct2: 0x00674E6C
|
|
|
|
*/
|
2015-08-29 14:12:52 +02:00
|
|
|
const utf8 *get_file_path(int pathId)
|
2014-04-04 20:59:32 +02:00
|
|
|
{
|
2016-01-09 01:34:34 +01:00
|
|
|
static utf8 path[MAX_PATH];
|
2015-02-16 23:47:11 +01:00
|
|
|
strcpy(path, gConfigGeneral.game_path);
|
2014-06-15 15:10:35 +02:00
|
|
|
|
|
|
|
// Make sure base path is terminated with a slash
|
2016-01-09 01:34:34 +01:00
|
|
|
if (strlen(path) == 0 || path[strlen(path) - 1] != platform_get_path_separator()) {
|
|
|
|
if (strlen(path) >= MAX_PATH - 1) {
|
|
|
|
log_error("Path for %s too long", RCT2FilePaths[pathId]);
|
2014-06-15 15:10:35 +02:00
|
|
|
path[0] = '\0';
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
2015-09-19 09:29:39 +02:00
|
|
|
char separator[] = {platform_get_path_separator(), 0};
|
|
|
|
strcat(path, separator);
|
2014-06-15 15:10:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Concatenate file path
|
2016-01-09 01:34:34 +01:00
|
|
|
if (strlen(path) + strlen(RCT2FilePaths[pathId]) > MAX_PATH) {
|
|
|
|
log_error("Path for %s too long", RCT2FilePaths[pathId]);
|
2014-06-15 15:10:35 +02:00
|
|
|
path[0] = '\0';
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
2015-10-02 17:44:18 +02:00
|
|
|
char *pathp = path + strnlen(path, sizeof(path));
|
2016-01-09 01:34:34 +01:00
|
|
|
strcat(path, RCT2FilePaths[pathId]);
|
2015-10-02 17:44:18 +02:00
|
|
|
while (*pathp) {
|
|
|
|
if (*pathp == '\\') *pathp = platform_get_path_separator();
|
|
|
|
pathp++;
|
|
|
|
}
|
|
|
|
|
2014-06-15 15:10:35 +02:00
|
|
|
return path;
|
2014-04-08 18:52:39 +02:00
|
|
|
}
|
2016-04-19 23:09:42 +02:00
|
|
|
|
|
|
|
uint32 get_file_extension_type(const utf8 *path)
|
|
|
|
{
|
|
|
|
const utf8 *extension = path_get_extension(path);
|
|
|
|
if (strcicmp(extension, ".dat") == 0) return FILE_EXTENSION_DAT;
|
|
|
|
if (strcicmp(extension, ".sc4") == 0) return FILE_EXTENSION_SC4;
|
|
|
|
if (strcicmp(extension, ".sv4") == 0) return FILE_EXTENSION_SV4;
|
|
|
|
if (strcicmp(extension, ".td4") == 0) return FILE_EXTENSION_TD4;
|
|
|
|
if (strcicmp(extension, ".sc6") == 0) return FILE_EXTENSION_SC6;
|
|
|
|
if (strcicmp(extension, ".sv6") == 0) return FILE_EXTENSION_SV6;
|
|
|
|
if (strcicmp(extension, ".td6") == 0) return FILE_EXTENSION_TD6;
|
2016-04-22 19:37:04 +02:00
|
|
|
return FILE_EXTENSION_UNKNOWN;
|
2016-04-28 13:40:12 +02:00
|
|
|
}
|