1 /*---------------------------------------------------------------------------*
2 * N I N T E N D O C O N F I D E N T I A L P R O P R I E T A R Y
3 *---------------------------------------------------------------------------*
4 *
5 * Project: Dolphin OS - TextWindow primitives
6 * File: txwin.c
7 *
8 * Copyright 1999, 2000 Nintendo. All rights reserved.
9 *
10 * These coded instructions, statements, and computer programs contain
11 * proprietary information of Nintendo of America Inc. and/or Nintendo
12 * Company Ltd., and are protected by Federal copyright law. They may
13 * not be disclosed to third parties or copied or duplicated in any form,
14 * in whole or in part, without the prior written consent of Nintendo.
15 *
16 * $Log: DEMOWin.c,v $
17 * Revision 1.3.38.1 2008/07/10 03:02:55 yasuh-to
18 * Changed some variables to be static.
19 *
20 * Revision 1.3 2006/05/21 15:02:09 ekwon
21 * Revised to accommodate MEM library usage if DEMO_USE_MEMLIB is #define'd before DEMOWIN.h is included.
22 *
23 * Also supports using MEM2 via #define of DEMOWIN_USE_MEM2. However, this has not been tested yet.
24 *
25 * Note that these changes are backwards compatible with older demos.
26 *
27 * Revision 1.2 2006/02/20 04:37:44 mitu
28 * Changed include path from dolphin/ to revolution/.
29 *
30 * Revision 1.1.1.1 2005/05/12 02:15:48 yasuh-to
31 * Ported from dolphin source tree
32 *
33
34 20 2002/08/26 10:03 Hashida
35 Deleted an unused variable.
36
37 19 2002/02/05 4:01p Eugene
38 Added pad data to window structure so that it may be exposed to the
39 calling application.
40
41 18 2001/07/27 11:49a Eugene
42 Failed to set window handles to NULL after freeing in
43 DEMOWinDestroy*Window() functions. Ooops, heee.
44
45 17 2001/05/21 12:14p Eugene
46 Modified default window color to accommodate gamma 1.0
47
48 16 2001/05/21 12:04p Eugene
49 Moved DEMOWIN.H to include/demo/demowin.h
50
51 15 2001/05/10 12:00a Eugene
52 Debounced MNU_SELECT and MNU_RIGHT inputs
53
54 14 2001/05/09 9:13p Eugene
55 Fixed consecutive SEPARATOR menu item bug.
56
57 13 2001/05/09 2:20p Eugene
58
59 12 2001/05/08 10:49p Eugene
60 1. Added Menu system.
61 2. Added List system.
62 3. No more special window types (log/state). Unified buffer system.
63 4. Windows are scrollable.
64 5. Menus support "child" menus recursively.
65 6. DEMO-lib friendly graphics for windows.
66 7. Window priority system. (using Z-buffer).
67 8. Window creation/destruction performed w/ separate API calls, to
68 facilitate handle reuse (and minimize mem allocation).
69 9. errrrmmm.....other stuff. repeat-mode pad inputs...
70
71 11 2001/05/08 4:05a Eugene
72
73 10 2001/05/08 2:18a Eugene
74
75 9 2001/05/08 2:05a Eugene
76
77 8 2001/05/07 11:54p Eugene
78
79 7 2001/05/07 11:27p Eugene
80
81 6 2001/05/07 11:12p Eugene
82
83 5 2001/05/07 10:02p Eugene
84
85 4 2001/05/07 1:28p Eugene
86
87 3 2001/05/06 11:28p Eugene
88
89 2 2001/05/06 11:07p Eugene
90
91 1 2001/05/06 8:29p Eugene
92 Simple text-windowing system. Not documented, not officially supported.
93 Include <dolphin/DEMOWin.h> to use the API. Does not impact old DEMO
94 library.
95
96 1 2000/12/04 7:28p Eugene
97 *
98 *
99 * $NoKeywords: $
100 *
101 *---------------------------------------------------------------------------*/
102
103
104 /*---------------------------------------------------------------------------*
105 * Includes
106 *---------------------------------------------------------------------------*/
107 #include <demo.h>
108 #include <stdlib.h>
109 #include <string.h>
110 #include <stddef.h>
111 #include <stdarg.h>
112
113 #include <revolution.h>
114
115 #include <demo/DEMOWin.h>
116
117
118
119 /*---------------------------------------------------------------------------*
120 * Local types
121 *---------------------------------------------------------------------------*/
122
123
124
125 /*---------------------------------------------------------------------------*
126 * Private module variables
127 *---------------------------------------------------------------------------*/
128
129 static DEMOWinInfo *__first_node;
130 static DEMOWinInfo *__last_node;
131 static DEMOWinInfo *__curr_node;
132
133 static GXRenderModeObj *__rmp;
134
135 #define __DEF_BKGND_R 0x1a
136 #define __DEF_BKGND_G 0x1f
137 #define __DEF_BKGND_B 0x21
138 #define __DEF_BKGND_A 0xff
139
140 #define __DEF_CAP_R 0x55
141 #define __DEF_CAP_G 0x1f
142 #define __DEF_CAP_B 0x1f
143 #define __DEF_CAP_A 0xff
144
145 #define __DEF_BORDER_R 0x45
146 #define __DEF_BORDER_G 0x25
147 #define __DEF_BORDER_B 0x25
148 #define __DEF_BORDER_A 0xff
149
150 static s32 fontShift = 0;
151
152 static u32 __DEMOWIN_PAD_repeat_threshold = DEMOWIN_PAD_REPEAT_THRESH_DEF;
153 static u32 __DEMOWIN_PAD_repeat_rate = DEMOWIN_PAD_REPEAT_RATE_DEF;
154
155
156 //
157 // hackery to use MEM library, and to specify MEM1 or MEM2
158 // based on whether or not DEMO_USE_MEMLIB and DEMOWIN_USE_MEM2 are #define'd
159 //
160
161 static BOOL __DEMOWin_use_memlib = FALSE;
162 static BOOL __DEMOWin_use_mem2 = FALSE;
163
164 static MEMAllocator *__DEMOWin_memallocator_ptr;
165
166
167 /*---------------------------------------------------------------------------*
168 * Private function prototypes
169 *---------------------------------------------------------------------------*/
170 static void __DEMOWin_add_node (DEMOWinInfo *handle);
171 static void __DEMOWin_delete_node (DEMOWinInfo *handle);
172 static void __DEMOWin_puts_n ( s16 x, s16 y, s16 z, u16 n, char* string );
173
174 static u16 __DEMOWinMenu_get_user_input (DEMOWinPadInfo *p);
175 static void __DEMOWinMenu_refesh_menu (DEMOWinInfo *w);
176 static void __DEMOWinList_refresh_list (DEMOWinInfo *w);
177
178 static void *__DEMOWin_alloc (u32 size);
179 static void __DEMOWin_free (void *ptr);
180
181 /*---------------------------------------------------------------------------*
182 * Name :
183 * Description :
184 * Arguments : None.
185 * Returns : None.
186 *---------------------------------------------------------------------------*/
__DEMOWin_alloc(u32 size)187 static void *__DEMOWin_alloc(u32 size)
188 {
189
190 void *ptr;
191
192 if (__DEMOWin_use_memlib)
193 {
194 ptr = MEMAllocFromAllocator(__DEMOWin_memallocator_ptr, size);
195 }
196 else
197 {
198 ptr = OSAlloc(size);
199 }
200
201 return(ptr);
202
203 } // End __DEMOWin_alloc()
204
205
206 /*---------------------------------------------------------------------------*
207 * Name :
208 * Description :
209 * Arguments : None.
210 * Returns : None.
211 *---------------------------------------------------------------------------*/
__DEMOWin_free(void * ptr)212 static void __DEMOWin_free(void *ptr)
213 {
214
215 if (__DEMOWin_use_memlib)
216 {
217 MEMFreeToAllocator(__DEMOWin_memallocator_ptr, ptr);
218 }
219 else
220 {
221 OSFree(ptr);
222 }
223
224 } // End __DEMOWin_free()
225
226 /*---------------------------------------------------------------------------*
227 * Name : DEMOWinInit()
228 *
229 * Description :
230 *
231 * Arguments : None.
232 *
233 * Returns : None.
234 *
235 *---------------------------------------------------------------------------*/
DEMOWinInit_Real(BOOL mem_lib_flag,BOOL mem2_flag)236 void DEMOWinInit_Real(BOOL mem_lib_flag, BOOL mem2_flag)
237 {
238
239 __DEMOWin_use_memlib = mem_lib_flag;
240 __DEMOWin_use_mem2 = mem2_flag;
241
242 if (__DEMOWin_use_memlib)
243 {
244 if (__DEMOWin_use_mem2)
245 {
246 __DEMOWin_memallocator_ptr = &DemoAllocator2;
247 }
248 else
249 {
250 __DEMOWin_memallocator_ptr = &DemoAllocator1;
251 }
252 }
253
254 // Initialize window list
255 __first_node = NULL;
256 __last_node = NULL;
257 __curr_node = NULL;
258
259 __rmp = DEMOGetRenderModeObj();
260
261 GXSetCopyClear( (GXColor){ 0x00, 0x00, 0x00, 0x00 }, GX_MAX_Z24 );
262
263 } // End winInit()
264
265 /*---------------------------------------------------------------------------*
266 * Name : DEMOWinCreateWindow()
267 *
268 * Description :
269 *
270 * Arguments : None.
271 *
272 * Returns : None.
273 *
274 *---------------------------------------------------------------------------*/
DEMOWinCreateWindow(s32 x1,s32 y1,s32 x2,s32 y2,char * caption,u16 scroll,void * func)275 DEMOWinInfo *DEMOWinCreateWindow(s32 x1, s32 y1, s32 x2, s32 y2, char *caption, u16 scroll, void *func)
276 {
277
278 DEMOWinInfo *handle;
279
280 ASSERTMSG((x1 < x2), "DEMOWIN: Illegal X coords for window\n");
281 ASSERTMSG((y1 < y2), "DEMOWIN: Illegal y coords for window\n");
282
283 // Allocate window structure
284 handle = (DEMOWinInfo *)__DEMOWin_alloc(sizeof(DEMOWinInfo));
285 ASSERTMSG(handle, "DEMOWIN: FAILED TO ALLOCATE WINDOW!\n");
286
287 handle->x1 = x1;
288 handle->y1 = y1;
289 handle->x2 = x2;
290 handle->y2 = y2;
291
292 handle->pixel_width = (u16)(x2 - x1 + 1);
293 handle->pixel_height = (u16)(y2 - y1 + 1);
294
295 handle->caption = caption;
296
297 handle->char_width = (u16)(((handle->pixel_width)/FONT_CHAR_WIDTH)-1); // Save a column for padding
298 handle->char_height = (u16)(((handle->pixel_height)/FONT_CHAR_HEIGHT)-2); // Save first line for caption, extra line for padding
299
300 handle->x_cal = (u16)((handle->pixel_width - (handle->char_width * FONT_CHAR_WIDTH) + 1) / 2);
301 handle->y_cal = (u16)(((handle->pixel_height - FONT_CHAR_HEIGHT) - (handle->char_height * FONT_CHAR_HEIGHT) + 1) / 2);
302
303 #ifdef DEMOWIN_DEBUG
304
305 OSReport("\n");
306 OSReport("======================================\n");
307 OSReport("WINDOW: '%s'\n", caption);
308 OSReport("======================================\n");
309 OSReport("x1: %4d\n", handle->x1);
310 OSReport("y1: %4d\n", handle->y1);
311 OSReport("x2: %4d\n", handle->x2);
312 OSReport("y2: %4d\n", handle->y2);
313 OSReport("pixel_width : %4d\n", handle->pixel_width);
314 OSReport("pixel_height: %4d\n", handle->pixel_height);
315 OSReport("char_width : %4d\n", handle->char_width);
316 OSReport("char_height : %4d\n", handle->char_height);
317 OSReport("x_cal : %4d\n", handle->x_cal);
318 OSReport("y_cal : %4d\n", handle->y_cal);
319
320 #endif
321
322 handle->num_scroll_lines = scroll;
323
324 handle->total_lines = (u16)(handle->char_height + handle->num_scroll_lines);
325
326 handle->curr_output_line = 0;
327 handle->curr_output_col = 0;
328 handle->curr_view_line = 0;
329
330 // User refresh function
331 handle->refresh = func;
332
333 // Clear flags
334 handle->flags = 0;
335
336 // Set priority
337 handle->priority = DEMOWIN_PRIORITY_FORE;
338
339
340 handle->buffer = (u8 *)__DEMOWin_alloc(sizeof(u8) * handle->total_lines * handle->char_width);
341 ASSERTMSG(handle->buffer, "DEMOWinCreateWindow(): Unable to allocation buffer!\n");
342
343 memset((void *)(handle->buffer), 0x20, sizeof(u8) * handle->total_lines * handle->char_width);
344
345
346 DEMOWinSetWindowColor(handle, DEMOWIN_COLOR_RESET, 0, 0, 0, 0);
347
348 // Turn off cursor;
349 handle->cursor_line = -1;
350
351 // Initialize parent to NULL
352 handle->parent = NULL;
353
354
355 // Do this last!
356 __DEMOWin_add_node(handle);
357
358 return(handle);
359
360
361 } // End DEMOWinCreateWindow()
362
363
364
365 /*---------------------------------------------------------------------------*
366 * Name : DEMOWinDestroyWindow()
367 *
368 * Description :
369 *
370 * Arguments : None.
371 *
372 * Returns : None.
373 *
374 *---------------------------------------------------------------------------*/
DEMOWinDestroyWindow(DEMOWinInfo * handle)375 void DEMOWinDestroyWindow(DEMOWinInfo *handle)
376 {
377 BOOL old;
378
379 ASSERTMSG(handle, "DEMOWinDestroyWindow(): NULL handle!\n");
380
381
382 old = OSDisableInterrupts();
383
384 __DEMOWin_delete_node(handle);
385
386 /*
387 for (i=0; i < handle->total_lines; i++)
388 {
389 __DEMOWin_free(handle->buffer[i]);
390 }
391 */
392 __DEMOWin_free(handle->buffer);
393
394 __DEMOWin_free(handle);
395
396 OSRestoreInterrupts(old);
397
398 } // End DEMOWinDestroyWindow()
399
400 /*---------------------------------------------------------------------------*
401 * Name : DEMOWinOpenWindow()
402 *
403 * Description :
404 *
405 * Arguments : None.
406 *
407 * Returns : None.
408 *
409 *---------------------------------------------------------------------------*/
DEMOWinOpenWindow(DEMOWinInfo * handle)410 void DEMOWinOpenWindow(DEMOWinInfo *handle)
411 {
412
413 ASSERTMSG(handle, "DEMOWinOpenWindow(): NULL handle!\n");
414 handle->flags |= DEMOWIN_FLAG_VISIBLE;
415 }
416
417 /*---------------------------------------------------------------------------*
418 * Name : DEMOWinCloseWindow()
419 *
420 * Description :
421 *
422 * Arguments : None.
423 *
424 * Returns : None.
425 *
426 *---------------------------------------------------------------------------*/
DEMOWinCloseWindow(DEMOWinInfo * handle)427 void DEMOWinCloseWindow(DEMOWinInfo *handle)
428 {
429 ASSERTMSG(handle, "DEMOWinCloseWindow(): NULL handle!\n");
430 handle->flags &= ~DEMOWIN_FLAG_VISIBLE;
431 }
432
433
434 /*---------------------------------------------------------------------------*
435 * Name : DEMOWinSetWindowColor()
436 *
437 * Description :
438 *
439 * Arguments : None.
440 *
441 * Returns : None.
442 *
443 *---------------------------------------------------------------------------*/
DEMOWinSetWindowColor(DEMOWinInfo * handle,u32 item,u8 r,u8 g,u8 b,u8 a)444 void DEMOWinSetWindowColor(DEMOWinInfo *handle, u32 item, u8 r, u8 g, u8 b, u8 a)
445 {
446
447 ASSERTMSG(handle, "DEMOWinSetWinColor(): NULL window handle\n");
448
449 switch (item)
450 {
451 case DEMOWIN_COLOR_CAPTION:
452 handle->cap.r = r;
453 handle->cap.g = g;
454 handle->cap.b = b;
455 handle->cap.a = a;
456 break;
457
458 case DEMOWIN_COLOR_BORDER:
459 handle->border.r = r;
460 handle->border.g = g;
461 handle->border.b = b;
462 handle->border.a = a;
463 break;
464
465 case DEMOWIN_COLOR_BKGND:
466 handle->bkgnd.r = r;
467 handle->bkgnd.g = g;
468 handle->bkgnd.b = b;
469 handle->bkgnd.a = a;
470 break;
471
472 case DEMOWIN_COLOR_RESET:
473 handle->bkgnd.r = __DEF_BKGND_R;
474 handle->bkgnd.g = __DEF_BKGND_G;
475 handle->bkgnd.b = __DEF_BKGND_B;
476 handle->bkgnd.a = __DEF_BKGND_A;
477
478 handle->cap.r = __DEF_CAP_R;
479 handle->cap.g = __DEF_CAP_G;
480 handle->cap.b = __DEF_CAP_B;
481 handle->cap.a = __DEF_CAP_A;
482
483 handle->border.r = __DEF_BORDER_R;
484 handle->border.g = __DEF_BORDER_G;
485 handle->border.b = __DEF_BORDER_B;
486 handle->border.a = __DEF_BORDER_A;
487 break;
488
489 default:
490 ASSERTMSG(0, "DEMOWinSetWinColor(): Unknown item\n");
491 break;
492 } // End switch
493
494 } // DEMOWinSetWinColor()
495
496
497 /*---------------------------------------------------------------------------*
498 * Name : DEMOWinLogPrintf()
499 *
500 * Description :
501 *
502 * Arguments : None.
503 *
504 * Returns : None.
505 *
506 *---------------------------------------------------------------------------*/
DEMOWinLogPrintf(DEMOWinInfo * handle,char * fmt,...)507 void DEMOWinLogPrintf(DEMOWinInfo *handle, char *fmt, ...)
508 {
509 va_list vlist;
510 char buffer[DEMOWIN_MAX_STRING_SIZE];
511 u16 len;
512 u16 i;
513 BOOL old;
514
515 u16 index = 0;
516
517 // get output string
518 va_start(vlist, fmt);
519 vsprintf(buffer, fmt, vlist);
520 va_end(vlist);
521
522
523 old = OSDisableInterrupts();
524
525
526 len = (u16)strlen(buffer);
527
528 for (i=0; i<len; i++)
529 {
530
531 if (buffer[i] == '\n')
532 {
533 // Advance current output line and view line
534 handle->curr_output_line = (u16)((handle->curr_output_line + 1) % handle->total_lines);
535 handle->curr_view_line = (u16)((handle->curr_view_line + 1) % handle->total_lines);
536 handle->curr_output_col = 0;
537
538 // Clobber new output line
539 index = (u16)(handle->curr_output_line * handle->char_width + handle->curr_output_col);
540 memset((void *)(&handle->buffer[index]), 0x20, sizeof(u8) * handle->char_width);
541
542 }
543 else
544 {
545 index = (u16)(handle->curr_output_line * handle->char_width + handle->curr_output_col);
546 handle->buffer[index] = (u8)buffer[i];
547 handle->curr_output_col++;
548 }
549
550 if (handle->curr_output_col >= handle->char_width)
551 {
552 handle->curr_output_col = 0;
553 handle->curr_output_line = (u16)((handle->curr_output_line + 1) % handle->total_lines);
554 handle->curr_view_line = (u16)((handle->curr_view_line + 1) % handle->total_lines);
555
556 // Clobber new output line
557 index = (u16)(handle->curr_output_line * handle->char_width + handle->curr_output_col);
558 memset((void *)(&handle->buffer[index]), 0x20, sizeof(u8) * handle->char_width);
559
560 }
561 }
562
563 OSRestoreInterrupts(old);
564
565 } // End DEMOWinLogPrintf()
566
567 /*---------------------------------------------------------------------------*
568 * Name : DEMOWinPrintfXY()
569 *
570 * Description :
571 *
572 * Arguments : None.
573 *
574 * Returns : None.
575 *
576 *---------------------------------------------------------------------------*/
DEMOWinPrintfXY(DEMOWinInfo * handle,u16 col,u16 row,char * fmt,...)577 void DEMOWinPrintfXY(DEMOWinInfo *handle, u16 col, u16 row, char *fmt, ...)
578 {
579
580 BOOL old;
581
582 va_list vlist;
583 char string[DEMOWIN_MAX_STRING_SIZE];
584
585 u16 buffer_row; // Map window row-coord to buffer space
586 u16 i;
587 u16 index;
588
589
590 // If row/col coords are outside of the window, then don't bother
591 if ((row >= handle->char_height) || (col >= handle->char_width))
592 {
593 return;
594 }
595
596 old = OSDisableInterrupts();
597
598 // get output string
599 va_start(vlist, fmt);
600 vsprintf(string, fmt, vlist);
601 va_end(vlist);
602
603 // Find top line of window in buffer
604 buffer_row = (u16)( ((handle->curr_view_line + handle->total_lines) - (handle->char_height-1)) % handle->total_lines);
605
606 // Now descend through buffer until we get the desired row
607 buffer_row = (u16)((buffer_row + row) % handle->total_lines);
608 // Truncate string to right screen edge
609 string[handle->char_width - col] = 0;
610
611 index = (u16)(buffer_row * handle->char_width + col);
612
613 for (i=0; i<strlen(string); i++)
614 {
615 handle->buffer[index+i] = (u8)string[i];
616 }
617
618 OSRestoreInterrupts(old);
619
620
621 } // End DEMOWinLogPrintf()
622
623 /*---------------------------------------------------------------------------*
624 * Name : DEMOWinScroll()
625 *
626 * Description : Scrolls ONE line up or down.
627 *
628 * Arguments : None.
629 *
630 * Returns : None.
631 *
632 *---------------------------------------------------------------------------*/
DEMOWinScrollWindow(DEMOWinInfo * handle,u32 dir)633 void DEMOWinScrollWindow(DEMOWinInfo *handle, u32 dir)
634 {
635
636 BOOL old;
637
638 u16 n;
639 u16 v_start;
640
641
642 ASSERTMSG(handle, "DEMOWinScrollWindow(): NULL handle!\n");
643 ASSERTMSG(handle->num_scroll_lines, "DEMOWinScrollWindow(): No scrollback buffer!\n");
644
645
646 switch(dir)
647 {
648 case DEMOWIN_SCROLL_UP:
649 old = OSDisableInterrupts();
650
651 n = (u16)(((handle->curr_view_line + handle->total_lines) - 1) % handle->total_lines);
652
653 v_start = (u16)(((n + handle->total_lines) - handle->char_height+1) % handle->total_lines);
654
655 if (v_start != handle->curr_output_line)
656 {
657 handle->curr_view_line = n;
658 }
659 OSRestoreInterrupts(old);
660 break;
661
662 case DEMOWIN_SCROLL_DOWN:
663 old = OSDisableInterrupts();
664 if (handle->curr_view_line != handle->curr_output_line)
665 {
666 handle->curr_view_line = (u16)((handle->curr_view_line + 1) % handle->total_lines);
667 }
668 OSRestoreInterrupts(old);
669 break;
670
671 case DEMOWIN_SCROLL_HOME:
672 old = OSDisableInterrupts();
673 handle->curr_view_line = handle->curr_output_line;
674 OSRestoreInterrupts(old);
675 break;
676
677 default:
678 ASSERTMSG(0, "DEMOWinScrollWindow(): Unknown token\n");
679 break;
680
681 } // End switch
682
683
684 } // End DEMOWinScrollWindow
685
686
687 /*---------------------------------------------------------------------------*
688 * Name : DEMOWinBringToFront()
689 *
690 * Description :
691 *
692 * Arguments : None.
693 *
694 * Returns : None.
695 *
696 *---------------------------------------------------------------------------*/
DEMOWinBringToFront(DEMOWinInfo * handle)697 void DEMOWinBringToFront(DEMOWinInfo *handle)
698 {
699 DEMOWinInfo *ptr;
700
701 ASSERTMSG(__first_node, "DEMOWinBringToFront(): Window list is empty!\n");
702 ASSERTMSG(handle, "DEMOWinBringToFront(): NULL handle!\n");
703
704 if (DEMOWIN_PRIORITY_FORE == handle->priority)
705 {
706 return;
707 }
708
709 // Send everyone else to the background
710 ptr = __first_node;
711 while (ptr)
712 {
713 ptr->priority = DEMOWIN_PRIORITY_BACK;
714 ptr = ptr->next;
715 }
716
717 // Bring our window to the front
718 handle->priority = DEMOWIN_PRIORITY_FORE;
719
720
721
722 } // End DEMOWinBringToFront()
723
724 /*---------------------------------------------------------------------------*
725 * Name : DEMOWinSendToBack()
726 *
727 * Description :
728 *
729 * Arguments : None.
730 *
731 * Returns : None.
732 *
733 *---------------------------------------------------------------------------*/
DEMOWinSendToBack(DEMOWinInfo * handle)734 void DEMOWinSendToBack(DEMOWinInfo *handle)
735 {
736
737 ASSERTMSG(handle, "DEMOWinSendToBack(): NULL handle!\n");
738 handle->priority = DEMOWIN_PRIORITY_BACK;
739
740 } // End DEMOWinSendToBack()
741
742
743 /*---------------------------------------------------------------------------*
744 * Name : DEMOWinClearRow()
745 *
746 * Description :
747 *
748 * Arguments : None.
749 *
750 * Returns : None.
751 *
752 *---------------------------------------------------------------------------*/
DEMOWinClearRow(DEMOWinInfo * handle,u16 row)753 void DEMOWinClearRow(DEMOWinInfo *handle, u16 row)
754 {
755
756 u16 buffer_row;
757 u16 index;
758 u16 i;
759 BOOL old;
760
761 ASSERTMSG(handle, "DEMOWinClearRow(): NULL handle!\n");
762
763
764 // Bail if the row is outside the window
765 if (row >= handle->char_height)
766 {
767 return;
768 }
769
770 old = OSDisableInterrupts();
771
772 // Find top line of window in buffer
773 buffer_row = (u16)( ((handle->curr_view_line + handle->total_lines) - (handle->char_height-1)) % handle->total_lines);
774
775 // Now descend through buffer until we get the desired row
776 buffer_row = (u16)((buffer_row + row) % handle->total_lines);
777
778 index = (u16)(buffer_row * handle->char_width);
779
780 for (i=0; i<handle->char_width; i++)
781 {
782 handle->buffer[index+i] = 0x20;
783 }
784
785 OSRestoreInterrupts(old);
786
787
788
789
790 } // End DEMOWinClearRow()
791
792 /*---------------------------------------------------------------------------*
793 * Name : DEMOWinClearWindow()
794 *
795 * Description :
796 *
797 * Arguments : None.
798 *
799 * Returns : None.
800 *
801 *---------------------------------------------------------------------------*/
DEMOWinClearWindow(DEMOWinInfo * handle)802 void DEMOWinClearWindow(DEMOWinInfo *handle)
803 {
804
805 u16 buffer_row;
806 u16 index;
807 u16 i;
808 BOOL old;
809
810 ASSERTMSG(handle, "DEMOWinClearWindow(): NULL handle!\n");
811
812
813 old = OSDisableInterrupts();
814
815 // Find top line of window in buffer
816 buffer_row = (u16)( ((handle->curr_view_line + handle->total_lines) - (handle->char_height-1)) % handle->total_lines);
817
818 for (i=0; i<handle->char_height; i++)
819 {
820 index = (u16)(buffer_row * handle->char_width);
821 memset((void *)(&handle->buffer[index]), 0x20, sizeof(u8) * handle->char_width);
822 buffer_row = (u16)((buffer_row + 1) % handle->total_lines);
823 }
824
825 OSRestoreInterrupts(old);
826
827 } // End DEMOWinClearWindow()
828
829
830 /*---------------------------------------------------------------------------*
831 * Name : DEMOWinClearBuffer()
832 *
833 * Description :
834 *
835 * Arguments : None.
836 *
837 * Returns : None.
838 *
839 *---------------------------------------------------------------------------*/
DEMOWinClearBuffer(DEMOWinInfo * handle)840 void DEMOWinClearBuffer(DEMOWinInfo *handle)
841 {
842 BOOL old;
843
844 ASSERTMSG(handle, "DEMOWinClearBuffer(): NULL handle!\n");
845
846 old = OSDisableInterrupts();
847
848 memset(handle->buffer, 0x20, sizeof(u8) * handle->total_lines * handle->char_width);
849
850
851 OSRestoreInterrupts(old);
852
853 } // End DEMOWinClearBuffer()
854
855
856
857
858
859
860
861 /*---------------------------------------------------------------------------*
862 * Name : DEMOWinRefresh()
863 *
864 * Description :
865 *
866 * Arguments : None.
867 *
868 * Returns : None.
869 *
870 *---------------------------------------------------------------------------*/
DEMOWinRefresh(void)871 void DEMOWinRefresh(void)
872 {
873
874 DEMOWinInfo *ptr;
875
876 u16 i;
877 u16 index;
878 u16 n;
879
880 u16 y;
881
882 BOOL old;
883
884 ASSERTMSG(__first_node, "DEMOWinRefresh(): Windowlist is empty!\n");
885
886 ptr = __first_node;
887
888 while(ptr)
889 {
890
891
892 if (ptr->flags & DEMOWIN_FLAG_VISIBLE)
893 {
894
895 // ------------------------------------------------------------
896 // DRAW WINDOWS FIRST - they are drawn without alpha/blending
897 // ------------------------------------------------------------
898
899 // Windows
900 GXSetZMode( GX_ENABLE, GX_LEQUAL, GX_ENABLE );
901 GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR);
902
903 // Set vertex descriptor
904 GXClearVtxDesc();
905 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
906 GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
907
908 // Position has 3 elements (x,y,z), each of a float type
909 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
910 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
911
912 // Disable lighting
913 GXSetNumChans(1);
914 GXSetChanCtrl( GX_COLOR0A0, GX_DISABLE, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE );
915
916 // One tevstage that passes color
917 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
918 GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
919 GXSetNumTexGens(0);
920 GXSetNumTevStages(1);
921
922 GXSetLineWidth( 6, GX_TO_ZERO );
923
924 // Window background
925 GXBegin(GX_QUADS, GX_VTXFMT0, 4);
926 GXPosition3f32(ptr->x1, ptr->y1, (f32)(ptr->priority));
927 GXColor4u8( ptr->bkgnd.r, ptr->bkgnd.g, ptr->bkgnd.b, ptr->bkgnd.a );
928
929 GXPosition3f32(ptr->x2, ptr->y1, (f32)(ptr->priority));
930 GXColor4u8( ptr->bkgnd.r, ptr->bkgnd.g, ptr->bkgnd.b, ptr->bkgnd.a );
931
932 GXPosition3f32(ptr->x2, ptr->y2, (f32)(ptr->priority));
933 GXColor4u8( ptr->bkgnd.r, ptr->bkgnd.g, ptr->bkgnd.b, ptr->bkgnd.a );
934
935 GXPosition3f32(ptr->x1, ptr->y2, (f32)(ptr->priority));
936 GXColor4u8( ptr->bkgnd.r, ptr->bkgnd.g, ptr->bkgnd.b, ptr->bkgnd.a );
937 GXEnd();
938
939
940 // Caption
941 GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR);
942 GXBegin(GX_QUADS, GX_VTXFMT0, 4);
943 GXPosition3f32(ptr->x1, ptr->y1, (f32)(ptr->priority));
944 GXColor4u8( ptr->cap.r, ptr->cap.g, ptr->cap.b, 0xff );
945
946 GXPosition3f32(ptr->x2, ptr->y1, (f32)(ptr->priority));
947 GXColor4u8( 0, 0, 0, 64 );
948
949 GXPosition3f32(ptr->x2, ptr->y1+FONT_CHAR_HEIGHT+2, (f32)(ptr->priority));
950 GXColor4u8( 0, 0, 0, 64 );
951
952 GXPosition3f32(ptr->x1, ptr->y1+FONT_CHAR_HEIGHT+2, (f32)(ptr->priority));
953 GXColor4u8( ptr->cap.r, ptr->cap.g, ptr->cap.b, 0xff );
954 GXEnd();
955
956 // Border
957 GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR);
958 {
959 u8 r1,g1,b1;
960 u8 r2,g2,b2;
961 u8 a;
962
963 r1 = (u8)((f32)(ptr->border.r)*1.3);
964 g1 = (u8)((f32)(ptr->border.g)*1.3);
965 b1 = (u8)((f32)(ptr->border.b)*1.3);
966
967 r2 = (u8)((f32)(ptr->border.r)*0.40);
968 g2 = (u8)((f32)(ptr->border.g)*0.40);
969 b2 = (u8)((f32)(ptr->border.b)*0.40);
970
971 a = 0x40;
972
973 GXSetLineWidth( 6, GX_TO_ZERO );
974 GXBegin(GX_LINESTRIP, GX_VTXFMT0, 7);
975 GXPosition3f32(ptr->x1, ptr->y1, (f32)(ptr->priority));
976 GXColor4u8(r1, g1, b1, a);
977
978 GXPosition3f32(ptr->x2, ptr->y1, (f32)(ptr->priority));
979 GXColor4u8(r1, g1, b1, a);
980
981 GXPosition3f32(ptr->x2, ptr->y1, (f32)(ptr->priority));
982 GXColor4u8(r2, g2, b2, a);
983
984 GXPosition3f32(ptr->x2, ptr->y2, (f32)(ptr->priority));
985 GXColor4u8(r2, g2, b2, a);
986
987 GXPosition3f32(ptr->x1, ptr->y2, (f32)(ptr->priority));
988 GXColor4u8(r2, g2, b2, a);
989
990 GXPosition3f32(ptr->x1, ptr->y2, (f32)(ptr->priority));
991 GXColor4u8(r1, g1, b1, a);
992
993 GXPosition3f32(ptr->x1, ptr->y1, (f32)(ptr->priority));
994 GXColor4u8(r1, g1, b1, a);
995 GXEnd();
996
997 }
998
999 // Invoke user refresh callback
1000 if (ptr->refresh)
1001 {
1002 // Invoke refresh callback
1003 // User refresh should be invoked before application of caption/title and cursor highlighting, if any
1004 (*(ptr->refresh))(ptr);
1005 }
1006
1007 // ------------------------------------------------------------
1008 // Now slap on the text
1009 // ------------------------------------------------------------
1010 DEMOInitCaption(DM_FT_XLU, __rmp->fbWidth, __rmp->efbHeight);
1011 GXSetZMode( GX_ENABLE, GX_LEQUAL, GX_ENABLE );
1012
1013 old = OSDisableInterrupts();
1014
1015 n = ptr->curr_view_line;
1016
1017 y = (u16)(ptr->y2 - FONT_CHAR_HEIGHT - ptr->y_cal);
1018 n = (u16)(ptr->curr_view_line);
1019 index = (u16)(n * ptr->char_width);
1020
1021 for (i=0; i<ptr->char_height; i++)
1022 {
1023
1024 __DEMOWin_puts_n((s16)(ptr->x1+ptr->x_cal), (s16)y, (s16)ptr->priority, ptr->char_width, (char *)(&ptr->buffer[index]));
1025
1026 y = (u16)(y - FONT_CHAR_HEIGHT); // Decrement y-coord
1027 n = (u16)((((n + ptr->total_lines) - 1) % ptr->total_lines)); // Decrement current view line
1028 index = (u16)(n * ptr->char_width); // Recalc index
1029 }
1030
1031 DEMOPrintf((s16)(ptr->x1+2), (s16)ptr->y1, (s16)ptr->priority, "%s", ptr->caption);
1032
1033 // ------------------------------------------------------------
1034 // Now add highlighting, if any
1035 // ------------------------------------------------------------
1036 if (ptr->cursor_line >= 0)
1037 {
1038
1039 GXSetLineWidth( 6, GX_TO_ZERO );
1040
1041 GXSetZMode( GX_ENABLE, GX_LEQUAL, GX_ENABLE );
1042 GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR);
1043
1044 // Set vertex descriptor
1045 GXClearVtxDesc();
1046 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
1047 GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
1048
1049 // Position has 3 elements (x,y,z), each of a float type
1050 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
1051 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
1052
1053 // Disable lighting
1054 GXSetNumChans(1);
1055 GXSetChanCtrl( GX_COLOR0A0, GX_DISABLE, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE );
1056
1057 // One tevstage that passes color
1058 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
1059 GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
1060 GXSetNumTexGens(0);
1061 GXSetNumTevStages(1);
1062
1063
1064 GXSetLineWidth( 6, GX_TO_ZERO );
1065 {
1066 u8 r;
1067 u8 g;
1068 u8 b;
1069 u8 a;
1070 s32 curr_y;
1071
1072
1073 curr_y = ptr->y2 - FONT_CHAR_HEIGHT - ptr->y_cal;
1074 curr_y = curr_y - ( ((ptr->char_height-1)*FONT_CHAR_HEIGHT) - ((ptr->cursor_line)*FONT_CHAR_HEIGHT));
1075
1076 r = (u8)((f32)(ptr->bkgnd.r) * 1.9);
1077 g = (u8)((f32)(ptr->bkgnd.g) * 1.9);
1078 b = (u8)((f32)(ptr->bkgnd.b) * 1.9);
1079 a = 0x64;
1080
1081 GXBegin(GX_QUADS, GX_VTXFMT0, 4);
1082 GXPosition3f32( (f32)(ptr->x1), (f32)(curr_y), (f32)(ptr->priority));
1083 GXColor4u8(r,g,b,a);
1084
1085 GXPosition3f32( (f32)(ptr->x2), (f32)(curr_y), (f32)(ptr->priority));
1086 GXColor4u8(r,g,b,a);
1087
1088 GXPosition3f32( (f32)(ptr->x2), (f32)(curr_y+FONT_CHAR_HEIGHT), (f32)(ptr->priority));
1089 GXColor4u8(r,g,b,a);
1090
1091 GXPosition3f32( (f32)(ptr->x1), (f32)(curr_y+FONT_CHAR_HEIGHT), (f32)(ptr->priority));
1092 GXColor4u8(r,g,b,a);
1093 GXEnd();
1094 }
1095 }
1096
1097 OSRestoreInterrupts(old);
1098
1099 } // If visible
1100
1101 ptr = ptr->next;
1102
1103 } // End while...
1104
1105
1106
1107 } // End DEMOWinRefresh()
1108
1109
1110
1111 /*---------------------------------------------------------------------------*
1112 * Name : __DEMOWinadd_node()
1113 *
1114 * Description :
1115 *
1116 * Arguments : None.
1117 *
1118 * Returns : None.
1119 *
1120 *---------------------------------------------------------------------------*/
__DEMOWin_add_node(DEMOWinInfo * handle)1121 static void __DEMOWin_add_node(DEMOWinInfo *handle)
1122 {
1123
1124 ASSERTMSG(handle, "__add_node(): you're adding a NULL node!\n");
1125
1126 if (NULL == __last_node)
1127 {
1128 // We're the first node!
1129 __first_node = __last_node = __curr_node = handle;
1130
1131 handle->next = NULL;
1132 handle->prev = NULL;
1133
1134 ASSERTMSG(__first_node, " > __first_node: NULL HANDLE!\n");
1135 }
1136 else
1137 {
1138
1139 __last_node->next = handle;
1140 handle->next = NULL;
1141 handle->prev = __last_node;
1142 __last_node = handle;
1143 }
1144
1145 handle->flags |= DEMOWIN_FLAG_ATTACHED;
1146
1147 } // add_node()
1148
1149
1150 /*---------------------------------------------------------------------------*
1151 * Name : __DEMOWin__delete_node()
1152 *
1153 * Description :
1154 *
1155 * Arguments : None.
1156 *
1157 * Returns : None.
1158 *
1159 *---------------------------------------------------------------------------*/
__DEMOWin_delete_node(DEMOWinInfo * handle)1160 static void __DEMOWin_delete_node(DEMOWinInfo *handle)
1161 {
1162
1163 ASSERTMSG(handle, "__delete_node(): you're deleting a NULL node!\n");
1164
1165
1166 // It's the first node
1167 if (__first_node == handle)
1168 {
1169 // Does a next node even exist?
1170 if (handle->next)
1171 {
1172 __first_node = (handle->next);
1173 (handle->next)->prev = NULL;
1174 }
1175 else
1176 {
1177 // Nope, it must have been the only node in the universe
1178 __first_node = __last_node = NULL;
1179 }
1180
1181 }
1182 else if (__last_node == handle)
1183 {
1184 // Does a previous node even exist?
1185 if (handle->prev)
1186 {
1187 // Yes
1188 __last_node = (handle->prev);
1189 (handle->prev)->next = NULL;
1190
1191 }
1192 else
1193 {
1194 // Nope, it was the only node in the universe
1195 __first_node = __last_node = NULL;
1196 }
1197
1198 }
1199 else
1200 {
1201 (handle->prev)->next = (handle->next);
1202 (handle->next)->prev = (handle->prev);
1203
1204 }
1205
1206 handle->flags = (handle->flags & (~DEMOWIN_FLAG_ATTACHED));
1207
1208
1209 } // add_node()
1210
1211
1212 /*---------------------------------------------------------------------------*
1213 * Name : __DEMOWin_puts_n()
1214 *
1215 * Description : Writes specified number of characters in string to screen
1216 *
1217 * Arguments :
1218 *
1219 * Returns :
1220 *
1221 *---------------------------------------------------------------------------*/
__DEMOWin_puts_n(s16 x,s16 y,s16 z,u16 n,char * string)1222 static void __DEMOWin_puts_n( s16 x, s16 y, s16 z, u16 n, char* string )
1223 {
1224 s32 s, t;
1225 s32 w, len, i;
1226
1227 // Set up vertex descriptors
1228 GXClearVtxDesc();
1229 GXSetVtxDesc( GX_VA_POS, GX_DIRECT );
1230 GXSetVtxDesc( GX_VA_TEX0, GX_DIRECT );
1231 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0 );
1232 GXSetVtxAttrFmt( GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 1 );
1233
1234 len = n;
1235
1236 if ( len > 0 )
1237 {
1238 // Put a line
1239 GXBegin( GX_QUADS, GX_VTXFMT0, (u16)(len*4) );
1240 for ( i = 0; i < len; i ++ )
1241 {
1242 // Draw a letter
1243 w = string[i] - ' ';
1244 s = ( w % 8 ) * 16 + fontShift;
1245 t = ( w / 8 ) * 16 + fontShift;
1246 GXPosition3s16( (s16)(i*8+x ), (s16)(y ), z );
1247 GXTexCoord2s16( (s16)(s ), (s16)(t ) );
1248 GXPosition3s16( (s16)(i*8+x+8), (s16)(y ), z );
1249 GXTexCoord2s16( (s16)(s+16 ), (s16)(t ) );
1250 GXPosition3s16( (s16)(i*8+x+8), (s16)(y+8 ), z );
1251 GXTexCoord2s16( (s16)(s+16 ), (s16)(t+16) );
1252 GXPosition3s16( (s16)(i*8+x ), (s16)(y+8 ), z );
1253 GXTexCoord2s16( (s16)(s ), (s16)(t+16) );
1254 }
1255 GXEnd( );
1256 }
1257
1258 } // End __DEMOWinPutsN()
1259
1260
1261 //****************************************************************************
1262 // Menu Stuff
1263 //****************************************************************************
1264
1265 /*---------------------------------------------------------------------------*
1266 * Name : DEMOWinCreateMenuWindow()
1267 *
1268 * Description : Obvious
1269 *
1270 * Arguments : None.
1271 *
1272 * Returns : None.
1273 *
1274 *---------------------------------------------------------------------------*/
1275
DEMOWinCreateMenuWindow(DEMOWinMenuInfo * menu,u16 x,u16 y)1276 DEMOWinMenuInfo *DEMOWinCreateMenuWindow(DEMOWinMenuInfo *menu, u16 x, u16 y)
1277 {
1278
1279 DEMOWinMenuItem *ptr;
1280
1281 // Calculate max name/title string length
1282 // Calculate number of items in list
1283 ptr = menu->items;
1284
1285 menu->max_str_len = strlen(menu->title);
1286 menu->num_items = 0;
1287
1288 while (!(ptr->flags & DEMOWIN_ITM_TERMINATOR))
1289 {
1290 if (strlen(ptr->name) > menu->max_str_len)
1291 {
1292 menu->max_str_len = strlen(ptr->name);
1293 }
1294 (menu->num_items)++;
1295 ptr++;
1296 }
1297
1298 // Calculate actual number of items to display
1299 // It may be less than the max number specified by the user
1300 if (menu->num_items > menu->max_display_items)
1301 {
1302 menu->num_display_items = menu->max_display_items;
1303 }
1304 else
1305 {
1306 menu->num_display_items = menu->num_items;
1307 }
1308
1309 // Open window.
1310 // Note: This call will ASSERT if it fails to allocate a window
1311 menu->handle = DEMOWinCreateWindow((s16)x,
1312 (s16)y,
1313 (s16)(x + DEMOWIN_CALC_MENU_WIDTH_PIXELS(menu->max_str_len)),
1314 (s16)(y + DEMOWIN_CALC_MENU_HEIGHT_PIXELS(menu->num_display_items)),
1315 menu->title,
1316 0, // No scrollback lines! Menu function handles list scrolling
1317 __DEMOWinMenu_refesh_menu);
1318
1319
1320 // Parent of this window is the "menu" structure
1321 (menu->handle)->parent = menu;
1322
1323
1324
1325 if (menu->num_items)
1326 {
1327 return(menu);
1328 }
1329
1330 return(NULL);
1331
1332
1333 } // End DEMOWinCreateMenuWindow()
1334
1335
1336 /*---------------------------------------------------------------------------*
1337 * Name : DEMOWinDestroyMenuWindow()
1338 *
1339 * Description : Obvious
1340 *
1341 * Arguments : None.
1342 *
1343 * Returns : None.
1344 *
1345 *---------------------------------------------------------------------------*/
1346
DEMOWinDestroyMenuWindow(DEMOWinMenuInfo * menu)1347 void DEMOWinDestroyMenuWindow(DEMOWinMenuInfo *menu)
1348 {
1349
1350 if (menu->handle)
1351 {
1352 DEMOWinCloseWindow(menu->handle);
1353 DEMOWinDestroyWindow(menu->handle);
1354
1355 menu->handle = NULL;
1356 }
1357
1358 } // End DEMOWinDestroyMenuWindow()
1359
1360 /*---------------------------------------------------------------------------*
1361 * Name : DEMOWinMenuChild()
1362 *
1363 * Description : Obvious
1364 *
1365 * Arguments : None.
1366 *
1367 * Returns : None.
1368 *
1369 *---------------------------------------------------------------------------*/
1370
DEMOWinMenuChild(DEMOWinMenuInfo * menu,BOOL child_flag)1371 u32 DEMOWinMenuChild(DEMOWinMenuInfo *menu, BOOL child_flag)
1372 {
1373
1374 DEMOWinPadInfo *pad; // Pointer to pad data associated with this menu's window
1375 DEMOWinInfo *handle; // Pointer to window associated with this menu
1376
1377 u16 user_input; // User input from PAD
1378 BOOL exit_flag = FALSE;
1379 u32 result = 0;
1380
1381
1382
1383 // This is cheesy, but...
1384 handle = menu->handle;
1385 pad = &(menu->handle)->pad;
1386
1387
1388 // Display window, bring to foreground
1389 DEMOWinOpenWindow(handle);
1390 DEMOWinBringToFront(handle);
1391
1392
1393 // Initialize cursor and display-position state
1394 menu->curr_pos = 0;
1395 menu->display_pos = 0;
1396
1397 // Is there a callback for "open" event?
1398 if (menu->cb_open)
1399 {
1400 (*menu->cb_open)(menu, (u32)menu->curr_pos);
1401 }
1402
1403
1404 // Debounce
1405 DEMOWinPadInit(pad);
1406
1407 DEMOBeforeRender();
1408 DEMOWinRefresh();
1409 DEMODoneRender();
1410
1411 DEMOWinPadRead(pad);
1412
1413 DEMOBeforeRender();
1414 DEMOWinRefresh();
1415 DEMODoneRender();
1416
1417
1418 while(!exit_flag)
1419 {
1420
1421 user_input = __DEMOWinMenu_get_user_input(pad);
1422
1423 switch(user_input)
1424 {
1425 case DEMOWIN_MNU_UP:
1426
1427 menu->curr_pos = (u16)((menu->curr_pos - 1 + menu->num_items) % (menu->num_items));
1428 while( (menu->items[menu->curr_pos].flags & (DEMOWIN_ITM_DISABLED | DEMOWIN_ITM_SEPARATOR)) )
1429 {
1430 menu->curr_pos = (u16)((menu->curr_pos - 1 + menu->num_items) % (menu->num_items));
1431 }
1432 if (menu->cb_move)
1433 {
1434 (*(menu->cb_move))(menu, (u32)menu->curr_pos);
1435 }
1436
1437 break;
1438
1439 case DEMOWIN_MNU_DOWN:
1440 menu->curr_pos = (u16)((menu->curr_pos + 1) % (menu->num_items));
1441 while ((menu->items[menu->curr_pos].flags & (DEMOWIN_ITM_DISABLED | DEMOWIN_ITM_SEPARATOR)))
1442 {
1443 menu->curr_pos = (u16)((menu->curr_pos + 1) % (menu->num_items));
1444 }
1445 if (menu->cb_move)
1446 {
1447 (*(menu->cb_move))(menu, (u32)menu->curr_pos);
1448 }
1449
1450 break;
1451
1452 case DEMOWIN_MNU_LEFT:
1453 if (TRUE == child_flag)
1454 {
1455 // We are a child of another popup menu.
1456 exit_flag = TRUE;
1457 if (menu->cb_cancel)
1458 {
1459 (*(menu->cb_cancel))(menu, (u32)menu->curr_pos);
1460 }
1461
1462 }
1463 break;
1464
1465 case DEMOWIN_MNU_RIGHT:
1466 // Callback?
1467 if (menu->cb_move)
1468 {
1469 (*(menu->cb_move))(menu, (u32)menu->curr_pos);
1470 }
1471
1472
1473 // Ugh. Now, is there a link?
1474 if (menu->items[menu->curr_pos].link)
1475 {
1476 // Yes, there's a link. Is there an associated window handle?
1477 if ((menu->items[menu->curr_pos].link)->handle)
1478 {
1479 // Yup! So replace the window coordinates...
1480 ((menu->items[menu->curr_pos].link)->handle)->x1 = (u16)(handle->x1 + 20);
1481 ((menu->items[menu->curr_pos].link)->handle)->y1 = (u16)(handle->y1 + 20);
1482
1483 // ...and invoke the menu
1484 result = DEMOWinMenuChild(menu->items[menu->curr_pos].link, TRUE);
1485 if ((menu->items[menu->curr_pos].link)->flags & DEMOWIN_MNU_EOM)
1486 {
1487 exit_flag=TRUE;
1488 }
1489
1490 }
1491 else
1492 {
1493 // Nope. No window handle. So...create one!
1494 DEMOWinCreateMenuWindow(menu->items[menu->curr_pos].link, (u16)(handle->x1+20), (u16)(handle->y1+20));
1495 result = DEMOWinMenuChild(menu->items[menu->curr_pos].link, TRUE);
1496 if ((menu->items[menu->curr_pos].link)->flags & DEMOWIN_MNU_EOM)
1497 {
1498 exit_flag=TRUE;
1499 }
1500 DEMOWinDestroyMenuWindow(menu->items[menu->curr_pos].link);
1501
1502 }
1503 VIWaitForRetrace();
1504 DEMOWinPadRead(pad);
1505
1506 }
1507
1508 break;
1509
1510 case DEMOWIN_MNU_SELECT:
1511 if (menu->cb_select)
1512 {
1513 (*(menu->cb_select))(menu, (u32)menu->curr_pos);
1514 }
1515
1516 if (menu->items[menu->curr_pos].link)
1517 {
1518 // Yes, there's a link. Is there an associated window handle?
1519 if ((menu->items[menu->curr_pos].link)->handle)
1520 {
1521 // Yup! So replace the window coordinates...
1522 ((menu->items[menu->curr_pos].link)->handle)->x1 = (u16)(handle->x1 + 20);
1523 ((menu->items[menu->curr_pos].link)->handle)->y1 = (u16)(handle->y1 + 20);
1524
1525 // ...and invoke the menu
1526 result = DEMOWinMenuChild(menu->items[menu->curr_pos].link, TRUE);
1527 if ((menu->items[menu->curr_pos].link)->flags & DEMOWIN_MNU_EOM)
1528 {
1529 exit_flag=TRUE;
1530 }
1531
1532 }
1533 else
1534 {
1535 // Nope. No window handle. So...create one!
1536 DEMOWinCreateMenuWindow(menu->items[menu->curr_pos].link, (u16)(handle->x1+20), (u16)(handle->y1+20));
1537
1538 // ...and invoke the menu
1539 result = DEMOWinMenuChild(menu->items[menu->curr_pos].link, TRUE);
1540
1541
1542 // Now...should we kill the parent on this link?
1543 if ((menu->items[menu->curr_pos].link)->flags & DEMOWIN_MNU_EOM)
1544 {
1545 exit_flag=TRUE;
1546 }
1547 DEMOWinDestroyMenuWindow(menu->items[menu->curr_pos].link);
1548
1549
1550
1551 }
1552 VIWaitForRetrace();
1553 DEMOWinPadRead(pad);
1554
1555 }
1556 else
1557 {
1558 if (menu->items[menu->curr_pos].function)
1559 {
1560 (menu->items[menu->curr_pos].function)(menu, (u32)menu->curr_pos, &result);
1561 if (menu->items[menu->curr_pos].flags & DEMOWIN_ITM_EOF)
1562 {
1563 exit_flag = TRUE;
1564 }
1565 VIWaitForRetrace();
1566 DEMOWinPadRead(pad);
1567
1568 }
1569
1570 }
1571 break;
1572
1573 case DEMOWIN_MNU_CANCEL:
1574 if (menu->cb_cancel)
1575 {
1576 (*(menu->cb_cancel))(menu, (u32)menu->curr_pos);
1577 }
1578 exit_flag = TRUE;
1579 break;
1580
1581 }// End switch(parse_input)
1582
1583
1584 // Fix display pointer
1585 if (menu->curr_pos > (menu->display_pos+menu->num_display_items-1))
1586 {
1587 menu->display_pos = menu->curr_pos - menu->num_display_items + 1;
1588
1589 }
1590 else if (menu->curr_pos < menu->display_pos)
1591 {
1592 menu->display_pos = menu->curr_pos;
1593 }
1594
1595 // Calculate cursor position
1596 if (menu->display_pos > menu->curr_pos)
1597 {
1598 handle->cursor_line = (s16)(menu->display_pos - menu->curr_pos);
1599 }
1600 else
1601 {
1602 handle->cursor_line = (s16)(menu->curr_pos - menu->display_pos);
1603 }
1604
1605
1606 DEMOBeforeRender();
1607 DEMOWinRefresh();
1608 DEMODoneRender();
1609
1610
1611 } // While exit
1612
1613
1614 DEMOWinCloseWindow(handle);
1615
1616 DEMOBeforeRender();
1617 DEMOWinRefresh();
1618 DEMODoneRender();
1619
1620
1621 return(result);
1622
1623
1624 } // End DEMOWinMenuChild()
1625
1626 /*---------------------------------------------------------------------------*
1627 * Name : __DEMOWinMenu_display_menu()
1628 *
1629 * Description : Obvious
1630 *
1631 * Arguments : None.
1632 *
1633 * Returns : None.
1634 *
1635 *---------------------------------------------------------------------------*/
1636
__DEMOWinMenu_refesh_menu(DEMOWinInfo * w)1637 static void __DEMOWinMenu_refesh_menu(DEMOWinInfo *w)
1638 {
1639
1640 DEMOWinMenuInfo *m;
1641
1642 s32 i;
1643 s32 j;
1644 char check;
1645 char para_start;
1646 char para_end;
1647 char link;
1648
1649
1650 // Clear window contents
1651 DEMOWinClearWindow(w);
1652
1653 // Parent should be a Menu info structure
1654 m = (w->parent);
1655
1656 j = m->display_pos;
1657
1658 for (i=0; i<m->num_display_items; i++)
1659 {
1660 if (m->items[j].flags & DEMOWIN_ITM_SEPARATOR)
1661 {
1662
1663 if (strlen(m->items[(u16)j].name))
1664 {
1665 DEMOWinPrintfXY(w, 0, (u16)i, " %s ", m->items[(u16)j].name);
1666 }
1667
1668 }
1669 else
1670 {
1671
1672 check = (char)((m->items[j].flags & DEMOWIN_ITM_CHK_STATE) ? 'X' : ' ');
1673 para_start = (char)((m->items[j].flags & DEMOWIN_ITM_DISABLED) ? '(' : ' ');
1674 para_end = (char)((m->items[j].flags & DEMOWIN_ITM_DISABLED) ? ')' : ' ');
1675 link = (char)((NULL != m->items[j].link) ? '>' : ' ');
1676
1677 DEMOWinPrintfXY(w, 0, (u16)i, "%c %c%s%c %c", check, para_start, m->items[(u16)j].name, para_end, link);
1678 }
1679 j++;
1680 }
1681
1682
1683 } // End __DEMOWinMenu_display_menu()
1684
1685
1686 /*---------------------------------------------------------------------------*
1687 * Name : DEMOWinPadInit()
1688 *
1689 * Description : Obvious
1690 *
1691 * Arguments : None.
1692 *
1693 * Returns : None.
1694 *
1695 *---------------------------------------------------------------------------*/
1696
DEMOWinPadInit(DEMOWinPadInfo * p)1697 void DEMOWinPadInit(DEMOWinPadInfo *p)
1698 {
1699 u16 i;
1700
1701
1702 for (i=0; i<PAD_MAX_CONTROLLERS ;i++)
1703 {
1704 p->old_button[i] = 0;
1705 p->changed_button [i] = 0;
1706 p->repeat_button [i] = 0;
1707 p->repeat_ctr [i] = 0;
1708 }
1709 }
1710
1711 /*---------------------------------------------------------------------------*
1712 * Name : DEMOWinPadRead()
1713 *
1714 * Description : Obvious
1715 *
1716 * Arguments : None.
1717 *
1718 * Returns : None.
1719 *
1720 *---------------------------------------------------------------------------*/
DEMOWinPadRead(DEMOWinPadInfo * p)1721 void DEMOWinPadRead(DEMOWinPadInfo *p)
1722 {
1723
1724 PADStatus *pad;
1725
1726 u16 index;
1727
1728 u32 curr;
1729 u32 old;
1730
1731 u32 repeat;
1732
1733
1734 PADRead(p->pads);
1735
1736 for (index=0; index<PAD_MAX_CONTROLLERS; index++)
1737 {
1738
1739 old = p->old_button[index];
1740 pad = &(p->pads[index]);
1741
1742 curr = ( (pad->stickX > PAD_THRESHOLD)? DEMOWIN_STICK_R : 0 ) |
1743 ( (pad->stickX < -PAD_THRESHOLD)? DEMOWIN_STICK_L : 0 ) |
1744 ( (pad->stickY > PAD_THRESHOLD)? DEMOWIN_STICK_U : 0 ) |
1745 ( (pad->stickY < -PAD_THRESHOLD)? DEMOWIN_STICK_D : 0 ) |
1746 ( (pad->substickX > PAD_THRESHOLD)? DEMOWIN_SUBSTICK_R : 0 ) |
1747 ( (pad->substickX < -PAD_THRESHOLD)? DEMOWIN_SUBSTICK_L : 0 ) |
1748 ( (pad->substickY > PAD_THRESHOLD)? DEMOWIN_SUBSTICK_U : 0 ) |
1749 ( (pad->substickY < -PAD_THRESHOLD)? DEMOWIN_SUBSTICK_D : 0 ) |
1750 ( (pad->triggerLeft > TRIGGER_THRESHOLD)? DEMOWIN_TRIGGER_L : 0 ) |
1751 ( (pad->triggerRight > TRIGGER_THRESHOLD)? DEMOWIN_TRIGGER_R : 0 ) |
1752 (u32)pad->button;
1753
1754 p->changed_button[index] = (u32)((old ^ curr) & curr);
1755
1756 if (curr)
1757 {
1758 if (old == curr)
1759 {
1760 p->repeat_ctr[index]++;
1761 }
1762 else
1763 {
1764 p->repeat_ctr[index] = 1;
1765 }
1766 }
1767 else
1768 {
1769 p->repeat_ctr[index] = 0;
1770 }
1771
1772 repeat = p->repeat_ctr[index];
1773
1774 if (repeat == 1)
1775 {
1776 p->repeat_button[index] = curr;
1777 }
1778 else if (repeat > __DEMOWIN_PAD_repeat_threshold)
1779 {
1780 if ( ((repeat - __DEMOWIN_PAD_repeat_threshold) % __DEMOWIN_PAD_repeat_rate) == 0)
1781 {
1782 p->repeat_button[index] = curr;
1783 }
1784 else
1785 {
1786 p->repeat_button[index] = 0;
1787 }
1788 }
1789 else
1790 {
1791 p->repeat_button[index] = 0;
1792 }
1793 p->old_button[index] = curr;
1794 }
1795
1796 } // End DEMOWinPadRead()
1797
1798 /*---------------------------------------------------------------------------*
1799 * Name : __DEMOWinMenu_get_user_input()
1800 *
1801 * Description : Obvious
1802 *
1803 * Arguments : None.
1804 *
1805 * Returns : None.
1806 *
1807 *---------------------------------------------------------------------------*/
1808
__DEMOWinMenu_get_user_input(DEMOWinPadInfo * p)1809 static u16 __DEMOWinMenu_get_user_input(DEMOWinPadInfo *p)
1810 {
1811
1812 u16 user_input;
1813
1814 DEMOWinPadRead(p);
1815
1816 if (p->repeat_button[0] & (PAD_BUTTON_UP|DEMOWIN_STICK_U))
1817 {
1818 user_input = DEMOWIN_MNU_UP;
1819 }
1820 else if (p->repeat_button[0] & (PAD_BUTTON_DOWN|DEMOWIN_STICK_D))
1821 {
1822 user_input = DEMOWIN_MNU_DOWN;
1823 }
1824 else if (p->repeat_button[0] & (PAD_BUTTON_LEFT|DEMOWIN_STICK_L))
1825 {
1826 user_input = DEMOWIN_MNU_LEFT;
1827 }
1828 else if (p->repeat_button[0] & (PAD_BUTTON_RIGHT|DEMOWIN_STICK_R))
1829 {
1830 user_input = DEMOWIN_MNU_RIGHT;
1831 }
1832 else if (p->changed_button[0] & PAD_BUTTON_A) // No repeat!
1833 {
1834 user_input = DEMOWIN_MNU_SELECT;
1835 }
1836 else if (p->changed_button[0] & PAD_BUTTON_B) // No repeat!
1837 {
1838 user_input = DEMOWIN_MNU_CANCEL;
1839 }
1840 else
1841 {
1842 user_input = 0;
1843 }
1844
1845 /*
1846 if (PADButtonDown(*old_button, pads[0].button) & PAD_BUTTON_UP)
1847 {
1848 user_input = DEMOWIN_MNU_UP;
1849 }
1850 else if (PADButtonDown(*old_button, pads[0].button) & PAD_BUTTON_DOWN)
1851 {
1852 user_input = DEMOWIN_MNU_DOWN;
1853 }
1854 else if (PADButtonDown(*old_button, pads[0].button) & PAD_BUTTON_LEFT)
1855 {
1856 user_input = DEMOWIN_MNU_LEFT;
1857 }
1858 else if (PADButtonDown(*old_button, pads[0].button) & PAD_BUTTON_RIGHT)
1859 {
1860 user_input = DEMOWIN_MNU_RIGHT;
1861 }
1862 else if (PADButtonDown(*old_button, pads[0].button) & PAD_BUTTON_A)
1863 {
1864 user_input = DEMOWIN_MNU_SELECT;
1865 }
1866 else if (PADButtonDown(*old_button, pads[0].button) & PAD_BUTTON_B)
1867 {
1868 user_input = DEMOWIN_MNU_CANCEL;
1869 }
1870 else
1871 {
1872 user_input = 0;
1873 }
1874
1875 *old_button = pads[0].button;
1876 */
1877
1878 return(user_input);
1879
1880 } // End __DEMOWinMenu_display_menu()
1881
1882
1883 /*---------------------------------------------------------------------------*
1884 * Name : DEMOWinSetRepeat()
1885 *
1886 * Description : Obvious
1887 *
1888 * Arguments : None.
1889 *
1890 * Returns : None.
1891 *
1892 *---------------------------------------------------------------------------*/
DEMOWinSetRepeat(u32 threshold,u32 rate)1893 void DEMOWinSetRepeat(u32 threshold, u32 rate)
1894 {
1895
1896 __DEMOWIN_PAD_repeat_rate = rate;
1897 __DEMOWIN_PAD_repeat_threshold = threshold;
1898
1899 } // End DEMOWinSetRepeat()
1900
1901 /*---------------------------------------------------------------------------*
1902 * Name : DEMOWinResetRepeat()
1903 *
1904 * Description : Obvious
1905 *
1906 * Arguments : None.
1907 *
1908 * Returns : None.
1909 *
1910 *---------------------------------------------------------------------------*/
1911
DEMOWinResetRepeat(void)1912 void DEMOWinResetRepeat(void)
1913 {
1914
1915 __DEMOWIN_PAD_repeat_threshold = DEMOWIN_PAD_REPEAT_THRESH_DEF;
1916 __DEMOWIN_PAD_repeat_rate = DEMOWIN_PAD_REPEAT_RATE_DEF;
1917
1918 } // End DEMOWinResetRepeat()
1919
1920
1921 /*---------------------------------------------------------------------------*
1922 * Name : DEMOWinCreateListWindow()
1923 *
1924 * Description : Obvious
1925 *
1926 * Arguments : None.
1927 *
1928 * Returns : None.
1929 *
1930 *---------------------------------------------------------------------------*/
1931
DEMOWinCreateListWindow(DEMOWinListInfo * list,u16 x,u16 y)1932 DEMOWinListInfo *DEMOWinCreateListWindow(DEMOWinListInfo *list, u16 x, u16 y)
1933 {
1934
1935 DEMOWinListItem *ptr;
1936
1937
1938 ASSERTMSG(list, "DEMOWinCreateListWindow(): List is NULL!\n");
1939
1940 // Calculate max name/title string length
1941 // Calculate number of items in list
1942 ptr = list->items;
1943
1944 list->max_str_len = strlen(list->title);
1945 list->num_items = 0;
1946
1947 while (!(ptr->flags & DEMOWIN_ITM_TERMINATOR))
1948 {
1949 if (strlen(ptr->name) > list->max_str_len)
1950 {
1951 list->max_str_len = strlen(ptr->name);
1952 }
1953 (list->num_items)++;
1954 ptr++;
1955 }
1956
1957 // Calculate actual number of items to display
1958 // It may be less than the max number specified by the user
1959 if (list->num_items > list->max_display_items)
1960 {
1961 list->num_display_items = list->max_display_items;
1962 }
1963 else
1964 {
1965 list->num_display_items = list->num_items;
1966 }
1967
1968 // Open window.
1969 // Note: This call will ASSERT if it fails to allocate a window
1970 list->handle = DEMOWinCreateWindow((s16)x,
1971 (s16)y,
1972 (s16)(x + DEMOWIN_CALC_MENU_WIDTH_PIXELS(list->max_str_len)),
1973 (s16)(y + DEMOWIN_CALC_MENU_HEIGHT_PIXELS(list->num_display_items)),
1974 list->title,
1975 0, // No scrollback lines! Menu function handles list scrolling
1976 __DEMOWinList_refresh_list); // No callback function
1977
1978
1979 // Set parent of this window to this list
1980 (list->handle)->parent = (void *)(list);
1981
1982
1983 if (list->num_items)
1984 {
1985 return(list);
1986 }
1987
1988 return(NULL);
1989
1990
1991 } // End DEMOWinCreateListWindow()
1992
1993 /*---------------------------------------------------------------------------*
1994 * Name : DEMOWinDestroyListWindow()
1995 *
1996 * Description : Obvious
1997 *
1998 * Arguments : None.
1999 *
2000 * Returns : None.
2001 *
2002 *---------------------------------------------------------------------------*/
2003
DEMOWinDestroyListWindow(DEMOWinListInfo * list)2004 void DEMOWinDestroyListWindow(DEMOWinListInfo *list)
2005 {
2006
2007 if (list->handle)
2008 {
2009 DEMOWinCloseWindow(list->handle);
2010 DEMOWinDestroyWindow(list->handle);
2011
2012 list->handle = NULL;
2013 }
2014
2015 } // End DEMOWinDestroyListWindow()
2016
2017
2018 /*---------------------------------------------------------------------------*
2019 * Name : __DEMOWinList_update_list()
2020 *
2021 * Description : Obvious
2022 *
2023 * Arguments : None.
2024 *
2025 * Returns : None.
2026 *
2027 *---------------------------------------------------------------------------*/
2028
__DEMOWinList_refresh_list(DEMOWinInfo * w)2029 static void __DEMOWinList_refresh_list(DEMOWinInfo *w)
2030 {
2031
2032
2033 DEMOWinListInfo *l;
2034
2035 s32 i;
2036 s32 j;
2037
2038 // The parent better the hell be a List info structure
2039 l = (w->parent);
2040
2041 // Just in case...
2042 l->curr_pos = l->curr_pos % l->num_items;
2043
2044 // Fix display pointer
2045 if (l->curr_pos > (l->display_pos+l->num_display_items-1))
2046 {
2047 l->display_pos = l->curr_pos - l->num_display_items + 1;
2048
2049 }
2050 else if (l->curr_pos < l->display_pos)
2051 {
2052 l->display_pos = l->curr_pos;
2053 }
2054
2055 if (l->cursor_state)
2056 {
2057 // Calculate cursor line
2058 if (l->display_pos > l->curr_pos)
2059 {
2060 w->cursor_line = (s16)(l->display_pos - l->curr_pos);
2061 }
2062 else
2063 {
2064 w->cursor_line = (s16)(l->curr_pos - l->display_pos);
2065 }
2066
2067 }// End cursor state check
2068 else
2069 {
2070 w->cursor_line = -1;
2071 }
2072
2073 // Display menu
2074 DEMOWinClearWindow(w);
2075
2076
2077 j = l->display_pos;
2078
2079 for (i=0; i<l->num_display_items; i++)
2080 {
2081 if (!(l->items[j].flags & DEMOWIN_ITM_SEPARATOR))
2082 {
2083 DEMOWinPrintfXY(w, 0, (u16)i, " %s ",l->items[(u16)j].name);
2084 }
2085 j++;
2086 }
2087
2088
2089 } // end __DEMOWinList_update_list()
2090
2091 /*---------------------------------------------------------------------------*
2092 * Name : DEMOWinListSetCursor()
2093 *
2094 * Description : Obvious
2095 *
2096 * Arguments : TRUE or FALSE.
2097 *
2098 * Returns : None.
2099 *
2100 *---------------------------------------------------------------------------*/
2101
DEMOWinListSetCursor(DEMOWinListInfo * list,BOOL x)2102 void DEMOWinListSetCursor(DEMOWinListInfo *list, BOOL x)
2103 {
2104
2105 list->cursor_state = x;
2106
2107 } // End DEMOWinListSetCursor()
2108
2109
2110 /*---------------------------------------------------------------------------*
2111 * Name : DEMOWinListScrollList()
2112 *
2113 * Description : Obvious
2114 *
2115 * Arguments : TRUE or FALSE.
2116 *
2117 * Returns : None.
2118 *
2119 *---------------------------------------------------------------------------*/
2120
DEMOWinListScrollList(DEMOWinListInfo * list,u32 dir)2121 s32 DEMOWinListScrollList(DEMOWinListInfo *list, u32 dir)
2122 {
2123
2124 ASSERTMSG(list, "DEMOWinListScrollList(): NULL handle!\n");
2125
2126 switch(dir)
2127 {
2128 case DEMOWIN_SCROLL_UP:
2129 if (list->display_pos)
2130 {
2131 // If it's zero, don't allow scroll
2132 list->display_pos = (u16)((list->display_pos - 1 + list->num_items) % (list->num_items));
2133 }
2134 break;
2135
2136 case DEMOWIN_SCROLL_DOWN:
2137 if (list->display_pos < (list->num_items - list->num_display_items))
2138 {
2139 // If display_pos is at the start of the last 'pageful' of items, then don't allow scroll
2140 list->display_pos = (u16)((list->display_pos + 1) % (list->num_items));
2141 }
2142 break;
2143
2144 case DEMOWIN_SCROLL_HOME:
2145 list->display_pos = 0;
2146 break;
2147
2148 default:
2149 ASSERTMSG(0, "DEMOWinListScrollList(): Invalid dimension!\n");
2150 break;
2151 }
2152
2153 // Fix up current_pos
2154
2155 if (list->curr_pos > (list->display_pos+list->num_display_items-1))
2156 {
2157 list->curr_pos = list->display_pos + list->num_display_items - 1;
2158 }
2159 else if (list->curr_pos < list->display_pos)
2160 {
2161 list->curr_pos = list->display_pos;
2162 }
2163
2164
2165 return(list->display_pos);
2166
2167 } // End DEMOWinListScrollList()
2168
2169
2170 /*---------------------------------------------------------------------------*
2171 * Name : DEMOWinListSetCursor()
2172 *
2173 * Description : Obvious
2174 *
2175 * Arguments : TRUE or FALSE.
2176 *
2177 * Returns : None.
2178 *
2179 *---------------------------------------------------------------------------*/
2180
DEMOWinListMoveCursor(DEMOWinListInfo * list,u32 dir)2181 s32 DEMOWinListMoveCursor(DEMOWinListInfo *list, u32 dir)
2182 {
2183
2184 ASSERTMSG(list, "DEMOWinListScrollList(): NULL handle!\n");
2185
2186 switch(dir)
2187 {
2188 case DEMOWIN_LIST_UP:
2189 list->curr_pos = (list->curr_pos + list->num_items - 1) % list->num_items;
2190 break;
2191
2192 case DEMOWIN_LIST_DOWN:
2193 list->curr_pos = (list->curr_pos + 1) % list->num_items;
2194 break;
2195
2196 default:
2197 ASSERTMSG(0, "DEMOWinListMoveCursor(): Invalid dimension!\n");
2198 break;
2199 }
2200
2201
2202 return(list->curr_pos);
2203
2204 } // End DEMOWinListMoveCursor()
2205
2206