diff --git a/src/Editor.c b/src/Editor.c index 2ce8d87..0635695 100644 --- a/src/Editor.c +++ b/src/Editor.c @@ -22,7 +22,6 @@ #include "rlog.h" #if defined(_WIN32) #include -//#include #else #include #include @@ -136,6 +135,19 @@ void setMostRecentFile(const text_t* filename) { Window_populateRecentList((const text_t**)s_recentFiles); } +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void Editor_setLoadedFilename(const text_t* filename) { + s_loadedFilename = (text_t*)filename; + setMostRecentFile(filename); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +struct TrackData* Editor_getTrackData(void) { + return &s_editorData.trackData; +} + // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/Editor.h b/src/Editor.h index 82271e1..6c6a772 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -19,6 +19,8 @@ void Editor_loadRecentFile(int file); bool Editor_saveBeforeExit(void); bool Editor_needsSave(void); +void Editor_setLoadedFilename(const text_t* filename); +struct TrackData* Editor_getTrackData(void); text_t** Editor_getRecentFiles(void); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/args.c b/src/args.c new file mode 100644 index 0000000..e075398 --- /dev/null +++ b/src/args.c @@ -0,0 +1,44 @@ +#include "args.h" +#include + +#if defined(_WIN32) +#include +#define STRCMP wcscmp +#define STRICMP _wcsicmp +#define STRLEN wcslen +#define STR(s) L##s +#else +#include +#define STRCMP strcmp +#define STRICMP strcasecmp +#define STRLEN strlen +#define STR(s) s +#endif + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static int hasExtension(const text_t* path, const text_t* ext) { + size_t pathLen = STRLEN(path); + size_t extLen = STRLEN(ext); + if (pathLen < extLen) return 0; + return STRICMP(path + pathLen - extLen, ext) == 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void Args_parse(Args* args, int argc, const text_t* const* argv) { + args->loadFile = NULL; + + for (int i = 1; i < argc; i++) { + // Check for --load or -l flag + if ((STRCMP(argv[i], STR("--load")) == 0 || STRCMP(argv[i], STR("-l")) == 0) && i + 1 < argc) { + args->loadFile = argv[i + 1]; + return; + } + // Check for bare filename (ends with .rocket or .xml) + if (hasExtension(argv[i], STR(".rocket")) || hasExtension(argv[i], STR(".xml"))) { + args->loadFile = argv[i]; + return; + } + } +} diff --git a/src/args.h b/src/args.h new file mode 100644 index 0000000..5de781d --- /dev/null +++ b/src/args.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +// Parsed command line arguments +typedef struct Args { + const text_t* loadFile; // File to load on startup (NULL if none) +} Args; + +// Parse command line arguments +// argc/argv should be in the native format for the platform +// On Windows: use CommandLineToArgvW to get wide strings +// On Linux/macOS: use standard argc/argv +void Args_parse(Args* args, int argc, const text_t* const* argv); diff --git a/src/linux/main.c b/src/linux/main.c index 8e0714d..f0b737b 100644 --- a/src/linux/main.c +++ b/src/linux/main.c @@ -3,6 +3,9 @@ #include #include #include +#include +#include "args.h" +#include "loadsave.h" #include "Editor.h" #include "Menu.h" #ifdef HAVE_GTK @@ -415,6 +418,10 @@ void loadRecents() { } int main(int argc, char* argv[]) { + // Store original argc/argv before GTK initialization + int original_argc = argc; + char** original_argv = argv; + #ifdef HAVE_GTK gtk_init(&argc, &argv); #endif @@ -449,6 +456,21 @@ int main(int argc, char* argv[]) { EMGFXBackend_updateViewPort(800, 600); Editor_setWindowSize(800, 600); + // Check for rocket file argument and load it + { + Args args; + Args_parse(&args, original_argc, (const text_t* const*)original_argv); + + if (args.loadFile) { + if (LoadSave_loadRocketXML(args.loadFile, Editor_getTrackData())) { + Editor_setLoadedFilename(args.loadFile); + } else { + Dialog_showError("Failed to load rocket file"); + fprintf(stderr, "Failed to load rocket file: %s\n", args.loadFile); + } + } + } + run(window); saveRecents(); diff --git a/src/macosx/RocketAppDelegate.m b/src/macosx/RocketAppDelegate.m index e186d1b..3e300a2 100644 --- a/src/macosx/RocketAppDelegate.m +++ b/src/macosx/RocketAppDelegate.m @@ -1,4 +1,6 @@ #import "RocketAppDelegate.h" +#include "../args.h" +#include "../loadsave.h" #include "../Editor.h" #include "../RemoteConnection.h" #include "rlog.h" @@ -16,7 +18,7 @@ @implementation RocketAppDelegate - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { NSUInteger exitcode = NSTerminateNow; - + if (!Editor_needsSave()) return exitcode; @@ -46,7 +48,7 @@ - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sende /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { char** recent_list = Editor_getRecentFiles(); @@ -69,13 +71,43 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification } } + // Check for rocket file argument and load it + NSArray* arguments = [[NSProcessInfo processInfo] arguments]; + NSUInteger argCount = [arguments count]; + + if (argCount > 1) { + // Convert NSArray to C array for Args_parse + const char** argv = malloc(argCount * sizeof(char*)); + for (NSUInteger i = 0; i < argCount; i++) { + argv[i] = [[arguments objectAtIndex:i] UTF8String]; + } + + Args args; + Args_parse(&args, (int)argCount, argv); + + if (args.loadFile) { + if (LoadSave_loadRocketXML(args.loadFile, Editor_getTrackData())) { + Editor_setLoadedFilename(args.loadFile); + } else { + NSAlert* alert = [[NSAlert alloc] init]; + [alert setMessageText:@"Failed to load rocket file"]; + [alert setInformativeText:[NSString stringWithFormat:@"Could not load file: %s", args.loadFile]]; + [alert setAlertStyle:NSWarningAlertStyle]; + [alert runModal]; + [alert release]; + } + } + + free(argv); + } + Window_buildMenu(); Window_populateRecentList(recent_list); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -- (IBAction) buttonClicked:(id)sender +- (IBAction) buttonClicked:(id)sender { Editor_menuEvent((int)((NSButton*)sender).tag); } diff --git a/src/windows/RocketWindow.c b/src/windows/RocketWindow.c index e252f2b..4b57811 100644 --- a/src/windows/RocketWindow.c +++ b/src/windows/RocketWindow.c @@ -4,10 +4,14 @@ // clang-format off #include #include +#include #include // clang-format on #include +#include "../args.h" #include "../Editor.h" +#include "../loadsave.h" +#include "../Dialog.h" #include "Menu.h" #include "afxres.h" #include "resource.h" @@ -638,11 +642,38 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmndLine, i MSG msg; HACCEL accel; bool done = false; + int argc = 0; + wchar_t** argv = NULL; + Args args = {0}; + + (void)instance; + (void)prevInstance; + (void)cmndLine; + (void)show; memset(&msg, 0, sizeof(MSG)); - if (!createWindow(L"RocketEditor" EDITOR_VERSION, 800, 600)) + // Parse command line arguments + argv = CommandLineToArgvW(GetCommandLineW(), &argc); + if (argv) { + Args_parse(&args, argc, (const text_t* const*)argv); + } + + if (!createWindow(L"RocketEditor" EDITOR_VERSION, 800, 600)) { + if (argv) LocalFree(argv); return 0; + } + + // Load file if specified on command line + if (args.loadFile) { + if (LoadSave_loadRocketXML(args.loadFile, Editor_getTrackData())) { + Editor_setLoadedFilename(args.loadFile); + } else { + Dialog_showError(L"Failed to load rocket file"); + } + } + + if (argv) LocalFree(argv); accel = CreateAcceleratorTable(s_accelTable, s_accelCount);