diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj
index 5d856b42d7..dc4b8b876c 100644
--- a/projects/openrct2.vcxproj
+++ b/projects/openrct2.vcxproj
@@ -42,6 +42,7 @@
+
@@ -71,6 +72,7 @@
+
@@ -139,6 +141,7 @@
+
@@ -165,6 +168,7 @@
+
diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters
index e1b4435a08..f70267d16a 100644
--- a/projects/openrct2.vcxproj.filters
+++ b/projects/openrct2.vcxproj.filters
@@ -367,7 +367,6 @@
-
Source\Windows
@@ -377,9 +376,6 @@
-
- Libraries\libspeex
-
@@ -415,6 +411,14 @@
Libraries\lodepng
+
+
+
+ Source
+
+
+ Source
+
@@ -600,5 +604,11 @@
Source\Management
+
+ Source
+
+
+ Source
+
\ No newline at end of file
diff --git a/projects/openrct2.vcxproj.user b/projects/openrct2.vcxproj.user
index 80981e45c6..3695926811 100644
--- a/projects/openrct2.vcxproj.user
+++ b/projects/openrct2.vcxproj.user
@@ -12,5 +12,6 @@
$(TargetDir)\openrct2.exe
$(TargetDir)
WindowsLocalDebugger
+ "C:\Users\Ted\Documents\OpenRCT2\scenarios\RCT Forest Frontiers.SC6"
\ No newline at end of file
diff --git a/src/cmdline.c b/src/cmdline.c
new file mode 100644
index 0000000000..fca9191417
--- /dev/null
+++ b/src/cmdline.c
@@ -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 .
+ *****************************************************************************/
+
+#include
+#ifdef _MSC_VER
+#include
+#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);
+//}
\ No newline at end of file
diff --git a/src/cmdline.h b/src/cmdline.h
new file mode 100644
index 0000000000..09baea261b
--- /dev/null
+++ b/src/cmdline.h
@@ -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 .
+ *****************************************************************************/
+
+#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
\ No newline at end of file
diff --git a/src/editor.c b/src/editor.c
index dd79fb9723..30fc1f4785 100644
--- a/src/editor.c
+++ b/src/editor.c
@@ -78,7 +78,7 @@ void editor_load()
RCT2_CALLPROC_EBPSAFE(0x006837E3);
gfx_invalidate_screen();
RCT2_GLOBAL(0x009DEA66, sint16) = 0;
- rct2_endupdate();
+ // rct2_endupdate();
}
/**
diff --git a/src/openrct2.c b/src/openrct2.c
new file mode 100644
index 0000000000..b6227145de
--- /dev/null
+++ b/src/openrct2.c
@@ -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 .
+ *****************************************************************************/
+
+#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);
+}
\ No newline at end of file
diff --git a/src/openrct2.h b/src/openrct2.h
new file mode 100644
index 0000000000..055fb7f245
--- /dev/null
+++ b/src/openrct2.h
@@ -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 .
+ *****************************************************************************/
+
+#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
\ No newline at end of file
diff --git a/src/platform/unix.c b/src/platform/unix.c
index 47aecde2d2..e5151df42d 100644
--- a/src/platform/unix.c
+++ b/src/platform/unix.c
@@ -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()
diff --git a/src/platform/windows.c b/src/platform/windows.c
index 1d683f9e8b..1de14e0272 100644
--- a/src/platform/windows.c
+++ b/src/platform/windows.c
@@ -21,6 +21,11 @@
#ifdef _WIN32
#include
+#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
\ No newline at end of file
diff --git a/src/rct2.c b/src/rct2.c
index 9e6a05190b..9a2e00ded7 100644
--- a/src/rct2.c
+++ b/src/rct2.c
@@ -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;
-}
+}
\ No newline at end of file
diff --git a/src/rct2.h b/src/rct2.h
index 51f982c4ed..85d13baf0e 100644
--- a/src/rct2.h
+++ b/src/rct2.h
@@ -21,6 +21,7 @@
#ifndef _RCT2_H_
#define _RCT2_H_
+#include
#include
#include
#include
@@ -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