diff --git a/src/headers/gameStateManager.h b/src/headers/gameStateManager.h index 6bc7369..7171816 100644 --- a/src/headers/gameStateManager.h +++ b/src/headers/gameStateManager.h @@ -50,6 +50,9 @@ public: int currentStage; int numCoins; int currentGameType; // 0 = nonstop, 1 = free, 2 = mission + bool allowLogins; + bool leftPlayerPresent; // used when starting a game + bool rightPlayerPresent; // used when starting a game // operator data bool isInitialized; @@ -269,6 +272,8 @@ public: { //isVersus = true; // for debugging - otherwise this cannot happen } + allowLogins = true; + leftPlayerPresent = rightPlayerPresent = false; // operator settings isInitialized = false; @@ -374,21 +379,29 @@ public: // read a short version number int vnum = checkFileVersion(fp, "DMXM"); - if ( vnum != CURRENT_VERSION_NUMBER ) + if ( vnum > CURRENT_SETTING_VERSION_NUMBER || vnum <= 0 ) { - TRACE("Wrong msettings version number."); + globalError(CLEARED_MACHINE_SETTINGS, "Existing machine settings could not be read."); return; // later when multiple versions exist, ideas for converting them } // okay, read everything - fread(&numSongsPerSet, sizeof(long), 1, fp); - fread(&numCoinsPerCredit, sizeof(long), 1, fp); - fread(&n, sizeof(long), 1, fp); - isFreeplay = n != 0; - fread(&n, sizeof(long), 1, fp); - isVersusPremium = n != 0; - fread(&n, sizeof(long), 1, fp); - isDoublePremium = n != 0; + if ( vnum >= 1 ) + { + fread(&numSongsPerSet, sizeof(long), 1, fp); + fread(&numCoinsPerCredit, sizeof(long), 1, fp); + fread(&n, sizeof(long), 1, fp); + isFreeplay = n != 0; + fread(&n, sizeof(long), 1, fp); + isVersusPremium = n != 0; + fread(&n, sizeof(long), 1, fp); + isDoublePremium = n != 0; + } + if ( vnum >= 2 ) + { + fread(&n, sizeof(long), 1, fp); + allowLogins = n != 0; + } isInitialized = true; fclose(fp); @@ -407,7 +420,7 @@ public: // write the version fprintf(fp, "DMXM"); - int vnum = CURRENT_VERSION_NUMBER; + int vnum = CURRENT_SETTING_VERSION_NUMBER; fwrite(&vnum, sizeof(long), 1, fp); fwrite(&numSongsPerSet, sizeof(long), 1, fp); fwrite(&numCoinsPerCredit, sizeof(long), 1, fp); @@ -417,6 +430,8 @@ public: fwrite(&n, sizeof(long), 1, fp); n = isDoublePremium ? 1 : 0; fwrite(&n, sizeof(long), 1, fp); + n = allowLogins ? 1 : 0; + fwrite(&n, sizeof(long), 1, fp); safeCloseFile(fp, MSETTING_FILENAME); } diff --git a/src/source/attractMode.cpp b/src/source/attractMode.cpp index ee11586..00166af 100644 --- a/src/source/attractMode.cpp +++ b/src/source/attractMode.cpp @@ -173,6 +173,8 @@ void firstAttractLoop() attractSubState = submodeTimer = 0; advanceToNextMode(); gs.killSong(); // when time runs out on the main menu + + gs.leftPlayerPresent = gs.rightPlayerPresent = false; } void mainAttractLoop(UTIME dt) @@ -198,6 +200,14 @@ void mainAttractLoop(UTIME dt) { if ( im.getKeyState(MENU_START_1P) == JUST_DOWN || im.getKeyState(MENU_START_2P) == JUST_DOWN ) { + if ( im.getKeyState(MENU_START_1P) == JUST_DOWN ) + { + gs.leftPlayerPresent = true; // intentionally only set one of these here + } + else + { + gs.rightPlayerPresent = true; // intentionally only set one of these here + } gs.g_currentGameMode = CAUTIONMODE; gs.g_gameModeTransition = 1; em.playSample(SFX_CREDIT_BEGIN); diff --git a/src/source/main.cpp b/src/source/main.cpp index 2d06590..dd5a451 100644 --- a/src/source/main.cpp +++ b/src/source/main.cpp @@ -53,6 +53,7 @@ bool isTestingChart = false; int testChartSongID = 101; int testChartLevel = SINGLE_MILD; bool SHOW_LAMPS = true; +bool held_printscreen = false; BITMAP** m_banners; // used globally BITMAP* m_caution; @@ -507,6 +508,17 @@ int main() } #endif rm.flip(); + + // allow screenshots anywhere, even in release mode + if ( key[KEY_PRTSCR] && !held_printscreen ) + { + held_printscreen = true; + rm.screenshot(); + } + else + { + held_printscreen = false; + } } } @@ -995,21 +1007,24 @@ void mainOperatorLoop(UTIME dt) songs[i].numPlays = 0; } } - if ( testMenuSubIndex == 1 ) // reset last logins + if ( testMenuSubIndex == 1 ) // disallow name entry + { + } + if ( testMenuSubIndex == 2 ) // reset last logins { resetPrevNames(); } - if ( testMenuSubIndex == 2 ) // delete player + if ( testMenuSubIndex == 3 ) // delete player { } - if ( testMenuSubIndex == 3 ) // change player pin + if ( testMenuSubIndex == 4 ) // change player pin { } - if ( testMenuSubIndex == 4 ) // update software + if ( testMenuSubIndex == 5 ) // update software { getUpdateAndRestart(); } - if ( testMenuSubIndex == 5 ) + if ( testMenuSubIndex == 6 ) { testMenuMainIndex = 0; testMenuSubIndex = -1; @@ -1017,11 +1032,18 @@ void mainOperatorLoop(UTIME dt) } if ( im.getKeyState(MENU_RIGHT_1P) == JUST_DOWN || im.getKeyState(MENU_SERVICE) == JUST_DOWN ) { - testMenuSubIndex = (testMenuSubIndex + 1) % 6; + testMenuSubIndex = (testMenuSubIndex + 1) % 7; } if ( im.getKeyState(MENU_LEFT_1P) == JUST_DOWN ) { - testMenuSubIndex = (testMenuSubIndex - 1 + 6) % 6; + testMenuSubIndex = (testMenuSubIndex - 1 + 7) % 7; + } + if ( im.getKeyState(MENU_LEFT_2P) == JUST_DOWN || im.getKeyState(MENU_RIGHT_2P) == JUST_DOWN ) + { + if ( testMenuSubIndex == 0 ) + { + gs.allowLogins = !gs.allowLogins; + } } break; @@ -1106,6 +1128,21 @@ void mainCautionLoop(UTIME dt) gs.g_gameModeTransition = 1; gs.g_currentGameMode = PLAYERSELECT; } + + // allow a second player to add in? + bool enoughCreditsForVersus = gs.isVersusPremium || gs.isFreeplay || (gs.numCoins >= gs.numCoinsPerCredit*2); + bool leftPlayerAdding = !gs.leftPlayerPresent && im.getKeyState(MENU_START_1P) == JUST_DOWN; + bool rightPlayerAdding = !gs.rightPlayerPresent && im.getKeyState(MENU_START_2P) == JUST_DOWN; + if ( leftPlayerAdding && enoughCreditsForVersus ) + { + gs.leftPlayerPresent = true; + em.playSample(SFX_CREDIT_BEGIN); + } + if ( rightPlayerAdding && enoughCreditsForVersus ) + { + gs.rightPlayerPresent = true; + em.playSample(SFX_CREDIT_BEGIN); + } } void firstBootLoop() @@ -1117,7 +1154,7 @@ void firstBootLoop() void mainBootLoop(UTIME dt) { - static char results[6][5] = { ".", "..", "...", "....", "OK", "BAD" }; + static char results[7][5] = { ".", "..", "...", "....", "OK", "BAD", "SKIP" }; int dotdotdot = (bootStepTime / 333) % 3; bootStepTime += dt; @@ -1153,7 +1190,7 @@ void mainBootLoop(UTIME dt) } else if ( currentBootStep == 1 ) { - textprintf(rm.m_backbuf, font, 154, 140, GREEN, results[4]); + textprintf(rm.m_backbuf, font, 154, 140, extio.isReady() ? GREEN : WHITE, extio.isReady() ? results[4] : results[6]); textprintf(rm.m_backbuf, font, 154, 160, WHITE, results[dotdotdot]); if ( bootStepTime >= 3000 ) @@ -1164,7 +1201,7 @@ void mainBootLoop(UTIME dt) } else if ( currentBootStep == 2 ) { - textprintf(rm.m_backbuf, font, 154, 140, GREEN, results[4]); + textprintf(rm.m_backbuf, font, 154, 140, extio.isReady() ? GREEN : WHITE, extio.isReady() ? results[4] : results[6]); textprintf(rm.m_backbuf, font, 154, 160, GREEN, results[4]); textprintf(rm.m_backbuf, font, 154, 180, WHITE, results[dotdotdot]); @@ -1176,7 +1213,14 @@ void mainBootLoop(UTIME dt) } else { - textprintf(rm.m_backbuf, font, 154, 140, (bootStepTime/75) %2 == 0 && bootStepTime < 2500 ? WHITE : GREEN, results[4]); + if ( extio.isReady() ) + { + textprintf(rm.m_backbuf, font, 154, 140, (bootStepTime/75) %2 == 0 && bootStepTime < 2500 ? WHITE : GREEN, results[4]); + } + else + { + textprintf(rm.m_backbuf, font, 154, 140, WHITE, results[6]); + } textprintf(rm.m_backbuf, font, 154, 160, (bootStepTime/75) %2 == 0 && bootStepTime < 2500 ? WHITE : GREEN, results[4]); textprintf(rm.m_backbuf, font, 154, 180, (bootStepTime/75) %2 == 0 && bootStepTime < 2500 ? WHITE : GREEN, results[4]); @@ -1283,9 +1327,15 @@ int loadSongDB() { break; // good! this was another sanity check } + allegro_message("The declared number of songs in song_db.csv might be incorrect. Check for errors."); return -1; // the declared NUM_SONGS was incorrect } + if ( id < 100 || id > 400 ) + { + allegro_message("Unexpected file contents in song_db.csv - check line %d.", i-1); + return -1; + } songIDs[i] = id; songTitles[i].assign(name, strlen(name)); songArtists[i].assign(artist, strlen(artist)); @@ -1330,7 +1380,7 @@ void savePlayersHitList() // write the version fprintf(fp, "DMXH"); - int vnum = CURRENT_VERSION_NUMBER; + int vnum = CURRENT_HITLIST_VERSION_NUMBER; fwrite(&vnum, sizeof(long), 1, fp); // write everything out @@ -1355,7 +1405,7 @@ void loadPlayersHitList() // check the version int vnum = checkFileVersion(fp, "DMXH"); - if ( vnum != CURRENT_VERSION_NUMBER ) + if ( vnum != CURRENT_HITLIST_VERSION_NUMBER ) { TRACE("Wrong hitlist version number."); return; // later when multiple versions exist, ideas for converting them @@ -1745,14 +1795,16 @@ void renderDataOptions() { textprintf_centre(rm.m_backbuf, font, 320, 50, WHITE, "DATA OPTIONS"); - textprintf(rm.m_backbuf, font, 50, 100, testMenuSubIndex == 0 ? RED : WHITE, "RESET PLAYERS HITS CHART"); - textprintf(rm.m_backbuf, font, 50, 130, testMenuSubIndex == 1 ? RED : WHITE, "RESET PREVIOUS LOGIN LIST"); - textprintf(rm.m_backbuf, font, 50, 160, testMenuSubIndex == 2 ? RED : WHITE, "DELETE PLAYER"); - textprintf(rm.m_backbuf, font, 50, 190, testMenuSubIndex == 3 ? RED : WHITE, "MODIFY PLAYER PIN"); - textprintf(rm.m_backbuf, font, 50, 220, testMenuSubIndex == 4 ? RED : WHITE, "UPDATE SOFTWARE"); - textprintf(rm.m_backbuf, font, 50, 340, testMenuSubIndex == 5 ? RED : WHITE, "EXIT"); + textprintf(rm.m_backbuf, font, 50, 100, testMenuSubIndex == 0 ? RED : WHITE, "ALLOW PLAYER LOGIN"); + textprintf(rm.m_backbuf, font, 236, 100, gs.allowLogins ? GREEN : RED, gs.allowLogins ? "ON" : "OFF" ); + textprintf(rm.m_backbuf, font, 50, 130, testMenuSubIndex == 1 ? RED : WHITE, "RESET PLAYERS HITS CHART"); + textprintf(rm.m_backbuf, font, 50, 160, testMenuSubIndex == 2 ? RED : WHITE, "RESET PREVIOUS LOGIN LIST"); + textprintf(rm.m_backbuf, font, 50, 190, testMenuSubIndex == 3 ? RED : WHITE, "DELETE PLAYER"); + textprintf(rm.m_backbuf, font, 50, 220, testMenuSubIndex == 4 ? RED : WHITE, "MODIFY PLAYER PIN"); + textprintf(rm.m_backbuf, font, 50, 260, testMenuSubIndex == 5 ? RED : WHITE, "UPDATE SOFTWARE"); + textprintf(rm.m_backbuf, font, 50, 340, testMenuSubIndex == 6 ? RED : WHITE, "EXIT"); textprintf(rm.m_backbuf, font, 50, 400, makecol(196, 255, 255), "PRESS 1P LEFT / RIGHT = select item"); - //textprintf(rm.m_backbuf, font, 50, 420, makecol(196, 255, 255), "PRESS 2P LEFT / RIGHT = modify setting"); + textprintf(rm.m_backbuf, font, 50, 420, makecol(196, 255, 255), "PRESS 2P LEFT / RIGHT = modify setting"); textprintf(rm.m_backbuf, font, 50, 440, makecol(196, 255, 255), "PRESS 1P START BUTTON = confirm selection"); } \ No newline at end of file diff --git a/src/source/menuMode.cpp b/src/source/menuMode.cpp index 7ef3912..e40647a 100644 --- a/src/source/menuMode.cpp +++ b/src/source/menuMode.cpp @@ -120,6 +120,10 @@ void firstMenuLoop() timeRemaining = 15999; currentRow = 0; playersChoice = 0; + if ( gs.leftPlayerPresent && gs.rightPlayerPresent ) // you both pressed start during the attract/caution, so here you go + { + playersChoice = 2; + } modesY = MODE_Y_TOP; modesDirection = 0; @@ -168,7 +172,7 @@ void mainMenuLoop(UTIME dt) } playTimeLowSFX(dt); - // proces the unfolding animation + // process the unfolding animation if ( modesDirection != 0 ) { modeMovingTimer += dt; @@ -204,39 +208,68 @@ void mainMenuLoop(UTIME dt) bool noDouble = !gs.isFreeplay && !gs.isDoublePremium && gs.numCoins < gs.numCoinsPerCredit*2; bool noVersus = !gs.isFreeplay && !gs.isVersusPremium && gs.numCoins < gs.numCoinsPerCredit*2; + bool forcedVersus = gs.leftPlayerPresent && gs.rightPlayerPresent; int numModRows = gs.isDoubles || gs.isVersus ? 3 : 4; // only show the last modifier (which side) for singles play // check input if ( currentRow == 0 && modesDirection == 0 ) { - if ( im.getKeyState(MENU_LEFT_1P) == JUST_DOWN || im.getKeyState(MENU_LEFT_2P) == JUST_DOWN ) + // here the triangle buttons choose between single/double/versus + if ( forcedVersus ) { - int originalSelection = playersChoice; - playersChoice = playersChoice == 0 ? 0 : playersChoice - 1; - if ( playersChoice == 1 && noDouble ) + // if we're in forced versus mode then the triangles don't matter + if ( im.getKeyState(MENU_LEFT_1P) == JUST_DOWN || im.getKeyState(MENU_LEFT_2P) == JUST_DOWN || im.getKeyState(MENU_RIGHT_1P) == JUST_DOWN || im.getKeyState(MENU_RIGHT_2P) == JUST_DOWN ) { - playersChoice = 0; // singles + em.playSample(SFX_MENU_STUCK); } - - em.playSample(originalSelection == playersChoice ? SFX_MENU_STUCK : SFX_MENU_MOVE); } - if ( im.getKeyState(MENU_RIGHT_1P) == JUST_DOWN || im.getKeyState(MENU_RIGHT_2P) == JUST_DOWN ) + else { - int originalSelection = playersChoice; - playersChoice = playersChoice == 2 ? 2 : playersChoice + 1; - if ( playersChoice == 2 && noVersus ) + // select single/double/versus except skip double or versus if either is locked out due to a lack of credits + if ( im.getKeyState(MENU_LEFT_1P) == JUST_DOWN || im.getKeyState(MENU_LEFT_2P) == JUST_DOWN ) { - playersChoice = 1; // doubles - } - if ( playersChoice == 1 && noDouble ) - { - playersChoice = noVersus ? 0 : 2; // single or versus - } + int originalSelection = playersChoice; + playersChoice = playersChoice == 0 ? 0 : playersChoice - 1; + if ( playersChoice == 1 && noDouble ) + { + playersChoice = 0; // singles + } - em.playSample(originalSelection == playersChoice ? SFX_MENU_STUCK : SFX_MENU_MOVE); + em.playSample(originalSelection == playersChoice ? SFX_MENU_STUCK : SFX_MENU_MOVE); + } + if ( im.getKeyState(MENU_RIGHT_1P) == JUST_DOWN || im.getKeyState(MENU_RIGHT_2P) == JUST_DOWN ) + { + int originalSelection = playersChoice; + playersChoice = playersChoice == 2 ? 2 : playersChoice + 1; + if ( playersChoice == 2 && noVersus ) + { + playersChoice = 1; // doubles + } + if ( playersChoice == 1 && noDouble ) + { + playersChoice = noVersus ? 0 : 2; // single or versus + } + + em.playSample(originalSelection == playersChoice ? SFX_MENU_STUCK : SFX_MENU_MOVE); + } } + + // pressing start will confirm the current selection and potentially add a second player if ( im.getKeyState(MENU_START_1P) == JUST_DOWN || im.getKeyState(MENU_START_2P) == JUST_DOWN ) { + bool leftPlayerAdding = !gs.leftPlayerPresent && im.getKeyState(MENU_START_1P) == JUST_DOWN; + bool rightPlayerAdding = !gs.rightPlayerPresent && im.getKeyState(MENU_START_2P) == JUST_DOWN; + bool enoughCreditsForVersus = gs.isVersusPremium || gs.isFreeplay || (gs.numCoins >= gs.numCoinsPerCredit*2); + + // second player added! versus mode is auto-confirmed + if ( (leftPlayerAdding || rightPlayerAdding) && enoughCreditsForVersus ) + { + gs.leftPlayerPresent = true; + playersChoice = 2; + em.playSample(SFX_CREDIT_BEGIN); + } + + // sanity check if ( (playersChoice == 1 && noDouble) || (playersChoice == 2 && noVersus) ) { em.playSample(SFX_MENU_STUCK); @@ -255,7 +288,14 @@ void mainMenuLoop(UTIME dt) em.announcerQuipChance(71, 33); } - modesDirection = 1; // automatically starts the unfolding animation + if ( gs.allowLogins ) + { + modesDirection = 1; // automatically starts the unfolding animation + } + else + { + currentRow = 1; // skip directly to the mode selection + } return; } } @@ -505,6 +545,12 @@ void renderMenuLoop() color = 2; } + // if this is forced versus time then single and double should be darkened as well + if ( (i == 0 || i == 1) && gs.leftPlayerPresent && gs.rightPlayerPresent ) + { + color = 2; + } + sx = color * 114; masked_blit(m_mainPlayers, rm.m_backbuf, sx, i*32, i*114 + (i+1)*74, 84, 114, 32); }