1 //
2 // Copyright(C) 2005-2014 Simon Howard
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include "config.h"
20 #include "textscreen.h"
21
22 #include "execute.h"
23
24 #include "m_argv.h"
25 #include "m_config.h"
26 #include "m_controls.h"
27 #include "m_misc.h"
28 #include "z_zone.h"
29
30 #include "setup_icon.c"
31 #include "mode.h"
32
33 #include "compatibility.h"
34 #include "display.h"
35 #include "joystick.h"
36 #include "keyboard.h"
37 #include "mouse.h"
38 #include "multiplayer.h"
39 #include "sound.h"
40
41 #define WINDOW_HELP_URL "https://www.chocolate-doom.org/setup"
42
43 static const int cheat_sequence[] =
44 {
45 KEY_UPARROW, KEY_UPARROW, KEY_DOWNARROW, KEY_DOWNARROW,
46 KEY_LEFTARROW, KEY_RIGHTARROW, KEY_LEFTARROW, KEY_RIGHTARROW,
47 'b', 'a', KEY_ENTER, 0
48 };
49
50 static unsigned int cheat_sequence_index = 0;
51
52 // I think these are good "sensible" defaults:
53
SensibleDefaults(void)54 static void SensibleDefaults(void)
55 {
56 key_up = 'w';
57 key_down = 's';
58 key_strafeleft = 'a';
59 key_straferight = 'd';
60 key_jump = '/';
61 key_lookup = KEY_PGUP;
62 key_lookdown = KEY_PGDN;
63 key_lookcenter = KEY_HOME;
64 key_flyup = KEY_INS;
65 key_flydown = KEY_DEL;
66 key_flycenter = KEY_END;
67 key_prevweapon = ',';
68 key_nextweapon = '.';
69 key_invleft = '[';
70 key_invright = ']';
71 key_message_refresh = '\'';
72 key_mission = 'i'; // Strife keys
73 key_invpop = 'o';
74 key_invkey = 'p';
75 key_multi_msgplayer[0] = 'g';
76 key_multi_msgplayer[1] = 'h';
77 key_multi_msgplayer[2] = 'j';
78 key_multi_msgplayer[3] = 'k';
79 key_multi_msgplayer[4] = 'v';
80 key_multi_msgplayer[5] = 'b';
81 key_multi_msgplayer[6] = 'n';
82 key_multi_msgplayer[7] = 'm';
83 mousebprevweapon = 4; // Scroll wheel = weapon cycle
84 mousebnextweapon = 3;
85 snd_musicdevice = 3;
86 joybspeed = 29; // Always run
87 vanilla_savegame_limit = 0;
88 vanilla_keyboard_mapping = 0;
89 vanilla_demo_limit = 0;
90 graphical_startup = 0;
91 show_endoom = 0;
92 dclick_use = 0;
93 novert = 1;
94 snd_dmxoption = "-opl3 -reverse";
95 png_screenshots = 1;
96 }
97
MainMenuKeyPress(txt_window_t * window,int key,void * user_data)98 static int MainMenuKeyPress(txt_window_t *window, int key, void *user_data)
99 {
100 if (key == cheat_sequence[cheat_sequence_index])
101 {
102 ++cheat_sequence_index;
103
104 if (cheat_sequence[cheat_sequence_index] == 0)
105 {
106 SensibleDefaults();
107 cheat_sequence_index = 0;
108
109 window = TXT_MessageBox(NULL, " \x01 ");
110
111 return 1;
112 }
113 }
114 else
115 {
116 cheat_sequence_index = 0;
117 }
118
119 return 0;
120 }
121
DoQuit(void * widget,void * dosave)122 static void DoQuit(void *widget, void *dosave)
123 {
124 if (dosave != NULL)
125 {
126 M_SaveDefaults();
127 }
128
129 TXT_Shutdown();
130
131 exit(0);
132 }
133
QuitConfirm(void * unused1,void * unused2)134 static void QuitConfirm(void *unused1, void *unused2)
135 {
136 txt_window_t *window;
137 txt_label_t *label;
138 txt_button_t *yes_button;
139 txt_button_t *no_button;
140
141 window = TXT_NewWindow(NULL);
142
143 TXT_AddWidgets(window,
144 label = TXT_NewLabel("Exiting setup.\nSave settings?"),
145 TXT_NewStrut(24, 0),
146 yes_button = TXT_NewButton2(" Yes ", DoQuit, DoQuit),
147 no_button = TXT_NewButton2(" No ", DoQuit, NULL),
148 NULL);
149
150 TXT_SetWidgetAlign(label, TXT_HORIZ_CENTER);
151 TXT_SetWidgetAlign(yes_button, TXT_HORIZ_CENTER);
152 TXT_SetWidgetAlign(no_button, TXT_HORIZ_CENTER);
153
154 // Only an "abort" button in the middle.
155 TXT_SetWindowAction(window, TXT_HORIZ_LEFT, NULL);
156 TXT_SetWindowAction(window, TXT_HORIZ_CENTER,
157 TXT_NewWindowAbortAction(window));
158 TXT_SetWindowAction(window, TXT_HORIZ_RIGHT, NULL);
159 }
160
LaunchDoom(void * unused1,void * unused2)161 static void LaunchDoom(void *unused1, void *unused2)
162 {
163 execute_context_t *exec;
164
165 // Save configuration first
166
167 M_SaveDefaults();
168
169 // Shut down textscreen GUI
170
171 TXT_Shutdown();
172
173 // Launch Doom
174
175 exec = NewExecuteContext();
176 PassThroughArguments(exec);
177 ExecuteDoom(exec);
178
179 exit(0);
180 }
181
GetLaunchButton(void)182 static txt_button_t *GetLaunchButton(void)
183 {
184 char *label;
185
186 switch (gamemission)
187 {
188 case doom:
189 label = "Save parameters and launch DOOM";
190 break;
191 case heretic:
192 label = "Save parameters and launch Heretic";
193 break;
194 case hexen:
195 label = "Save parameters and launch Hexen";
196 break;
197 case strife:
198 label = "Save parameters and launch STRIFE!";
199 break;
200 default:
201 label = "Save parameters and launch game";
202 break;
203 }
204
205 return TXT_NewButton2(label, LaunchDoom, NULL);
206 }
207
MainMenu(void)208 void MainMenu(void)
209 {
210 txt_window_t *window;
211 txt_window_action_t *quit_action;
212 txt_window_action_t *warp_action;
213
214 window = TXT_NewWindow("Main Menu");
215
216 TXT_SetWindowHelpURL(window, WINDOW_HELP_URL);
217
218 TXT_AddWidgets(window,
219 TXT_NewButton2("Configure Display",
220 (TxtWidgetSignalFunc) ConfigDisplay, NULL),
221 TXT_NewButton2("Configure Sound",
222 (TxtWidgetSignalFunc) ConfigSound, NULL),
223 TXT_NewButton2("Configure Keyboard",
224 (TxtWidgetSignalFunc) ConfigKeyboard, NULL),
225 TXT_NewButton2("Configure Mouse",
226 (TxtWidgetSignalFunc) ConfigMouse, NULL),
227 TXT_NewButton2("Configure Gamepad/Joystick",
228 (TxtWidgetSignalFunc) ConfigJoystick, NULL),
229 TXT_NewButton2("Compatibility",
230 (TxtWidgetSignalFunc) CompatibilitySettings, NULL),
231 GetLaunchButton(),
232 TXT_NewStrut(0, 1),
233 TXT_NewButton2("Start a Network Game",
234 (TxtWidgetSignalFunc) StartMultiGame, NULL),
235 TXT_NewButton2("Join a Network Game",
236 (TxtWidgetSignalFunc) JoinMultiGame, NULL),
237 TXT_NewButton2("Multiplayer Configuration",
238 (TxtWidgetSignalFunc) MultiplayerConfig, NULL),
239 NULL);
240
241 quit_action = TXT_NewWindowAction(KEY_ESCAPE, "Quit");
242 warp_action = TXT_NewWindowAction(KEY_F2, "Warp");
243 TXT_SignalConnect(quit_action, "pressed", QuitConfirm, NULL);
244 TXT_SignalConnect(warp_action, "pressed",
245 (TxtWidgetSignalFunc) WarpMenu, NULL);
246 TXT_SetWindowAction(window, TXT_HORIZ_LEFT, quit_action);
247 TXT_SetWindowAction(window, TXT_HORIZ_CENTER, warp_action);
248
249 TXT_SetKeyListener(window, MainMenuKeyPress, NULL);
250 }
251
252 //
253 // Initialize all configuration variables, load config file, etc
254 //
255
InitConfig(void)256 static void InitConfig(void)
257 {
258 M_SetConfigDir(NULL);
259 InitBindings();
260
261 SetChatMacroDefaults();
262 SetPlayerNameDefault();
263
264 M_LoadDefaults();
265 }
266
267 //
268 // Application icon
269 //
270
SetIcon(void)271 static void SetIcon(void)
272 {
273 extern SDL_Window *TXT_SDLWindow;
274 SDL_Surface *surface;
275
276 surface = SDL_CreateRGBSurfaceFrom((void *) setup_icon_data, setup_icon_w,
277 setup_icon_h, 32, setup_icon_w * 4,
278 0xff << 24, 0xff << 16,
279 0xff << 8, 0xff << 0);
280
281 SDL_SetWindowIcon(TXT_SDLWindow, surface);
282 SDL_FreeSurface(surface);
283 }
284
SetWindowTitle(void)285 static void SetWindowTitle(void)
286 {
287 char *title;
288
289 title = M_StringReplace(PACKAGE_NAME " Setup ver " PACKAGE_VERSION,
290 "Doom",
291 GetGameTitle());
292
293
294 TXT_SetDesktopTitle(title);
295
296 free(title);
297 }
298
299 // Initialize the textscreen library.
300
InitTextscreen(void)301 static void InitTextscreen(void)
302 {
303 SetDisplayDriver();
304
305 if (!TXT_Init())
306 {
307 fprintf(stderr, "Failed to initialize GUI\n");
308 exit(-1);
309 }
310
311 SetIcon();
312 SetWindowTitle();
313 }
314
315 // Restart the textscreen library. Used when the video_driver variable
316 // is changed.
317
RestartTextscreen(void)318 void RestartTextscreen(void)
319 {
320 TXT_Shutdown();
321 InitTextscreen();
322 }
323
324 //
325 // Initialize and run the textscreen GUI.
326 //
327
RunGUI(void)328 static void RunGUI(void)
329 {
330 InitTextscreen();
331
332 TXT_GUIMainLoop();
333 }
334
MissionSet(void)335 static void MissionSet(void)
336 {
337 SetWindowTitle();
338 InitConfig();
339 MainMenu();
340 }
341
D_DoomMain(void)342 void D_DoomMain(void)
343 {
344 SetupMission(MissionSet);
345
346 RunGUI();
347 }
348