diff --git a/CMakeLists.txt b/CMakeLists.txt index eb91866f..e141537c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,10 +98,10 @@ add_subdirectory(assets) ## config.h generation set(GIT_EXECUTABLE "git" CACHE FILEPATH "Path to git binary") include(GitUtilities) -git_describe(SRB2_GIT_DESCRIBE "${CMAKE_SOURCE_DIR}") +git_latest_commit(SRB2_COMP_COMMIT "${CMAKE_SOURCE_DIR}") git_current_branch(SRB2_GIT_BRANCH "${CMAKE_SOURCE_DIR}") set(SRB2_COMP_BRANCH "${SRB2_GIT_BRANCH}") -set(SRB2_COMP_REVISION "${SRB2_GIT_DESCRIBE}") +set(SRB2_COMP_REVISION "${SRB2_COMP_COMMIT}") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/config.h) ##### PACKAGE CONFIGURATION ##### @@ -116,7 +116,7 @@ if(${CMAKE_SYSTEM} MATCHES "Darwin") set(CPACK_GENERATOR "DragNDrop") endif() -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Sonic Robo Blast 2") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Sonic Robo Blast 2 Kart") set(CPACK_PACKAGE_VENDOR "Sonic Team Jr.") #set(CPACK_PACKAGE_DESCRIPTION_FILE ) set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") diff --git a/bin/Resources/i686/exchndl.dll b/bin/Resources/i686/exchndl.dll deleted file mode 100644 index d836a676..00000000 Binary files a/bin/Resources/i686/exchndl.dll and /dev/null differ diff --git a/cmake/Modules/GitUtilities.cmake b/cmake/Modules/GitUtilities.cmake index 683cf9b6..d29e6b50 100644 --- a/cmake/Modules/GitUtilities.cmake +++ b/cmake/Modules/GitUtilities.cmake @@ -27,5 +27,17 @@ function(git_current_branch variable path) OUTPUT_STRIP_TRAILING_WHITESPACE ) + set(${variable} "${output}" PARENT_SCOPE) +endfunction() + +function(git_latest_commit variable path) + execute_process(COMMAND ${GIT_EXECUTABLE} "rev-parse" "--short" "HEAD" + WORKING_DIRECTORY "${path}" + RESULT_VARIABLE result + OUTPUT_VARIABLE output + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + set(${variable} "${output}" PARENT_SCOPE) endfunction() \ No newline at end of file diff --git a/libs/DLL-README.txt b/libs/DLL-README.txt new file mode 100644 index 00000000..06fae127 --- /dev/null +++ b/libs/DLL-README.txt @@ -0,0 +1,43 @@ +# SRB2Kart - Which DLLs do I need to bundle? + +Updated 12/4/2018 (v2.1.21) + +Here are the required DLLs, per build. For each architecture, copy all the binaries from these folders: + +* libs\dll-binaries\[i686/x86_64] +* libs\SDL2\[i686/x86_64]...\bin +* libs\SDL2_mixer\[i686/x86_64]...\bin + +and don't forget to build r_opengl.dll for srb2dd. + +## srb2kart, 32-bit + +* libs\dll-binaries\i686\exchndl.dll +* libs\dll-binaries\i686\libgme.dll +* libs\dll-binaries\i686\mgwhelp.dll (depend for exchndl.dll) +* libs\SDL2\i686-w64-mingw32\bin\SDL2.dll +* libs\SDL2_mixer\i686-w64-mingw32\bin\*.dll (get everything) + +## srb2kart, 64-bit + +* libs\dll-binaries\x86_64\exchndl.dll +* libs\dll-binaries\x86_64\libgme.dll +* libs\dll-binaries\x86_64\mgwhelp.dll (depend for exchndl.dll) +* libs\SDL2\x86_64-w64-mingw32\bin\SDL2.dll +* libs\SDL2_mixer\x86_64-w64-mingw32\bin\*.dll (get everything) + +## srb2kartdd, 32-bit + +* libs\dll-binaries\i686\exchndl.dll +* libs\dll-binaries\i686\fmodex.dll +* libs\dll-binaries\i686\libgme.dll +* libs\dll-binaries\i686\mgwhelp.dll (depend for exchndl.dll) +* r_opengl.dll (build this from make) + +## srb2kartdd, 64-bit + +* libs\dll-binaries\x86_64\exchndl.dll +* libs\dll-binaries\x86_64\fmodex.dll +* libs\dll-binaries\x86_64\libgme.dll +* libs\dll-binaries\x86_64\mgwhelp.dll (depend for exchndl.dll) +* r_opengl.dll (build this from make) diff --git a/bin/Resources/i686/fmod.dll b/libs/dll-binaries/i686/Old/fmod.dll similarity index 100% rename from bin/Resources/i686/fmod.dll rename to libs/dll-binaries/i686/Old/fmod.dll diff --git a/bin/Resources/i686/fmodexL.dll b/libs/dll-binaries/i686/Old/fmodexL.dll similarity index 100% rename from bin/Resources/i686/fmodexL.dll rename to libs/dll-binaries/i686/Old/fmodexL.dll diff --git a/bin/Resources/i686/libgcc_s_dw2-1.dll b/libs/dll-binaries/i686/Old/libgcc_s_dw2-1.dll similarity index 100% rename from bin/Resources/i686/libgcc_s_dw2-1.dll rename to libs/dll-binaries/i686/Old/libgcc_s_dw2-1.dll diff --git a/bin/Resources/i686/libintl-8.dll b/libs/dll-binaries/i686/Old/libintl-8.dll similarity index 100% rename from bin/Resources/i686/libintl-8.dll rename to libs/dll-binaries/i686/Old/libintl-8.dll diff --git a/libs/dll-binaries/i686/exchndl.dll b/libs/dll-binaries/i686/exchndl.dll new file mode 100644 index 00000000..d6beb764 Binary files /dev/null and b/libs/dll-binaries/i686/exchndl.dll differ diff --git a/bin/Resources/i686/fmodex.dll b/libs/dll-binaries/i686/fmodex.dll similarity index 100% rename from bin/Resources/i686/fmodex.dll rename to libs/dll-binaries/i686/fmodex.dll diff --git a/bin/Resources/i686/libgme.dll b/libs/dll-binaries/i686/libgme.dll similarity index 100% rename from bin/Resources/i686/libgme.dll rename to libs/dll-binaries/i686/libgme.dll diff --git a/libs/dll-binaries/i686/mgwhelp.dll b/libs/dll-binaries/i686/mgwhelp.dll new file mode 100644 index 00000000..3cf97424 Binary files /dev/null and b/libs/dll-binaries/i686/mgwhelp.dll differ diff --git a/bin/Resources/x86_64/fmod64.dll b/libs/dll-binaries/x86_64/Old/fmod64.dll similarity index 100% rename from bin/Resources/x86_64/fmod64.dll rename to libs/dll-binaries/x86_64/Old/fmod64.dll diff --git a/bin/Resources/x86_64/fmodexL64.dll b/libs/dll-binaries/x86_64/Old/fmodexL64.dll similarity index 100% rename from bin/Resources/x86_64/fmodexL64.dll rename to libs/dll-binaries/x86_64/Old/fmodexL64.dll diff --git a/libs/dll-binaries/x86_64/exchndl.dll b/libs/dll-binaries/x86_64/exchndl.dll new file mode 100644 index 00000000..747d7a3d Binary files /dev/null and b/libs/dll-binaries/x86_64/exchndl.dll differ diff --git a/bin/Resources/x86_64/fmodex64.dll b/libs/dll-binaries/x86_64/fmodex64.dll similarity index 100% rename from bin/Resources/x86_64/fmodex64.dll rename to libs/dll-binaries/x86_64/fmodex64.dll diff --git a/bin/Resources/x86_64/libgme.dll b/libs/dll-binaries/x86_64/libgme.dll similarity index 100% rename from bin/Resources/x86_64/libgme.dll rename to libs/dll-binaries/x86_64/libgme.dll diff --git a/libs/dll-binaries/x86_64/mgwhelp.dll b/libs/dll-binaries/x86_64/mgwhelp.dll new file mode 100644 index 00000000..4e30e140 Binary files /dev/null and b/libs/dll-binaries/x86_64/mgwhelp.dll differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f4e2898e..faa860d4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -358,7 +358,7 @@ if(${SRB2_CONFIG_HAVE_ZLIB}) set(SRB2_HAVE_ZLIB ON) add_definitions(-DHAVE_ZLIB) else() - message(WARNING "You have specified that ZLIB is available but it was not found. SRB2 may not compile correctly.") + message(WARNING "You have specified that ZLIB is available but it was not found. SRB2Kart may not compile correctly.") endif() endif() @@ -380,7 +380,7 @@ if(${SRB2_CONFIG_HAVE_PNG} AND ${SRB2_CONFIG_HAVE_ZLIB}) add_definitions(-DHAVE_PNG) add_definitions(-D_LARGEFILE64_SOURCE) else() - message(WARNING "You have specified that PNG is available but it was not found. SRB2 may not compile correctly.") + message(WARNING "You have specified that PNG is available but it was not found. SRB2Kart may not compile correctly.") endif() endif() endif() @@ -485,5 +485,5 @@ if(${CMAKE_SYSTEM} MATCHES Windows) endif() if(NOT ${SRB2_SDL2_AVAILABLE} AND NOT ${SRB2_WIN32_AVAILABLE}) - message(FATAL_ERROR "There are no targets available to build an SRB2 executable. :(") + message(FATAL_ERROR "There are no targets available to build an SRB2Kart executable. :(") endif() diff --git a/src/Makefile.cfg b/src/Makefile.cfg index 20219168..cdd4c3c7 100644 --- a/src/Makefile.cfg +++ b/src/Makefile.cfg @@ -20,7 +20,7 @@ GCC64=1 endif ifdef GCC64 -GCC64=1 +GCC63=1 endif ifdef GCC63 diff --git a/src/config.h.in b/src/config.h.in index 885d21d6..ab96b333 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -28,8 +28,6 @@ #define SRB2_COMP_REVISION "${SRB2_COMP_REVISION}" #define SRB2_COMP_BRANCH "${SRB2_COMP_BRANCH}" -#define SRB2_GIT_DESCRIBE "${SRB2_GIT_DESCRIBE}" -#define SRB2_GIT_BRANCH "${SRB2_GIT_BRANCH}" #define CMAKE_ASSETS_DIR "${CMAKE_SOURCE_DIR}/assets" diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 76c319b9..eafc1283 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -25,6 +25,7 @@ #include "g_game.h" #include "hu_stuff.h" #include "keys.h" +#include "g_input.h" // JOY1 #include "m_menu.h" #include "console.h" #include "d_netfil.h" @@ -1916,7 +1917,7 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent) M_StartMessage(M_GetText( "You have too many WAD files loaded\n" "to add ones the server is using.\n" - "Please restart SRB2 before connecting.\n\n" + "Please restart SRB2Kart before connecting.\n\n" "Press ESC\n" ), NULL, MM_NOTHING); return false; @@ -2073,7 +2074,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic I_OsPolling(); key = I_GetKey(); - if (key == KEY_ESCAPE) + if (key == KEY_ESCAPE || key == KEY_JOY1+1) { CONS_Printf(M_GetText("Network game synchronization aborted.\n")); // M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING); @@ -3552,7 +3553,7 @@ static void HandleConnect(SINT8 node) SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server")); else if (netbuffer->u.clientcfg.version != VERSION || netbuffer->u.clientcfg.subversion != SUBVERSION) - SV_SendRefuse(node, va(M_GetText("Different SRB2 versions cannot\nplay a netgame!\n(server version %d.%d.%d)"), VERSION/100, VERSION%100, SUBVERSION)); + SV_SendRefuse(node, va(M_GetText("Different SRB2Kart versions cannot\nplay a netgame!\n(server version %d.%d.%d)"), VERSION/100, VERSION%100, SUBVERSION)); else if (!cv_allownewplayer.value && node) SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment")); else if (D_NumPlayers() >= maxplayers) diff --git a/src/f_finale.c b/src/f_finale.c index 4394ee6e..24acf2d6 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -471,6 +471,7 @@ static const char *credits[] = { "\"Spherallic\"", "\"VAdaPEGA\"", "\"Virt\"", + "\"zxyspku\"", "", "\1Sound Design", "James \"SeventhSentinel\" Hall", @@ -585,7 +586,7 @@ static struct { // This Tyler52 gag is troublesome // Alignment should be ((spaces+1 * 100) + (headers+1 * 38) + (lines * 15)) // Current max image spacing: (200*17) - {112, (15*100)+(17*38)+(101*15), "TYLER52", SKINCOLOR_NONE}, + {112, (15*100)+(17*38)+(102*15), "TYLER52", SKINCOLOR_NONE}, {0, 0, NULL, SKINCOLOR_NONE} }; diff --git a/src/g_game.c b/src/g_game.c index 64b76363..ac8e27a3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1209,7 +1209,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) INT32 laim, th, tspeed, forward, side, axis; //i const INT32 speed = 1; // these ones used for multiple conditions - boolean turnleft, turnright, invertmouse, mouseaiming, lookaxis, usejoystick, analogjoystickmove, gamepadjoystickmove, kbl, rd; + boolean turnleft, turnright, mouseaiming, analogjoystickmove, gamepadjoystickmove; + boolean invertmouse, lookaxis, usejoystick, kbl, rd; player_t *player; camera_t *thiscam; angle_t lang; @@ -1800,7 +1801,7 @@ boolean G_Responder(event_t *ev) { // allow spy mode changes even during the demo if (gamestate == GS_LEVEL && ev->type == ev_keydown - && (ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1])) + && (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1])) { if (splitscreen || !netgame) displayplayer = consoleplayer; @@ -2430,7 +2431,10 @@ void G_PlayerReborn(INT32 player) } // Keep Shrink status, remove Grow status - growshrinktimer = min(players[player].kartstuff[k_growshrinktimer], 0); + if (players[player].kartstuff[k_growshrinktimer] < 0) + growshrinktimer = players[player].kartstuff[k_growshrinktimer]; + else + growshrinktimer = 0; bumper = players[player].kartstuff[k_bumper]; comebackpoints = players[player].kartstuff[k_comebackpoints]; diff --git a/src/info.c b/src/info.c index 9851ee23..93804b0c 100644 --- a/src/info.c +++ b/src/info.c @@ -15476,7 +15476,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_JAWZ_DEAD1, // deathstate S_JAWZ_DEAD2, // xdeathstate sfx_s3k5d, // deathsound - 7*FRACUNIT, // speed + 64*FRACUNIT, // speed 16*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset @@ -15503,7 +15503,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_JAWZ_DEAD1, // deathstate S_JAWZ_DEAD2, // xdeathstate sfx_s3k5d, // deathsound - 56*FRACUNIT, // speed + 64*FRACUNIT, // speed 16*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset @@ -15773,7 +15773,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_BALLHOG_DEAD, // deathstate S_NULL, // xdeathstate sfx_hogbom, // deathsound - 0, // speed + 64*FRACUNIT, // speed 16*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset diff --git a/src/k_kart.c b/src/k_kart.c index b462d961..2a152162 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -493,31 +493,31 @@ boolean K_IsPlayerWanted(player_t *player) #define NUMKARTODDS 80 // Less ugly 2D arrays -static INT32 K_KartItemOddsRace[NUMKARTRESULTS][9] = +static INT32 K_KartItemOddsRace[NUMKARTRESULTS][10] = { - //P-Odds 0 1 2 3 4 5 6 7 8 - /*Sneaker*/ {20, 0, 0, 4, 6, 6, 0, 0, 0 }, // Sneaker - /*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 1, 3, 5, 3 }, // Rocket Sneaker - /*Invincibility*/ { 0, 0, 0, 0, 0, 1, 4, 6,14 }, // Invincibility - /*Banana*/ { 0, 9, 4, 2, 1, 0, 0, 0, 0 }, // Banana - /*Eggman Monitor*/ { 0, 4, 3, 2, 0, 0, 0, 0, 0 }, // Eggman Monitor - /*Orbinaut*/ { 0, 6, 5, 3, 2, 0, 0, 0, 0 }, // Orbinaut - /*Jawz*/ { 0, 0, 3, 2, 1, 1, 0, 0, 0 }, // Jawz - /*Mine*/ { 0, 0, 2, 2, 1, 0, 0, 0, 0 }, // Mine - /*Ballhog*/ { 0, 0, 0, 2, 1, 0, 0, 0, 0 }, // Ballhog - /*Self-Propelled Bomb*/ { 0, 0, 1, 2, 3, 4, 2, 2, 0 }, // Self-Propelled Bomb - /*Grow*/ { 0, 0, 0, 0, 0, 1, 3, 5, 3 }, // Grow - /*Shrink*/ { 0, 0, 0, 0, 0, 0, 0, 2, 0 }, // Shrink - /*Thunder Shield*/ { 0, 1, 2, 0, 0, 0, 0, 0, 0 }, // Thunder Shield - /*Hyudoro*/ { 0, 0, 0, 0, 1, 2, 1, 0, 0 }, // Hyudoro - /*Pogo Spring*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Pogo Spring - /*Kitchen Sink*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Kitchen Sink - /*Sneaker x3*/ { 0, 0, 0, 0, 3, 7, 9, 2, 0 }, // Sneaker x3 - /*Banana x3*/ { 0, 0, 1, 1, 0, 0, 0, 0, 0 }, // Banana x3 - /*Banana x10*/ { 0, 0, 0, 0, 1, 0, 0, 0, 0 }, // Banana x10 - /*Orbinaut x3*/ { 0, 0, 0, 1, 0, 0, 0, 0, 0 }, // Orbinaut x3 - /*Orbinaut x4*/ { 0, 0, 0, 0, 1, 1, 0, 0, 0 }, // Orbinaut x4 - /*Jawz x2*/ { 0, 0, 0, 1, 2, 0, 0, 0, 0 } // Jawz x2 + //P-Odds 0 1 2 3 4 5 6 7 8 9 + /*Sneaker*/ {20, 0, 0, 4, 6, 6, 0, 0, 0, 0 }, // Sneaker + /*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 1, 3, 5, 3, 0 }, // Rocket Sneaker + /*Invincibility*/ { 0, 0, 0, 0, 0, 1, 4, 6,14, 0 }, // Invincibility + /*Banana*/ { 0, 9, 4, 2, 1, 0, 0, 0, 0, 0 }, // Banana + /*Eggman Monitor*/ { 0, 4, 3, 2, 0, 0, 0, 0, 0, 0 }, // Eggman Monitor + /*Orbinaut*/ { 0, 6, 5, 3, 2, 0, 0, 0, 0, 0 }, // Orbinaut + /*Jawz*/ { 0, 0, 3, 2, 1, 1, 0, 0, 0, 0 }, // Jawz + /*Mine*/ { 0, 0, 2, 2, 1, 0, 0, 0, 0, 0 }, // Mine + /*Ballhog*/ { 0, 0, 0, 2, 1, 0, 0, 0, 0, 0 }, // Ballhog + /*Self-Propelled Bomb*/ { 0, 0, 1, 2, 3, 4, 2, 2, 0,20 }, // Self-Propelled Bomb + /*Grow*/ { 0, 0, 0, 0, 0, 1, 3, 5, 3, 0 }, // Grow + /*Shrink*/ { 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // Shrink + /*Thunder Shield*/ { 0, 1, 2, 0, 0, 0, 0, 0, 0, 0 }, // Thunder Shield + /*Hyudoro*/ { 0, 0, 0, 0, 1, 2, 1, 0, 0, 0 }, // Hyudoro + /*Pogo Spring*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Pogo Spring + /*Kitchen Sink*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Kitchen Sink + /*Sneaker x3*/ { 0, 0, 0, 0, 3, 7, 9, 2, 0, 0 }, // Sneaker x3 + /*Banana x3*/ { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 }, // Banana x3 + /*Banana x10*/ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, // Banana x10 + /*Orbinaut x3*/ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, // Orbinaut x3 + /*Orbinaut x4*/ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 }, // Orbinaut x4 + /*Jawz x2*/ { 0, 0, 0, 1, 2, 0, 0, 0, 0, 0 } // Jawz x2 }; static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][6] = @@ -706,12 +706,13 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed) break; case KITEM_SPB: //POWERITEMODDS(newodds); - if ((!cv_selfpropelledbomb.value) + if (((!cv_selfpropelledbomb.value) || (indirectitemcooldown > 0) || (pexiting > 0) - || (secondist/distvar < (4+gamespeed))) + || (secondist/distvar < 3)) + && (pos != 9)) // Force SPB newodds = 0; - newodds *= min((secondist/distvar)-(3+gamespeed), 3); + newodds *= min((secondist/distvar)-4, 3); break; case KITEM_GROW: POWERITEMODDS(newodds); @@ -770,16 +771,16 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed) //{ SRB2kart Roulette Code - Distance Based, no waypoints -static INT32 K_FindUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT32 bestbumper, boolean spbrush) +static INT32 K_FindUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT32 bestbumper, boolean spbrush, boolean dontforcespb) { const INT32 distvar = (64*14); INT32 i; INT32 pdis = 0, useodds = 0; UINT8 disttable[14]; UINT8 distlen = 0; - boolean oddsvalid[9]; + boolean oddsvalid[10]; - for (i = 0; i < 9; i++) + for (i = 0; i < 10; i++) { INT32 j; boolean available = false; @@ -860,6 +861,10 @@ static INT32 K_FindUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT3 useodds = 0; else if (pdis <= 0) // (64*14) * 0 = 0 useodds = disttable[0]; + else if (player->kartstuff[k_position] == 2 && pdis > (distvar*6) + && spbplace == -1 && !indirectitemcooldown && !dontforcespb + && oddsvalid[9]) // Force SPB in 2nd + useodds = 9; else if (pdis > distvar * ((12 * distlen) / 14)) // (64*14) * 12 = 10752 useodds = disttable[distlen-1]; else @@ -892,6 +897,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) INT32 chance = 0, numchoices = 0; INT32 bestbumper = 0; fixed_t mashed = 0; + boolean dontforcespb = false; // This makes the roulette cycle through items - if this is 0, you shouldn't be here. if (player->kartstuff[k_itemroulette]) @@ -905,6 +911,8 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) if (!playeringame[i] || players[i].spectator) continue; pingame++; + if (players[i].exiting) + dontforcespb = true; if (players[i].kartstuff[k_bumper] > bestbumper) bestbumper = players[i].kartstuff[k_bumper]; } @@ -987,7 +995,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) spawnchance[i] = 0; // Split into another function for a debug function below - useodds = K_FindUseodds(player, mashed, pingame, bestbumper, (spbplace != -1 && player->kartstuff[k_position] == spbplace+1)); + useodds = K_FindUseodds(player, mashed, pingame, bestbumper, (spbplace != -1 && player->kartstuff[k_position] == spbplace+1), dontforcespb); #define SETITEMRESULT(itemnum) \ for (chance = 0; chance < K_KartGetItemOdds(useodds, itemnum, mashed); chance++) \ @@ -1981,6 +1989,18 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto return; } +static void K_RemoveGrowShrink(player_t *player) +{ + player->kartstuff[k_growshrinktimer] = 0; + if (player->kartstuff[k_invincibilitytimer] == 0) + player->mo->color = player->skincolor; + player->mo->scalespeed = mapheaderinfo[gamemap-1]->mobj_scale/TICRATE; + player->mo->destscale = mapheaderinfo[gamemap-1]->mobj_scale; + if (cv_kartdebugshrink.value && !modeattacking && !player->bot) + player->mo->destscale = 6*player->mo->destscale/8; + P_RestoreMusic(player); +} + void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor) { UINT8 scoremultiply = 1; @@ -2076,8 +2096,8 @@ void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor) if (player->kartstuff[k_growshrinktimer] < 0) { player->kartstuff[k_growshrinktimer] += TICRATE; - if (player->kartstuff[k_growshrinktimer] > -2) - player->kartstuff[k_growshrinktimer] = -2; + if (player->kartstuff[k_growshrinktimer] >= 0) + K_RemoveGrowShrink(player); } player->powers[pw_flashing] = K_GetKartFlashing(player); @@ -2444,25 +2464,25 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color) } } -static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t angle, INT32 flags2, fixed_t speed) +static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, INT32 flags2, fixed_t speed) { mobj_t *th; - angle_t an; fixed_t x, y, z; fixed_t finalspeed = speed; mobj_t *throwmo; - //INT32 dir; - - // angle at which you fire, is player angle - an = angle; - - //if (source->player->kartstuff[k_throwdir] != 0) - // dir = source->player->kartstuff[k_throwdir]; - //else - // dir = 1; if (source->player && source->player->speed > K_GetKartSpeed(source->player, false)) - finalspeed = FixedMul(speed, FixedDiv(source->player->speed, K_GetKartSpeed(source->player, false))); + { + angle_t input = source->angle - an; + boolean invert = (input > ANGLE_180); + if (invert) + input = InvAngle(input); + + finalspeed = max(speed, FixedMul(speed, FixedMul( + FixedDiv(source->player->speed, K_GetKartSpeed(source->player, false)), // Multiply speed to be proportional to your own, boosted maxspeed. + (((180<x + source->momx + FixedMul(finalspeed, FINECOSINE(an>>ANGLETOFINESHIFT)); y = source->y + source->momy + FixedMul(finalspeed, FINESINE(an>>ANGLETOFINESHIFT)); @@ -2479,15 +2499,8 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t angle th->threshold = 10; -#ifdef WEAPON_SFX - //Since rail and bounce have no thrown objects, this hack is necessary. - //Is creating thrown objects for rail and bounce more or less desirable than this? - if (th->info->seesound && !(th->flags2 & MF2_RAILRING) && !(th->flags2 & MF2_SCATTER)) - S_StartSound(source, th->info->seesound); -#else if (th->info->seesound) S_StartSound(source, th->info->seesound); -#endif P_SetTarget(&th->target, source); @@ -2517,6 +2530,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t angle th->color = source->player->skincolor; else th->color = SKINCOLOR_GREY; + th->movefactor = finalspeed; break; case MT_JAWZ: if (source && source->player) @@ -2526,6 +2540,9 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t angle /* FALLTHRU */ case MT_JAWZ_DUD: S_StartSound(th, th->info->activesound); + /* FALLTHRU */ + case MT_SPB: + th->movefactor = finalspeed; break; default: break; @@ -2875,17 +2892,29 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map return NULL; // Figure out projectile speed by game speed - switch (gamespeed) + if (missile && mapthing != MT_BALLHOG) // Trying to keep compatability... { - case 0: - PROJSPEED = 68*(mapheaderinfo[gamemap-1]->mobj_scale); // Avg Speed is 34 - break; - case 2: - PROJSPEED = 96*(mapheaderinfo[gamemap-1]->mobj_scale); // Avg Speed is 48 - break; - default: - PROJSPEED = 82*(mapheaderinfo[gamemap-1]->mobj_scale); // Avg Speed is 41 - break; + PROJSPEED = mobjinfo[mapthing].speed; + if (gamespeed == 0) + PROJSPEED = FixedMul(PROJSPEED, FRACUNIT-FRACUNIT/4); + else if (gamespeed == 2) + PROJSPEED = FixedMul(PROJSPEED, FRACUNIT+FRACUNIT/4); + PROJSPEED = FixedMul(PROJSPEED, mapheaderinfo[gamemap-1]->mobj_scale); + } + else + { + switch (gamespeed) + { + case 0: + PROJSPEED = 68*(mapheaderinfo[gamemap-1]->mobj_scale); // Avg Speed is 34 + break; + case 2: + PROJSPEED = 96*(mapheaderinfo[gamemap-1]->mobj_scale); // Avg Speed is 48 + break; + default: + PROJSPEED = 82*(mapheaderinfo[gamemap-1]->mobj_scale); // Avg Speed is 41 + break; + } } if (altthrow) @@ -2945,7 +2974,7 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map if (dir == -1 && mapthing != MT_SPB) { // Shoot backward - mo = K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180, 0, PROJSPEED/4); + mo = K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180, 0, PROJSPEED/2); } else { @@ -3265,12 +3294,12 @@ static void K_DoShrink(player_t *user) players[i].mo->destscale = 6*(mapheaderinfo[gamemap-1]->mobj_scale)/8; if (cv_kartdebugshrink.value && !modeattacking && !players[i].bot) players[i].mo->destscale = 6*players[i].mo->destscale/8; - players[i].kartstuff[k_growshrinktimer] -= (200+(40*(MAXPLAYERS-players[i].kartstuff[k_position]))); + players[i].kartstuff[k_growshrinktimer] = -(200+(40*(MAXPLAYERS-players[i].kartstuff[k_position]))); } // Grow should get taken away. if (players[i].kartstuff[k_growshrinktimer] > 0) - players[i].kartstuff[k_growshrinktimer] = 2; + K_RemoveGrowShrink(&players[i]); //P_FlashPal(&players[i], PAL_NUKE, 10); S_StartSound(players[i].mo, sfx_kc59); @@ -4301,22 +4330,16 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_invincibilitytimer]) player->kartstuff[k_invincibilitytimer]--; - if (!player->kartstuff[k_respawn]) + if (!player->kartstuff[k_respawn] && player->kartstuff[k_growshrinktimer] != 0) { if (player->kartstuff[k_growshrinktimer] > 0) player->kartstuff[k_growshrinktimer]--; if (player->kartstuff[k_growshrinktimer] < 0) player->kartstuff[k_growshrinktimer]++; - } - if (player->kartstuff[k_growshrinktimer] == 1 || player->kartstuff[k_growshrinktimer] == -1) - { - if (player->kartstuff[k_invincibilitytimer] == 0) - player->mo->color = player->skincolor; - player->mo->destscale = mapheaderinfo[gamemap-1]->mobj_scale; - if (cv_kartdebugshrink.value && !modeattacking && !player->bot) - player->mo->destscale = 6*player->mo->destscale/8; - P_RestoreMusic(player); + // Back to normal + if (player->kartstuff[k_growshrinktimer] == 0) + K_RemoveGrowShrink(player); } if (player->kartstuff[k_stealingtimer] == 0 && player->kartstuff[k_stolentimer] == 0 @@ -4871,10 +4894,7 @@ void K_StripOther(player_t *player) player->kartstuff[k_roulettetype] = 0; player->kartstuff[k_invincibilitytimer] = 0; - if (player->kartstuff[k_growshrinktimer] > 0) - player->kartstuff[k_growshrinktimer] = 2; - else if (player->kartstuff[k_growshrinktimer] < 0) - player->kartstuff[k_growshrinktimer] = -2; + K_RemoveGrowShrink(player); if (player->kartstuff[k_eggmanexplode]) { @@ -5475,6 +5495,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) // Increase your size while charging your engine. if (leveltime < starttime+10) { + player->mo->scalespeed = mapheaderinfo[gamemap-1]->mobj_scale/12; player->mo->destscale = (mapheaderinfo[gamemap-1]->mobj_scale) + (player->kartstuff[k_boostcharge]*131); if (cv_kartdebugshrink.value && !modeattacking && !player->bot) player->mo->destscale = 6*player->mo->destscale/8; @@ -6425,7 +6446,7 @@ static void K_drawKartItem(void) else localpatch = kp_nodraw; } - else if (stplyr->kartstuff[k_growshrinktimer] > 1) + else if (stplyr->kartstuff[k_growshrinktimer] > 0) { if (leveltime & 1) localpatch = kp_grow[offset]; @@ -7888,7 +7909,7 @@ static void K_drawLapStartAnim(void) V_DrawFixedPatch((BASEVIDWIDTH/2 + (32*max(0, stplyr->kartstuff[k_lapanimation]-76)))*FRACUNIT, (48 - (32*max(0, progress-76)))*FRACUNIT, - FRACUNIT, V_HUDTRANS, + FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, (modeattacking ? kp_lapanim_emblem[1] : kp_lapanim_emblem[0]), colormap); if (stplyr->kartstuff[k_laphand] >= 1 && stplyr->kartstuff[k_laphand] <= 3) @@ -7896,7 +7917,7 @@ static void K_drawLapStartAnim(void) V_DrawFixedPatch((BASEVIDWIDTH/2 + (32*max(0, stplyr->kartstuff[k_lapanimation]-76)))*FRACUNIT, (48 - (32*max(0, progress-76)) + 4 - abs((leveltime % 8) - 4))*FRACUNIT, - FRACUNIT, V_HUDTRANS, + FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, kp_lapanim_hand[stplyr->kartstuff[k_laphand]-1], NULL); } @@ -7904,14 +7925,14 @@ static void K_drawLapStartAnim(void) { V_DrawFixedPatch((62 - (32*max(0, progress-76)))*FRACUNIT, // 27 30*FRACUNIT, // 24 - FRACUNIT, V_HUDTRANS, + FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, kp_lapanim_final[min(progress/2, 10)], NULL); if (progress/2-12 >= 0) { V_DrawFixedPatch((188 + (32*max(0, progress-76)))*FRACUNIT, // 194 30*FRACUNIT, // 24 - FRACUNIT, V_HUDTRANS, + FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, kp_lapanim_lap[min(progress/2-12, 6)], NULL); } } @@ -7919,21 +7940,21 @@ static void K_drawLapStartAnim(void) { V_DrawFixedPatch((82 - (32*max(0, progress-76)))*FRACUNIT, // 61 30*FRACUNIT, // 24 - FRACUNIT, V_HUDTRANS, + FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, kp_lapanim_lap[min(progress/2, 6)], NULL); if (progress/2-8 >= 0) { V_DrawFixedPatch((188 + (32*max(0, progress-76)))*FRACUNIT, // 194 30*FRACUNIT, // 24 - FRACUNIT, V_HUDTRANS, + FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, kp_lapanim_number[(((UINT32)stplyr->laps+1) / 10)][min(progress/2-8, 2)], NULL); if (progress/2-10 >= 0) { V_DrawFixedPatch((208 + (32*max(0, progress-76)))*FRACUNIT, // 221 30*FRACUNIT, // 24 - FRACUNIT, V_HUDTRANS, + FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, kp_lapanim_number[(((UINT32)stplyr->laps+1) % 10)][min(progress/2-10, 2)], NULL); } } @@ -7983,6 +8004,7 @@ static void K_drawDistributionDebugger(void) INT32 pingame = 0, bestbumper = 0; INT32 i; INT32 x = -9, y = -9; + boolean dontforcespb = false; if (stplyr != &players[displayplayer]) // only for p1 return; @@ -7993,11 +8015,13 @@ static void K_drawDistributionDebugger(void) if (!playeringame[i] || players[i].spectator) continue; pingame++; + if (players[i].exiting) + dontforcespb = true; if (players[i].kartstuff[k_bumper] > bestbumper) bestbumper = players[i].kartstuff[k_bumper]; } - useodds = K_FindUseodds(stplyr, 0, pingame, bestbumper, (spbplace != -1 && stplyr->kartstuff[k_position] == spbplace+1)); + useodds = K_FindUseodds(stplyr, 0, pingame, bestbumper, (spbplace != -1 && stplyr->kartstuff[k_position] == spbplace+1), dontforcespb); for (i = 1; i < NUMKARTRESULTS; i++) { diff --git a/src/locale/en.po b/src/locale/en.po index 2665082a..ce451080 100644 --- a/src/locale/en.po +++ b/src/locale/en.po @@ -3629,7 +3629,7 @@ msgid "another castle!" msgstr "" #: st_stuff.c:2328 st_stuff.c:2334 st_stuff.c:2356 -msgid "Press F12 to watch another player." +msgid "Press Viewpoint Key to watch a player." msgstr "" #: st_stuff.c:2333 diff --git a/src/locale/srb2.pot b/src/locale/srb2.pot index 37d14f8b..c61cbcc9 100644 --- a/src/locale/srb2.pot +++ b/src/locale/srb2.pot @@ -3820,7 +3820,7 @@ msgid "another castle!" msgstr "" #: st_stuff.c:2092 st_stuff.c:2098 st_stuff.c:2120 -msgid "Press F12 to watch another player." +msgid "Press Viewpoint Key to watch a player." msgstr "" #: st_stuff.c:2097 diff --git a/src/m_menu.c b/src/m_menu.c index 907a6d74..a925e95a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -59,6 +59,8 @@ #include "k_kart.h" // SRB2kart #include "d_player.h" // KITEM_ constants +#include "i_joy.h" // for joystick menu controls + // Condition Sets #include "m_cond.h" @@ -168,7 +170,7 @@ typedef enum levellist_mode_t levellistmode = LLM_CREATESERVER; UINT8 maplistoption = 0; -static char joystickInfo[8][25]; +static char joystickInfo[8][29]; #ifndef NONET static UINT32 serverlistpage; #endif @@ -2443,6 +2445,7 @@ boolean M_Responder(event_t *ev) INT32 ch = -1; // INT32 i; static tic_t joywait = 0, mousewait = 0; + static INT32 pjoyx = 0, pjoyy = 0; static INT32 pmousex = 0, pmousey = 0; static INT32 lastx = 0, lasty = 0; void (*routine)(INT32 choice); // for some casting problem @@ -2458,63 +2461,84 @@ boolean M_Responder(event_t *ev) // (but still allow shift keyup so caps doesn't get stuck) return false; } - else if (ev->type == ev_keydown) - { - ch = ev->data1; - - // added 5-2-98 remap virtual keys (mouse & joystick buttons) - switch (ch) - { - case KEY_MOUSE1: - case KEY_JOY1: - case KEY_JOY1 + 2: - ch = KEY_ENTER; - break; - case KEY_JOY1 + 3: - ch = 'n'; - break; - case KEY_MOUSE1 + 1: - case KEY_JOY1 + 1: - ch = KEY_BACKSPACE; - break; - case KEY_HAT1: - ch = KEY_UPARROW; - break; - case KEY_HAT1 + 1: - ch = KEY_DOWNARROW; - break; - case KEY_HAT1 + 2: - ch = KEY_LEFTARROW; - break; - case KEY_HAT1 + 3: - ch = KEY_RIGHTARROW; - break; - } - } else if (menuactive) { - if (ev->type == ev_joystick && ev->data1 == 0 && joywait < I_GetTime()) + if (ev->type == ev_keydown) { - if (ev->data3 == -1) + ch = ev->data1; + + // added 5-2-98 remap virtual keys (mouse & joystick buttons) + switch (ch) { - ch = KEY_UPARROW; - joywait = I_GetTime() + NEWTICRATE/7; + case KEY_MOUSE1: + case KEY_JOY1: + ch = KEY_ENTER; + break; + case KEY_JOY1 + 3: + ch = 'n'; + break; + case KEY_MOUSE1 + 1: + case KEY_JOY1 + 1: + ch = KEY_ESCAPE; + break; + case KEY_JOY1 + 2: + ch = KEY_BACKSPACE; + break; + case KEY_HAT1: + ch = KEY_UPARROW; + break; + case KEY_HAT1 + 1: + ch = KEY_DOWNARROW; + break; + case KEY_HAT1 + 2: + ch = KEY_LEFTARROW; + break; + case KEY_HAT1 + 3: + ch = KEY_RIGHTARROW; + break; } - else if (ev->data3 == 1) + } + else if (ev->type == ev_joystick && ev->data1 == 0 && joywait < I_GetTime()) + { + const INT32 jdeadzone = JOYAXISRANGE/4; + if (ev->data3 != INT32_MAX) { - ch = KEY_DOWNARROW; - joywait = I_GetTime() + NEWTICRATE/7; + if (Joystick.bGamepadStyle || abs(ev->data3) > jdeadzone) + { + if (ev->data3 < 0 && pjoyy >= 0) + { + ch = KEY_UPARROW; + joywait = I_GetTime() + NEWTICRATE/7; + } + else if (ev->data3 > 0 && pjoyy <= 0) + { + ch = KEY_DOWNARROW; + joywait = I_GetTime() + NEWTICRATE/7; + } + pjoyy = ev->data3; + } + else + pjoyy = 0; } - if (ev->data2 == -1) + if (ev->data2 != INT32_MAX) { - ch = KEY_LEFTARROW; - joywait = I_GetTime() + NEWTICRATE/17; - } - else if (ev->data2 == 1) - { - ch = KEY_RIGHTARROW; - joywait = I_GetTime() + NEWTICRATE/17; + if (Joystick.bGamepadStyle || abs(ev->data2) > jdeadzone) + { + if (ev->data2 < 0 && pjoyx >= 0) + { + ch = KEY_LEFTARROW; + joywait = I_GetTime() + NEWTICRATE/17; + } + else if (ev->data2 > 0 && pjoyx <= 0) + { + ch = KEY_RIGHTARROW; + joywait = I_GetTime() + NEWTICRATE/17; + } + pjoyx = ev->data2; + } + else + pjoyx = 0; } } else if (ev->type == ev_mouse && mousewait < I_GetTime()) @@ -2548,6 +2572,8 @@ boolean M_Responder(event_t *ev) } } } + else if (ev->type == ev_keydown) // Preserve event for other responders + ch = ev->data1; if (ch == -1) return false; @@ -3383,7 +3409,7 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines) // // Draw border for the savegame description // -static void M_DrawSaveLoadBorder(INT32 x,INT32 y) +/*static void M_DrawSaveLoadBorder(INT32 x,INT32 y) { INT32 i; @@ -3396,7 +3422,7 @@ static void M_DrawSaveLoadBorder(INT32 x,INT32 y) } V_DrawScaledPatch (x,y+7,0,W_CachePatchName("M_LSRGHT",PU_CACHE)); -} +}*/ // horizontally centered text static void M_CentreText(INT32 y, const char *string) @@ -4865,7 +4891,7 @@ static void M_HandleAddons(INT32 choice) case EXT_LUA: #ifndef HAVE_BLUA S_StartSound(NULL, sfx_s26d); - M_StartMessage(va("%c%s\x80\nThis copy of SRB2 was compiled\nwithout support for .lua files.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING); + M_StartMessage(va("%c%s\x80\nThis copy of SRB2Kart was compiled\nwithout support for .lua files.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING); break; #endif // else intentional fallthrough @@ -8546,35 +8572,32 @@ static void M_DrawJoystick(void) for (i = 0; i < 8; i++) { - M_DrawSaveLoadBorder(OP_JoystickSetDef.x, OP_JoystickSetDef.y+LINEHEIGHT*i); + M_DrawTextBox(OP_JoystickSetDef.x-8, OP_JoystickSetDef.y+LINEHEIGHT*i-12, 28, 1); + //M_DrawSaveLoadBorder(OP_JoystickSetDef.x, OP_JoystickSetDef.y+LINEHEIGHT*i); if ((setupcontrolplayer == 4 && (i == cv_usejoystick4.value)) || (setupcontrolplayer == 3 && (i == cv_usejoystick3.value)) || (setupcontrolplayer == 2 && (i == cv_usejoystick2.value)) || (setupcontrolplayer == 1 && (i == cv_usejoystick.value))) - V_DrawString(OP_JoystickSetDef.x, OP_JoystickSetDef.y+LINEHEIGHT*i,recommendedflags,joystickInfo[i]); + V_DrawString(OP_JoystickSetDef.x, OP_JoystickSetDef.y+LINEHEIGHT*i-4,recommendedflags,joystickInfo[i]); else - V_DrawString(OP_JoystickSetDef.x, OP_JoystickSetDef.y+LINEHEIGHT*i,0,joystickInfo[i]); + V_DrawString(OP_JoystickSetDef.x, OP_JoystickSetDef.y+LINEHEIGHT*i-4,0,joystickInfo[i]); } } static void M_SetupJoystickMenu(INT32 choice) { INT32 i = 0; - const char *joyname = "None"; const char *joyNA = "Unavailable"; INT32 n = I_NumJoys(); (void)choice; - strcpy(joystickInfo[i], joyname); + strcpy(joystickInfo[i], "None"); for (i = 1; i < 8; i++) { - if (i <= n && (joyname = I_GetJoyName(i)) != NULL) - { - strncpy(joystickInfo[i], joyname, 24); - joystickInfo[i][24] = '\0'; - } + if (i <= n && (I_GetJoyName(i)) != NULL) + strncpy(joystickInfo[i], I_GetJoyName(i), 28); else strcpy(joystickInfo[i], joyNA); } diff --git a/src/m_misc.c b/src/m_misc.c index 603e3de0..003bf925 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1499,9 +1499,9 @@ boolean M_ScreenshotResponder(event_t *ev) if (ch >= KEY_MOUSE1 && menuactive) // If it's not a keyboard key, then don't allow it in the menus! return false; - if (ch == gamecontrol[gc_screenshot][0] || ch == gamecontrol[gc_screenshot][1]) // remappable F8 + if (ch == KEY_F8 || ch == gamecontrol[gc_screenshot][0] || ch == gamecontrol[gc_screenshot][1]) // remappable F8 M_ScreenShot(); - else if (ch == gamecontrol[gc_recordgif][0] || ch == gamecontrol[gc_recordgif][1]) // remappable F9 + else if (ch == KEY_F9 || ch == gamecontrol[gc_recordgif][0] || ch == gamecontrol[gc_recordgif][1]) // remappable F9 ((moviemode) ? M_StopMovie : M_StartMovie)(); else return false; diff --git a/src/p_enemy.c b/src/p_enemy.c index cc37c774..3fb3aca6 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8276,7 +8276,7 @@ void A_JawzChase(mobj_t *actor) ret->frame |= ((leveltime % 10) / 2) + 5; ret->color = actor->cvmem; - P_Thrust(actor, R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y), actor->info->speed); + P_Thrust(actor, R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y), (7*actor->movefactor)/64); return; } else @@ -8348,11 +8348,7 @@ void A_SPBChase(mobj_t *actor) #endif // Default speed - wspeed = FixedMul(actor->info->speed, mapheaderinfo[gamemap-1]->mobj_scale); - if (gamespeed == 0) - wspeed = FixedMul(wspeed, FRACUNIT-FRACUNIT/4); - else if (gamespeed == 2) - wspeed = FixedMul(wspeed, FRACUNIT+FRACUNIT/4); + wspeed = actor->movefactor; if (actor->threshold) // Just fired, go straight. { diff --git a/src/p_inter.c b/src/p_inter.c index 7c599016..fce8ccd5 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -131,8 +131,8 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon) else { // Item-specific timer going off - if (player->kartstuff[k_stealingtimer] || player->kartstuff[k_stolentimer] - || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_rocketsneakertimer] + if (player->kartstuff[k_stealingtimer] || player->kartstuff[k_stolentimer] + || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_rocketsneakertimer] || player->kartstuff[k_eggmanexplode]) return false; diff --git a/src/p_mobj.c b/src/p_mobj.c index 40b107dc..e393c11e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8025,15 +8025,10 @@ void P_MobjThinker(mobj_t *mobj) } else { - fixed_t finalspeed = mobj->info->speed; + fixed_t finalspeed = mobj->movefactor; P_SpawnGhostMobj(mobj); - if (gamespeed == 0) - finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4); - else if (gamespeed == 2) - finalspeed = FixedMul(finalspeed, FRACUNIT+FRACUNIT/4); - mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); if (mobj->health <= 5) { @@ -8041,7 +8036,6 @@ void P_MobjThinker(mobj_t *mobj) for (i = 5; i >= mobj->health; i--) finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4); } - finalspeed = FixedMul(finalspeed, mapheaderinfo[gamemap-1]->mobj_scale); P_InstaThrust(mobj, mobj->angle, finalspeed); if (grounded) @@ -8064,7 +8058,7 @@ void P_MobjThinker(mobj_t *mobj) case MT_JAWZ: { sector_t *sec2; - fixed_t topspeed = 64*FRACUNIT; + fixed_t topspeed = mobj->movefactor; fixed_t distbarrier = 512*FRACUNIT; fixed_t distaway; @@ -8076,18 +8070,10 @@ void P_MobjThinker(mobj_t *mobj) S_StartSound(mobj, mobj->info->activesound); if (gamespeed == 0) - { - topspeed = FixedMul(topspeed, FRACUNIT-FRACUNIT/4); distbarrier = FixedMul(distbarrier, FRACUNIT-FRACUNIT/4); - } else if (gamespeed == 2) - { - topspeed = FixedMul(topspeed, FRACUNIT+FRACUNIT/4); distbarrier = FixedMul(distbarrier, FRACUNIT+FRACUNIT/4); - } - distbarrier = FixedMul(distbarrier, mapheaderinfo[gamemap-1]->mobj_scale); - topspeed = FixedMul(topspeed, mapheaderinfo[gamemap-1]->mobj_scale); if (G_RaceGametype() && mobj->tracer) { @@ -8146,7 +8132,7 @@ void P_MobjThinker(mobj_t *mobj) { P_SpawnGhostMobj(mobj); mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); - P_InstaThrust(mobj, mobj->angle, mobj->info->speed); + P_InstaThrust(mobj, mobj->angle, mobj->movefactor); if (grounded) { diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index a1a9df90..bfd89728 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -133,16 +133,16 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); // Locations for searching the srb2.srb #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) -#define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2" -#define DEFAULTWADLOCATION2 "/usr/local/games/SRB2" -#define DEFAULTWADLOCATION3 "/usr/share/games/SRB2" -#define DEFAULTWADLOCATION4 "/usr/games/SRB2" +#define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2Kart" +#define DEFAULTWADLOCATION2 "/usr/local/games/SRB2Kart" +#define DEFAULTWADLOCATION3 "/usr/share/games/SRB2Kart" +#define DEFAULTWADLOCATION4 "/usr/games/SRB2Kart" #define DEFAULTSEARCHPATH1 "/usr/local/games" #define DEFAULTSEARCHPATH2 "/usr/games" #define DEFAULTSEARCHPATH3 "/usr/local" #elif defined (_WIN32) -#define DEFAULTWADLOCATION1 "c:\\games\\srb2" -#define DEFAULTWADLOCATION2 "\\games\\srb2" +#define DEFAULTWADLOCATION1 "c:\\games\\srb2kart" +#define DEFAULTWADLOCATION2 "\\games\\srb2kart" #define DEFAULTSEARCHPATH1 "c:\\games" #define DEFAULTSEARCHPATH2 "\\games" #endif @@ -923,8 +923,8 @@ void I_GetJoystickEvents(void) UINT64 joyhats = 0; #if 0 UINT64 joybuttons = 0; -#endif Sint16 axisx, axisy; +#endif if (!joystick_started) return; @@ -992,6 +992,7 @@ void I_GetJoystickEvents(void) } } +#if 0 // send joystick axis positions event.type = ev_joystick; @@ -1042,6 +1043,7 @@ void I_GetJoystickEvents(void) } D_PostEvent(&event); } +#endif } /** \brief Open joystick handle @@ -1206,8 +1208,8 @@ void I_GetJoystick2Events(void) UINT64 joyhats = 0; #if 0 INT64 joybuttons = 0; -#endif INT32 axisx, axisy; +#endif if (!joystick2_started) return; @@ -1277,6 +1279,7 @@ void I_GetJoystick2Events(void) } } +#if 0 // send joystick axis positions event.type = ev_joystick2; @@ -1327,7 +1330,7 @@ void I_GetJoystick2Events(void) } D_PostEvent(&event); } - +#endif } /** \brief Open joystick handle @@ -2083,18 +2086,28 @@ INT32 I_NumJoys(void) return numjoy; } +static char joyname[255]; // MAX_PATH; joystick name is straight from the driver + const char *I_GetJoyName(INT32 joyindex) { - const char *joyname = "NA"; + const char *tempname = NULL; joyindex--; //SDL's Joystick System starts at 0, not 1 if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) { if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != -1) - joyname = SDL_JoystickNameForIndex(joyindex); + { + tempname = SDL_JoystickNameForIndex(joyindex); + if (tempname) + strncpy(joyname, tempname, 255); + } SDL_QuitSubSystem(SDL_INIT_JOYSTICK); } else - joyname = SDL_JoystickNameForIndex(joyindex); + { + tempname = SDL_JoystickNameForIndex(joyindex); + if (tempname) + strncpy(joyname, tempname, 255); + } return joyname; } @@ -2171,7 +2184,7 @@ void I_UpdateMumble(const mobj_t *mobj, const listener_t listener) if(mumble->uiVersion != 2) { wcsncpy(mumble->name, L"SRB2Kart "VERSIONSTRINGW, 256); - wcsncpy(mumble->description, L"Sonic Robo Blast 2 with integrated Mumble Link support.", 2048); + wcsncpy(mumble->description, L"Sonic Robo Blast 2 Kart with integrated Mumble Link support.", 2048); mumble->uiVersion = 2; } mumble->uiTick++; diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index b3587601..78dfc820 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -819,6 +819,33 @@ static void Impl_HandleJoystickAxisEvent(SDL_JoyAxisEvent evt) D_PostEvent(&event); } +#if 0 +static void Impl_HandleJoystickHatEvent(SDL_JoyHatEvent evt) +{ + event_t event; + SDL_JoystickID joyid[2]; + + // Determine the Joystick IDs for each current open joystick + joyid[0] = SDL_JoystickInstanceID(JoyInfo.dev); + joyid[1] = SDL_JoystickInstanceID(JoyInfo2.dev); + + if (evt.hat >= JOYHATS) + return; // ignore hats with too high an index + + if (evt.which == joyid[0]) + { + event.data1 = KEY_HAT1 + (evt.hat*4); + } + else if (evt.which == joyid[1]) + { + event.data1 = KEY_2HAT1 + (evt.hat*4); + } + else return; + + // NOTE: UNFINISHED +} +#endif + static void Impl_HandleJoystickButtonEvent(SDL_JoyButtonEvent evt, Uint32 type) { event_t event; @@ -866,6 +893,8 @@ static void Impl_HandleJoystickButtonEvent(SDL_JoyButtonEvent evt, Uint32 type) if (event.type != ev_console) D_PostEvent(&event); } + + void I_GetEvent(void) { SDL_Event evt; @@ -906,6 +935,11 @@ void I_GetEvent(void) case SDL_JOYAXISMOTION: Impl_HandleJoystickAxisEvent(evt.jaxis); break; +#if 0 + case SDL_JOYHATMOTION: + Impl_HandleJoystickHatEvent(evt.jhat) + break; +#endif case SDL_JOYBUTTONUP: case SDL_JOYBUTTONDOWN: Impl_HandleJoystickButtonEvent(evt.jbutton, evt.type); @@ -1529,7 +1563,7 @@ void I_StartupGraphics(void) HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); // check gl renderer lib if (HWD.pfnGetRenderVersion() != VERSION) - I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); + I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2Kart properly.\n")); if (!HWD.pfnInit(I_Error)) // let load the OpenGL library { rendermode = render_soft; diff --git a/src/sdl/macosx/Srb2mac.icns b/src/sdl/macosx/Srb2mac.icns index 4baedc1c..96cb8a36 100644 Binary files a/src/sdl/macosx/Srb2mac.icns and b/src/sdl/macosx/Srb2mac.icns differ diff --git a/src/sdl12/i_system.c b/src/sdl12/i_system.c index 8299f6eb..0e5adbb4 100644 --- a/src/sdl12/i_system.c +++ b/src/sdl12/i_system.c @@ -155,9 +155,9 @@ void __set_fpscr(long); // in libgcc / kernel's startup.s? //#define DEFAULTSEARCHPATH3 "/pc/home/alam/srb2code/data" #elif defined (GP2X) #define DEFAULTWADLOCATION1 "/mnt/sd" -#define DEFAULTWADLOCATION2 "/mnt/sd/SRB2" +#define DEFAULTWADLOCATION2 "/mnt/sd/SRB2Kart" #define DEFAULTWADLOCATION3 "/tmp/mnt/sd" -#define DEFAULTWADLOCATION4 "/tmp/mnt/sd/SRB2" +#define DEFAULTWADLOCATION4 "/tmp/mnt/sd/SRB2Kart" #define DEFAULTSEARCHPATH1 "/mnt/sd" #define DEFAULTSEARCHPATH2 "/tmp/mnt/sd" #elif defined (_WII) @@ -184,10 +184,10 @@ void __set_fpscr(long); // in libgcc / kernel's startup.s? #define DEFAULTSEARCHPATH1 "host0:/" #define DEFAULTSEARCHPATH2 "ms0:/PSP/GAME/SRB2PSP" #elif defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) -#define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2" -#define DEFAULTWADLOCATION2 "/usr/local/games/SRB2" -#define DEFAULTWADLOCATION3 "/usr/share/games/SRB2" -#define DEFAULTWADLOCATION4 "/usr/games/SRB2" +#define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2Kart" +#define DEFAULTWADLOCATION2 "/usr/local/games/SRB2Kart" +#define DEFAULTWADLOCATION3 "/usr/share/games/SRB2Kart" +#define DEFAULTWADLOCATION4 "/usr/games/SRB2Kart" #define DEFAULTSEARCHPATH1 "/usr/local/games" #define DEFAULTSEARCHPATH2 "/usr/games" #define DEFAULTSEARCHPATH3 "/usr/local" @@ -196,21 +196,21 @@ void __set_fpscr(long); // in libgcc / kernel's startup.s? #ifdef __GNUC__ #include #endif -#define DEFAULTWADLOCATION1 "c:\\srb2" -#define DEFAULTWADLOCATION2 "d:\\srb2" -#define DEFAULTWADLOCATION3 "e:\\srb2" -#define DEFAULTWADLOCATION4 "f:\\srb2" -#define DEFAULTWADLOCATION5 "g:\\srb2" -#define DEFAULTWADLOCATION6 "h:\\srb2" -#define DEFAULTWADLOCATION7 "i:\\srb2" +#define DEFAULTWADLOCATION1 "c:\\srb2kart" +#define DEFAULTWADLOCATION2 "d:\\srb2kart" +#define DEFAULTWADLOCATION3 "e:\\srb2kart" +#define DEFAULTWADLOCATION4 "f:\\srb2kart" +#define DEFAULTWADLOCATION5 "g:\\srb2kart" +#define DEFAULTWADLOCATION6 "h:\\srb2kart" +#define DEFAULTWADLOCATION7 "i:\\srb2kart" #elif defined (_WIN32_WCE) #define NOCWD #define NOHOME -#define DEFAULTWADLOCATION1 "\\Storage Card\\SRB2DEMO" +#define DEFAULTWADLOCATION1 "\\Storage Card\\SRB2Kart" #define DEFAULTSEARCHPATH1 "\\Storage Card" #elif defined (_WIN32) -#define DEFAULTWADLOCATION1 "c:\\games\\srb2" -#define DEFAULTWADLOCATION2 "\\games\\srb2" +#define DEFAULTWADLOCATION1 "c:\\games\\srb2kart" +#define DEFAULTWADLOCATION2 "\\games\\srb2kart" #define DEFAULTSEARCHPATH1 "c:\\games" #define DEFAULTSEARCHPATH2 "\\games" #endif @@ -2236,18 +2236,28 @@ INT32 I_NumJoys(void) return numjoy; } +static char joyname[255]; // MAX_PATH; joystick name is straight from the driver + const char *I_GetJoyName(INT32 joyindex) { - const char *joyname = "NA"; + const char *tempname = NULL; joyindex--; //SDL's Joystick System starts at 0, not 1 if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) { if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != -1) - joyname = SDL_JoystickName(joyindex); + { + tempname = SDL_JoystickNameForIndex(joyindex); + if (tempname) + strncpy(joyname, tempname, 255); + } SDL_QuitSubSystem(SDL_INIT_JOYSTICK); } else - joyname = SDL_JoystickName(joyindex); + { + tempname = SDL_JoystickNameForIndex(joyindex); + if (tempname) + strncpy(joyname, tempname, 255); + } return joyname; } @@ -2324,7 +2334,7 @@ void I_UpdateMumble(const mobj_t *mobj, const listener_t listener) if(mumble->uiVersion != 2) { wcsncpy(mumble->name, L"SRB2Kart "VERSIONSTRING, 256); - wcsncpy(mumble->description, L"Sonic Robo Blast 2 with integrated Mumble Link support.", 2048); + wcsncpy(mumble->description, L"Sonic Robo Blast 2 Kart with integrated Mumble Link support.", 2048); mumble->uiVersion = 2; } mumble->uiTick++; diff --git a/src/sdl12/macosx/Srb2mac.icns b/src/sdl12/macosx/Srb2mac.icns index 4baedc1c..96cb8a36 100644 Binary files a/src/sdl12/macosx/Srb2mac.icns and b/src/sdl12/macosx/Srb2mac.icns differ diff --git a/src/st_stuff.c b/src/st_stuff.c index 770321da..a3429690 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1931,12 +1931,12 @@ static void ST_overlayDrawer(void) if (!hu_showscores && netgame && !mapreset) { /*if (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player.")); + V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press Viewpoint Key to watch a player.")); else if (gametype == GT_HIDEANDSEEK && (!stplyr->spectator && !(stplyr->pflags & PF_TAGIT)) && (leveltime > hidetime * TICRATE)) { V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(116), 0, M_GetText("You cannot move while hiding.")); - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player.")); + V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press Viewpoint Key to watch a player.")); } else if (!G_RaceGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. { diff --git a/windows-installer/! MAKE SURE FILES ARE IN new-install ARCHIVE FOLDER !.txt b/windows-installer/! MAKE SURE FILES ARE IN new-install ARCHIVE FOLDER !.txt new file mode 100644 index 00000000..e69de29b diff --git a/windows-installer/.gitignore b/windows-installer/.gitignore new file mode 100644 index 00000000..40ca3713 --- /dev/null +++ b/windows-installer/.gitignore @@ -0,0 +1,10 @@ +* +*.* +!staging +!sfx +!uninstaller +!! MAKE SURE FILES ARE IN new-install ARCHIVE FOLDER !.txt +!BuildInstaller.bat +!README.txt +!VersionFileName.txt +!.gitignore diff --git a/windows-installer/BuildInstaller.bat b/windows-installer/BuildInstaller.bat new file mode 100644 index 00000000..3a75afb2 --- /dev/null +++ b/windows-installer/BuildInstaller.bat @@ -0,0 +1,76 @@ +@echo off + +set "SCRIPTDIR=%~dp0" +set "SCRIPTDIR=%SCRIPTDIR:~0,-1%" + +IF [%SRB2VERSIONNAME%] == [] set /p SRB2VERSIONNAME=<"%SCRIPTDIR%\VersionFileName.txt" + +:: Find 7z + +set SVZIP= + +if NOT [%1] == [] ( + echo.%~1 | findstr /C:"7z" 1>nul + if NOT errorlevel 1 ( + if exist "%~1" set "SVZIP=%~1" + ) +) + +if ["%SVZIP%"] == [""] ( + if exist "%ProgramFiles(x86)%\7-Zip\7z.exe" set "SVZIP=%ProgramFiles(x86)%\7-Zip\7z.exe" + if exist "%ProgramFiles%\7-Zip\7z.exe" set "SVZIP=%ProgramFiles%\7-Zip\7z.exe" + if exist "%ProgramW6432%\7-Zip\7z.exe" set "SVZIP=%ProgramW6432%\7-Zip\7z.exe" +) + +:: Is it in PATH? + +if ["%SVZIP%"] == [""] ( + "7z.exe" --help > NUL 2> NUL + if NOT errorlevel 1 ( + set "SVZIP=7z.exe" + ) +) + +:: Create the uninstaller + +if NOT ["%SVZIP%"] == [""] ( + del /f /q "%SCRIPTDIR%\Uninstaller.7z" 2> NUL + "%SVZIP%" a -t7z "%SCRIPTDIR%\Uninstaller.7z" "%SCRIPTDIR%\uninstaller\*" -m5=LZMA2 + copy /y /b "%SCRIPTDIR%\sfx\7zsd_LZMA2.sfx" + "%SCRIPTDIR%\sfx\config-uninstaller.txt" + "%SCRIPTDIR%\Uninstaller.7z" "%SCRIPTDIR%\staging\new-install\uninstall.exe" + del /f /q "%SCRIPTDIR%\uninstaller.7z" +) + +:: Operate on install archives + +type NUL > "%SCRIPTDIR%\staging\new-install\staging.txt" + +if exist "%SCRIPTDIR%\Installer.7z" ( + if NOT ["%SVZIP%"] == [""] ( + "%SVZIP%" a "%SCRIPTDIR%\Installer.7z" "%SCRIPTDIR%\staging\*" + ) + copy /y /b "%SCRIPTDIR%\sfx\7zsd_LZMA2.sfx" + "%SCRIPTDIR%\sfx\config-installer.txt" + "%SCRIPTDIR%\Installer.7z" "%SCRIPTDIR%\SRB2Kart-%SRB2VERSIONNAME%-Installer.exe" +) + +if exist "%SCRIPTDIR%\Patch.7z" ( + if NOT ["%SVZIP%"] == [""] ( + "%SVZIP%" a "%SCRIPTDIR%\Patch.7z" "%SCRIPTDIR%\staging\*" + ) + copy /y /b "%SCRIPTDIR%\sfx\7zsd_LZMA2.sfx" + "%SCRIPTDIR%\sfx\config-patch.txt" + "%SCRIPTDIR%\Patch.7z" "%SCRIPTDIR%\SRB2Kart-%SRB2VERSIONNAME%-Patch.exe" +) + +if exist "%SCRIPTDIR%\Installer_x64.7z" ( + if NOT ["%SVZIP%"] == [""] ( + "%SVZIP%" a "%SCRIPTDIR%\Installer_x64.7z" "%SCRIPTDIR%\staging\*" + ) + copy /y /b "%SCRIPTDIR%\sfx\7zsd_LZMA2_x64.sfx" + "%SCRIPTDIR%\sfx\config-installer.txt" + "%SCRIPTDIR%\Installer_x64.7z" "%SCRIPTDIR%\SRB2Kart-%SRB2VERSIONNAME%-x64-Installer.exe" +) + +if exist "%SCRIPTDIR%\Patch_x64.7z" ( + if NOT ["%SVZIP%"] == [""] ( + "%SVZIP%" a "%SCRIPTDIR%\Patch_x64.7z" "%SCRIPTDIR%\staging\*" + ) + copy /y /b "%SCRIPTDIR%\sfx\7zsd_LZMA2_x64.sfx" + "%SCRIPTDIR%\sfx\config-patch.txt" + "%SCRIPTDIR%\Patch_x64.7z" "%SCRIPTDIR%\SRB2Kart-%SRB2VERSIONNAME%-x64-Patch.exe" +) + +del /f /q "%SCRIPTDIR%\staging\new-install\staging.txt" +del /f /q "%SCRIPTDIR%\staging\new-install\uninstall.exe" diff --git a/windows-installer/README.txt b/windows-installer/README.txt new file mode 100644 index 00000000..51b8a7e9 --- /dev/null +++ b/windows-installer/README.txt @@ -0,0 +1,48 @@ +Windows Install Builder +for SRB2Kart + +This installer is much like the 7-Zip self-extracting archive, except +this allows for scripting the post-install step. + +This also allows for some light customization, including dialog messages +and program shortcuts. + +The included install scripts manage the game data location depending on the +install location -- if installed in Program Files or AppData\Local, the +game data location is set to %UserProfile%\SRB2Kart. + +Program shortcuts are also added, as well as an uninstaller that +will remove the icons and also selectively uninstall the core game files. +The uninstaller gives you the option to preserve your game data and mods. + +How to Use +---------- + +1. Zip up the install contents in 7z format. + * ALL FILES MUST BE IN THE `new-install/` ARCHIVE SUBFOLDER, OR THE + POST-INSTALL SCRIPT WILL NOT WORK! + * Make sure you are using the LZMA2 algorithm, which is 7-Zip's default. + +2. Copy the 7z archive to this folder using the following names: + * Installer.7z - 32-bit full installer + * Patch.7z - 32-bit patch + * Installer_x64.7z - 64-bit full installer + * Patch_x64.7z - 64-bit patch + +3. Set the text in VersionFilename.txt to the version identifier for the + installer's filename. + * e.g., v102 for v1.0.2, from "SRB2Kart-v102-Installer.exe" + * Also look through sfx/config-installer.txt and sfx/config-patch.txt + and update the version strings. Templating is TODO. + +4. Run BuildInstaller.bat [7z.exe install path] + * First argument is the path to 7z.exe. If this is not specified, the + script will try to look for it in C:\Program Files [(x86)] + * This script will automatically add the install scripts to each + installer. + +Credit +------ + +OlegScherbakov/7zSFX +https://github.com/OlegScherbakov/7zSFX diff --git a/windows-installer/VersionFileName.txt b/windows-installer/VersionFileName.txt new file mode 100644 index 00000000..c65b1654 --- /dev/null +++ b/windows-installer/VersionFileName.txt @@ -0,0 +1 @@ +v102 \ No newline at end of file diff --git a/windows-installer/sfx/7zsd_LZMA2.sfx b/windows-installer/sfx/7zsd_LZMA2.sfx new file mode 100644 index 00000000..c4ba9c58 Binary files /dev/null and b/windows-installer/sfx/7zsd_LZMA2.sfx differ diff --git a/windows-installer/sfx/7zsd_LZMA2_x64.sfx b/windows-installer/sfx/7zsd_LZMA2_x64.sfx new file mode 100644 index 00000000..758e4c2d Binary files /dev/null and b/windows-installer/sfx/7zsd_LZMA2_x64.sfx differ diff --git a/windows-installer/sfx/config-installer.txt b/windows-installer/sfx/config-installer.txt new file mode 100644 index 00000000..2811acc7 --- /dev/null +++ b/windows-installer/sfx/config-installer.txt @@ -0,0 +1,22 @@ +;!@Install@!UTF-8! + +GUIFlags="8+32+64+4096" +GUIMode="1" + +Title="Sonic Robo Blast 2 Kart v1.0.2" +BeginPrompt="Sonic Robo Blast 2 Kart v1.0.2\nFull Installer\n\nSelect a folder to install SRB2Kart in.\n\nIf you install in \"AppData\\Local\" or \"Program Files\", your game data will be saved to:\n%UserProfile%\\SRB2Kart\n\nOtherwise, your game data will be in the installation folder.\n\nShortcuts will be created in your Start Menu." + +ExtractPathText="Installation folder: (no exclamation points, please!)" +InstallPath="%LocalAppData%\\SRB2Kart" +ExtractTitle="Installing..." +ExtractDialogText="Installing SRB2Kart v1.0.2...\n\nCheck out our modding community!\nWe make levels, characters, and much more!\n\nVisit http://www.srb2.org/mods" + +Shortcut="Pu,{%%T\\srb2kart.exe},{},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{SRB2Kart},{%%T\\},{%%T\\srb2kart.exe},{0}" +Shortcut="Pu,{%%T\\srb2kart.exe},{-win},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{SRB2Kart (Windowed)},{%%T\\},{%%T\\srb2kart.exe},{0}" +Shortcut="Pu,{%%T\\srb2kart.exe},{-opengl},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{SRB2Kart (OpenGL)},{%%T\\},{%%T\\srb2kart.exe},{0}" +Shortcut="Pu,{%%T\\srb2kart.exe},{-opengl -win},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{SRB2Kart (OpenGL, Windowed)},{%%T\\},{%%T\\srb2kart.exe},{0}" +Shortcut="Pu,{%%T\\uninstall.exe},{},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{Uninstall SRB2Kart},{%%T\\},{shell32.dll},{31}" + +RunProgram="nowait:\"%%T\\new-install\\staging.bat\"" + +;!@InstallEnd@! diff --git a/windows-installer/sfx/config-patch.txt b/windows-installer/sfx/config-patch.txt new file mode 100644 index 00000000..2b516f8c --- /dev/null +++ b/windows-installer/sfx/config-patch.txt @@ -0,0 +1,22 @@ +;!@Install@!UTF-8! + +GUIFlags="8+32+64+4096" +GUIMode="1" + +Title="Sonic Robo Blast 2 Kart v1.0.2" +BeginPrompt="Sonic Robo Blast 2 Kart v1.0.2\nPatch Installer\n\nYou must have at least v1.0.0 to use this patch.\n\nSelect your current SRB2Kart folder.\n\nShortcuts will be created in your Start Menu." + +ExtractPathText="Current SRB2Kart folder: (no exclamation points, please!)" +InstallPath="%LocalAppData%\\SRB2Kart" +ExtractTitle="Installing..." +ExtractDialogText="Installing SRB2Kart v1.0.2...\n\nCheck out our modding community!\nWe make levels, characters, and much more!\n\nVisit http://www.srb2.org/mods" + +Shortcut="Pu,{%%T\\srb2kart.exe},{},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{SRB2Kart},{%%T\\},{%%T\\srb2kart.exe},{0}" +Shortcut="Pu,{%%T\\srb2kart.exe},{-win},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{SRB2Kart (Windowed)},{%%T\\},{%%T\\srb2kart.exe},{0}" +Shortcut="Pu,{%%T\\srb2kart.exe},{-opengl},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{SRB2Kart (OpenGL)},{%%T\\},{%%T\\srb2kart.exe},{0}" +Shortcut="Pu,{%%T\\srb2kart.exe},{-opengl -win},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{SRB2Kart (OpenGL, Windowed)},{%%T\\},{%%T\\srb2kart.exe},{0}" +Shortcut="Pu,{%%T\\uninstall.exe},{},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{Uninstall SRB2Kart},{%%T\\},{shell32.dll},{31}" + +RunProgram="nowait:\"%%T\\new-install\\staging.bat\"" + +;!@InstallEnd@! diff --git a/windows-installer/sfx/config-uninstaller.txt b/windows-installer/sfx/config-uninstaller.txt new file mode 100644 index 00000000..2b35ad23 --- /dev/null +++ b/windows-installer/sfx/config-uninstaller.txt @@ -0,0 +1,13 @@ +;!@Install@!UTF-8! + +GUIFlags="1+2+8" +GUIMode="2" + +Title="Uninstall SRB2Kart" +BeginPrompt="Are you sure you want to uninstall Sonic Robo Blast 2 Kart?\n\nYour game data and mods will be preserved, as well as\nany extra files in your install folder." + +InstallPath="%%S" + +RunProgram="nowait:\"%%S\\uninstall.bat\" /y" + +;!@InstallEnd@! diff --git a/windows-installer/staging/! SRB2KART INSTALL INSTRUCTIONS !.txt b/windows-installer/staging/! SRB2KART INSTALL INSTRUCTIONS !.txt new file mode 100644 index 00000000..91d055be --- /dev/null +++ b/windows-installer/staging/! SRB2KART INSTALL INSTRUCTIONS !.txt @@ -0,0 +1,11 @@ +SRB2Kart Install Instructions + +1. Move every file from the "new-install" folder to this main install folder. + +2. DELETE "staging.bat" and "staging.txt"! These can mess up your installation if run by accident! + +3. Optionally, create a folder in your user profile named "SRB2Kart". This is where your game data and addons may live. For example, + + C:\Users\[User]\SRB2Kart + +4. Run the game! Double-click srb2kart.exe -- or see if you have Start Menu icons under "SRB2Kart". \ No newline at end of file diff --git a/windows-installer/staging/new-install/old-install-list.txt b/windows-installer/staging/new-install/old-install-list.txt new file mode 100644 index 00000000..5fd2adc1 --- /dev/null +++ b/windows-installer/staging/new-install/old-install-list.txt @@ -0,0 +1,14 @@ +exchndl.dll +fmodex.dll +libFLAC-8.dll +libgme.dll +libintl-8.dll +libmikmod-2.dll +libogg-0.dll +libvorbis-0.dll +libvorbisfile-3.dll +r_opengl.dll +SDL2.dll +SDL2_mixer.dll +smpeg2.dll +srb2kart.exe \ No newline at end of file diff --git a/windows-installer/staging/new-install/staging.bat b/windows-installer/staging/new-install/staging.bat new file mode 100644 index 00000000..85ca3fd4 --- /dev/null +++ b/windows-installer/staging/new-install/staging.bat @@ -0,0 +1,363 @@ +@echo off + +setlocal enabledelayedexpansion + +cls + +:: SRB2Kart Install Staging +:: +:: This accomplishes the following tasks: +:: +:: 1. Creates a user profile folder if SRB2Kart is installed in AppData or Program Files, and config.cfg is not already in the install folder +:: +:: 2. Moves old installation files into old-install +:: +:: 3. Moves new installaton files into install folder +:: + +:: Get Parent folder (the SRB2Kart install folder) +:: +:: https://wiert.me/2011/08/30/batch-file-to-get-parent-directory-not-the-directory-of-the-batch-file-but-the-parent-of-that-directory/ + +set "STAGINGDIR=%~dp0" +:: strip trailing backslash +set "STAGINGDIR=!STAGINGDIR:~0,-1!" +:: ~dp only works for batch file parameters and loop indexes +for %%d in ("!STAGINGDIR!") do set "INSTALLDIR=%%~dpd" +set "INSTALLDIR=!INSTALLDIR:~0,-1!" + +:: Find 7z + +set SVZIP= +if ["%SVZIP%"] == [""] ( + if exist "!ProgramFiles(x86)!\7-Zip\7z.exe" set "SVZIP=!ProgramFiles(x86)!\7-Zip\7z.exe" + if exist "!ProgramFiles!\7-Zip\7z.exe" set "SVZIP=!ProgramFiles!\7-Zip\7z.exe" + if exist "!ProgramW6432!\7-Zip\7z.exe" set "SVZIP=!ProgramW6432!\7-Zip\7z.exe" +) + +:: Is it in PATH? + +if ["%SVZIP%"] == [""] ( + "7z.exe" --help > NUL 2> NUL + if NOT errorlevel 1 ( + set "SVZIP=7z.exe" + ) +) + +:: FAILSAFE: Check if staging.txt exists in the directory +:: If not, exit, so we don't mess up anything by accident. + +if NOT exist "!STAGINGDIR!\staging.txt" ( + exit +) + +: CheckPermissionsInstall + +:: Write a dummy file and check for an error. If error, we need administrator rights + +:: NOTE: We should never have to deal with this because the main installer should +:: already have the rights. + +mkdir "!INSTALLDIR!\install-dummy" + +:: TODO elevate automatically +if errorlevel 1 ( + echo Finish installing SRB2Kart with these steps: + echo. + echo 1. Go to your SRB2Kart install folder + echo. + echo !INSTALLDIR! + echo. + echo 2. Copy all files from the "new-install" subfolder into the main folder + echo and DELETE staging.bat and staging.txt!!! + echo. + echo 3. Optionally, create a folder in your user profile named "SRB2Kart". + echo This is where your game data and addons may live. + echo To create the folder, go here: + echo. + echo !USERPROFILE! + echo. + echo If anything fails, you may delete the files and try to run the installer + echo again with Administrator Rights: Right-click on the icon and click + echo "Run as administrator." + echo. + "!SystemRoot!\explorer.exe" "!INSTALLDIR!" + set /p ADMINFINAL="Press Enter key to exit. " + + exit +) else ( + rmdir /s /q "!INSTALLDIR!\install-dummy" + goto CheckUserDir +) + +: CheckUserDir + +:: Check if we need to create !userprofile!\SRB2Kart + +set "USERDIR=!INSTALLDIR!" + +:: Is config.cfg in our install dir? +if exist "!INSTALLDIR!\config.cfg" goto MoveOldInstall + +:: Are we in AppData? +echo.!STAGINGDIR! | findstr /C:"!LocalAppData!" 1>nul +if errorlevel 1 ( + echo. +) else ( + goto SetUserDir +) + +: Are we in Program Files? +echo.!STAGINGDIR! | findstr /C:"!ProgramFiles!" 1>nul +if NOT errorlevel 1 ( + goto SetUserDir +) + +:: Are we in Program Files (x86)? +echo.!STAGINGDIR! | findstr /C:"!ProgramFiles(X86)!" 1>nul +if NOT errorlevel 1 ( + goto SetUserDir +) + +:: Are we 32-bit and actually in Program Files? +echo.!STAGINGDIR! | findstr /C:"!ProgramW6432!" 1>nul +if NOT errorlevel 1 ( + goto SetUserDir +) + +goto MoveOldInstall + +: SetUserDir +: CheckPermissionsUserDir + +set "USERDIR=!UserProfile!\SRB2Kart" + +:: Check for permissions and create the folder +if exist "!USERDIR!\*" ( + mkdir "!USERDIR!\install-dummy" + + if errorlevel 1 ( + echo User profile folder exists, but we won't operate on it. + echo. + goto MoveOldInstall + ) else ( + rmdir /s /q "!USERDIR!\install-dummy" + ) +) else ( + mkdir "!USERDIR!" + + if errorlevel 1 ( + echo Could not create user profile folder + echo Defaulting to install dir: "!INSTALLDIR!" + echo. + set "USERDIR=!INSTALLDIR!" + goto MoveOldInstall + ) +) + +:: Now copy READMEs +:: echo f answers xcopy's prompt as to whether the destination is a file or a folder +echo f | xcopy /y "!STAGINGDIR!\README.txt" "!USERDIR!\README.txt" +echo f | xcopy /y "!STAGINGDIR!\LICENSE.txt" "!USERDIR!\LICENSE.txt" +echo f | xcopy /y "!STAGINGDIR!\LICENSE-3RD-PARTY.txt" "!USERDIR!\LICENSE-3RD-PARTY.txt" +echo Your game data and mods folder is: > "!USERDIR!\^! Data and Mods Go Here ^!.txt" +echo. >> "!USERDIR!\^! Data and Mods Go Here ^!.txt" +echo !USERDIR! >> "!USERDIR!\^! Data and Mods Go Here ^!.txt" +echo. >> "!USERDIR!\^! Data and Mods Go Here ^!.txt" +echo Your install folder is: >> "!USERDIR!\^! Data and Mods Go Here ^!.txt" +echo. >> "!USERDIR!\^! Data and Mods Go Here ^!.txt" +echo !INSTALLDIR! >> "!USERDIR!\^! Data and Mods Go Here ^!.txt" +echo. >> "!USERDIR!\^! Data and Mods Go Here ^!.txt" +echo To run SRB2, go to: >> "!USERDIR!\^! Data and Mods Go Here ^!.txt" +echo. >> "!USERDIR!\^! Data and Mods Go Here ^!.txt" +echo Start Menu ^> Programs ^> SRB2Kart >> "!USERDIR!\^! Data and Mods Go Here ^!.txt" + +:: Copy path to install folder + +set "SCRIPT=!TEMP!\!RANDOM!-!RANDOM!-!RANDOM!-!RANDOM!.vbs" +echo Set oWS = WScript.CreateObject("WScript.Shell") >> "!SCRIPT!" +echo sLinkFile = "!USERDIR!\^! SRB2Kart Install Folder ^!.lnk" >> "!SCRIPT!" +echo Set oLink = oWS.CreateShortcut(sLinkFile) >> "!SCRIPT!" +echo oLink.TargetPath = "!INSTALLDIR!" >> "!SCRIPT!" +echo oLink.WorkingDirectory = "!INSTALLDIR!" >> "!SCRIPT!" +echo oLink.Arguments = "" >> "!SCRIPT!" +echo oLink.IconLocation = "!INSTALLDIR!\srb2kart.exe,0" >> "!SCRIPT!" +echo oLink.Save >> "!SCRIPT!" +cscript /nologo "!SCRIPT!" +del "!SCRIPT!" + +:: Also do it the other way around + +set "SCRIPT=!TEMP!\!RANDOM!-!RANDOM!-!RANDOM!-!RANDOM!.vbs" +echo Set oWS = WScript.CreateObject("WScript.Shell") >> "!SCRIPT!" +echo sLinkFile = "!INSTALLDIR!\^! SRB2Kart Data Folder ^!.lnk" >> "!SCRIPT!" +echo Set oLink = oWS.CreateShortcut(sLinkFile) >> "!SCRIPT!" +echo oLink.TargetPath = "!USERDIR!" >> "!SCRIPT!" +echo oLink.WorkingDirectory = "!USERDIR!" >> "!SCRIPT!" +echo oLink.Arguments = "" >> "!SCRIPT!" +echo oLink.IconLocation = "!INSTALLDIR!\srb2kart.exe,0" >> "!SCRIPT!" +echo oLink.Save >> "!SCRIPT!" +cscript /nologo "!SCRIPT!" +del "!SCRIPT!" + +: MoveOldInstall + +if exist "!INSTALLDIR!\old-install\*" ( + set "OLDINSTALLDIR=!INSTALLDIR!\old-install-!RANDOM!" +) else ( + set "OLDINSTALLDIR=!INSTALLDIR!\old-install" +) + +mkdir "!OLDINSTALLDIR!" + +:: +:: Move all old install files +:: We support a list of explicit files to copy to old-install +:: And later, we also loop through our staging files, look for the pre-existing copy in +:: install root, then copy that also to old-install +:: + +:: Extract the uninstall-list.txt and uninstall-userdir.txt files from uninstaller.exe +:: if it exists + +if exist "!INSTALLDIR!\uninstall.exe" ( + if NOT ["!SVZIP!"] == [""] ( + "!SVZIP!" x "!INSTALLDIR!\uninstall.exe" "uninstall-list.txt" -o"!INSTALLDIR!" + "!SVZIP!" x "!INSTALLDIR!\uninstall.exe" "uninstall-userdir.txt" -o"!INSTALLDIR!" + ) +) + +set OLDINSTALLCHANGED= + +if exist "!STAGINGDIR!\old-install-list.txt" ( + goto MoveOldInstallOldFiles +) else ( + goto MoveOldInstallNewFiles +) + +: MoveOldInstallOldFiles + +set "TESTFILE=!TEMP!\!RANDOM!.txt" + +:: Do our failsafes before copying the file in the list +:: See uninstall.bat for details +for /F "usebackq tokens=*" %%A in ("!STAGINGDIR!\old-install-list.txt") do ( + if exist "!INSTALLDIR!\%%A" ( + if NOT ["%%A"] == [""] ( + if NOT ["%%A"] == ["%~nx0"] ( + echo %%A> "!TESTFILE!" + findstr /r ".*[<>:\"\"/\\|?*%%].*" "!TESTFILE!" >nul + if !errorlevel! equ 0 ( + echo %%A has invalid characters, skipping... + ) else ( + if exist "!INSTALLDIR!\%%A\*" ( + echo %%A is a folder, skipping... + ) else ( + echo Moving !INSTALLDIR!\%%A to "old-install" folder + echo f | xcopy /y /v "!INSTALLDIR!\%%A" "!OLDINSTALLDIR!\%%A" + if errorlevel 0 del /f /q "!INSTALLDIR!\%%A" + ) + ) + ) + ) + ) +) + +del /q /f "!STAGINGDIR!\old-install-list.txt" + +for %%F in ("!OLDINSTALLDIR!\*") DO ( + set OLDINSTALLCHANGED=1 + goto MoveOldInstallNewFiles +) + +: MoveOldInstallNewFiles + +:: Save a list of standard files +:: So the uninstall script will know what to remove +:: Append to any existing file, in case we are a patch + +dir /b /a-d "!STAGINGDIR!" >> "!INSTALLDIR!\uninstall-list.txt" + +:: Overwrite the last known gamedata folder + +echo !USERDIR! > "!INSTALLDIR!\uninstall-userdir.txt" + +:: Add the install-generated to the uninstall list +:: NO FOLLOWING SPACES AFTER THE FILENAME!!! + +echo uninstall.bat>> "!INSTALLDIR!\uninstall-list.txt" +echo uninstall-list.txt>> "!INSTALLDIR!\uninstall-list.txt" +echo uninstall-userdir.txt>> "!INSTALLDIR!\uninstall-list.txt" +:: *ahem* Prints as ^! SRB2Kart Data Folder ^!.lnk +:: We need to escape the exclamations (^^!) and the carets themselves (^^^^) +echo ^^^^^^! SRB2Kart Data Folder ^^^^^^!.lnk>> "!INSTALLDIR!\uninstall-list.txt" + +:: Add the uninstall list files to the uninstall EXE + +if NOT ["!SVZIP!"] == [""] ( + if exist "!INSTALLDIR!\new-install\uninstall.exe" ( + "!SVZIP!" a "!INSTALLDIR!\new-install\uninstall.exe" "!INSTALLDIR!\uninstall-list.txt" -sdel + "!SVZIP!" a "!INSTALLDIR!\new-install\uninstall.exe" "!INSTALLDIR!\uninstall-userdir.txt" -sdel + ) +) + +:: Start moving files + +for %%F in ("!STAGINGDIR!\*") DO ( + if exist "!INSTALLDIR!\%%~nxF" ( + set OLDINSTALLCHANGED=1 + move "!INSTALLDIR!\%%~nxF" "!OLDINSTALLDIR!\%%~nxF" + ) + if NOT ["%%~nxF"] == ["staging.bat"] ( + if NOT ["%%~nxF"] == ["staging.txt"] ( + move "!STAGINGDIR!\%%~nxF" "!INSTALLDIR!\%%~nxF" + ) + ) +) + +: Finished + +del /q /f "!INSTALLDIR!\^! SRB2KART INSTALL INSTRUCTIONS ^!.txt" + +set MSGEXE= +if exist "!SystemRoot!\System32\msg.exe" ( + set MSGEXE=!SystemRoot!\System32\msg.exe +) else ( + if exist "!SystemRoot!\Sysnative\msg.exe" ( + set MSGEXE=!SystemRoot!\Sysnative\msg.exe + ) +) + +if ["!OLDINSTALLCHANGED!"] == ["1"] ( + "!systemroot!\explorer.exe" /select, "!OLDINSTALLDIR!" + echo Finished^^! Some of your old installation files were moved to the "old-install" folder. > !TEMP!\srb2kartmsgprompt.txt + echo. >> !TEMP!\srb2kartmsgprompt.txt + echo If you no longer need these files, you may delete the folder safely. >> !TEMP!\srb2kartmsgprompt.txt + echo. >> !TEMP!\srb2kartmsgprompt.txt + echo To run SRB2Kart, go to: Start Menu ^> Programs ^> SRB2Kart. >> !TEMP!\srb2kartmsgprompt.txt + !MSGEXE! "!username!" < !TEMP!\srb2kartmsgprompt.txt + del !TEMP!\srb2kartmsgprompt.txt +) else ( + if /I ["!USERDIR!"] == ["!INSTALLDIR!"] ( + "!systemroot!\explorer.exe" "!INSTALLDIR!" + echo Finished^^! > !TEMP!\srb2kartmsgprompt.txt + echo. >> !TEMP!\srb2kartmsgprompt.txt + echo To run SRB2Kart, go to: Start Menu ^> Programs ^> SRB2Kart. >> !TEMP!\srb2kartmsgprompt.txt + !MSGEXE! "!username!" < !TEMP!\srb2kartmsgprompt.txt + del !TEMP!\srb2kartmsgprompt.txt + ) else ( + "!systemroot!\explorer.exe" "!USERDIR!" + echo Finished^^! You may find your game data in this folder: > !TEMP!\srb2kartmsgprompt.txt + echo. >> !TEMP!\srb2kartmsgprompt.txt + echo !USERDIR! >> !TEMP!\srb2kartmsgprompt.txt + echo. >> !TEMP!\srb2kartmsgprompt.txt + echo To run SRB2Kart, go to: Start Menu ^> Programs ^> SRB2Kart. >> !TEMP!\srb2kartmsgprompt.txt + !MSGEXE! "!username!" < !TEMP!\srb2kartmsgprompt.txt + del !TEMP!\srb2kartmsgprompt.txt + ) +) + +: Attempt to remove OLDINSTALLDIR, in case it's empty +rmdir /q "!OLDINSTALLDIR!" +cd \ +start "" /b "cmd" /s /c " del /f /q "%STAGINGDIR%\*"&rmdir /s /q "%STAGINGDIR%"&exit /b " diff --git a/windows-installer/uninstaller/uninstall.bat b/windows-installer/uninstaller/uninstall.bat new file mode 100644 index 00000000..4a788425 --- /dev/null +++ b/windows-installer/uninstaller/uninstall.bat @@ -0,0 +1,183 @@ +@echo off + +setlocal enabledelayedexpansion + +cls + +set "INSTALLDIR=%~dp0" +set "INSTALLDIR=!INSTALLDIR:~0,-1!" +set /p USERDIR=<"!INSTALLDIR!\uninstall-userdir.txt" +set "USERDIR=!USERDIR:~0,-1!" + +: ProceedPrompt + +if ["%1"] == ["/y"] ( + set "PROCEED=1" +) else ( + set PROCEED= + set /p PROCEED="Are you sure you want to uninstall SRB2Kart? [yes/no] " + + if /I ["!PROCEED:~0,1!"] == ["n"] exit + if /I ["!PROCEED!"] == ["y"] ( + echo Type Yes or No + echo. + goto ProceedPrompt + ) else ( + if /I ["!PROCEED!"] == ["yes"] ( + set PROCEED=1 + ) else ( + echo. + goto ProceedPrompt + ) + ) +) + +:: Failsafe, in case we Ctrl+C and decline "Terminate batch file?" + +if NOT ["!PROCEED!"] == ["1"] ( + exit +) + +: CheckPermissions + +:: Write a dummy file and check for an error. If error, we need administrator rights + +mkdir "!INSTALLDIR!\uninstall-dummy" + +:: TODO elevate automatically +if errorlevel 1 ( + echo We need Administrator Rights to uninstall SRB2Kart. + echo. + echo Try running this uninstaller by right-clicking on the icon + echo and click "Run as administrator" + echo. + set /p ADMINFINAL="Press Enter key to exit. " + exit +) else ( + rmdir /s /q "!INSTALLDIR!\uninstall-dummy" + goto DeleteFiles +) + +: DeleteFiles + +:: Our deletion list is a list of filenames, no paths, in the current folder +:: +:: We apply the following failsafes: +:: 1. Is filename the script itself? +:: 2. Does filename have illegal characters? https://stackoverflow.com/a/33625339/241046 +:: 3. Is filename a directory? +:: +:: TODO hack this to support .\file.txt relative paths +:: Can %%A be substring'd to get only the filename and extension? +:: If so, print that to the temp file instead of the whole line +:: And possibly do the folder check before the invalid char check. +:: ALSO: Don't honor upward relative paths! (..\) +:: +set "TESTFILE=!TEMP!\!RANDOM!.txt" + +for /F "usebackq tokens=*" %%A in ("!INSTALLDIR!\uninstall-list.txt") do ( + if exist "!INSTALLDIR!\%%A" ( + if NOT ["%%A"] == [""] ( + if NOT ["%%A"] == ["%~nx0"] ( + echo %%A> "!TESTFILE!" + findstr /r ".*[<>:\"\"/\\|?*%%].*" "!TESTFILE!" >nul + if !errorlevel! equ 0 ( + echo %%A has invalid characters, skipping... + ) else ( + if exist "!INSTALLDIR!\%%A\*" ( + echo %%A is a folder, skipping... + ) else ( + echo Deleting !INSTALLDIR!\%%A + del /q /f "!INSTALLDIR!\%%A" + ) + ) + ) + ) + ) +) + +del /q /f "!TESTFILE!" + +: AllDone + +:: Delete the program icons +echo Deleting your program icons... +echo. + +cd \ +rmdir /s /q "!AppData!\Microsoft\Windows\Start Menu\Programs\SRB2Kart" + +:: Check if our install folder is non-empty + +set USERDIRFILLED= +set INSTALLDIRFILLED= +for /F %%i in ('dir /b /a "!USERDIR!\*"') do ( + if NOT ["%%i"] == ["%~nx0"] ( + set USERDIRFILLED=1 + goto InstallFilledCheck + ) +) + +: InstallFilledCheck + +if /I NOT ["!USERDIR!"] == ["!INSTALLDIR!"] ( + for /F %%i in ('dir /b /a "!INSTALLDIR!\*"') do ( + if ["%%i"] == ["%~nx0"] ( + echo. + ) else ( + set INSTALLDIRFILLED=1 + goto Final + ) + ) +) + +: Final + +echo All done^^! Visit http://www.srb2.org if you want to play SRB2Kart again^^! +echo. + +set "FINALPROMPT=Press Enter key to exit." +if ["!USERDIRFILLED!"] == ["1"] ( + echo We left your game data and mods alone, so you may delete those manually. + echo. + echo !USERDIR! + echo. + set "FINALPROMPT=Do you want to view your data? [yes/no]" +) + +if ["!INSTALLDIRFILLED!"] == ["1"] ( + echo We left some extra files alone in your install folder. + echo. + echo !INSTALLDIR! + echo. + set "FINALPROMPT=Do you want to view your data? [yes/no]" +) + +set FINALRESPONSE= +set /p FINALRESPONSE="!FINALPROMPT! " + +if NOT ["!FINALPROMPT!"] == ["Press Enter key to exit."] ( + if /I ["!FINALRESPONSE:~0,1!"] == ["y"] ( + if ["!USERDIRFILLED!"] == ["1"] ( + "!SystemRoot!\explorer.exe" "!USERDIR!" + ) + if ["!INSTALLDIRFILLED!"] == ["1"] ( + "!SystemRoot!\explorer.exe" "!INSTALLDIR!" + ) + ) else ( + if ["!FINALRESPONSE!"] == [""] ( + if ["!USERDIRFILLED!"] == ["1"] ( + "!SystemRoot!\explorer.exe" "!USERDIR!" + ) + if ["!INSTALLDIRFILLED!"] == ["1"] ( + "!SystemRoot!\explorer.exe" "!INSTALLDIR!" + ) + ) + ) +) + +: DeferredDelete + +:: Now let's delete our installation folder! +cd \ +start "" /b "cmd" /s /c " del /q /f "%INSTALLDIR%\uninstall.bat"&timeout /t 2 > NUL&rmdir "%INSTALLDIR%"&exit /b "