OpenRCT2/src/rct2.c

606 lines
17 KiB
C
Raw Normal View History

/*****************************************************************************
* Copyright (c) 2014 Ted John, Matthias Lanzinger
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
2015-10-20 20:16:30 +02:00
*
* This file is part of OpenRCT2.
2015-10-20 20:16:30 +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
#include <setjmp.h>
2015-07-03 12:06:53 +02:00
#include <time.h>
#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"
#include "game.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"
2015-11-21 19:59:48 +01:00
#include "interface/screenshot.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"
#include "peep/staff.h"
#include "platform/platform.h"
#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"
#include "title.h"
2014-10-06 18:36:58 +02:00
#include "world/map.h"
#include "world/park.h"
#include "world/climate.h"
#include "world/scenery.h"
2014-10-06 18:36:58 +02:00
#include "world/sprite.h"
2015-07-29 04:06:51 +02:00
uint32 gCurrentDrawCount = 0;
2014-05-23 13:15:08 +02:00
typedef struct tm tm_t;
void print_launch_information();
2014-04-15 01:50:20 +02:00
int rct2_init_directories();
int rct2_startup_checks();
static void rct2_update_2();
static jmp_buf _end_update_jump;
2015-05-21 04:11:53 +02:00
void rct2_quit()
{
RCT2_GLOBAL(RCT2_ADDRESS_SAVE_PROMPT_MODE, uint16) = PM_QUIT;
window_save_prompt_open();
}
int rct2_init()
{
log_verbose("initialising game");
2015-07-05 17:19:01 +02:00
RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, uint32) = 0;
RCT2_GLOBAL(0x009AC310, char*) = RCT2_GLOBAL(RCT2_ADDRESS_CMDLINE, char*);
2014-04-08 18:52:39 +02:00
get_system_time();
2015-05-19 04:53:37 +02:00
srand((unsigned int)time(0));
RCT2_GLOBAL(0x009DEA69, short) = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_DAY, short);
RCT2_GLOBAL(0x009DEA6B, short) = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_MONTH, short);
if (!rct2_init_directories())
return 0;
if (!rct2_startup_checks())
return 0;
2014-04-26 02:16:32 +02:00
config_reset_shortcut_keys();
config_shortcut_keys_load();
RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) = 0;
2014-10-09 16:55:47 +02:00
// config_load();
2014-12-07 22:58:19 +01:00
2014-05-24 02:34:17 +02:00
object_list_load();
2014-04-06 18:45:09 +02:00
scenario_load_list();
ride_list_item item = { 253, 0 };
track_load_list(item);
2014-04-04 20:59:32 +02:00
gfx_load_g1();
gfx_load_g2();
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-04 17:31:32 +02:00
get_local_time();
reset_park_entrances();
user_string_clear_all();
reset_sprite_list();
2014-04-09 03:39:28 +02:00
ride_init_all();
window_guest_list_init_vars_a();
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);
scenery_set_default_placement_configuration();
2014-05-10 00:11:51 +02:00
window_new_ride_init_vars();
window_guest_list_init_vars_b();
window_staff_list_init_vars();
2015-05-29 21:45:21 +02:00
if (!gOpenRCT2Headless) {
title_load();
2015-05-29 21:45:21 +02:00
gfx_clear(RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo), 10);
}
2015-02-04 18:44:39 +01:00
log_verbose("initialising game finished");
return 1;
}
/**
2015-10-20 20:16:30 +02:00
*
* rct2: 0x00683499
*/
int rct2_init_directories()
{
// 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
if (!platform_original_game_data_exists(gConfigGeneral.game_path)) {
log_verbose("install directory does not exist or invalid directory selected, %s", gConfigGeneral.game_path);
if (!config_find_or_browse_install_directory()) {
log_fatal("Invalid RCT2 installation path. Please correct in config.ini.");
return 0;
}
2014-05-03 15:04:40 +02:00
}
char separator[] = {platform_get_path_separator(), 0};
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char), gConfigGeneral.game_path);
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH_SLASH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char));
strcat(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH_SLASH, char), separator);
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char));
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);
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char));
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");
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_LANDSCAPES_PATH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char));
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");
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char));
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");
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char));
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?");
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH_2, char), RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH, char));
return 1;
}
2014-05-24 00:52:13 +02:00
void subsitute_path(char *dest, const char *path, const char *filename)
{
while (*path != '*') {
*dest++ = *path++;
}
strcpy(dest, filename);
}
/**
2015-10-20 20:16:30 +02:00
*
* rct2: 0x00674B42
*/
int rct2_startup_checks()
{
if (!check_file_paths())
return 0;
if (!check_files_integrity())
return 0;
2015-10-20 20:16:30 +02:00
return 1;
}
void rct2_update()
{
2014-04-06 18:45:09 +02:00
// Set 0x009DE564 to the value of esp
// RCT2 sets the stack pointer to the value of this address when ending the current game tick from anywhere
2014-05-19 22:53:14 +02:00
#ifdef _MSC_VER
__asm {
mov eax, 009DE564h
2014-04-06 18:45:09 +02:00
mov [eax], esp
}
2014-05-19 22:53:14 +02:00
#else
__asm__ ( "\
\n\
movl $0x009DE564, %%eax \n\
movl %%esp, (%%eax) \n\
2014-05-19 22:53:14 +02:00
" : : : "eax" );
#endif
if (!setjmp(_end_update_jump))
rct2_update_2();
}
2015-07-04 21:00:32 +02:00
void rct2_draw()
{
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();
2015-07-04 21:00:32 +02:00
console_draw(RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo));
if (RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) != 0) {
//intro
} else if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TITLE_DEMO) {
//title
DrawOpenRCT2(0, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) - 20);
} else {
//game
}
2015-10-20 20:16:30 +02:00
2015-07-29 04:06:51 +02:00
gCurrentDrawCount++;
2015-11-21 19:59:48 +01:00
screenshot_gif_update();
2015-07-04 21:00:32 +02:00
}
2014-09-10 20:36:11 +02:00
int rct2_open_file(const char *path)
{
2014-09-10 20:36:11 +02:00
char *extension = strrchr(path, '.');
if (extension == NULL)
return 0;
extension++;
2014-10-09 02:36:59 +02:00
if (_stricmp(extension, "sv6") == 0) {
strcpy((char*)RCT2_ADDRESS_SAVED_GAMES_PATH_2, path);
2014-09-10 20:36:11 +02:00
game_load_save(path);
2014-09-25 03:39:17 +02:00
return 1;
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);
2014-10-09 02:36:59 +02:00
} else if (_stricmp(extension, "td6") == 0 || _stricmp(extension, "td4") == 0) {
2014-09-25 03:39:17 +02:00
return 1;
2014-09-10 20:36:11 +02:00
} else if (!_stricmp(extension, "td6") || !_stricmp(extension, "td4")) {
// TODO track design install
2014-09-25 03:39:17 +02:00
return 1;
2014-09-10 20:36:11 +02:00
}
2014-09-25 03:39:17 +02:00
return 0;
2014-09-10 20:36:11 +02:00
}
/**
2015-10-20 20:16:30 +02:00
*
* rct2: 0x00674C95
*/
int check_file_paths()
2014-06-19 13:51:54 +02:00
{
for (int pathId = 0; pathId < PATH_ID_END; pathId++)
if (!check_file_path(pathId))
2014-06-19 13:51:54 +02:00
return 0;
return 1;
}
/**
2015-10-20 20:16:30 +02:00
*
* rct2: 0x00674CA5
*/
int check_file_path(int pathId)
{
const utf8* path = get_file_path(pathId);
SDL_RWops *file = SDL_RWFromFile(path, "rb");
switch (pathId) {
case PATH_ID_G1:
if (file == NULL) {
// A data file is missing from the installation directory. The original implementation
// asks for a CD-ROM path at this point and stores it in cdrom_path @ 0x9AA318.
// The file_on_cdrom[pathId] @ 0x009AA0B flag is set to 1 as well.
// For PATH_ID_SIXFLAGS_MAGICMOUNTAIN (and the now removed PATH_ID_SIXFLAGS_BUILDYOUROWN),
// the original implementation always assumes they are stored on CD-ROM.
// This has been removed for now for the sake of simplicity and could be added
// later in a more convenient way using the INI file.
log_fatal("Could not find file %s", path);
return 0;
}
break;
case PATH_ID_CUSTOM1:
if (file != NULL)
2015-11-16 23:39:40 +01:00
gRideMusicInfoList[36]->length = (uint32)SDL_RWsize(file); // Store file size in music_custom1_size @ 0x009AF164
break;
case PATH_ID_CUSTOM2:
if (file != NULL)
2015-11-16 23:39:40 +01:00
gRideMusicInfoList[37]->length = (uint32)SDL_RWsize(file); // Store file size in music_custom2_size @ 0x009AF16E
break;
}
if (file != NULL)
SDL_RWclose(file);
return 1;
}
/**
2015-10-20 20:16:30 +02:00
*
* rct2: 0x00674C0B
*/
int check_files_integrity()
2014-06-19 13:52:34 +02:00
{
int i;
const char *path;
#ifdef _WIN32
HANDLE file;
2014-06-19 13:52:34 +02:00
WIN32_FIND_DATA find_data;
for (i = 0; files_to_check[i].pathId != PATH_ID_END; i++) {
path = get_file_path(files_to_check[i].pathId);
file = FindFirstFile(path, &find_data);
if (file == INVALID_HANDLE_VALUE || find_data.nFileSizeLow != files_to_check[i].fileSize) {
2014-06-19 13:52:34 +02:00
if (file != INVALID_HANDLE_VALUE)
FindClose(file);
log_fatal("Integrity check failed for %s", path);
return 0;
2014-06-19 13:52:34 +02:00
}
FindClose(file);
}
#else
STUB();
#endif // _WIN32
return 1;
2014-06-19 13:52:34 +02:00
}
void rct2_update_2()
{
int tick, tick2;
tick = SDL_GetTicks();
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);
2015-10-03 20:00:29 +02:00
RCT2_GLOBAL(RCT2_ADDRESS_LAST_TICK_COUNT, sint32) = tick;
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) == 0)
RCT2_GLOBAL(RCT2_ADDRESS_PALETTE_EFFECT_FRAME_NO, sint32) += tick2;
if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) != 0)
2015-10-03 20:00:29 +02:00
RCT2_GLOBAL(RCT2_ADDRESS_TICKS_SINCE_LAST_UPDATE, sint16) = 31;
// TODO: screenshot countdown process
2015-08-16 00:19:15 +02:00
network_update();
// check_cmdline_arg();
// Screens
if (RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) != 0)
intro_update();
2015-06-24 18:22:12 +02:00
else if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TITLE_DEMO)
title_update();
else
game_update();
2015-05-19 04:53:37 +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
}
2014-04-09 18:06:47 +02:00
void rct2_endupdate()
{
longjmp(_end_update_jump, 0);
}
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
*/
const utf8 *get_file_path(int pathId)
2014-04-04 20:59:32 +02:00
{
static utf8 path[MAX_PATH]; // get_file_path_buffer @ 0x009E3605
2014-04-04 20:59:32 +02:00
// The original implementation checks if the file is on CD-ROM here (file_on_cdrom[pathId] @ 0x009AA0B1).
// If so, the CD-ROM path (cdrom_path @ 0x9AA318) is used instead. This has been removed for now for
// the sake of simplicity.
strcpy(path, gConfigGeneral.game_path);
2014-06-15 15:10:35 +02:00
// Make sure base path is terminated with a slash
if (strlen(path) == 0 || path[strlen(path) - 1] != platform_get_path_separator())
2014-06-15 15:10:35 +02:00
{
if (strlen(path) >= MAX_PATH - 1)
{
log_error("Path for %s too long", file_paths[pathId]);
2014-06-15 15:10:35 +02:00
path[0] = '\0';
return path;
}
char separator[] = {platform_get_path_separator(), 0};
strcat(path, separator);
2014-06-15 15:10:35 +02:00
}
// Concatenate file path
if (strlen(path) + strlen(file_paths[pathId]) > MAX_PATH) {
log_error("Path for %s too long", file_paths[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));
2014-06-15 15:10:35 +02:00
strcat(path, file_paths[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
}
2014-04-27 13:04:45 +02:00
/**
* Obtains basic system versions and capabilities.
* rct2: 0x004076B1
*/
void get_system_info()
{
#ifdef _WIN32
2014-04-27 13:04:45 +02:00
OSVERSIONINFO versionInfo;
SYSTEM_INFO sysInfo;
MEMORYSTATUS memInfo;
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&versionInfo)) {
2014-04-27 13:04:45 +02:00
RCT2_GLOBAL(RCT2_ADDRESS_OS_PLATFORM_ID, uint32) = versionInfo.dwPlatformId;
RCT2_GLOBAL(RCT2_ADDRESS_OS_MAJOR_VERSION, uint32) = versionInfo.dwMajorVersion;
RCT2_GLOBAL(RCT2_ADDRESS_OS_MINOR_VERSION, uint32) = versionInfo.dwMinorVersion;
RCT2_GLOBAL(RCT2_ADDRESS_OS_BUILD_NUMBER, uint32) = versionInfo.dwBuildNumber;
} else {
#endif // _WIN32
2014-04-27 13:04:45 +02:00
RCT2_GLOBAL(RCT2_ADDRESS_OS_PLATFORM_ID, uint32) = -1;
RCT2_GLOBAL(RCT2_ADDRESS_OS_MAJOR_VERSION, uint32) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_OS_MINOR_VERSION, uint32) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_OS_BUILD_NUMBER, uint32) = 0;
#ifdef _WIN32
2014-04-27 13:04:45 +02:00
}
GetSystemInfo(&sysInfo);
// RCT2 only has 2 bytes reserved for OEM_ID even though it should be a DWORD
2014-05-12 02:45:45 +02:00
RCT2_GLOBAL(RCT2_ADDRESS_SYS_OEM_ID, uint16) = (uint16)sysInfo.dwOemId;
2014-04-27 13:04:45 +02:00
RCT2_GLOBAL(RCT2_ADDRESS_SYS_CPU_LEVEL, uint16) = sysInfo.wProcessorLevel;
RCT2_GLOBAL(RCT2_ADDRESS_SYS_CPU_REVISION, uint16) = sysInfo.wProcessorRevision;
RCT2_GLOBAL(RCT2_ADDRESS_SYS_CPU_NUMBER, uint32) = sysInfo.dwNumberOfProcessors;
GlobalMemoryStatus(&memInfo);
RCT2_GLOBAL(RCT2_ADDRESS_MEM_TOTAL_PHYSICAL, uint32) = memInfo.dwTotalPhys;
RCT2_GLOBAL(RCT2_ADDRESS_MEM_TOTAL_PAGEFILE, uint32) = memInfo.dwTotalPageFile;
RCT2_GLOBAL(RCT2_ADDRESS_MEM_TOTAL_VIRTUAL, uint32) = memInfo.dwTotalVirtual;
2014-05-20 12:49:27 +02:00
DWORD size = 80;
2014-05-12 02:45:45 +02:00
GetUserName((char*)RCT2_ADDRESS_OS_USER_NAME, &size);
2014-04-27 13:04:45 +02:00
size = 80;
2014-05-12 02:45:45 +02:00
GetComputerName((char*)RCT2_ADDRESS_OS_COMPUTER_NAME, &size);
2014-04-27 13:04:45 +02:00
// Screen Display Width/Height but RCT_ADDRESS_SCREEN_HEIGHT/WIDTH already taken?
RCT2_GLOBAL(0x01423C08, sint32) = GetSystemMetrics(SM_CXSCREEN);
RCT2_GLOBAL(0x01423C0C, sint32) = GetSystemMetrics(SM_CYSCREEN);
HDC screenHandle = GetDC(NULL);
if (screenHandle) {
2014-04-27 13:04:45 +02:00
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_CAP_BPP, sint32) = GetDeviceCaps(screenHandle, BITSPIXEL);
2015-10-20 20:16:30 +02:00
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_CAP_RASTER_STRETCH, sint32) = GetDeviceCaps(screenHandle, RASTERCAPS) >> 8;
2014-04-27 13:04:45 +02:00
ReleaseDC(NULL, screenHandle);
} else {
2014-04-27 13:04:45 +02:00
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_CAP_BPP, sint32) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_CAP_RASTER_STRETCH, sint32) = 0;
}
RCT2_GLOBAL(0x01423C1C, uint32) = (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_CAP_BPP, sint32) >= 8);
if (RCT2_GLOBAL(RCT2_ADDRESS_OS_MAJOR_VERSION, uint32) < 4 || RCT2_GLOBAL(0x1423C10, sint32) < 4)
RCT2_GLOBAL(0x1423C18, sint32) = 0;
else
RCT2_GLOBAL(0x1423C18, sint32) = 1;
RCT2_GLOBAL(0x01423C20, uint32) = (SDL_HasMMX() == SDL_TRUE);
#else
STUB();
#endif // _WIN32
2014-04-27 13:04:45 +02:00
}
2014-04-08 18:52:39 +02:00
/**
* Obtains os system time (day, month, year and day of the week).
* rct2: 0x00407671
*/
void get_system_time()
{
2015-09-29 23:35:15 +02:00
rct2_date date;
platform_get_date(&date);
RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_DAY, sint16) = date.day;
RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_MONTH, sint16) = date.month;
RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_YEAR, sint16) = date.year;
RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_DAYOFWEEK, sint16) = date.day_of_week;
2014-04-04 20:59:32 +02:00
}
2014-05-04 17:31:32 +02:00
/**
* Obtains os local time (hour and minute)
* rct2: 0x006C45E7;
*/
void get_local_time()
{
2015-09-29 23:35:15 +02:00
rct2_time t;
platform_get_time(&t);
RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_HOUR, sint16) = t.hour;
RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_MINUTE, sint16) = t.minute;
2014-05-04 17:31:32 +02:00
}
2014-04-04 20:59:32 +02:00
/**
2014-04-06 18:45:09 +02:00
* RCT2 and this DLL can not free each other's allocated memory blocks. Use this to allocate memory if RCT2 is still able to
* free it.
2014-04-04 20:59:32 +02:00
* rct2: 0x004068B2
*/
void *rct2_malloc(size_t numBytes)
{
Make it work on Linux Right now the project is decompiled to the point where it is feasible to try porting it to another platform. It doesn't work 100% correctly, but it's nearing this state. To port it to Linux I mmapped the openrct2.exe into expected places, disabled two offending calls (RCT2_CALLPROC_EBPSAFE(0x0040701D) and RCT2_CALLPROC_X(0x006E7FF3…)), replaced memory management routines with generic ones and removed all the function-pointer calls. A basic, non-exhaustive check is included to verify that memory is loaded correctly in place. That last bit is probably the most intrusive one, but had to be done, as the calling convention on Linux differs from the one on Windows. It could possibly be emulated (just like RCT2_CALLFUNC_X) until dependency on exe is dropped. It is possible to completely remove calls out to original code by commenting out contents of RCT2_CALLFUNC_X, right now this will yield working UI, but no rendering of peeps, rides or rest of world. This can be used as a benchmark or test platform for correctness of implementation. The data sections will still be required for now. Assets are expected to be in specific places, so to launch it, following needs to satisified: * $build/data/ has to have contents of $RCT2/Data/ * $build/data/ (same as above) has to have contents of $repo/data/ * $build/ObjData/ has to have contents of $RCT2/ObjData/ * $build/../openrct2.exe has to be $repo/openrct2.exe (as of 976ea0d) Keep in mind you can symlink stuff and that filesystems are case sensitive! You can copy more of required data to possibly improve your experience. Pretty much all of this commit will possibly have to be reverted by the time OpenRCT2 gains independence. Remember to build with -DDISABLE_NETWORK=ON -DDISABLE_HTTP_TWITCH=ON
2015-09-22 23:36:05 +02:00
#ifdef _WIN32
2014-04-04 20:59:32 +02:00
return RCT2_CALLFUNC_1(0x004068B2, void*, size_t, numBytes);
Make it work on Linux Right now the project is decompiled to the point where it is feasible to try porting it to another platform. It doesn't work 100% correctly, but it's nearing this state. To port it to Linux I mmapped the openrct2.exe into expected places, disabled two offending calls (RCT2_CALLPROC_EBPSAFE(0x0040701D) and RCT2_CALLPROC_X(0x006E7FF3…)), replaced memory management routines with generic ones and removed all the function-pointer calls. A basic, non-exhaustive check is included to verify that memory is loaded correctly in place. That last bit is probably the most intrusive one, but had to be done, as the calling convention on Linux differs from the one on Windows. It could possibly be emulated (just like RCT2_CALLFUNC_X) until dependency on exe is dropped. It is possible to completely remove calls out to original code by commenting out contents of RCT2_CALLFUNC_X, right now this will yield working UI, but no rendering of peeps, rides or rest of world. This can be used as a benchmark or test platform for correctness of implementation. The data sections will still be required for now. Assets are expected to be in specific places, so to launch it, following needs to satisified: * $build/data/ has to have contents of $RCT2/Data/ * $build/data/ (same as above) has to have contents of $repo/data/ * $build/ObjData/ has to have contents of $RCT2/ObjData/ * $build/../openrct2.exe has to be $repo/openrct2.exe (as of 976ea0d) Keep in mind you can symlink stuff and that filesystems are case sensitive! You can copy more of required data to possibly improve your experience. Pretty much all of this commit will possibly have to be reverted by the time OpenRCT2 gains independence. Remember to build with -DDISABLE_NETWORK=ON -DDISABLE_HTTP_TWITCH=ON
2015-09-22 23:36:05 +02:00
#else
//log_warning("call rct's function");
return malloc(numBytes);
#endif // _WIN32
2014-04-06 18:45:09 +02:00
}
/**
* RCT2 and this DLL can not free each other's allocated memory blocks. Use this to reallocate memory if RCT2 is still able to
* free it.
* rct2: 0x004068BD
*/
void *rct2_realloc(void *block, size_t numBytes)
{
Make it work on Linux Right now the project is decompiled to the point where it is feasible to try porting it to another platform. It doesn't work 100% correctly, but it's nearing this state. To port it to Linux I mmapped the openrct2.exe into expected places, disabled two offending calls (RCT2_CALLPROC_EBPSAFE(0x0040701D) and RCT2_CALLPROC_X(0x006E7FF3…)), replaced memory management routines with generic ones and removed all the function-pointer calls. A basic, non-exhaustive check is included to verify that memory is loaded correctly in place. That last bit is probably the most intrusive one, but had to be done, as the calling convention on Linux differs from the one on Windows. It could possibly be emulated (just like RCT2_CALLFUNC_X) until dependency on exe is dropped. It is possible to completely remove calls out to original code by commenting out contents of RCT2_CALLFUNC_X, right now this will yield working UI, but no rendering of peeps, rides or rest of world. This can be used as a benchmark or test platform for correctness of implementation. The data sections will still be required for now. Assets are expected to be in specific places, so to launch it, following needs to satisified: * $build/data/ has to have contents of $RCT2/Data/ * $build/data/ (same as above) has to have contents of $repo/data/ * $build/ObjData/ has to have contents of $RCT2/ObjData/ * $build/../openrct2.exe has to be $repo/openrct2.exe (as of 976ea0d) Keep in mind you can symlink stuff and that filesystems are case sensitive! You can copy more of required data to possibly improve your experience. Pretty much all of this commit will possibly have to be reverted by the time OpenRCT2 gains independence. Remember to build with -DDISABLE_NETWORK=ON -DDISABLE_HTTP_TWITCH=ON
2015-09-22 23:36:05 +02:00
#ifdef _WIN32
2014-04-06 18:45:09 +02:00
return RCT2_CALLFUNC_2(0x004068BD, void*, void*, size_t, block, numBytes);
Make it work on Linux Right now the project is decompiled to the point where it is feasible to try porting it to another platform. It doesn't work 100% correctly, but it's nearing this state. To port it to Linux I mmapped the openrct2.exe into expected places, disabled two offending calls (RCT2_CALLPROC_EBPSAFE(0x0040701D) and RCT2_CALLPROC_X(0x006E7FF3…)), replaced memory management routines with generic ones and removed all the function-pointer calls. A basic, non-exhaustive check is included to verify that memory is loaded correctly in place. That last bit is probably the most intrusive one, but had to be done, as the calling convention on Linux differs from the one on Windows. It could possibly be emulated (just like RCT2_CALLFUNC_X) until dependency on exe is dropped. It is possible to completely remove calls out to original code by commenting out contents of RCT2_CALLFUNC_X, right now this will yield working UI, but no rendering of peeps, rides or rest of world. This can be used as a benchmark or test platform for correctness of implementation. The data sections will still be required for now. Assets are expected to be in specific places, so to launch it, following needs to satisified: * $build/data/ has to have contents of $RCT2/Data/ * $build/data/ (same as above) has to have contents of $repo/data/ * $build/ObjData/ has to have contents of $RCT2/ObjData/ * $build/../openrct2.exe has to be $repo/openrct2.exe (as of 976ea0d) Keep in mind you can symlink stuff and that filesystems are case sensitive! You can copy more of required data to possibly improve your experience. Pretty much all of this commit will possibly have to be reverted by the time OpenRCT2 gains independence. Remember to build with -DDISABLE_NETWORK=ON -DDISABLE_HTTP_TWITCH=ON
2015-09-22 23:36:05 +02:00
#else
//log_warning("call rct's function");
return realloc(block, numBytes);
#endif // _WIN32
2014-04-06 18:45:09 +02:00
}
/**
* RCT2 and this DLL can not free each other's allocated memory blocks. Use this to free memory that was allocated by RCT2.
* rct2: 0x004068CD
2014-04-06 18:45:09 +02:00
*/
void rct2_free(void *block)
{
Make it work on Linux Right now the project is decompiled to the point where it is feasible to try porting it to another platform. It doesn't work 100% correctly, but it's nearing this state. To port it to Linux I mmapped the openrct2.exe into expected places, disabled two offending calls (RCT2_CALLPROC_EBPSAFE(0x0040701D) and RCT2_CALLPROC_X(0x006E7FF3…)), replaced memory management routines with generic ones and removed all the function-pointer calls. A basic, non-exhaustive check is included to verify that memory is loaded correctly in place. That last bit is probably the most intrusive one, but had to be done, as the calling convention on Linux differs from the one on Windows. It could possibly be emulated (just like RCT2_CALLFUNC_X) until dependency on exe is dropped. It is possible to completely remove calls out to original code by commenting out contents of RCT2_CALLFUNC_X, right now this will yield working UI, but no rendering of peeps, rides or rest of world. This can be used as a benchmark or test platform for correctness of implementation. The data sections will still be required for now. Assets are expected to be in specific places, so to launch it, following needs to satisified: * $build/data/ has to have contents of $RCT2/Data/ * $build/data/ (same as above) has to have contents of $repo/data/ * $build/ObjData/ has to have contents of $RCT2/ObjData/ * $build/../openrct2.exe has to be $repo/openrct2.exe (as of 976ea0d) Keep in mind you can symlink stuff and that filesystems are case sensitive! You can copy more of required data to possibly improve your experience. Pretty much all of this commit will possibly have to be reverted by the time OpenRCT2 gains independence. Remember to build with -DDISABLE_NETWORK=ON -DDISABLE_HTTP_TWITCH=ON
2015-09-22 23:36:05 +02:00
#ifdef _WIN32
RCT2_CALLPROC_1(0x004068CD, void*, block);
Make it work on Linux Right now the project is decompiled to the point where it is feasible to try porting it to another platform. It doesn't work 100% correctly, but it's nearing this state. To port it to Linux I mmapped the openrct2.exe into expected places, disabled two offending calls (RCT2_CALLPROC_EBPSAFE(0x0040701D) and RCT2_CALLPROC_X(0x006E7FF3…)), replaced memory management routines with generic ones and removed all the function-pointer calls. A basic, non-exhaustive check is included to verify that memory is loaded correctly in place. That last bit is probably the most intrusive one, but had to be done, as the calling convention on Linux differs from the one on Windows. It could possibly be emulated (just like RCT2_CALLFUNC_X) until dependency on exe is dropped. It is possible to completely remove calls out to original code by commenting out contents of RCT2_CALLFUNC_X, right now this will yield working UI, but no rendering of peeps, rides or rest of world. This can be used as a benchmark or test platform for correctness of implementation. The data sections will still be required for now. Assets are expected to be in specific places, so to launch it, following needs to satisified: * $build/data/ has to have contents of $RCT2/Data/ * $build/data/ (same as above) has to have contents of $repo/data/ * $build/ObjData/ has to have contents of $RCT2/ObjData/ * $build/../openrct2.exe has to be $repo/openrct2.exe (as of 976ea0d) Keep in mind you can symlink stuff and that filesystems are case sensitive! You can copy more of required data to possibly improve your experience. Pretty much all of this commit will possibly have to be reverted by the time OpenRCT2 gains independence. Remember to build with -DDISABLE_NETWORK=ON -DDISABLE_HTTP_TWITCH=ON
2015-09-22 23:36:05 +02:00
#else
//log_warning("call rct's function");
free(block);
#endif // _WIN32
}