1 /* 2 C-Dogs SDL 3 A port of the legendary (and fun) action/arcade cdogs. 4 Copyright (C) 1995 Ronny Wester 5 Copyright (C) 2003 Jeremy Chin 6 Copyright (C) 2003-2007 Lucas Martin-King 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 22 This file incorporates work covered by the following copyright and 23 permission notice: 24 25 Copyright (c) 2013-2018, 2020-2021 Cong Xu 26 All rights reserved. 27 28 Redistribution and use in source and binary forms, with or without 29 modification, are permitted provided that the following conditions are met: 30 31 Redistributions of source code must retain the above copyright notice, this 32 list of conditions and the following disclaimer. 33 Redistributions in binary form must reproduce the above copyright notice, 34 this list of conditions and the following disclaimer in the documentation 35 and/or other materials provided with the distribution. 36 37 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 38 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 39 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 40 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 41 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 42 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 43 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 44 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 45 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 47 POSSIBILITY OF SUCH DAMAGE. 48 */ 49 #pragma once 50 51 #include <cdogs/c_array.h> 52 #include <cdogs/campaigns.h> 53 #include <cdogs/events.h> 54 #include <cdogs/gamedata.h> 55 #include <cdogs/grafx.h> 56 57 #include "credits.h" 58 #include "game_loop.h" 59 60 typedef enum 61 { 62 MENU_TYPE_NORMAL, // normal menu with items, up/down/left/right moves 63 // cursor 64 MENU_TYPE_OPTIONS, // menu with items, only up/down moves 65 MENU_TYPE_BASIC, // no items, does nothing (use custom callbacks) 66 MENU_TYPE_SET_OPTION_TOGGLE, // no items, sets option on/off 67 MENU_TYPE_SET_OPTION_RANGE, // no items, sets option range low-high 68 MENU_TYPE_SET_OPTION_SEED, // set random seed 69 MENU_TYPE_SET_OPTION_UP_DOWN_VOID_FUNC_VOID, // set option using up/down 70 // functions 71 MENU_TYPE_SET_OPTION_RANGE_GET_SET, // set option range low-high using 72 // get/set functions 73 MENU_TYPE_SET_OPTION_CHANGE_KEY, // redefine key 74 MENU_TYPE_VOID_FUNC, // call a void (*f)(void *) function 75 MENU_TYPE_BACK, 76 MENU_TYPE_QUIT, 77 MENU_TYPE_RETURN, // Return with a code 78 MENU_TYPE_CUSTOM // use custom callbacks for input and drawing 79 } menu_type_e; 80 81 typedef enum 82 { 83 MENU_OPTION_DISPLAY_STYLE_NONE, 84 MENU_OPTION_DISPLAY_STYLE_STR_FUNC, // use a function that returns string 85 MENU_OPTION_DISPLAY_STYLE_INT_TO_STR_FUNC, // function that converts int to 86 // string 87 } menu_option_display_style_e; 88 89 typedef enum 90 { 91 MENU_DISPLAY_ITEMS_CREDITS = 0x01, 92 MENU_DISPLAY_ITEMS_AUTHORS = 0x02 93 } menu_display_items_e; 94 95 typedef struct menu menu_t; 96 97 // Callback for drawing custom menu 98 // menu, graphics, pos, size, data 99 typedef void (*MenuDisplayFunc)( 100 const menu_t *, GraphicsDevice *, const struct vec2i, const struct vec2i, 101 const void *); 102 // Callback for handling user input 103 // cmd, data 104 // returns: 0 if stay on menu, 1 if exit from menu 105 typedef int (*MenuInputFunc)(int, void *); 106 // Callback for processing custom function on menu 107 typedef void (*MenuFunc)(menu_t *, void *); 108 // Callback for processing custom menu function post input 109 // menu, cmd, data 110 typedef void (*MenuPostInputFunc)(menu_t *, int cmd, void *); 111 112 typedef enum 113 { 114 MENU_ALIGN_CENTER, 115 MENU_ALIGN_LEFT 116 } MenuAlignStyle; 117 118 typedef enum 119 { 120 MENU_SOUND_ENTER, 121 MENU_SOUND_BACK, 122 MENU_SOUND_SWITCH, 123 MENU_SOUND_START, 124 MENU_SOUND_ERROR 125 } MenuSound; 126 127 struct menu 128 { 129 char *name; 130 menu_type_e type; 131 struct menu *parentMenu; 132 bool isDisabled; 133 color_t color; 134 MenuFunc customPostEnterFunc; 135 void *customPostEnterData; 136 bool isCustomPostEnterDataDynamic; 137 MenuFunc customPostUpdateFunc; 138 void *customPostUpdateData; 139 bool isCustomPostUpdateDataDynamic; 140 MenuPostInputFunc customPostInputFunc; 141 void *customPostInputData; 142 MenuDisplayFunc customDisplayFunc; 143 const void *customDisplayData; 144 MenuSound enterSound; 145 union { 146 // normal menu, with sub menus 147 struct 148 { 149 char title[64]; 150 CArray subMenus; // of menu_t 151 // whether to use alternate control to enter submenus 152 bool isSubmenusAlt; 153 int index; 154 int scroll; 155 int maxItems; // 0 means unlimited 156 MenuAlignStyle align; 157 int quitMenuIndex; 158 int displayItems; 159 int setOptions; 160 struct menu 161 *changeKeyMenu; // if in change key mode, and which item 162 } normal; 163 // menu item only 164 struct 165 { 166 union { 167 bool *optionToggle; 168 struct 169 { 170 int *option; 171 int low; 172 int high; 173 int increment; 174 } optionRange; 175 unsigned int *seed; 176 // function to call 177 struct 178 { 179 void (*upFunc)(void); 180 void (*downFunc)(void); 181 } upDownFuncs; 182 struct 183 { 184 int (*getFunc)(void); 185 void (*setFunc)(int); 186 int low; 187 int high; 188 int increment; 189 } optionRangeGetSet; 190 struct 191 { 192 void (*func)(void *); 193 void *data; 194 } voidFunc; 195 struct 196 { 197 input_device_e *device0; 198 input_device_e *device1; 199 } changeControl; 200 } uHook; 201 menu_option_display_style_e displayStyle; 202 union { 203 char *(*str)(void); 204 const char *(*intToStr)(int); 205 } uFunc; 206 } option; 207 // change key 208 struct 209 { 210 key_code_e code; 211 int playerIndex; 212 // If key is optional, allow it to be unset 213 bool isOptional; 214 } changeKey; 215 int returnCode; 216 struct 217 { 218 MenuDisplayFunc displayFunc; 219 MenuInputFunc inputFunc; 220 void *data; 221 } customData; 222 } u; 223 }; 224 225 typedef struct 226 { 227 MenuDisplayFunc Func; 228 void *Data; 229 } MenuCustomDisplayFunc; 230 typedef struct 231 { 232 menu_t *root; 233 menu_t *current; 234 CArray exitTypes; // of menu_type_e 235 credits_displayer_t *creditsDisplayer; 236 EventHandlers *handlers; 237 GraphicsDevice *graphics; 238 struct vec2i pos; 239 struct vec2i size; 240 MenuAlignStyle align; 241 bool allowAborts; 242 bool hasAbort; 243 CArray customDisplayFuncs; // of MenuCustomDisplayFunc 244 } MenuSystem; 245 246 void MenuSystemInit( 247 MenuSystem *ms, EventHandlers *handlers, GraphicsDevice *graphics, 248 struct vec2i pos, struct vec2i size); 249 void MenuSystemTerminate(MenuSystem *ms); 250 void MenuSetCreditsDisplayer( 251 MenuSystem *menu, credits_displayer_t *creditsDisplayer); 252 void MenuAddExitType(MenuSystem *menu, menu_type_e exitType); 253 void MenuSystemAddCustomDisplay( 254 MenuSystem *ms, MenuDisplayFunc func, void *data); 255 int MenuIsExit(MenuSystem *ms); 256 GameLoopData *MenuLoop(MenuSystem *menu); 257 GameLoopResult MenuUpdate(MenuSystem *ms); 258 void MenuDraw(const MenuSystem *ms); 259 void MenuDisplay(const MenuSystem *ms); 260 void MenuProcessCmd(MenuSystem *ms, int cmd); 261 void MenuReset(MenuSystem *menu); 262 void MenuDisableSubmenu(menu_t *menu, int index); 263 void MenuEnableSubmenu(menu_t *menu, int index); 264 void MenuSetDisabled(menu_t *menu, const bool isDisabled); 265 menu_t *MenuGetSubmenuByName(menu_t *menu, const char *name); 266 int MenuGetNumMenuItemsShown(const menu_t *menu); 267 268 void ShowControls(void); 269 struct vec2i DisplayMenuItem( 270 GraphicsDevice *g, const Rect2i bounds, const char *s, const bool selected, 271 const bool isDisabled, const color_t color); 272 273 menu_t *MenuCreate(const char *name, menu_type_e type); 274 menu_t *MenuCreateNormal( 275 const char *name, const char *title, menu_type_e type, int displayItems); 276 menu_t *MenuAddSubmenu(menu_t *menu, menu_t *subMenu); 277 void MenuSetPostEnterFunc( 278 menu_t *menu, MenuFunc func, void *data, const bool isDynamicData); 279 void MenuSetPostUpdateFunc( 280 menu_t *menu, MenuFunc func, void *data, const bool isDynamicData); 281 void MenuSetPostInputFunc(menu_t *menu, MenuPostInputFunc func, void *data); 282 void MenuSetCustomDisplay( 283 menu_t *menu, MenuDisplayFunc func, const void *data); 284 285 void MenuAddConfigOptionsItem(menu_t *menu, Config *c); 286 menu_t *MenuCreateOptionToggle(const char *name, bool *config); 287 menu_t *MenuCreateOptionRange( 288 const char *name, int *config, int low, int high, int increment, 289 menu_option_display_style_e style, void (*func)(void)); 290 menu_t *MenuCreateOptionSeed(const char *name, unsigned int *seed); 291 menu_t *MenuCreateOptionUpDownFunc( 292 const char *name, void (*upFunc)(void), void (*downFunc)(void), 293 menu_option_display_style_e style, char *(*strFunc)(void)); 294 menu_t *MenuCreateVoidFunc(const char *name, void (*func)(void *), void *data); 295 menu_t *MenuCreateOptionRangeGetSet( 296 const char *name, int (*getFunc)(void), void (*setFunc)(int), int low, 297 int high, int increment, menu_option_display_style_e style, 298 void (*func)(void)); 299 menu_t *MenuCreateSeparator(const char *name); 300 menu_t *MenuCreateBack(const char *name); 301 // Create a menu entry that exits the menu while setting a return code 302 // The return code can be retrieved from the menu system via 303 // ms.current->u.returnCode 304 menu_t *MenuCreateReturn(const char *name, int returnCode); 305 menu_t *MenuCreateCustom( 306 const char *name, MenuDisplayFunc displayFunc, MenuInputFunc inputFunc, 307 void *data); 308 309 void MenuPlaySound(MenuSound s); 310 311 void MenuClearSubmenus(menu_t *menu); 312