bool GameOptions(const GameMode gm) { // Create selection menus const int w = gGraphicsDevice.cachedConfig.Res.x; const int h = gGraphicsDevice.cachedConfig.Res.y; MenuSystem ms; MenuSystemInit( &ms, &gEventHandlers, &gGraphicsDevice, Vec2iZero(), Vec2iNew(w, h)); ms.align = MENU_ALIGN_CENTER; ms.allowAborts = true; AllowedWeaponsData awData; AllowedWeaponsDataInit(&awData, &gMission.Weapons); switch (gm) { case GAME_MODE_DEATHMATCH: ms.root = ms.current = MenuCreateNormal( "", "", MENU_TYPE_OPTIONS, 0); MenuAddConfigOptionsItem( ms.current, ConfigGet(&gConfig, "Game.PlayerHP")); MenuAddConfigOptionsItem( ms.current, ConfigGet(&gConfig, "Deathmatch.Lives")); MenuAddConfigOptionsItem( ms.current, ConfigGet(&gConfig, "Game.HealthPickups")); MenuAddConfigOptionsItem( ms.current, ConfigGet(&gConfig, "Game.Ammo")); MenuAddSubmenu(ms.current, MenuCreateAllowedWeapons("Weapons...", &awData)); MenuAddSubmenu(ms.current, MenuCreateSeparator("")); MenuAddSubmenu(ms.current, MenuCreateReturn("Done", 0)); break; case GAME_MODE_DOGFIGHT: ms.root = ms.current = MenuCreateNormal( "", "", MENU_TYPE_OPTIONS, 0); MenuAddConfigOptionsItem( ms.current, ConfigGet(&gConfig, "Dogfight.PlayerHP")); MenuAddConfigOptionsItem( ms.current, ConfigGet(&gConfig, "Dogfight.FirstTo")); MenuAddSubmenu(ms.current, MenuCreateAllowedWeapons("Weapons...", &awData)); MenuAddSubmenu(ms.current, MenuCreateSeparator("")); MenuAddSubmenu(ms.current, MenuCreateReturn("Done", 0)); break; default: CASSERT(false, "unknown game mode"); break; } MenuAddExitType(&ms, MENU_TYPE_RETURN); MenuLoop(&ms); const bool ok = !ms.hasAbort; if (ok) { ConfigApply(&gConfig); // Save options for later ConfigSave(&gConfig, GetConfigFilePath(CONFIG_FILE)); // Set allowed weapons // First check if the player has unwittingly disabled all weapons // if so, enable all weapons bool allDisabled = true; for (int i = 0, j = 0; i < (int)awData.allowed.size; i++, j++) { const bool *allowed = CArrayGet(&awData.allowed, i); if (*allowed) { allDisabled = false; break; } } if (!allDisabled) { for (int i = 0, j = 0; i < (int)awData.allowed.size; i++, j++) { const bool *allowed = CArrayGet(&awData.allowed, i); if (!*allowed) { CArrayDelete(&gMission.Weapons, j); j--; } } } } AllowedWeaponsDataTerminate(&awData); MenuSystemTerminate(&ms); return ok; }
void MenuActivate(menu_t *menu, int cmd) { Config lastConfig = gConfig; SoundPlay(&gSoundDevice, SND_SWITCH); switch (menu->type) { case MENU_TYPE_SET_OPTION_TOGGLE: *menu->u.option.uHook.optionToggle = !*menu->u.option.uHook.optionToggle; break; case MENU_TYPE_SET_OPTION_RANGE: { int option = *menu->u.option.uHook.optionRange.option; int increment = menu->u.option.uHook.optionRange.increment; if (Left(cmd)) { if (menu->u.option.uHook.optionRange.low + increment > option) { option = menu->u.option.uHook.optionRange.low; } else { option -= increment; } } else if (Right(cmd)) { if (menu->u.option.uHook.optionRange.high - increment < option) { option = menu->u.option.uHook.optionRange.high; } else { option += increment; } } *menu->u.option.uHook.optionRange.option = option; } break; case MENU_TYPE_SET_OPTION_SEED: { unsigned int seed = *menu->u.option.uHook.seed; unsigned int increment = 1; if (Button1(cmd)) { increment *= 10; } if (Button2(cmd)) { increment *= 100; } if (Left(cmd)) { if (increment > seed) { seed = 0; } else { seed -= increment; } } else if (Right(cmd)) { if (UINT_MAX - increment < seed) { seed = UINT_MAX; } else { seed += increment; } } *menu->u.option.uHook.seed = seed; } break; case MENU_TYPE_SET_OPTION_UP_DOWN_VOID_FUNC_VOID: if (Left(cmd)) { menu->u.option.uHook.upDownFuncs.upFunc(); } else if (Right(cmd)) { menu->u.option.uHook.upDownFuncs.downFunc(); } break; case MENU_TYPE_SET_OPTION_RANGE_GET_SET: { int option = menu->u.option.uHook.optionRangeGetSet.getFunc(); int increment = menu->u.option.uHook.optionRangeGetSet.increment; if (Left(cmd)) { if (menu->u.option.uHook.optionRangeGetSet.low + increment > option) { option = menu->u.option.uHook.optionRangeGetSet.low; } else { option -= increment; } } else if (Right(cmd)) { if (menu->u.option.uHook.optionRangeGetSet.high - increment < option) { option = menu->u.option.uHook.optionRangeGetSet.high; } else { option += increment; } } menu->u.option.uHook.optionRangeGetSet.setFunc(option); } break; case MENU_TYPE_SET_OPTION_CHANGE_CONTROL: InputChangeDevice( menu->u.option.uHook.changeControl.device0, menu->u.option.uHook.changeControl.device1, gJoysticks.numJoys); break; case MENU_TYPE_VOID_FUNC_VOID: menu->u.option.uHook.toggleFuncs.toggle(); break; case MENU_TYPE_SET_OPTION_CHANGE_KEY: menu->parentMenu->u.normal.changeKeyMenu = menu; break; default: printf("Error unhandled menu type %d\n", menu->type); assert(0); break; } if (!ConfigApply(&gConfig)) { printf("Error: cannot apply new config; applying last config\n"); gConfig = lastConfig; if (!ConfigApply(&gConfig)) { printf("Error: cannot apply last config!\n"); exit(1); } } }
void MenuActivate(MenuSystem *ms, menu_t *menu, int cmd) { Config lastConfig = gConfig; MenuPlaySound(MENU_SOUND_SWITCH); switch (menu->type) { case MENU_TYPE_BASIC: // do nothing // TODO: change ConfigApply to a custom hook return; case MENU_TYPE_SET_OPTION_TOGGLE: *menu->u.option.uHook.optionToggle = !*menu->u.option.uHook.optionToggle; break; case MENU_TYPE_SET_OPTION_RANGE: { int option = *menu->u.option.uHook.optionRange.option; int increment = menu->u.option.uHook.optionRange.increment; int low = menu->u.option.uHook.optionRange.low; int high = menu->u.option.uHook.optionRange.high; if (Left(cmd)) { if (low == option) { option = high; } else if (low + increment > option) { option = low; } else { option -= increment; } } else if (Right(cmd)) { if (high == option) { option = low; } else if (high - increment < option) { option = high; } else { option += increment; } } *menu->u.option.uHook.optionRange.option = option; } break; case MENU_TYPE_SET_OPTION_SEED: { unsigned int seed = *menu->u.option.uHook.seed; unsigned int increment = 1; if (Button1(cmd)) { increment *= 10; } if (Button2(cmd)) { increment *= 100; } if (Left(cmd)) { if (increment > seed) { seed = 0; } else { seed -= increment; } } else if (Right(cmd)) { if (UINT_MAX - increment < seed) { seed = UINT_MAX; } else { seed += increment; } } *menu->u.option.uHook.seed = seed; } break; case MENU_TYPE_SET_OPTION_UP_DOWN_VOID_FUNC_VOID: if (Left(cmd)) { menu->u.option.uHook.upDownFuncs.upFunc(); } else if (Right(cmd)) { menu->u.option.uHook.upDownFuncs.downFunc(); } break; case MENU_TYPE_SET_OPTION_RANGE_GET_SET: { int option = menu->u.option.uHook.optionRangeGetSet.getFunc(); int increment = menu->u.option.uHook.optionRangeGetSet.increment; if (Left(cmd)) { if (menu->u.option.uHook.optionRangeGetSet.low + increment > option) { option = menu->u.option.uHook.optionRangeGetSet.low; } else { option -= increment; } } else if (Right(cmd)) { if (menu->u.option.uHook.optionRangeGetSet.high - increment < option) { option = menu->u.option.uHook.optionRangeGetSet.high; } else { option += increment; } } menu->u.option.uHook.optionRangeGetSet.setFunc(option); } break; case MENU_TYPE_VOID_FUNC_VOID: menu->u.option.uHook.toggleFuncs.toggle(); break; case MENU_TYPE_SET_OPTION_CHANGE_KEY: menu->parentMenu->u.normal.changeKeyMenu = menu; break; default: printf("Error unhandled menu type %d\n", menu->type); assert(0); break; } if (!ConfigApply(&gConfig)) { printf("Error: cannot apply new config; applying last config\n"); gConfig = lastConfig; if (!ConfigApply(&gConfig)) { printf("Error: cannot apply last config!\n"); exit(1); } } // Update menu system // Note: only for the main menu system! ms->pos = Vec2iZero(); ms->size = Vec2iNew( ms->graphics->cachedConfig.ResolutionWidth, ms->graphics->cachedConfig.ResolutionHeight); }