diff -urN origSrc/am_map.c src/am_map.c --- origSrc/am_map.c 2019-08-31 15:33:16.014386073 -0300 +++ src/am_map.c 2019-08-31 15:33:16.074386073 -0300 @@ -694,7 +694,7 @@ if (!automapactive) { - if (ev->type == ev_keydown && ev->data1 == AM_STARTKEY) + if (ev->type == ev_keydown && (ev->data1 == AM_STARTKEY || ev->data1 == gamecontrol[gc_automap][0] || ev->data1 == gamecontrol[gc_automap][1])) { //faB: prevent alt-tab in win32 version to activate automap just before minimizing the app // doesn't do any harm to the DOS version @@ -771,6 +771,10 @@ rc = false; break; } + + if(ev->data1 == gamecontrol[gc_automap][0] || ev->data1 == gamecontrol[gc_automap][1]){ + AM_Stop (); + } } else if (ev->type == ev_keyup) diff -urN origSrc/b_game.c src/b_game.c --- origSrc/b_game.c 2019-08-31 15:33:16.014386073 -0300 +++ src/b_game.c 2019-08-31 15:33:16.082386073 -0300 @@ -31,6 +31,8 @@ // //----------------------------------------------------------------------------- +#include + // Bot include #include "b_bot.h" #include "b_game.h" @@ -123,13 +125,14 @@ void B_Init_Bots() { boolean duplicateBot; - int botNum, i, j; + int botNum, botColor, i, j; for (i=0; i< MAXPLAYERS; i++) { do { - botNum = B_Random()%MAXPLAYERS; + botNum = i%MAXPLAYERS; + botColor = i%NUMSKINCOLORS; botinfo[i].name = botnames[botNum]; duplicateBot = false; j = 0; @@ -141,8 +144,8 @@ j++; } } while (duplicateBot); - - botinfo[i].colour = B_Random() % NUMSKINCOLORS; + + botinfo[i].colour = botcolors[botColor]; } botNodeArray = NULL; } @@ -154,7 +157,7 @@ void Command_AddBot(void) { byte buf = 0; - + if( !server ) { CONS_Printf("Only the server can add a bot\n"); diff -urN origSrc/d_clisrv.c src/d_clisrv.c --- origSrc/d_clisrv.c 2019-08-31 15:33:16.014386073 -0300 +++ src/d_clisrv.c 2019-08-31 15:33:16.082386073 -0300 @@ -160,6 +160,7 @@ #include "t_script.h" #include "b_game.h" //added by AC for acbot +#include "r_things.h" //for making bots use skins // @@ -273,6 +274,9 @@ // of 512 octet is like 0.1) uint16_t software_MAXPACKETLENGTH; +int totalBots = 0; +boolean addedBots[MAXPLAYERS] = {false}; + // By Client, Server int ExpandTics (int low) { @@ -1139,6 +1143,7 @@ } break; case 's': + case KEY_ENTER: if( server ) { // Start game, stop waiting for player nodes. @@ -1899,6 +1904,11 @@ servernode=0; // server to self doomcom->numplayers=0; + + totalBots = 0; + for(i=0; icurpos); // unsigned + int botNum, botColor, botSkin; //int node = 0; //int i = 0; newplayernum&=0x7F; // remove flag bit, and any sign extension playeringame[newplayernum]=true; - strcpy(player_names[newplayernum], botinfo[newplayernum].name); - players[newplayernum].skincolor = botinfo[newplayernum].colour; + + if(cv_randomizebots.value == 2 || cv_randomizebots.value == 3){ + // Adding bots randomly, by choosing a random color and name + // for each bot being added. + srand(time(0)); + + int i; + for(i=0; idoomcom->numplayers ) @@ -2045,6 +2085,8 @@ multiplayer=1; GenPrintf(EMSG_hud, "Bot %s has entered the game\n", player_names[newplayernum]); + + totalBots++; } // By Server. diff -urN origSrc/d_main.c src/d_main.c --- origSrc/d_main.c 2019-08-31 15:33:16.042386073 -0300 +++ src/d_main.c 2019-08-31 15:33:16.082386073 -0300 @@ -861,9 +861,19 @@ if (demorecording) G_BeginRecording(); - if( access( "autoexec.cfg", R_OK) == 0 ) - { - // user settings + // reading autoexec file + char pathAutoexecHome[_MAX_PATH + 16]; + cat_filename(pathAutoexecHome, legacyhome, "autoexec.cfg"); + if( access( pathAutoexecHome, R_OK) == 0 ){ + // try reading firstly from home folder + char autoexecHomeCommand[_MAX_PATH + 16]; + strcpy(autoexecHomeCommand, "exec "); + strcat(autoexecHomeCommand, legacyhome); + strcat(autoexecHomeCommand, "autoexec.cfg\n"); + + COM_BufAddText(autoexecHomeCommand); + } else if( access( "autoexec.cfg", R_OK) == 0 ) { + // read file from same path as the executable COM_BufAddText("exec autoexec.cfg\n"); } diff -urN origSrc/d_netcmd.c src/d_netcmd.c --- origSrc/d_netcmd.c 2019-08-31 15:33:16.042386073 -0300 +++ src/d_netcmd.c 2019-08-31 15:33:16.082386073 -0300 @@ -210,7 +210,7 @@ consvar_t cv_originalweaponswitch = { "originalweaponswitch", "0", CV_SAVE | CV_CALL | CV_NOINIT, CV_OnOff, Send_WeaponPref }; // secondary player for splitscreen mode -consvar_t cv_playername2 = { "name2", "big b", CV_SAVE | CV_CALL | CV_NOINIT, NULL, Send_NameColor2 }; +consvar_t cv_playername2 = { "name2", "p2", CV_SAVE | CV_CALL | CV_NOINIT, NULL, Send_NameColor2 }; consvar_t cv_playercolor2 = { "color2", "1", CV_SAVE | CV_CALL | CV_NOINIT, Color_cons_t, Send_NameColor2 }; consvar_t cv_skin2 = { "skin2", DEFAULTSKIN, CV_SAVE | CV_CALL | CV_NOINIT, NULL /*skin_cons_t */ , Send_NameColor2 }; @@ -319,9 +319,7 @@ // register main variables // //register these so it is saved to config - cv_playername.defaultvalue = I_GetUserName(); - if (cv_playername.defaultvalue == NULL) - cv_playername.defaultvalue = "gi john"; + cv_playername.defaultvalue = "p1"; CV_RegisterVar(&cv_playername); CV_RegisterVar(&cv_playercolor); CV_RegisterVar(&cv_weaponpref); diff -urN origSrc/g_game.c src/g_game.c --- origSrc/g_game.c 2019-08-31 15:33:16.046386073 -0300 +++ src/g_game.c 2019-08-31 15:33:16.102386074 -0300 @@ -1052,14 +1052,27 @@ if (j.playnum != which_player) continue; - - int value = (int)(j.scale * I_JoystickGetAxis(j.joynum, j.axisnum)); + + int realvalue = I_JoystickGetAxis(j.joynum, j.axisnum); + if(realvalue >= -4000 && realvalue <= 4000) realvalue = 0; // Deadzone + int value = (int)(j.scale * realvalue); + switch (j.action) { - case ja_pitch : pitch = value << 16; break; - case ja_move : forward += value; break; - case ja_turn : cmd->angleturn += value; break; - case ja_strafe : side += value; break; + case ja_pitch: + pitch = value << 16; + break; + case ja_move: + if(speed == 1) value *= 2; // Double value if player is running + forward += value; + break; + case ja_turn: + cmd->angleturn += value; + break; + case ja_strafe: + if(speed == 1) value *= 2; // Double value if player is running + side += value; + break; default: break; } } @@ -1338,7 +1351,7 @@ switch (ev->type) { case ev_keydown: - if (ev->data1 == KEY_PAUSE) + if (ev->data1 == KEY_PAUSE || ev->data1 == gamecontrol[gc_pause][0] || ev->data1 == gamecontrol[gc_pause][1] ) { COM_BufAddText("pause\n"); goto handled; @@ -2192,7 +2205,7 @@ { case 8: //BP add comment : no intermission screen - if( cv_deathmatch.EV ) + if( cv_deathmatch.EV || cv_randomizemaps.value ) wminfo.lev_next = 0; else { @@ -2214,7 +2227,7 @@ { if( !modifiedgame && gamemap == 5 ) // original chexquest ends at E1M5 { - if( cv_deathmatch.EV ) + if( cv_deathmatch.EV || cv_randomizemaps.value ) wminfo.lev_next=0; else { @@ -2336,7 +2349,7 @@ if ( gamemode == doom2_commercial) { - if( cv_deathmatch.EV == 0 ) + if( cv_deathmatch.EV == 0 && !cv_randomizemaps.value ) { switch (gamemap) { diff -urN origSrc/g_input.c src/g_input.c --- origSrc/g_input.c 2019-08-31 15:33:16.042386073 -0300 +++ src/g_input.c 2019-08-31 15:33:16.086386074 -0300 @@ -392,6 +392,38 @@ {KEY_JOY3BUT13, "Joy 3 b 13"}, {KEY_JOY3BUT14, "Joy 3 b 14"}, {KEY_JOY3BUT15, "Joy 3 b 15"}, + + {KEY_JOY0HATUP, "Joy 0 h u"}, + {KEY_JOY0HATRIGHT, "Joy 0 h r"}, + {KEY_JOY0HATDOWN, "Joy 0 h d"}, + {KEY_JOY0HATLEFT, "Joy 0 h l"}, + + {KEY_JOY1HATUP, "Joy 1 h u"}, + {KEY_JOY1HATRIGHT, "Joy 1 h r"}, + {KEY_JOY1HATDOWN, "Joy 1 h d"}, + {KEY_JOY1HATLEFT, "Joy 1 h l"}, + + {KEY_JOY2HATUP, "Joy 2 h u"}, + {KEY_JOY2HATRIGHT, "Joy 2 h r"}, + {KEY_JOY2HATDOWN, "Joy 2 h d"}, + {KEY_JOY2HATLEFT, "Joy 2 h l"}, + + {KEY_JOY3HATUP, "Joy 3 h u"}, + {KEY_JOY3HATRIGHT, "Joy 3 h r"}, + {KEY_JOY3HATDOWN, "Joy 3 h d"}, + {KEY_JOY3HATLEFT, "Joy 3 h l"}, + + {KEY_JOY0LEFTTRIGGER, "Joy 0 l t"}, + {KEY_JOY0RIGHTTRIGGER, "Joy 0 r t"}, + + {KEY_JOY1LEFTTRIGGER, "Joy 1 l t"}, + {KEY_JOY1RIGHTTRIGGER, "Joy 1 r t"}, + + {KEY_JOY2LEFTTRIGGER, "Joy 2 l t"}, + {KEY_JOY2RIGHTTRIGGER, "Joy 2 r t"}, + + {KEY_JOY3LEFTTRIGGER, "Joy 3 l t"}, + {KEY_JOY3RIGHTTRIGGER, "Joy 3 r t"}, }; char *gamecontrolname[num_gamecontrols] = @@ -422,7 +454,10 @@ "talkkey", "scores", "jump", + "automap", "console", + "mainmenu", + "pause", "nextweapon", "prevweapon", "bestweapon", @@ -551,7 +586,9 @@ gamecontrol[gc_talkkey ][0]='t'; gamecontrol[gc_scores ][0]='f'; gamecontrol[gc_jump ][0]='/'; + gamecontrol[gc_automap ][0]=KEY_JOY0BUT6; // Back button on Xbox360 controllers gamecontrol[gc_console ][0]=KEY_CONSOLE; + gamecontrol[gc_mainmenu ][0]=KEY_JOY0BUT7; // Start button on Xbox360 controllers //gamecontrol[gc_nextweapon ][1]=KEY_JOY0BUT4; //gamecontrol[gc_prevweapon ][1]=KEY_JOY0BUT5; gamecontrol[gc_screenshot ][0]=KEY_SYSREQ; diff -urN origSrc/g_input.h src/g_input.h --- origSrc/g_input.h 2019-08-31 15:33:16.006386073 -0300 +++ src/g_input.h 2019-08-31 15:33:16.054386073 -0300 @@ -89,7 +89,10 @@ gc_talkkey, gc_scores, gc_jump, + gc_automap, gc_console, + gc_mainmenu, + gc_pause, gc_nextweapon, gc_prevweapon, gc_bestweapon, diff -urN origSrc/keys.h src/keys.h --- origSrc/keys.h 2019-08-31 15:33:16.002386073 -0300 +++ src/keys.h 2019-08-31 15:33:16.050386073 -0300 @@ -114,6 +114,7 @@ MAXJOYSTICKS = 4, // "Only" 4 joysticks per machine. JOYBUTTONS = 16, // Max number of buttons for a joystick. JOYHATBUTTONS = 4, // Four hat directions. + XBOXTRIGGERS = 2, // Two triggers on Xbox-like controllers. KEY_MOUSE1 = KEY_NUMKB, // mouse buttons, including the wheel KEY_MOUSEWHEELUP = KEY_MOUSE1 + 3, // usually @@ -193,6 +194,39 @@ KEY_JOY3BUT14, KEY_JOY3BUT15, KEY_JOYLAST = KEY_JOY3BUT15, + + KEY_JOY0HATUP, + KEY_JOY0HATRIGHT, + KEY_JOY0HATDOWN, + KEY_JOY0HATLEFT, + + KEY_JOY1HATUP, + KEY_JOY1HATRIGHT, + KEY_JOY1HATDOWN, + KEY_JOY1HATLEFT, + + KEY_JOY2HATUP, + KEY_JOY2HATRIGHT, + KEY_JOY2HATDOWN, + KEY_JOY2HATLEFT, + + KEY_JOY3HATUP, + KEY_JOY3HATRIGHT, + KEY_JOY3HATDOWN, + KEY_JOY3HATLEFT, + + KEY_JOY0LEFTTRIGGER, + KEY_JOY0RIGHTTRIGGER, + + KEY_JOY1LEFTTRIGGER, + KEY_JOY1RIGHTTRIGGER, + + KEY_JOY2LEFTTRIGGER, + KEY_JOY2RIGHTTRIGGER, + + KEY_JOY3LEFTTRIGGER, + KEY_JOY3RIGHTTRIGGER, + #ifdef DBL_JOY_BUTTONS // duplicate all joy, all buttons, KEY_JOY0BUT0 .. KEY_JOY3BUT15 diff -urN origSrc/m_menu.c src/m_menu.c --- origSrc/m_menu.c 2019-08-31 15:33:16.046386073 -0300 +++ src/m_menu.c 2019-08-31 15:33:16.102386074 -0300 @@ -985,6 +985,11 @@ ,{5,"Nightmare!" } ,{0,NULL}}; +CV_PossibleValue_t randomizebots_cons_t[] = {{1,"Off"} + ,{2,"On game creation"} + ,{3,"On map change"} + ,{0,NULL}}; + CV_PossibleValue_t map_cons_t[] = {{ 1,"map01"} ,{ 2,"map02"} ,{ 3,"map03"} ,{ 4,"map04"} ,{ 5,"map05"} ,{ 6,"map06"} ,{ 7,"map07"} ,{ 8,"map08"} ,{ 9,"map09"} @@ -1014,14 +1019,18 @@ ,{47,"e5m7"} ,{48,"e5m8"} ,{49,"e5m9"} ,{0,NULL}}; -consvar_t cv_skill = {"skill" ,"4",CV_HIDEN,skill_cons_t}; +consvar_t cv_skill = {"skill" ,"2",CV_HIDEN,skill_cons_t}; consvar_t cv_monsters = {"monsters" ,"0",CV_HIDEN,CV_YesNo}; consvar_t cv_nextmap = {"nextmap" ,"1",CV_HIDEN,map_cons_t}; consvar_t cv_nextepmap = {"nextepmap" ,"11",CV_HIDEN,exmy_cons_t}; extern CV_PossibleValue_t deathmatch_cons_t[]; consvar_t cv_newdeathmatch = {"newdeathmatch" ,"3",CV_HIDEN,deathmatch_cons_t}; +CV_PossibleValue_t bots_cons_t[]= {{0,"MIN"}, {32,"MAX"}, {0,NULL}}; +consvar_t cv_bots = {"bots" ,"0",CV_HIDEN,bots_cons_t}; +consvar_t cv_randomizebots = {"randomizebots" ,"1",CV_HIDEN,randomizebots_cons_t}; +consvar_t cv_randomizemaps = {"randomizemaps" ,"0",CV_HIDEN,CV_YesNo}; CV_PossibleValue_t wait_players_cons_t[]= {{0,"MIN"}, {32,"MAX"}, {0,NULL}}; -consvar_t cv_wait_players = {"wait_players" ,"2",CV_HIDEN,wait_players_cons_t}; +consvar_t cv_wait_players = {"wait_players" ,"1",CV_HIDEN,wait_players_cons_t}; CV_PossibleValue_t wait_timeout_cons_t[]= {{0,"MIN"}, {5,"INC"}, {244,"MAX"}, {0,NULL}}; consvar_t cv_wait_timeout = {"wait_timeout" ,"0",CV_HIDEN,wait_timeout_cons_t}; @@ -1033,7 +1042,7 @@ netgame = true; multiplayer = true; - if( choice == 9 ) + if( choice == 12 ) { // Dedicated server menu choice. dedicated = true; @@ -1043,7 +1052,7 @@ } D_WaitPlayer_Setup(); - COM_BufAddText(va("stopdemo;splitscreen %d;deathmatch %d;map \"%s\" -monsters %d skill %d\n", + COM_BufAddText(va("stopdemo;splitscreen %d;deathmatch %d;map \"%s\" -monsters %d -skill %d\n", StartSplitScreenGame, cv_newdeathmatch.value, (gamemode==doom2_commercial)? cv_nextmap.string : cv_nextepmap.string, cv_monsters.value, cv_skill.value)); @@ -1056,23 +1065,34 @@ { COM_BufAddText ( va("%s \"%s\"\n", cv_skin2.name, cv_skin2.string)); } + + // Add bots + if(cv_bots.value > 0){ + int i; + for(i=0; iangle) +// Bots +extern consvar_t cv_bots; +extern consvar_t cv_randomizebots; + // // P_ENEMY // diff -urN origSrc/sdl/i_sound.c src/sdl/i_sound.c --- origSrc/sdl/i_sound.c 2019-08-31 15:33:16.014386073 -0300 +++ src/sdl/i_sound.c 2019-08-31 15:33:16.078386073 -0300 @@ -109,20 +109,24 @@ -#define MIDBUFFERSIZE 128*1024 +// MIDI music buffer +#define MIDBUFFERSIZE (128*1024) #define MUSIC_FADE_TIME 400 // ms // The number of internal mixing channels, // mixing buffer, and the samplerate of the raw data. -#define DOOM_SAMPLERATE 11025 // Hz, Doom sound effects +// Doom sound effects +#define DOOM_SAMPLERATE 11025 // Hz // Needed for calling the actual sound output. -#define NUM_CHANNELS 16 // max. number of simultaneous sounds +// max. number of simultaneous sounds +#define NUM_CHANNELS 16 #define CHANNEL_NUM_MASK (NUM_CHANNELS-1) #define SAMPLERATE 22050 // Hz -#define SAMPLECOUNT 512 // requested audio buffer size (512 means about 46 ms at 11 kHz) +// requested audio buffer size (512 means about 46 ms at 11 kHz) +#define SAMPLECOUNT 512 typedef struct { @@ -133,9 +137,12 @@ unsigned int step; // The channel step amount... unsigned int step_remainder; // ... and a 0.16 bit remainder of last step. - // When the channel started playing, and too many sounds + // When the channel starts playing, and there are too many sounds, // determine which to kill by oldest and priority. unsigned int age_priority; + + // The data sample rate + unsigned int samplerate; // The sound in channel handles, // determined on registration, @@ -204,7 +211,9 @@ // This table provides step widths for pitch parameters. for (i = 0; i < 256; i++) + { steptable[i] = (Sint32)(base_step * pow(2.0, ((i-128) / 64.0)) * 65536.0); + } // Generates volume lookup tables // which also turn the u8 samples into s16 samples. @@ -319,15 +328,19 @@ // e.g. for avoiding duplicates of chainsaw. chanp->sfxid = sfxid; + byte * header = S_sfx[sfxid].data; // Okay, in the less recent channel, // we will handle the new SFX. // Set pointer to raw data, skipping header. chanp->data_ptr = (unsigned char *) S_sfx[sfxid].data + 8; // Set pointer to end of raw data. chanp->data_end = chanp->data_ptr + S_sfx[sfxid].length; + + // Get samplerate from the sfx header, 16 bit, big endian + chanp->samplerate = (header[3] << 8) + header[2]; // Set stepping - chanp->step = steptable[pitch]; + chanp->step = steptable[pitch] * chanp->samplerate / DOOM_SAMPLERATE; // 16.16 fixed point chanp->step_remainder = 0; // balanced between age and priority @@ -459,7 +472,8 @@ chanp->rightvol_lookup = &vol_lookup[rightvol * 256]; // Set stepping - chanp->step = steptable[pitch]; +// chanp->step = steptable[pitch]; + chanp->step = steptable[pitch] * chanp->samplerate / DOOM_SAMPLERATE; } } @@ -838,7 +852,8 @@ audspec.freq = SAMPLERATE; audspec.format = AUDIO_S16SYS; audspec.channels = 2; - audspec.samples = SAMPLECOUNT; + // From eternity, adjust for new samplerate + audspec.samples = SAMPLECOUNT * SAMPLERATE / DOOM_SAMPLERATE; audspec.callback = I_UpdateSound_sdl; I_SetChannels(); diff -urN origSrc/sdl/i_system.c src/sdl/i_system.c --- origSrc/sdl/i_system.c 2019-08-31 15:33:16.014386073 -0300 +++ src/sdl/i_system.c 2019-08-31 15:33:16.078386073 -0300 @@ -115,6 +115,8 @@ int mouse2_started = 0; #endif +boolean checkJoystickXbox[4] = {false, false, false, false}; + // //I_OutputMsg // @@ -179,6 +181,38 @@ return KEY_JOY0BUT0 + JOYBUTTONS*which + button; } +static int TranslateJoyhat(Uint8 which, Uint8 value) +{ + if (which >= MAXJOYSTICKS) + which = MAXJOYSTICKS-1; + + if(value == SDL_HAT_UP){ + return KEY_JOY0HATUP + JOYHATBUTTONS*which; + } else if(value == SDL_HAT_RIGHT){ + return KEY_JOY0HATRIGHT + JOYHATBUTTONS*which; + } else if(value == SDL_HAT_DOWN){ + return KEY_JOY0HATDOWN + JOYHATBUTTONS*which; + } else if(value == SDL_HAT_LEFT){ + return KEY_JOY0HATLEFT + JOYHATBUTTONS*which; + } else { + return 0; + } +} + +static int TranslateXboxcontrollerTrigger(Uint8 which, Uint8 axis) +{ + if (which >= MAXJOYSTICKS) + which = MAXJOYSTICKS-1; + + if(axis == 2){ + return KEY_JOY0LEFTTRIGGER + XBOXTRIGGERS*which; + } else if(axis == 5){ + return KEY_JOY0RIGHTTRIGGER + XBOXTRIGGERS*which; + } else { + return 0; + } +} + int I_JoystickNumAxes(int joynum) { if (joynum < num_joysticks) @@ -212,6 +246,17 @@ boolean shiftdown = false; boolean altdown = false; +Uint8 jhatDirections[8] = { + SDL_HAT_UP, + SDL_HAT_RIGHTUP, + SDL_HAT_RIGHT, + SDL_HAT_RIGHTDOWN, + SDL_HAT_DOWN, + SDL_HAT_LEFTDOWN, + SDL_HAT_LEFT, + SDL_HAT_LEFTUP +}; +Uint8 previousJhatValues[2] = {0, 0}; void I_GetEvent(void) { @@ -380,7 +425,105 @@ inputEvent.jbutton.button); D_PostEvent(&event); break; - + + case SDL_JOYHATMOTION: // Adding event to allow joy hat mapping + if(inputEvent.jhat.value != SDL_HAT_CENTERED){ + // Joy hat pressed + + // Releasing previous value + int i; + for(i=0; i<2; i++){ + if(previousJhatValues[i] != 0){ + event.type = ev_keyup; + event.data1 = TranslateJoyhat(inputEvent.jhat.which, previousJhatValues[i]); + D_PostEvent(&event); + + previousJhatValues[i] = 0; + } + } + + // Dealing with diagonal directions + if(inputEvent.jhat.value == SDL_HAT_RIGHTUP){ + event.type = ev_keydown; + event.data1 = TranslateJoyhat(inputEvent.jhat.which, SDL_HAT_RIGHT); + D_PostEvent(&event); + previousJhatValues[0] = SDL_HAT_RIGHT; + + event.type = ev_keydown; + event.data1 = TranslateJoyhat(inputEvent.jhat.which, SDL_HAT_UP); + D_PostEvent(&event); + previousJhatValues[1] = SDL_HAT_UP; + } else if(inputEvent.jhat.value == SDL_HAT_RIGHTDOWN){ + event.type = ev_keydown; + event.data1 = TranslateJoyhat(inputEvent.jhat.which, SDL_HAT_RIGHT); + D_PostEvent(&event); + previousJhatValues[0] = SDL_HAT_RIGHT; + + event.type = ev_keydown; + event.data1 = TranslateJoyhat(inputEvent.jhat.which, SDL_HAT_DOWN); + D_PostEvent(&event); + previousJhatValues[1] = SDL_HAT_DOWN; + } else if(inputEvent.jhat.value == SDL_HAT_LEFTDOWN){ + event.type = ev_keydown; + event.data1 = TranslateJoyhat(inputEvent.jhat.which, SDL_HAT_LEFT); + D_PostEvent(&event); + previousJhatValues[0] = SDL_HAT_LEFT; + + event.type = ev_keydown; + event.data1 = TranslateJoyhat(inputEvent.jhat.which, SDL_HAT_DOWN); + D_PostEvent(&event); + previousJhatValues[1] = SDL_HAT_DOWN; + } else if(inputEvent.jhat.value == SDL_HAT_LEFTUP){ + event.type = ev_keydown; + event.data1 = TranslateJoyhat(inputEvent.jhat.which, SDL_HAT_LEFT); + D_PostEvent(&event); + previousJhatValues[0] = SDL_HAT_LEFT; + + event.type = ev_keydown; + event.data1 = TranslateJoyhat(inputEvent.jhat.which, SDL_HAT_UP); + D_PostEvent(&event); + previousJhatValues[1] = SDL_HAT_UP; + } else { + event.type = ev_keydown; + event.data1 = TranslateJoyhat(inputEvent.jhat.which, inputEvent.jhat.value); + D_PostEvent(&event); + + previousJhatValues[0] = inputEvent.jhat.value; + } + } else { + // Joy hat released + int i; + for(i=0; i<8; i++){ + event.type = ev_keyup; + event.data1 = TranslateJoyhat(inputEvent.jhat.which, jhatDirections[i]); + D_PostEvent(&event); + } + + previousJhatValues[0] = 0; + previousJhatValues[1] = 0; + } + + break; + + case SDL_JOYAXISMOTION: // Adding event for mapping triggers for Xbox-like controllers + if(checkJoystickXbox[inputEvent.jaxis.which]){ + if(inputEvent.jaxis.axis == 2 || inputEvent.jaxis.axis == 5){ + if(inputEvent.jaxis.value > 0){ + // Trigger pressed + event.type = ev_keydown; + event.data1 = TranslateXboxcontrollerTrigger(inputEvent.jaxis.which, inputEvent.jaxis.axis); + D_PostEvent(&event); + } else { + // Trigger released + event.type = ev_keyup; + event.data1 = TranslateXboxcontrollerTrigger(inputEvent.jaxis.which, inputEvent.jaxis.axis); + D_PostEvent(&event); + } + } + } + + break; + case SDL_QUIT: I_Quit(); //M_QuitResponse('y'); @@ -456,7 +599,6 @@ return; } - /// Initialize joysticks and print information. static void I_JoystickInit(void) { @@ -483,6 +625,13 @@ CONS_Printf(" %d hats.\n", SDL_JoystickNumHats(joy)); CONS_Printf(" %d trackballs.\n", SDL_JoystickNumBalls(joy)); } + + if( + strcmp(SDL_JoystickName(i), "Xbox 360 Wireless Receiver (XBOX)") == 0 || + strcmp(SDL_JoystickName(i), "Microsoft X-Box 360 pad") == 0 + ){ + checkJoystickXbox[i] = true; + } } } diff -urN origSrc/wi_stuff.c src/wi_stuff.c --- origSrc/wi_stuff.c 2019-08-31 15:33:16.006386073 -0300 +++ src/wi_stuff.c 2019-08-31 15:33:16.054386073 -0300 @@ -59,6 +59,7 @@ // //----------------------------------------------------------------------------- +#include #include "doomincl.h" #include "wi_stuff.h" @@ -78,6 +79,8 @@ // pars_valid_bex #include "m_menu.h" // M_DrawTextBox +#include "w_wad.h" + // lastReplacedMap // // Data needed to add patches to full screen intermission pics. @@ -463,6 +466,11 @@ // # of doom2_commercial levels static int num_lnames = 0; +int currentRandomLevel = 0; +boolean randomChosenLevels[32] = {false}; +boolean firstCallWIDrawLF = false; +boolean firstCallWIDrawShowNextLoc = false; + // [WDJ] All patch endian conversion is done in W_CachePatchNum @@ -532,6 +540,16 @@ V_DrawScaledPatch ((BASEVIDWIDTH - (V_patch(finished)->width))/2, y, finished); } + + // Storing random chosen level, if random map is activated + firstCallWIDrawShowNextLoc = false; + if(!firstCallWIDrawLF){ + firstCallWIDrawLF = true; + + if(multiplayer && cv_randomizemaps.value){ + randomChosenLevels[currentRandomLevel] = true; + } + } } @@ -959,6 +977,52 @@ int i; int last; + + // Choosing random map, but avoid choosing a repeated map + // until all maps are cycled. + firstCallWIDrawLF = false; + if(!firstCallWIDrawShowNextLoc){ + firstCallWIDrawShowNextLoc = true; + + if(multiplayer && cv_randomizemaps.value){ + srand(time(0)); + + int j; + boolean hasAvailableRandomMap = false; + for(j=0; jlev_next = randomLevel; + currentRandomLevel = randomLevel; + hasAvailableRandomMap = true; + break; + } + } + + // All maps already cycled, so reset the list and go back + // to the first map + if(!hasAvailableRandomMap){ + for(j=0; jlev_next = 0; + currentRandomLevel = 0; + } + } + + // Applying randomize bots routine on each level change, if applicable + if(multiplayer && cv_randomizebots.value == 3){ + srand(time(0)); + + int j; + for(j=0; jepsd<=2 && !*info_interpic) + && wbs->epsd<=2 && !*info_interpic && !(multiplayer && cv_randomizemaps.value)) { // You are here (YAH). last = (wbs->lev_prev == 8) ? wbs->lev_next - 1 : wbs->lev_prev; diff -urN origSrc/wi_stuff.h src/wi_stuff.h --- origSrc/wi_stuff.h 2019-08-31 15:33:16.006386073 -0300 +++ src/wi_stuff.h 2019-08-31 15:33:16.054386073 -0300 @@ -37,6 +37,8 @@ #include "doomtype.h" #include "d_player.h" // wb_start_t +#include "command.h" + // consvar_t //added:05-02-98: typedef struct { @@ -66,5 +68,7 @@ // For startup wait, and deathmatch wait. void WI_Draw_wait( int net_nodes, int net_players, int wait_players, int wait_tics ); +extern consvar_t cv_randomizebots; +extern consvar_t cv_randomizemaps; #endif diff -urN origSrc/w_wad.c src/w_wad.c --- origSrc/w_wad.c 2019-08-31 15:33:16.046386073 -0300 +++ src/w_wad.c 2019-08-31 15:33:16.102386074 -0300 @@ -112,6 +112,7 @@ #include "doomincl.h" #include "w_wad.h" #include "z_zone.h" +#include "g_game.h" #include "i_video.h" // rendermode @@ -135,6 +136,7 @@ //=========================================================================== int numwadfiles; // number of active wadfiles wadfile_t* wadfiles[MAX_WADFILES]; // 0 to numwadfiles-1 are valid +int lastReplacedMap; // Return the wadfile info for the lumpnum @@ -410,6 +412,81 @@ } wadfile->hwrcache = grPatch; #endif + + // Obtaining last replaced map number, to use as basis for randomize + // maps routine + if (filenum == 0){ + // Obtaining default value for last replaced map, according to + // IWAD's game mode. + if (gamemode == doom2_commercial){ + lastReplacedMap = 32; + } else { + lastReplacedMap = 9; + } + } else { + // Obtaining last replaced map number on PWADs. + // If no map is found, then assume the default value, obtained above. + int numMapsPwad = 0; + int maps[32] = {0}; + + // Obtaining all maps from this PWAD, if there's any + lumpinfo = wadfile->lumpinfo; + for (i=0; inumlumps; i++,lumpinfo++){ + char* name = lumpinfo->name; + int num = 0; // invalid + if (gamemode == doom2_commercial) { // Doom2 + if (name[0]=='M' && name[1]=='A' && name[2]=='P'){ + num = (name[3]-'0')*10 + (name[4]-'0'); + + maps[numMapsPwad] = num; + numMapsPwad++; + } + } else { + if (name[0]=='E' && + ((unsigned)name[1]-'0')<='9' && // a digit + name[2]=='M' && + ((unsigned)name[3]-'0')<='9' && + name[4]==0) + { + num = name[3]-'0'; + + maps[numMapsPwad] = num; + numMapsPwad++; + } + } + } + + // Ignore maps 31 and 32 on Doom2, if PWAD has less than 30 + // maps and uses secret levels. + if(gamemode == doom2_commercial && numMapsPwad <= 30){ + for(i=1; i<32; i++){ + if(maps[i] == 31){ + maps[i] = 0; + } else if(maps[i] == 32){ + maps[i] = 0; + } + } + } + + // If there's at least one map in the PWAD, proceed with the routine + // to obtain the number of the last replaced map, in order to use + // this in "Random Map" multiplayer option. + if(numMapsPwad > 0){ + int totalMaps; + if(gamemode==doom2_commercial){ + totalMaps = 32; + } else { + totalMaps = 9; + } + + for(i=1; i