From 2baa808e8c09ce822044be00774b57f8026b2229 Mon Sep 17 00:00:00 2001 From: temx Date: Mon, 12 Dec 2022 22:58:08 +0100 Subject: [PATCH] Drag and drop support for maps, mods, savegames and demos --- Quake/common.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++- Quake/common.h | 2 + Quake/in_sdl.c | 5 +++ 3 files changed, 107 insertions(+), 2 deletions(-) diff --git a/Quake/common.c b/Quake/common.c index 5cc3f2134..bdd593cb0 100644 --- a/Quake/common.c +++ b/Quake/common.c @@ -1231,8 +1231,8 @@ being registered. */ static void COM_CheckRegistered (void) { - int h; - int i; + int h; + int i; COM_OpenFile ("gfx/pop.lmp", &h, NULL); @@ -2271,6 +2271,104 @@ void COM_InitFilesystem (void) // johnfitz -- modified based on topaz's tutorial COM_CheckRegistered (); } +static qboolean switch_mod (char *mod_name) +{ + if (q_strcasecmp (mod_name, GAMENAME)) // only switch for stuff outside id1 + { + qboolean found = false; + + for (filelist_item_t *mod = modlist; mod; mod = mod->next) + if (!q_strcasecmp (mod_name, mod->name)) + found = true; + + if (!found) + { + Con_Warning ("mod %s not in search path\n", mod_name); + return false; + } + + const char *games = COM_GetGameNames (true); + char *pos = strstr (games, mod_name); + + if (!pos || *(pos - 1) != ';' || (*(pos + strlen (mod_name)) != ';' && *(pos + strlen (mod_name)) != 0)) + { + Cbuf_AddText ("game \""); + Cbuf_AddText (mod_name); + Cbuf_AddText ("\"\n"); + } + } + return true; +} + +/* +================= +COM_RunPath + +Tries to determine what to do with a path (mods, demos, bsps or savegames), switches mod if needed +================= +*/ +void COM_RunPath (char *in_path) +{ + char *path = q_strdup (in_path); + char *path1 = ""; + char *path2 = ""; + char *path3 = path; + char *c = path; + while (*c) + { + if (*c == '\\' || *c == '/') + { + path1 = path2; + path2 = path3; + path3 = c + 1; + *c = 0; + } + ++c; + } + const char *ext = COM_FileGetExtension (path3); + if (!q_strcasecmp (ext, "bsp")) + { + if (q_strcasecmp (path2, "maps") || !q_strcasecmp (path1, "") || !switch_mod (path1)) + { + Con_Warning ("map not in maps path\n"); + Mem_Free (path); + return; + } + Cbuf_AddText ("map \""); + Cbuf_AddText (path3); + Cbuf_AddText ("\"\n"); + } + else if (!q_strcasecmp (ext, "sav")) + { + if (!q_strcasecmp (path2, "") || !switch_mod (path2)) + { + Con_Warning ("savegame not in mod path\n"); + Mem_Free (path); + return; + } + Cbuf_AddText ("load \""); + Cbuf_AddText (path3); + Cbuf_AddText ("\"\n"); + } + else if (!q_strcasecmp (ext, "dem")) + { + if (!q_strcasecmp (path2, "") || !switch_mod (path2)) + { + Con_Warning ("demo not in mod path\n"); + Mem_Free (path); + return; + } + Cbuf_AddText ("playdemo \""); + Cbuf_AddText (path3); + Cbuf_AddText ("\"\n"); + } + else if (Sys_FileType (in_path) == FS_ENT_DIRECTORY) + switch_mod (path3); + else + Con_Warning ("unrecognized file type %s\n", in_path); + Mem_Free (path); +} + /* The following FS_*() stdio replacements are necessary if one is * to perform non-sequential reads on files reopened on pak files * because we need the bookkeeping about file start/end positions. diff --git a/Quake/common.h b/Quake/common.h index e2df096f0..8809a328a 100644 --- a/Quake/common.h +++ b/Quake/common.h @@ -227,6 +227,8 @@ const char *COM_FileGetExtension (const char *in); /* doesn't return NULL */ void COM_ExtractExtension (const char *in, char *out, size_t outsize); void COM_CreatePath (char *path); +void COM_RunPath (char *path); + char *va (const char *format, ...) FUNC_PRINTF (1, 2); // does a varargs printf into a temp buffer diff --git a/Quake/in_sdl.c b/Quake/in_sdl.c index 99d8f4248..0c4ee8e19 100644 --- a/Quake/in_sdl.c +++ b/Quake/in_sdl.c @@ -1001,6 +1001,11 @@ void IN_SendKeyEvents (void) Con_DPrintf ("Ignoring SDL_CONTROLLERDEVICEREMAPPED\n"); break; + case SDL_DROPFILE: + COM_RunPath (event.drop.file); + SDL_free (event.drop.file); + break; + case SDL_QUIT: CL_Disconnect (); Sys_Quit ();