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; }
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 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 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 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; }