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