refactor game startup and initialisation

This commit is contained in:
IntelOrca 2014-10-09 00:30:22 +01:00
parent dcb7fde625
commit e57a625c9f
12 changed files with 386 additions and 166 deletions

View File

@ -42,6 +42,7 @@
<ItemGroup>
<ClCompile Include="..\src\audio\audio.c" />
<ClCompile Include="..\src\audio\mixer.cpp" />
<ClCompile Include="..\src\cmdline.c" />
<ClCompile Include="..\src\config.c" />
<ClCompile Include="..\src\drawing\drawing.c" />
<ClCompile Include="..\src\drawing\line.c" />
@ -71,6 +72,7 @@
<ClCompile Include="..\src\management\research.c" />
<ClCompile Include="..\src\object.c" />
<ClCompile Include="..\src\object_list.c" />
<ClCompile Include="..\src\openrct2.c" />
<ClCompile Include="..\src\peep\peep.c" />
<ClCompile Include="..\src\peep\staff.c" />
<ClCompile Include="..\src\platform\shared.c" />
@ -139,6 +141,7 @@
<ClInclude Include="..\src\addresses.h" />
<ClInclude Include="..\src\audio\audio.h" />
<ClInclude Include="..\src\audio\mixer.h" />
<ClInclude Include="..\src\cmdline.h" />
<ClInclude Include="..\src\common.h" />
<ClInclude Include="..\src\config.h" />
<ClInclude Include="..\src\cursors.h" />
@ -165,6 +168,7 @@
<ClInclude Include="..\src\management\news_item.h" />
<ClInclude Include="..\src\management\research.h" />
<ClInclude Include="..\src\object.h" />
<ClInclude Include="..\src\openrct2.h" />
<ClInclude Include="..\src\peep\peep.h" />
<ClInclude Include="..\src\peep\staff.h" />
<ClInclude Include="..\src\platform\osinterface.h" />

View File

@ -367,7 +367,6 @@
</ClCompile>
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\src\windows\shortcut_key_change.c">
<Filter>Source\Windows</Filter>
</ClCompile>
@ -377,9 +376,6 @@
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\libspeex\resample.c">
<Filter>Libraries\libspeex</Filter>
</ClCompile>
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\lodepng\lodepng.c" />
@ -415,6 +411,14 @@
<Filter>Libraries\lodepng</Filter>
</ClCompile>
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\libspeex\resample.c;..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\libspeex\resample.c;..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\src\cmdline.c">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="..\src\openrct2.c">
<Filter>Source</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\management\award.h">
@ -600,5 +604,11 @@
<ClInclude Include="..\src\management\research.h">
<Filter>Source\Management</Filter>
</ClInclude>
<ClInclude Include="..\src\cmdline.h">
<Filter>Source</Filter>
</ClInclude>
<ClInclude Include="..\src\openrct2.h">
<Filter>Source</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -12,5 +12,6 @@
<LocalDebuggerCommand>$(TargetDir)\openrct2.exe</LocalDebuggerCommand>
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommandArguments>"C:\Users\Ted\Documents\OpenRCT2\scenarios\RCT Forest Frontiers.SC6"</LocalDebuggerCommandArguments>
</PropertyGroup>
</Project>

99
src/cmdline.c Normal file
View File

@ -0,0 +1,99 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of OpenRCT2.
*
* 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/>.
*****************************************************************************/
#include <string.h>
#ifdef _MSC_VER
#include <time.h>
#endif
#include "cmdline.h"
#include "openrct2.h"
typedef struct tm tm_t;
int gExitCode = 0;
static void print_launch_information();
/**
* A shared entry point to OpenRCT2. The command lines must be parsed before any further action is done. Invalid command lines
* will then terminate before any initialisation has even been done.
* @returns 1 if the game should run, otherwise 0.
*/
int cmdline_run(char *argv[], int argc)
{
print_launch_information();
if (argc > 0) {
if (_stricmp(argv[0], "edit") == 0) {
gOpenRCT2StartupAction = STARTUP_ACTION_EDIT;
if (argc >= 2)
strcpy(gOpenRCT2StartupActionPath, argv[1]);
} else {
gOpenRCT2StartupAction = STARTUP_ACTION_OPEN;
strcpy(gOpenRCT2StartupActionPath, argv[0]);
}
}
return 1;
}
static void print_launch_information()
{
char buffer[32];
time_t timer;
tm_t* tmInfo;
// Print version information
printf("Starting %s v%s\n", OPENRCT2_NAME, OPENRCT2_VERSION);
printf(" %s (%s)\n", OPENRCT2_PLATFORM, OPENRCT2_ARCHITECTURE);
printf(" %s\n\n", OPENRCT2_TIMESTAMP);
// Print current time
time(&timer);
tmInfo = localtime(&timer);
strftime(buffer, sizeof(buffer), "%Y/%m/%d %H:%M:%S", tmInfo);
printf("Time: %s\n", buffer);
// TODO Print other potential information (e.g. user, hardware)
}
//void check_cmdline_arg()
//{
// int argc;
// char **argv;
// char *args;
//
// args = RCT2_GLOBAL(0x009AC310, char*);
// if (args == (char*)0xFFFFFFFF)
// return;
// RCT2_GLOBAL(0x009AC310, char*) = (char*)0xFFFFFFFF;
//
// argv = CommandLineToArgvA(args, &argc);
// if (argc > 0) {
// if (_stricmp(argv[0], "edit") == 0) {
// if (argc >= 1)
// editor_load_landscape(argv[1]);
// } else {
// rct2_open_file(argv[0]);
// }
// }
//
// LocalFree(argv);
//}

31
src/cmdline.h Normal file
View File

@ -0,0 +1,31 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of OpenRCT2.
*
* 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/>.
*****************************************************************************/
#ifndef _CMDLINE_H_
#define _CMDLINE_H_
#include "common.h"
/** The exit code for OpenRCT2 when it exits. */
extern int gExitCode;
int cmdline_run(char *argv[], int argc);
#endif

View File

@ -78,7 +78,7 @@ void editor_load()
RCT2_CALLPROC_EBPSAFE(0x006837E3);
gfx_invalidate_screen();
RCT2_GLOBAL(0x009DEA66, sint16) = 0;
rct2_endupdate();
// rct2_endupdate();
}
/**

78
src/openrct2.c Normal file
View File

@ -0,0 +1,78 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of OpenRCT2.
*
* 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/>.
*****************************************************************************/
#include "addresses.h"
#include "audio/audio.h"
#include "audio/mixer.h"
#include "cmdline.h"
#include "config.h"
#include "editor.h"
#include "localisation/localisation.h"
#include "openrct2.h"
#include "platform/osinterface.h"
int gOpenRCT2StartupAction = STARTUP_ACTION_TITLE;
char gOpenRCT2StartupActionPath[512] = { 0 };
/**
* Launches the game, after command line arguments have been parsed and processed.
*/
void openrct2_launch()
{
get_system_info();
audio_init();
audio_get_devices();
get_dsound_devices();
config_init();
language_open(gGeneral_config.language);
rct2_init();
Mixer_Init(NULL);
switch (gOpenRCT2StartupAction) {
case STARTUP_ACTION_INTRO:
RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = 8;
break;
case STARTUP_ACTION_TITLE:
RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_TITLE_DEMO;
break;
case STARTUP_ACTION_OPEN:
assert(gOpenRCT2StartupActionPath != NULL);
rct2_open_file(gOpenRCT2StartupActionPath);
RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_PLAYING;
// TODO fix, crashes on first game logic update
break;
case STARTUP_ACTION_EDIT:
if (strlen(gOpenRCT2StartupActionPath) == 0)
editor_load();
else
editor_load_landscape(gOpenRCT2StartupActionPath);
break;
}
rct2_loop();
osinterface_free();
// HACK Some threads are still running which causes the game to not terminate. Investigation required!
exit(gExitCode);
}

38
src/openrct2.h Normal file
View File

@ -0,0 +1,38 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of OpenRCT2.
*
* 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/>.
*****************************************************************************/
#ifndef _OPENRCT2_H_
#define _OPENRCT2_H_
#include "common.h"
enum {
STARTUP_ACTION_INTRO,
STARTUP_ACTION_TITLE,
STARTUP_ACTION_OPEN,
STARTUP_ACTION_EDIT
};
extern int gOpenRCT2StartupAction;
extern char gOpenRCT2StartupActionPath[512];
void openrct2_launch();
#endif

View File

@ -21,12 +21,18 @@
#ifndef _WIN32
#ifndef __APPLE__
#include "../cmdline.h"
#include "../openrct2.h"
/**
* Unix, linux and fallback entry point to OpenRCT2.
*/
// int main(char *argv[], int argc)
// {
// return 0;
// if (cmdline_run(argv, argc))
// openrct2_launch();
//
// return gExitCode;
// }
char platform_get_path_separator()

View File

@ -21,6 +21,11 @@
#ifdef _WIN32
#include <windows.h>
#include "../addresses.h"
#include "../cmdline.h"
#include "../openrct2.h"
LPSTR *CommandLineToArgvA(LPSTR lpCmdLine, int *argc);
/**
* Windows entry point to OpenRCT2 without a console window.
@ -50,9 +55,24 @@ BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
* The function that is called directly from the host application (rct2.exe)'s WinMain. This will be removed when OpenRCT2 can
* be built as a stand alone application.
*/
// __declspec(dllexport) int StartOpenRCT(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
// {
// }
__declspec(dllexport) int StartOpenRCT(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
int argc, runGame;
char **argv;
RCT2_GLOBAL(RCT2_ADDRESS_HINSTANCE, HINSTANCE) = hInstance;
RCT2_GLOBAL(RCT2_ADDRESS_CMDLINE, LPSTR) = lpCmdLine;
// Get command line arguments in standard form
argv = CommandLineToArgvA(lpCmdLine, &argc);
runGame = cmdline_run(argv, argc);
LocalFree(argv);
if (runGame)
openrct2_launch();
return gExitCode;
}
char platform_get_path_separator()
{
@ -73,4 +93,87 @@ int platform_ensure_directory_exists(const char *path)
return CreateDirectory(path, NULL);
}
/**
* http://alter.org.ua/en/docs/win/args/
*/
PCHAR *CommandLineToArgvA(PCHAR CmdLine, int *_argc)
{
PCHAR* argv;
PCHAR _argv;
ULONG len;
ULONG argc;
CHAR a;
ULONG i, j;
BOOLEAN in_QM;
BOOLEAN in_TEXT;
BOOLEAN in_SPACE;
len = strlen(CmdLine);
i = ((len + 2) / 2)*sizeof(PVOID) + sizeof(PVOID);
argv = (PCHAR*)GlobalAlloc(GMEM_FIXED,
i + (len + 2)*sizeof(CHAR));
_argv = (PCHAR)(((PUCHAR)argv) + i);
argc = 0;
argv[argc] = _argv;
in_QM = FALSE;
in_TEXT = FALSE;
in_SPACE = TRUE;
i = 0;
j = 0;
while (a = CmdLine[i]) {
if (in_QM) {
if (a == '\"') {
in_QM = FALSE;
} else {
_argv[j] = a;
j++;
}
} else {
switch (a) {
case '\"':
in_QM = TRUE;
in_TEXT = TRUE;
if (in_SPACE) {
argv[argc] = _argv + j;
argc++;
}
in_SPACE = FALSE;
break;
case ' ':
case '\t':
case '\n':
case '\r':
if (in_TEXT) {
_argv[j] = '\0';
j++;
}
in_TEXT = FALSE;
in_SPACE = TRUE;
break;
default:
in_TEXT = TRUE;
if (in_SPACE) {
argv[argc] = _argv + j;
argc++;
}
_argv[j] = a;
j++;
in_SPACE = FALSE;
break;
}
}
i++;
}
_argv[j] = '\0';
argv[argc] = NULL;
(*_argc) = argc;
return argv;
}
#endif

View File

@ -58,60 +58,12 @@ void print_launch_information();
void rct2_init_directories();
void rct2_startup_checks();
static void rct2_init();
static void rct2_loop();
static void rct2_update();
static void rct2_update_2();
PCHAR *CommandLineToArgvA(PCHAR CmdLine, int *_argc);
static int _finished;
static jmp_buf _end_update_jump;
__declspec(dllexport) int StartOpenRCT(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
print_launch_information();
// Begin RCT2
RCT2_GLOBAL(RCT2_ADDRESS_HINSTANCE, HINSTANCE) = hInstance;
RCT2_GLOBAL(RCT2_ADDRESS_CMDLINE, LPSTR) = lpCmdLine;
get_system_info();
audio_init();
audio_get_devices();
get_dsound_devices();
config_init();
language_open(gGeneral_config.language);
rct2_init();
Mixer_Init(NULL);
rct2_loop();
osinterface_free();
exit(0);
return 0;
}
void print_launch_information()
{
char buffer[32];
time_t timer;
tm_t* tmInfo;
// Print version information
printf("Starting %s v%s\n", OPENRCT2_NAME, OPENRCT2_VERSION);
printf(" %s (%s)\n", OPENRCT2_PLATFORM, OPENRCT2_ARCHITECTURE);
printf(" %s\n\n", OPENRCT2_TIMESTAMP);
// Print current time
time(&timer);
tmInfo = localtime(&timer);
strftime(buffer, sizeof(buffer), "%Y/%m/%d %H:%M:%S", tmInfo);
printf("Time: %s\n", buffer);
// TODO Print other potential information (e.g. user, hardware)
}
void rct2_loop()
{
int last_tick = 0;
@ -286,30 +238,6 @@ int rct2_open_file(const char *path)
}
}
void check_cmdline_arg()
{
int argc;
char **argv;
char *args;
args = RCT2_GLOBAL(0x009AC310, char*);
if (args == (char*)0xFFFFFFFF)
return;
RCT2_GLOBAL(0x009AC310, char*) = (char*)0xFFFFFFFF;
argv = CommandLineToArgvA(args, &argc);
if (argc > 0) {
if (_stricmp(argv[0], "edit") == 0) {
if (argc >= 1)
editor_load_landscape(argv[1]);
} else {
rct2_open_file(argv[0]);
}
}
LocalFree(argv);
}
// rct2: 0x00407DB0
int check_mutex()
{
@ -425,7 +353,7 @@ void rct2_update_2()
// TODO: screenshot countdown process
check_cmdline_arg();
// check_cmdline_arg();
// Screens
if (RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) != 0)
intro_update();
@ -598,87 +526,4 @@ void *rct2_realloc(void *block, size_t numBytes)
void rct2_free(void *block)
{
RCT2_CALLPROC_1(0x004068DE, void*, block);
}
/**
* http://alter.org.ua/en/docs/win/args/
*/
PCHAR *CommandLineToArgvA(PCHAR CmdLine, int *_argc)
{
PCHAR* argv;
PCHAR _argv;
ULONG len;
ULONG argc;
CHAR a;
ULONG i, j;
BOOLEAN in_QM;
BOOLEAN in_TEXT;
BOOLEAN in_SPACE;
len = strlen(CmdLine);
i = ((len + 2) / 2)*sizeof(PVOID) + sizeof(PVOID);
argv = (PCHAR*)GlobalAlloc(GMEM_FIXED,
i + (len + 2)*sizeof(CHAR));
_argv = (PCHAR)(((PUCHAR)argv) + i);
argc = 0;
argv[argc] = _argv;
in_QM = FALSE;
in_TEXT = FALSE;
in_SPACE = TRUE;
i = 0;
j = 0;
while (a = CmdLine[i]) {
if (in_QM) {
if (a == '\"') {
in_QM = FALSE;
} else {
_argv[j] = a;
j++;
}
} else {
switch (a) {
case '\"':
in_QM = TRUE;
in_TEXT = TRUE;
if (in_SPACE) {
argv[argc] = _argv + j;
argc++;
}
in_SPACE = FALSE;
break;
case ' ':
case '\t':
case '\n':
case '\r':
if (in_TEXT) {
_argv[j] = '\0';
j++;
}
in_TEXT = FALSE;
in_SPACE = TRUE;
break;
default:
in_TEXT = TRUE;
if (in_SPACE) {
argv[argc] = _argv + j;
argc++;
}
_argv[j] = a;
j++;
in_SPACE = FALSE;
break;
}
}
i++;
}
_argv[j] = '\0';
argv[argc] = NULL;
(*_argc) = argc;
return argv;
}
}

View File

@ -21,6 +21,7 @@
#ifndef _RCT2_H_
#define _RCT2_H_
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
@ -268,6 +269,8 @@ static const struct file_to_check
{ PATH_ID_END, 0 }
};
void rct2_init();
void rct2_loop();
void rct2_endupdate();
void subsitute_path(char *dest, const char *path, const char *filename);
int check_mutex();
@ -283,4 +286,6 @@ void *rct2_realloc(void *block, size_t numBytes);
void rct2_free(void *block);
void rct2_quit();
int rct2_open_file(const char *path);
#endif