GameLoopResult GameLoopWaitForAnyKeyOrButtonFunc(void *data) { GameLoopWaitForAnyKeyOrButtonData *wData = data; int cmds[MAX_LOCAL_PLAYERS]; memset(cmds, 0, sizeof cmds); GetPlayerCmds(&gEventHandlers, &cmds); for (int i = 0; i < MAX_LOCAL_PLAYERS; i++) { if (cmds[i] & (CMD_BUTTON1 | CMD_BUTTON2)) { // Interpret anything other than CMD_BUTTON1 as cancel return WaitResult(wData, cmds[i] & CMD_BUTTON1); } } // Check menu commands const int menuCmd = GetMenuCmd(&gEventHandlers); if (menuCmd & (CMD_BUTTON1 | CMD_BUTTON2)) { // Interpret anything other than CMD_BUTTON1 as cancel return WaitResult(wData, menuCmd & CMD_BUTTON1); } // Check if anyone pressed escape if (EventIsEscape(&gEventHandlers, cmds, menuCmd)) { return WaitResult(wData, false); } return UPDATE_RESULT_OK; }
void MenuLoop(MenuSystem *menu) { assert(menu->numExitTypes > 0); for (;; SDL_Delay(10)) { // Input InputPoll(menu->joysticks, menu->keyboard); // Update if (menu->current->type == MENU_TYPE_KEYS && menu->current->u.normal.changeKeyMenu != NULL) { MenuProcessChangeKey(menu->current); } else { int cmd = GetMenuCmd(); menu->current = MenuProcessCmd(menu->current, cmd); } if (MenuHasExitType(menu, menu->current->type)) { break; } // Draw if (menu->bkg != NULL) { memcpy( GetDstScreen(), menu->bkg, GraphicsGetMemSize(&gGraphicsDevice.cachedConfig)); } ShowControls(); MenuDisplay(menu); CopyToScreen(); } }
void MenuLoop(MenuSystem *menu) { assert(menu->numExitTypes > 0); for (;; SDL_Delay(10)) { MusicSetPlaying(&gSoundDevice, SDL_GetAppState() & SDL_APPINPUTFOCUS); // Input InputPoll(menu->inputDevices, SDL_GetTicks()); // Update if (menu->current->type == MENU_TYPE_KEYS && menu->current->u.normal.changeKeyMenu != NULL) { MenuProcessChangeKey(menu->current); } else { int cmd = GetMenuCmd(gPlayerDatas); MenuProcessCmd(menu, cmd); } if (MenuIsExit(menu)) { break; } // Draw GraphicsBlitBkg(menu->graphics); ShowControls(); MenuDisplay(menu); BlitFlip(menu->graphics, &gConfig.Graphics); } }
int MainMenu(void *bkg) { int cmd, prev = 0; int mode; PaletteAdjust(); mode = MODE_MAIN; while (mode != MODE_QUIT && mode != MODE_PLAY) { memcpy(GetDstScreen(), bkg, SCREEN_MEMSIZE); ShowControls(); if (mode == MODE_MAIN) ShowCredits(); GetMenuCmd(&cmd); if (cmd == prev) cmd = 0; else prev = cmd; mode = MakeSelection(mode, cmd); CopyToScreen(); SDL_Delay(10); } WaitForRelease(); return mode == MODE_PLAY; }
int NumPlayersSelection( int *numPlayers, campaign_mode_e mode, GraphicsDevice *graphics, InputDevices *input) { MenuSystem ms; int i; int res = 0; MenuSystemInit( &ms, input, graphics, Vec2iZero(), Vec2iNew( graphics->cachedConfig.ResolutionWidth, graphics->cachedConfig.ResolutionHeight)); ms.root = ms.current = MenuCreateNormal( "", "Select number of players", MENU_TYPE_NORMAL, 0); for (i = 0; i < MAX_PLAYERS; i++) { if (mode == CAMPAIGN_MODE_DOGFIGHT && i == 0) { // At least two players for dogfights continue; } char buf[2]; sprintf(buf, "%d", i + 1); MenuAddSubmenu(ms.current, MenuCreateReturn(buf, i + 1)); } MenuAddExitType(&ms, MENU_TYPE_RETURN); for (;;) { int cmd; InputPoll(&gInputDevices, SDL_GetTicks()); if (KeyIsPressed(&gInputDevices.keyboard, SDLK_ESCAPE)) { res = 0; break; // hack to allow exit } cmd = GetMenuCmd(gPlayerDatas); MenuProcessCmd(&ms, cmd); if (MenuIsExit(&ms)) { *numPlayers = ms.current->u.returnCode; res = 1; break; } GraphicsBlitBkg(graphics); MenuDisplay(&ms); BlitFlip(graphics, &gConfig.Graphics); SDL_Delay(10); } MenuSystemTerminate(&ms); return res; }
static GameLoopResult PlayerEquipUpdate(void *data) { PlayerEquipData *pData = data; // Check if anyone pressed escape int cmds[MAX_LOCAL_PLAYERS]; memset(cmds, 0, sizeof cmds); GetPlayerCmds(&gEventHandlers, &cmds); if (EventIsEscape(&gEventHandlers, cmds, GetMenuCmd(&gEventHandlers))) { pData->IsOK = false; return UPDATE_RESULT_EXIT; } // Update menus int idx = 0; for (int i = 0; i < (int)gPlayerDatas.size; i++, idx++) { const PlayerData *p = CArrayGet(&gPlayerDatas, i); if (!p->IsLocal) { idx--; continue; } if (!MenuIsExit(&pData->menus[idx].ms)) { MenuProcessCmd(&pData->menus[idx].ms, cmds[idx]); } else if (p->weaponCount == 0) { // Check exit condition; must have selected at least one weapon // Otherwise reset the current menu pData->menus[idx].ms.current = pData->menus[idx].ms.root; } } bool isDone = true; for (int i = 0; i < GetNumPlayers(false, false, true); i++) { if (strcmp(pData->menus[i].ms.current->name, "(End)") != 0) { isDone = false; } } if (isDone) { pData->IsOK = true; return UPDATE_RESULT_EXIT; } return UPDATE_RESULT_DRAW; }
static GameLoopResult MenuUpdate(void *data) { MenuSystem *ms = data; if (ms->current->type == MENU_TYPE_KEYS && ms->current->u.normal.changeKeyMenu != NULL) { MenuProcessChangeKey(ms->current); } else { const int cmd = GetMenuCmd(ms->handlers); if (cmd) { MenuProcessCmd(ms, cmd); } } // Check if anyone pressed escape, or we need a hard exit int cmds[MAX_LOCAL_PLAYERS]; memset(cmds, 0, sizeof cmds); GetPlayerCmds(&gEventHandlers, &cmds); const bool aborted = ms->allowAborts && EventIsEscape(&gEventHandlers, cmds, GetMenuCmd(&gEventHandlers)); if (aborted || ms->handlers->HasQuit) { ms->hasAbort = true; return UPDATE_RESULT_EXIT; } if (MenuIsExit(ms)) { return UPDATE_RESULT_EXIT; } if (ms->current->customPostUpdateFunc) { ms->current->customPostUpdateFunc( ms->current, ms->current->customPostUpdateData); } return UPDATE_RESULT_DRAW; }
static GameLoopResult MissionBriefingUpdate(void *data) { MissionBriefingData *mData = data; // Check for player input; if any then skip to the end of the briefing int cmds[MAX_LOCAL_PLAYERS]; memset(cmds, 0, sizeof cmds); GetPlayerCmds(&gEventHandlers, &cmds); for (int i = 0; i < MAX_LOCAL_PLAYERS; i++) { if (AnyButton(cmds[i])) { // If the typewriter is still going, skip to end if (mData->TypewriterCount <= (int)strlen(mData->Description)) { strcpy(mData->TypewriterBuf, mData->Description); mData->TypewriterCount = strlen(mData->Description); return UPDATE_RESULT_DRAW; } // Otherwise, exit out of loop return UPDATE_RESULT_EXIT; } } // Check if anyone pressed escape if (EventIsEscape(&gEventHandlers, cmds, GetMenuCmd(&gEventHandlers))) { mData->IsOK = false; return UPDATE_RESULT_EXIT; } // Update the typewriter effect if (mData->TypewriterCount <= (int)strlen(mData->Description)) { mData->TypewriterBuf[mData->TypewriterCount] = mData->Description[mData->TypewriterCount]; mData->TypewriterCount++; return UPDATE_RESULT_DRAW; } return UPDATE_RESULT_OK; }
static GameLoopResult PlayerSelectionUpdate(void *data) { PlayerSelectionData *pData = data; // Check if anyone pressed escape int cmds[MAX_LOCAL_PLAYERS]; memset(cmds, 0, sizeof cmds); GetPlayerCmds(&gEventHandlers, &cmds); if (EventIsEscape(&gEventHandlers, cmds, GetMenuCmd(&gEventHandlers))) { pData->IsOK = false; return UPDATE_RESULT_EXIT; } // Menu input int idx = 0; for (int i = 0; i < (int)gPlayerDatas.size; i++, idx++) { const PlayerData *p = CArrayGet(&gPlayerDatas, i); if (!p->IsLocal) { idx--; continue; } if (p->inputDevice != INPUT_DEVICE_UNSET && !MenuIsExit(&pData->menus[idx].ms) && cmds[idx]) { MenuProcessCmd(&pData->menus[idx].ms, cmds[idx]); } } // Conditions for exit: at least one player has selected "Done", // and no other players, if any, are still selecting their player // The "players" with no input device are turned into AIs bool hasAtLeastOneInput = false; bool isDone = true; idx = 0; for (int i = 0; i < (int)gPlayerDatas.size; i++, idx++) { const PlayerData *p = CArrayGet(&gPlayerDatas, i); if (!p->IsLocal) { idx--; continue; } if (p->inputDevice != INPUT_DEVICE_UNSET) { hasAtLeastOneInput = true; if (strcmp(pData->menus[idx].ms.current->name, "Done") != 0) { isDone = false; } } } if (isDone && hasAtLeastOneInput) { return UPDATE_RESULT_EXIT; } AssignPlayerInputDevices(&gEventHandlers); return UPDATE_RESULT_DRAW; }