]> Shamusworld >> Repos - thunder/blob - src/gui.cpp
9eae58bc33d04252ec9826785359d1d5f1bd11c9
[thunder] / src / gui.cpp
1 //
2 // Thunder Graphic User Interface
3 //
4 // by James Hammons
5 // (c) 2004, 2014 Underground Software
6 //
7 // JLH = James Hammons <jlhamm@acm.org>
8 //
9 // WHO  WHEN        WHAT
10 // ---  ----------  -----------------------------------------------------------
11 // JLH  07/23/2009  Added changelog ;-)
12 //
13
14 #include "gui.h"
15
16 #include <string>
17 #include <fstream>       // Needed for tracelog
18 #include "screen.h"
19 #include "sound.h"
20 #include "resource.h"    // Thunder graphics & sounds
21
22 using namespace std;
23
24 // External shit
25
26 extern SDL_Surface * screen;
27
28 extern uint8_t my_scr[0x14000];         // Screen buffer...
29 extern uint8_t gram1[];                         // Game RAM (do here??)
30 extern uint8_t hScrollOffset;           // Horizontal scroll offset
31 extern uint8_t vScrollOffset;           // Vertical scroll offset
32 extern uint32_t voffsets[8];
33 extern fstream tr;                                      // Tracelog
34
35 // Global shit
36
37 uint16_t text_life;                             // How long text is visible
38 bool show_text;                                 // Whether or not to show text
39 uint16_t show_which_msg;                // Which message to show
40 bool show_gui;                                  // Whether or not to show GUI
41 uint16_t selection;                             // Which GUI item currently selected
42 uint16_t gui_debounce;                  // GUI key debounce value
43 uint16_t num_coins;                             // Number of coins dropped
44 uint16_t blink = 0;                             // Used to blink player 1 & 2 start buttons
45 uint16_t flash = 23;                    // Used to flash GUI lights
46 uint16_t iline = 0;                             // Used to roll line
47 uint16_t dcurcol = 179;                 // dipswitch cursor color
48 int  dcurdir = 1;                               // Initially going up...
49 bool blink_on = false;
50 bool game_refresh;                              // Refresh rate user set
51 bool do_decrement;                              // Flag to handle decrement...
52 bool user_selected_something;   // Flag for well, you know...
53 uint16_t dswitch;                               // Which dipswitch is selected...
54
55 // Bitmaps
56
57 uint8_t bmp1[] = {
58   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
59   0,0,1,1,0,0,0,1,1,0,0,1,0,0,1,0,0,0,0,0,0,
60   0,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,
61   0,1,1,1,0,0,1,0,0,1,0,1,1,1,1,0,0,0,1,0,0,
62   0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,
63   0,0,1,1,0,0,0,1,1,0,0,1,0,0,1,0,1,1,1,1,0,
64   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
65   };
66 uint8_t bmp2[] = {
67   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
68   0,1,1,1,0,0,0,1,1,0,0,1,0,0,1,0,0,0,0,0,0,
69   0,0,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,
70   0,0,1,1,0,0,1,0,0,1,0,1,1,1,1,0,0,0,1,0,0,
71   0,0,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,
72   0,1,1,1,0,0,0,1,1,0,0,1,0,0,1,0,1,1,1,1,0,
73   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
74   };
75 uint8_t bmp3[] = {
76   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
77   0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
78   0,1,0,0,0,0,1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,
79   0,0,1,1,0,0,1,0,0,1,0,0,0,0,1,0,1,0,0,1,0,
80   0,0,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,1,0,
81   0,1,1,1,0,0,1,0,0,1,0,0,1,1,1,0,1,1,1,0,0,
82   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0
83   };
84 uint8_t boptions[] = { // 35x9
85   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
86   0,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
87   0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
88   0,1,0,0,1,0,1,1,1,0,0,1,1,1,1,0,1,1,0,0,0,1,1,0,0,1,1,1,0,0,0,1,1,0,0,
89   0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,
90   0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,1,0,0,
91   0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,0,0,1,0,
92   0,0,1,1,0,0,1,1,1,0,0,0,0,1,1,0,1,1,1,0,0,1,1,0,0,1,0,0,1,0,0,1,1,0,0,
93   0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
94   };
95 uint8_t bn0[] = {
96   0,0,0,0,0,0,
97   0,0,1,1,0,0,
98   0,1,0,0,1,0,
99   0,1,0,0,1,0,
100   0,1,0,0,1,0,
101   0,0,1,1,0,0,
102   0,0,0,0,0,0
103   };
104 uint8_t bn1[] = {
105   0,0,0,0,0,0,
106   0,0,1,0,0,0,
107   0,1,1,0,0,0,
108   0,0,1,0,0,0,
109   0,0,1,0,0,0,
110   0,1,1,1,0,0,
111   0,0,0,0,0,0
112   };
113 uint8_t bn2[] = {
114   0,0,0,0,0,0,
115   0,1,1,1,0,0,
116   0,0,0,0,1,0,
117   0,0,1,1,0,0,
118   0,1,0,0,0,0,
119   0,1,1,1,1,0,
120   0,0,0,0,0,0
121   };
122 uint8_t bn3[] = {
123   0,0,0,0,0,0,
124   0,1,1,1,0,0,
125   0,0,0,0,1,0,
126   0,1,1,1,0,0,
127   0,0,0,0,1,0,
128   0,1,1,1,0,0,
129   0,0,0,0,0,0
130   };
131 uint8_t bn4[] = {
132   0,0,0,0,0,0,
133   0,0,0,1,0,0,
134   0,1,0,1,0,0,
135   0,1,0,1,0,0,
136   0,1,1,1,1,0,
137   0,0,0,1,0,0,
138   0,0,0,0,0,0
139   };
140 uint8_t bn5[] = {
141   0,0,0,0,0,0,
142   0,1,1,1,1,0,
143   0,1,0,0,0,0,
144   0,1,1,1,0,0,
145   0,0,0,0,1,0,
146   0,1,1,1,0,0,
147   0,0,0,0,0,0
148   };
149 uint8_t bn6[] = {
150   0,0,0,0,0,0,
151   0,0,1,1,0,0,
152   0,1,0,0,0,0,
153   0,1,1,1,0,0,
154   0,1,0,0,1,0,
155   0,0,1,1,0,0,
156   0,0,0,0,0,0
157   };
158 uint8_t bn7[] = {
159   0,0,0,0,0,0,
160   0,1,1,1,1,0,
161   0,0,0,0,1,0,
162   0,0,0,1,0,0,
163   0,0,1,0,0,0,
164   0,0,1,0,0,0,
165   0,0,0,0,0,0
166   };
167 uint8_t bn8[] = {
168   0,0,0,0,0,0,
169   0,0,1,1,0,0,
170   0,1,0,0,1,0,
171   0,0,1,1,0,0,
172   0,1,0,0,1,0,
173   0,0,1,1,0,0,
174   0,0,0,0,0,0
175   };
176 uint8_t bn9[] = {
177   0,0,0,0,0,0,
178   0,0,1,1,0,0,
179   0,1,0,0,1,0,
180   0,0,1,1,1,0,
181   0,0,0,0,1,0,
182   0,0,1,1,0,0,
183   0,0,0,0,0,0
184   };
185 uint8_t bnA[] = {
186   0,0,0,0,0,0,
187   0,0,1,1,0,0,
188   0,1,0,0,1,0,
189   0,1,1,1,1,0,
190   0,1,0,0,1,0,
191   0,1,0,0,1,0,
192   0,0,0,0,0,0
193   };
194 uint8_t bnB[] = {
195   0,0,0,0,0,0,
196   0,1,1,1,0,0,
197   0,1,0,0,1,0,
198   0,1,1,1,0,0,
199   0,1,0,0,1,0,
200   0,1,1,1,0,0,
201   0,0,0,0,0,0
202   };
203 uint8_t bnC[] = {
204   0,0,0,0,0,0,
205   0,0,1,1,0,0,
206   0,1,0,0,1,0,
207   0,1,0,0,0,0,
208   0,1,0,0,1,0,
209   0,0,1,1,0,0,
210   0,0,0,0,0,0
211   };
212 uint8_t bnD[] = {
213   0,0,0,0,0,0,
214   0,1,1,1,0,0,
215   0,1,0,0,1,0,
216   0,1,0,0,1,0,
217   0,1,0,0,1,0,
218   0,1,1,1,0,0,
219   0,0,0,0,0,0
220   };
221 uint8_t bnE[] = {
222   0,0,0,0,0,0,
223   0,1,1,1,1,0,
224   0,1,0,0,0,0,
225   0,1,1,1,1,0,
226   0,1,0,0,0,0,
227   0,1,1,1,1,0,
228   0,0,0,0,0,0
229   };
230 uint8_t bnF[] = {
231   0,0,0,0,0,0,
232   0,1,1,1,1,0,
233   0,1,0,0,0,0,
234   0,1,1,1,0,0,
235   0,1,0,0,0,0,
236   0,1,0,0,0,0,
237   0,0,0,0,0,0
238   };
239
240
241   //
242 // Initialize GUI
243 //
244 void InitGUI(void)
245 {
246         num_coins = 0;
247         gui_debounce = 0;
248         user_selected_something = false;
249 }
250
251
252 //
253 // Handle key debounce
254 //
255 void HandleGUIDebounce(void)
256 {
257         if (gui_debounce)
258                 gui_debounce--;   // Debounce GUI keys...
259
260         do_decrement = !do_decrement;        // Called at 60Hz, so skip decrementing blink
261
262         if (do_decrement)
263         {
264                 if (blink)
265                         blink--;  // Handle blinking stuff (Should prb go in DrawGUI)
266
267                 flash -= 2;  // Handle flashing stuff (Should prb go in DrawGUI)
268
269                 if (flash == 0xFFFF)
270                         flash = 23;
271
272                 iline++;
273
274                 if (iline > 30)
275                         iline = 0;  // 30 pixels high, going past by 1
276
277                 dcurcol += dcurdir;
278
279                 if (dcurcol == 186)
280                         dcurdir = -1;
281
282                 if (dcurcol == 179)
283                         dcurdir = 1;
284         }
285 }
286
287
288 //
289 // Set the refresh rate (30/60 Hz)
290 //
291 void SetRefreshRate(bool refresh)
292 {
293         game_refresh = refresh;
294 }
295
296
297 //
298 // Whether or not GUI is showing
299 //
300 bool ShowGUI(void)
301 {
302         return show_gui;
303 }
304
305
306 //
307 // Turn the GUI on
308 //
309 void ActivateGUI(void)
310 {
311         show_gui = true;
312 }
313
314
315 //
316 // Turn the GUI off
317 //
318 void DeactivateGUI(void)
319 {
320         show_gui = false;
321 }
322
323
324 //
325 // Draw the small icons...
326 //
327 void DrawSmallIcons(uint16_t icon_not_to_draw)
328 {
329         uint8_t * iconmem;
330         uint8_t xl, yl;
331         uint8_t * sIcons[12] = { inoguis, icoinus, ipl1sts, ipl2sts, ii30hzs,
332                 ii60hzs, idipsws, ichecks, ikeycns, isnapss, iresets, ibyebys };
333         uint8_t xlens[12] = { 31, 18, 32, 35, 37, 37, 29, 23, 28, 32, 19, 19 };
334         uint8_t ylens[12] = { 31, 18, 19, 19, 21, 21, 23, 20, 16, 17, 20, 23 };
335         uint8_t xpos[11] = { 33, 48, 63, 78, 104, 0, 184, 210, 225, 240, 255 };
336         uint8_t iconidx[11] = { 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 6 };
337
338         if (game_refresh)
339                 iconidx[9] = 5;       // 60 Hz...
340
341         // Draw small icons 1 to 5 on left, then 11 to 7 on right.
342
343         for(int i=0; i<5; i++)
344         {
345                 uint16_t idx = i + icon_not_to_draw;    // Get correct start pos.
346
347                 if (idx > 10)
348                         idx -= 11;
349
350                 iconmem = sIcons[iconidx[idx]];
351                 xl = xlens[iconidx[idx]];
352                 yl = ylens[iconidx[idx]];
353
354                 uint32_t scadr = hScrollOffset + voffsets[vScrollOffset];
355                 scadr += 320 * ((224 - yl) / 2);                // Center vertically
356                 scadr += xpos[i] - (xl / 2);                    // Center around horiz. pos.
357                 uint16_t bmpptr = 0;
358
359                 for(int yy=0; yy<yl; yy++)
360                 {
361                         for(int xx=0; xx<xl; xx++)
362                         {
363                                 uint8_t b = iconmem[bmpptr++];
364
365                                 if (b)
366                                         my_scr[scadr + xx + yy * 320] = b;
367                         }
368                 }
369         }
370
371         for(int i=10; i>5; i--)
372         {
373                 uint16_t idx = i + icon_not_to_draw;    // Get correct start pos.
374
375                 if (idx > 10)
376                         idx -= 11;
377
378                 iconmem = sIcons[iconidx[idx]];
379                 xl = xlens[iconidx[idx]];
380                 yl = ylens[iconidx[idx]];
381
382                 uint32_t scadr = hScrollOffset + voffsets[vScrollOffset];
383                 scadr += 320 * ((224 - yl) / 2);                // Center vertically
384                 scadr += xpos[i] - (xl / 2);                    // Center around horiz. pos.
385                 uint16_t bmpptr = 0;
386
387                 for(int yy=0; yy<yl; yy++)
388                 {
389                         for(int xx=0; xx<xl; xx++)
390                         {
391                                 uint8_t b = iconmem[bmpptr++];
392
393                                 if (b)
394                                         my_scr[scadr + xx + yy * 320] = b;
395                         }
396                 }
397         }
398 }
399
400
401 //
402 // Draw the large (selected) icon
403 //
404 void DrawLargeIcon(uint16_t icon)
405 {
406         uint8_t * iconmem;
407         uint8_t xl, yl;
408         uint8_t * lIcons[11] = { inoguib, icoinub, ipl1stb, ipl2stb, ii30hzb,
409                 ii60hzb, idipswb, ikeycnb, isnapsb, iresetb, ibyebyb };
410         uint8_t xlens[11] = { 44, 45, 50, 52, 59, 59, 42, 45, 48, 58, 42 };
411         uint8_t ylens[11] = { 44, 40, 33, 29, 52, 52, 34, 45, 37, 40, 50 };
412
413         uint8_t gsubs1[24] = { 21, 21, 20, 19, 168, 168, 31, 155, 68, 68, 67, 66,
414                                                 36, 36, 35, 34, 188, 188, 183, 181, 81, 81, 85, 80 },
415                 gsubs2[24] = { 20, 20, 19, 19, 31,  31,  155, 155, 67, 67, 66, 66,
416                                                 35, 35, 34, 34, 183, 183, 181, 181, 85, 85, 80, 80 },
417                 gsubs3[24] = { 35, 34, 188, 188, 183, 181, 81, 81, 85, 80, 21, 21,
418                                                 20, 19, 168, 168, 31, 155, 68, 68, 67, 66, 36, 36 },
419                 gsubs4[24] = { 34, 34, 183, 183, 181, 181, 85, 85, 80, 80, 20, 20,
420                                                 19, 19, 31,  31,  155, 155, 67, 67, 66, 66, 35, 35 },
421                 gsubs5[24] = { 20, 20, 183, 183, 31, 31, 85, 85, 67, 67, 20, 20,
422                                                 35, 35, 31, 31, 183, 183, 67, 67, 85, 85, 35, 35 };
423
424         iconmem = lIcons[icon];
425         xl = xlens[icon];
426         yl = ylens[icon];
427
428         if (icon == OPTIONS)
429         {
430                 iconmem = boptions;
431                 xl = 35;
432                 yl = 9;
433         }
434
435         if ((icon == REFRESH) && game_refresh)
436         {
437                 iconmem = lIcons[5];
438                 xl = xlens[5];
439                 yl = ylens[5];
440         }
441
442         if (icon == DIPSWITCH)
443         {
444                 iconmem = lIcons[6];
445                 xl = xlens[6];
446                 yl = ylens[6];
447         }
448
449         uint32_t scadr = hScrollOffset + voffsets[vScrollOffset];
450         scadr += 320 * ((224 - yl) / 2);                // Center vertically
451         scadr += (288 - xl) / 2;                      // Center horizontally
452         uint16_t bmpptr = 0;
453
454         for(int yy=0; yy<yl; yy++)
455         {
456                 for(int xx=0; xx<xl; xx++)
457                 {
458                         uint8_t b = iconmem[bmpptr++];
459
460                         if (b)
461                         {
462                                 if ((icon == PL1START) && (b == 235) && (num_coins) && !blink_on)
463                                 b = 125;                        // Light ON color
464                 /*noguib: 44x44 [Green (hi/lo): 36/235 Orange: 168/31 Neutral:12]
465                 Rainbow (ROYGBP, hi/med/lo): 21,20,19; 168, 31,155; 68,67,66;
466                                                                                 36,35,34; 188,183,181; 81,85,80 */
467                                 if (icon == NOGUI)
468                                 {
469                                         uint8_t fln = (23 - flash) + 1; // Want to go forward (maybe fix it?)
470                                         switch (b)
471                                         {
472                                                 case 36:   { b = gsubs1[fln];  break; }
473                                                 case 235:  { b = gsubs2[fln];  break; }
474                                                 case 168:  { b = gsubs3[fln];  break; }
475                                                 case 31:   { b = gsubs4[fln];  break; }
476                                                 case 12:   { b = gsubs5[fln];  break; }
477                                         }
478                                 }
479
480                                 if ((icon == REFRESH) && (iline == yy) && (b == 50))
481                                         b = 188;
482
483                                 my_scr[scadr+xx+yy*320] = b;
484                         }
485                 }
486         }
487
488         if (!blink)    // Should go here???
489         {
490                 blink_on = !blink_on;        // Switch blink state
491
492                 if (blink_on)
493                         blink = 12;
494                 else
495                         blink = 6;
496         }
497   //if (flash == 1)  flash = 23;       // Reset flash value
498 }
499
500
501 //
502 // Draw the dipswitch portion of the GUI
503 //
504 void DrawDipswitch(void)
505 {
506         uint8_t dseloff[16] = { 0, 1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 11, 12 };
507         uint8_t * dtxt[13] = { idstext1, idstext2, idstext3, idstext4, idstext5,
508                 idstext2, idstext6, idstext7, idstext8, idstext9, idstext10, idstext11,
509                 idstext12 };
510
511         uint8_t dtx[13] = { 48, 80, 96, 82, 60, 80, 76, 57, 33, 50, 62, 65, 63 },
512                 dty[13] = { 7, 9, 7, 9, 7, 9, 7, 7, 7, 9, 7, 9, 7 };
513         uint32_t dtxtoff[13] = { 4*320+24, 14*320-78, 25*320+24, 32*320-80,
514                 39*320+24, 49*320-78,  4*320+24, 11*320-55, 18*320+24, 25*320-48,
515                 32*320+24, 42*320-63, 53*320+24 };
516         uint32_t scadr, bmpptr;
517         //dsx = //26x65
518
519         uint32_t dbase = hScrollOffset + voffsets[vScrollOffset];
520         dbase += (288 - 26) / 2;                 // Center horizontally
521         dbase += 320 * ((224 - ((65 * 2) + 8)) / 2);   // Center vertically
522
523         scadr = dbase;   // Reset screen address
524         bmpptr = 0;
525
526         for(int yy=0; yy<65; yy++)
527         {
528                 for(int xx=0; xx<26; xx++)
529                 {
530                         uint8_t b = idswitch[bmpptr++];
531
532                         if (b)
533                                 my_scr[scadr + xx + yy * 320] = b;
534                 }
535         }
536
537         scadr = dbase + (320*73);   // Reset screen address
538         bmpptr = 0;
539
540         for(int yy=0; yy<65; yy++)
541         {
542                 for(int xx=0; xx<26; xx++)
543                 {
544                         uint8_t b = idswitch[bmpptr++];
545
546                         if (b)
547                                 my_scr[scadr + xx + yy * 320] = b;
548                 }
549         }
550
551         for(int i=0; i<16; i++)
552         {
553                 scadr = dbase + (5 * 320 + 5) + i * 7 * 320;
554
555                 if (i > 7)
556                         scadr += 17*320;   // Adjust for DSW #2
557
558                 bmpptr = 0;
559
560                 if (gram1[0x423D + (i << 1)])
561                         scadr += 12; // Adjust position if ON
562
563                 for(int yy=0; yy<5; yy++)
564                 {
565                         for(int xx=0; xx<5; xx++)
566                         {
567                                 my_scr[scadr++] = idsbutton[bmpptr++];
568                         }
569
570                         scadr += 315; // Adjust position...
571                 }
572         }
573
574         uint8_t dselected_text = dseloff[dswitch];
575
576         for(int i=0; i<13; i++)
577         {
578                 if (dselected_text != i)
579                 {
580                         scadr = dbase + dtxtoff[i];
581
582                         if (i > 5)
583                                 scadr += (73 * 320);
584
585                         bmpptr = 0;
586
587                         for(int yy=0; yy<dty[i]; yy++)
588                         {
589                                 for(int xx=0; xx<dtx[i]; xx++)
590                                 {
591                                         uint8_t b = dtxt[i][bmpptr++];
592
593                                         if (b)
594                                                 my_scr[scadr] = b;
595
596                                         scadr++;
597                                 }
598
599                                 scadr += (320 - dtx[i]); // Adjust position...
600                         }
601                 }
602         }
603
604         scadr = dbase + dtxtoff[dselected_text];
605
606         if (dselected_text>5)
607                 scadr += (73 * 320);
608
609         bmpptr = 0;
610
611         for(int yy=0; yy<dty[dselected_text]; yy++)
612         {
613                 for(int xx=0; xx<dtx[dselected_text]; xx++)
614                 {
615                         uint8_t b = dtxt[dselected_text][bmpptr++];
616
617                         if (b)
618                                 my_scr[scadr] = 125;
619
620                         scadr++;
621                 }
622
623                 scadr += (320 - dtx[dselected_text]); // Adjust position...
624         }
625
626         if (dswitch != 16)                   // Draw cursor
627         {
628                 scadr = dbase + (4 * 320 + 4) + dswitch * 7 * 320;
629
630                 if (dswitch>7)
631                         scadr += 17 * 320;   // Adjust for DSW #2
632
633                 for(int xx=0; xx<19; xx++)
634                         my_scr[scadr++] = dcurcol;
635
636                 scadr += 301;
637
638                 for(int xx=0; xx<5; xx++)
639                 {
640                         my_scr[scadr] = dcurcol;
641                         scadr += 18;
642                         my_scr[scadr] = dcurcol;
643                         scadr += 302;
644                 }
645
646                 for(int xx=0; xx<19; xx++)
647                         my_scr[scadr++] = dcurcol;
648         }
649 }
650
651
652 //
653 // The actual GUI display routine
654 //
655 void DrawGUI(void)
656 {
657         if (!user_selected_something)  // i.e. we're not inside a selection...
658         {
659                 DrawSmallIcons(selection);  // 'selection' is icon *not* to draw
660                 DrawLargeIcon(selection);
661         }
662         else
663         {
664                 if (selection == DIPSWITCH)
665                         DrawDipswitch();
666         }
667 }
668
669
670 //
671 // User pressed left arrow handler
672 //
673 void SelectLeft(void)
674 {
675         if (!gui_debounce)
676         {
677                 gui_debounce = 6;
678
679                 if (!user_selected_something)
680                 {
681                         selection++;
682
683                         if (selection > 10)
684                                 selection = 0;
685                 }
686                 else
687                 {
688                         if (gram1[0x423D + (dswitch << 1)])       // It's switchable...
689                         {}  //SpawnSound(USERSOUND, SCLICK);
690                         else
691                         {}  //SpawnSound(USERSOUND, SUNGH);
692
693                         gram1[0x423D + (dswitch << 1)] = 0;       // & turn it off
694                 }
695         }
696 }
697
698
699 //
700 // User pressed right arrow handler
701 //
702 void SelectRight(void)
703 {
704         if (!gui_debounce)
705         {
706                 gui_debounce = 6;
707
708                 if (!user_selected_something)
709                 {
710                         selection--;
711
712                         if (selection > 10)
713                                 selection = 10;  // Unsigned compare
714                 }
715                 else
716                 {
717                         if (!gram1[0x423D + (dswitch << 1)])       // It's switchable...
718                         {}  //SpawnSound(USERSOUND, SCLICK);
719                         else
720                         {}  //SpawnSound(USERSOUND, SUNGH);
721
722                         gram1[0x423D+(dswitch<<1)] = 1;       // & turn it on
723                 }
724         }
725 }
726
727
728 //
729 // User pressed Up arrow handler
730 //
731 void SelectUp(void)
732 {
733         if (!gui_debounce)
734         {
735                 gui_debounce = 6;
736
737                 if (user_selected_something)
738                 {
739                         if (selection == DIPSWITCH)
740                         {
741                                 dswitch--;
742
743                                 if (dswitch > 16)
744                                         dswitch = 16;  // Wrap non-int
745                                 //snd_num = dswitch;  SpawnMsg(MSHOWNUMS); // Temp...
746                         }
747                 }
748         }
749 }
750
751
752 //
753 // User pressed down arrow handler
754 //
755 void SelectDown(void)
756 {
757         if (!gui_debounce)
758         {
759                 gui_debounce = 6;
760
761                 if (user_selected_something)
762                 {
763                         if (selection == DIPSWITCH)
764                         {
765                                 dswitch++;
766
767                                 if (dswitch > 16)
768                                         dswitch = 0;
769                                 //snd_num = dswitch;  SpawnMsg(MSHOWNUMS); // Temp...
770                         }
771                 }
772         }
773 }
774
775
776 //
777 // User selected something! Handle it!
778 //
779 uint8_t UserSelectedSomething(void)
780 {
781         //extern uint8_t * gram1;
782
783         if (!gui_debounce)
784         {
785                 gui_debounce = 6;
786
787                 if (!user_selected_something)  // Inside a selection? no...
788                 {
789
790                         if (selection == NOGUI)     // Turn off GUI
791                         {
792                                 show_gui = false;
793                         }
794
795                         if (selection == COINUP)    // Coin up machine
796                         {
797                                 gram1[0x41A5]++;          // Add one coin... (prob. need sep. counter)
798                                 num_coins++;
799                                 gram1[0x4189] = num_coins / 10; // Should be in THUNDER.CPP?
800                                 gram1[0x418A] = num_coins - (gram1[0x4189] * 10);
801                         }
802
803                         if (selection == PL1START)  // 1 Player start
804                         {
805                                 if (num_coins)
806                                 {
807                                         num_coins--;
808                                         show_gui = false;       // Shut off GUI only if coined up
809                                 }
810
811                                 gram1[0x418C] = 1;        // Strobe start location
812                         }
813
814                         if (selection == PL2START)  // 2 Player start
815                         {
816                                 if (num_coins > 1)
817                                 {
818                                         num_coins -= 2;
819                                         show_gui = false;
820                                 }
821                         }
822
823                         if (selection == REFRESH)   // Toggle refresh rate
824                         {
825                                 //SpawnSound(USERSOUND, SCLICK);
826                         }
827
828                         if (selection == DIPSWITCH) // Edit game settings
829                         {
830                                 //SpawnSound(USERSOUND, SBLAH);
831                                 user_selected_something = true;
832                                 dswitch = 0;              // Set at first dipswitch
833                         }
834
835                         if (selection == OPTIONS)   // Edit emulator settings
836                         {
837                         }
838
839                         if (selection == KEYCONFIG) // Edit game keys
840                         {
841                         }
842
843                         if (selection == SNAPSHOT)  // Snapshot
844                         {
845                                 SpawnSound(USERSOUND, SCAMERA);
846                                 SavePCXSnapshot();
847                         }
848
849                         if (selection == RESET)     // Reset machine
850                         {
851                                 //SpawnSound(USERSOUND, SRESET);
852                         }
853
854                         if (selection == EXIT)
855                         {
856                                 SpawnSound(USERSOUND, SCYA);
857                         }
858
859                         return selection;
860                 }
861                 else           // Selected something inside selection...
862                 {
863                         if (selection == DIPSWITCH)
864                         {
865                                 if (dswitch == 16)  // Selected 'back to GUI'
866                                 {
867                                         //SpawnSound(USERSOUND, SBLAH2);
868                                         user_selected_something = false;
869                                 }
870                                 else
871                                 {
872                                         //SpawnSound(USERSOUND, SCLICK);
873                                         gram1[0x423D + (dswitch << 1)] = !gram1[0x423D + (dswitch << 1)];
874                                 }
875                         }
876
877                         return 0xFF;  // Nothing for main to do...
878                 }
879         }
880         else
881                 return 0xFF;  // Wasn't debounced, so return invalid
882 }
883
884
885 //
886 // Show byte passed to it
887 //
888 void ShowNumbers(int number)
889 {
890         uint8_t * bnarray[16] = { bn0, bn1, bn2, bn3, bn4, bn5, bn6, bn7, bn8, bn9,
891                 bnA, bnB, bnC, bnD, bnE, bnF };
892 //      uint32_t scadr = hScrollOffset + voffsets[vScrollOffset] + 642 + 2560;
893         uint32_t scadr = ((2 * 288) + 2) + (8 * 288);
894         uint16_t bmpptr = 0;
895
896         uint8_t first_dig = number >> 4, second_dig = number & 0x0F;
897
898         for(int y=0; y<7; y++)
899         {
900                 for(int x=0; x<6; x++)
901                 {
902                         if (bnarray[first_dig][bmpptr++] == 1)
903 //                              my_scr[scadr + x + y * 320] = 7;
904                                 my_scr[scadr + x + y * 288] = 7;
905                         else
906 //                              my_scr[scadr + x + y * 320] = 0;
907                                 my_scr[scadr + x + y * 288] = 0;
908                 }
909         }
910
911         bmpptr = 0;
912         scadr += 6;
913
914         for(int y=0; y<7; y++)
915         {
916                 for(int x=0; x<6; x++)
917                 {
918                         if (bnarray[second_dig][bmpptr++] == 1)
919 //                              my_scr[scadr + x + y * 320] = 7;
920                                 my_scr[scadr + x + y * 288] = 7;
921                         else
922 //                              my_scr[scadr + x + y * 320] = 0;
923                                 my_scr[scadr + x + y * 288] = 0;
924                 }
925         }
926 }
927
928
929 //
930 // Spawn a message
931 //
932 void SpawnMsg(uint8_t msg)
933 {
934         text_life = 60;                 // 1 second...
935         show_text = true;               // Show the damn thing...
936         show_which_msg = msg;   // And tell it which message to show...
937 }
938
939
940 //
941 // Draw text message
942 //
943 void DrawText(void)
944 {
945         // Kill text if it's time
946         if (!text_life)
947         {
948                 show_text = false;
949                 return;
950         }
951
952         // Your life force is running out...
953         text_life--;
954
955         // Draw the message here...
956 //      uint32_t scadr = hScrollOffset + voffsets[vScrollOffset] + 642;
957         uint32_t scadr = (288 * 2) + 2;
958         uint16_t bmpptr = 0;
959
960         for(int y=0; y<7; y++)
961         {
962                 for(int x=0; x<21; x++)
963                 {
964                         if (show_which_msg == M60FPS)
965                         {
966                                 if (bmp1[bmpptr++] == 1)
967 //                                      my_scr[scadr + x + y * 320] = 7;
968                                         my_scr[scadr + x + y * 288] = 7;
969                                 else
970 //                                      my_scr[scadr + x + y * 320] = 0;
971                                         my_scr[scadr + x + y * 288] = 0;
972                         }
973                         else if (show_which_msg == M30FPS)
974                         {
975                                 if (bmp2[bmpptr++] == 1)
976 //                                      my_scr[scadr + x + y * 320] = 7;
977                                         my_scr[scadr + x + y * 288] = 7;
978                                 else
979 //                                      my_scr[scadr + x + y * 320] = 0;
980                                         my_scr[scadr + x + y * 288] = 0;
981                         }
982                         else if (show_which_msg == MSNAPSHOT)
983                         {
984                                 if (bmp3[bmpptr++] == 1)
985 //                                      my_scr[scadr + x + y * 320] = 7;
986                                         my_scr[scadr + x + y * 288] = 7;
987                                 else
988 //                                      my_scr[scadr + x + y * 320] = 0;
989                                         my_scr[scadr + x + y * 288] = 0;
990                         }
991                 }
992         }
993
994         if (show_which_msg == MSHOWNUMS)
995                 ShowNumbers(snd_num);
996 }
997