1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - demos - VIB - pulse_vib
3 File: data.c
4
5 Copyright 2008 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Date:: $
14 $Rev: $
15 $Author: $
16 *---------------------------------------------------------------------------*/
17 #include <nitro.h>
18 #include "char_data.h"
19
20 /*-----------------------------------------------------------------------*
21 Type, Constant
22 *-----------------------------------------------------------------------*/
23
24 // #define USE_BACKUP
25
26 // Number of pulse state save slot
27 #define SAVE_SLOT_NUM 8
28
29 // Current scene
30 typedef enum
31 {
32 MM_SET_STATE,
33 MM_SAVE
34 }
35 MenuMode;
36
37 typedef struct
38 {
39 VIBPulseState pulse_state[SAVE_SLOT_NUM];
40 u32 check_sum;
41 }
42 PulseStateBackup;
43
44 #define KEY_NUM 14
45 #define KEYREPEAT_FIRST 25 // Key repeat default interval
46 #define KEYREPEAT_INTERVAL 5 // Key repeat interval
47
48 /*-----------------------------------------------------------------------*
49 Function prototypes
50 *-----------------------------------------------------------------------*/
51
52 //--- Auto Function Prototype --- Don't comment here
53 void NitroMain();
54 void read_key_data(void);
55 static void go_sleep_if_cover_fold(void);
56 static void VBlankIntr(void);
57 static void set_pulse_state(void);
58 static void save_and_load_pulse_state(void);
59 static void write_pulse_state(VIBPulseState * state);
60 static u32 *get_state_value_from_line(VIBPulseState * state, s32 line);
61 static void write_save_words(void);
62 static void print_message(char *str);
63 static void print_usage(MenuMode mode);
64 static void set_first_state(void);
65 static void read_tp(void);
66 static void cartridge_pullout_callback(void);
67 static u32 calc_sum(void *addr, u32 size);
68 static BOOL start_pulse_vib(VIBPulseState * state);
69 static void stop_pulse_vib(void);
70 //--- End of Auto Function Prototype
71
72 /*-----------------------------------------------------------------------*
73 Variables
74 *-----------------------------------------------------------------------*/
75
76 // Key information
77 static u16 Trg;
78 static u16 Cont;
79 static u16 Rpt;
80
81 // Touch Panel information
82 static TPData tp_last;
83 static TPData tp_pre;
84 static TPData tp_trg;
85 static TPData tp_uptrg;
86
87 // Pulse vibration save slot
88 static VIBPulseState save_slot[SAVE_SLOT_NUM];
89
90 static s32 line; // Line number in menu
91 static MenuMode menu_mode; // Current scene
92 static VIBPulseState pulse_state; // Current pulse state
93 static s32 cartridge_pullout_flag; // If TRUE, Game Pak is pulled out
94
95 static u16 backup_lockid;
96 static BOOL backup_is_enable;
97
98 /*-----------------------------------------------------------------------*
99 Global Function Definitions
100 *-----------------------------------------------------------------------*/
101
NitroMain()102 void NitroMain()
103 {
104 OS_Init();
105 GX_Init();
106
107 GX_SetPower(GX_POWER_ALL);
108
109 //---- Set V-Blank interrupt
110 (void)OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
111 (void)OS_EnableIrqMask(OS_IE_V_BLANK);
112 (void)OS_EnableIrq();
113
114 //---- Clear VRAM
115 GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
116 MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
117 (void)GX_DisableBankForLCDC();
118
119 //---- Clear OAM and palette
120 MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);
121 MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
122
123 // Initialize debug print
124 dp_init();
125
126 //---- V-Blank interrupt on
127 (void)GX_VBlankIntr(TRUE);
128
129 read_key_data();
130
131 { // Initialize Touch Panel
132 TPCalibrateParam calibrate;
133
134 TP_Init();
135 (void)TP_GetUserInfo(&calibrate);
136 TP_SetCalibrateParam(&calibrate);
137 }
138
139 dp_write("NRC PULSE TEST " __DATE__, LCD_TOP, 1, 1);
140 print_usage(MM_SET_STATE);
141
142 backup_lockid = (u16)OS_GetLockID();
143 backup_is_enable = FALSE;
144 #ifdef USE_BACKUP
145 CARD_LockBackup(backup_lockid);
146 (void)CARD_IdentifyBackup(CARD_BACKUP_TYPE_EEPROM_4KBITS);
147 CARD_UnlockBackup(backup_lockid);
148 #endif
149
150 // Initialize pulse vib
151 cartridge_pullout_flag = FALSE;
152
153
154 if (!VIB_Init())
155 {
156 dp_set_pltt(1);
157 dp_write("NRC NOT INSERTED", LCD_TOP, 1, 20);
158 dp_set_pltt(0);
159 }
160 VIB_SetCartridgePulloutCallback(cartridge_pullout_callback);
161
162 // Initialize variables
163 set_first_state();
164
165 //---- Begin display
166 OS_WaitVBlankIntr();
167 GX_DispOn();
168 GXS_DispOn();
169
170 while (1)
171 {
172 //---- Wait for V-Blank interrupt
173 OS_WaitVBlankIntr();
174
175 // Main process
176 dp_clear_scr(LCD_BOTTOM);
177
178 //---- Display message if Game Pak pullout
179 if (cartridge_pullout_flag)
180 {
181 dp_set_pltt(1);
182 dp_write("NRC PULLOUT!!", LCD_TOP, 1, 20);
183 dp_set_pltt(0);
184 }
185
186 //---- Read pad data
187 read_key_data();
188
189 //---- Read Touch Panel data
190 read_tp();
191
192 { // Display count up
193 static u8 count;
194 dp_write_byte(count++, LCD_TOP, 29, 1);
195 }
196
197 //---- Close cover to sleep
198 go_sleep_if_cover_fold();
199
200 switch (menu_mode)
201 {
202 case MM_SET_STATE:
203 set_pulse_state();
204 break;
205 case MM_SAVE:
206 save_and_load_pulse_state();
207 break;
208 }
209 }
210 }
211
212 /*-----------------------------------------------------------------------*
213 Local Function Definition
214 *-----------------------------------------------------------------------*/
215
go_sleep_if_cover_fold(void)216 static void go_sleep_if_cover_fold(void)
217 {
218
219 // If wake up at Game Pak pullout, sleep again
220 while (PAD_DetectFold())
221 {
222 stop_pulse_vib();
223 PM_GoSleepMode(PM_TRIGGER_COVER_OPEN | PM_TRIGGER_CARTRIDGE, 0, 0);
224 }
225 }
226
VBlankIntr(void)227 static void VBlankIntr(void)
228 {
229 dp_flush(); // Flush debug print
230
231 //---- Check V-Blank interrupt flag
232 OS_SetIrqCheckFlag(OS_IE_V_BLANK);
233 }
234
235 // Process of state change scene
set_pulse_state(void)236 static void set_pulse_state(void)
237 {
238
239 if (Trg & PAD_KEY_UP)
240 { // Select parameter
241 if (line == 0)
242 {
243 line = (s32)(pulse_state.pulse_num * 2 - 1);
244 }
245 else
246 {
247 line--;
248 }
249 }
250 else if (Trg & PAD_KEY_DOWN)
251 { // Select parameter
252 if (line == pulse_state.pulse_num * 2 - 1)
253 {
254 line = 0;
255 }
256 else
257 {
258 line++;
259 }
260 }
261 else if ((Cont & PAD_KEY_LEFT) && (Cont & PAD_BUTTON_R))
262 { // Increase value very fast
263 u32 *num = get_state_value_from_line(&pulse_state, line);
264
265 if (*num > 101)
266 {
267 *num -= 100;
268 }
269 else
270 {
271 *num = 1;
272 }
273 }
274 else if ((Cont & PAD_KEY_RIGHT) && (Cont & PAD_BUTTON_R))
275 { // Decrease value very fast
276 u32 *num = get_state_value_from_line(&pulse_state, line);
277
278 if (*num < 99899)
279 {
280 *num += 100;
281 }
282 else
283 {
284 *num = 99999;
285 }
286 }
287 else if ((Cont & PAD_KEY_LEFT) && (Cont & PAD_BUTTON_X))
288 { // Increase value fast
289 u32 *num = get_state_value_from_line(&pulse_state, line);
290
291 if (*num > 11)
292 {
293 *num -= 10;
294 }
295 else
296 {
297 *num = 1;
298 }
299 }
300 else if ((Cont & PAD_KEY_RIGHT) && (Cont & PAD_BUTTON_X))
301 { // Decrease value fast
302 u32 *num = get_state_value_from_line(&pulse_state, line);
303
304 if (*num < 99989)
305 {
306 *num += 10;
307 }
308 else
309 {
310 *num = 99999;
311 }
312 }
313 else if ((Trg & PAD_KEY_LEFT) || (Rpt & PAD_KEY_LEFT))
314 { // Increase value
315 u32 *num = get_state_value_from_line(&pulse_state, line);
316
317 if (*num != 1)
318 {
319 (*num)--;
320 }
321 }
322 else if ((Trg & PAD_KEY_RIGHT) || (Rpt & PAD_KEY_RIGHT))
323 { // Decrease value
324 u32 *num = get_state_value_from_line(&pulse_state, line);
325
326 if (*num != 99999)
327 {
328 (*num)++;
329 }
330 }
331 else if (Trg & PAD_BUTTON_Y)
332 { // Change pulse num
333 u32 old_pulse_num = pulse_state.pulse_num;
334
335 if (pulse_state.pulse_num == VIB_PULSE_NUM_MAX)
336 {
337 pulse_state.pulse_num = 1;
338 }
339 else
340 {
341 pulse_state.pulse_num++;
342 }
343 if (line == old_pulse_num * 2 - 1)
344 {
345 line = (s32)(pulse_state.pulse_num * 2 - 1);
346 }
347 else if (line >= pulse_state.pulse_num * 2 - 1)
348 {
349 line = 0;
350 }
351 }
352
353 if (line == pulse_state.pulse_num * 2 - 1)
354 { // Display cursor
355 dp_write("@", LCD_BOTTOM, 2, 13);
356 }
357 else
358 {
359 dp_write("@", LCD_BOTTOM, 2, line + 1);
360 }
361
362 write_pulse_state(&pulse_state); // Display current pulse state
363
364 if ((Trg & PAD_BUTTON_A) || (tp_trg.touch && tp_trg.x > 128))
365 { // Start pulse vibration
366 print_message("START PULSE VIB");
367 (void)start_pulse_vib(&pulse_state);
368 }
369 else if (tp_trg.touch && tp_trg.x <= 128)
370 { // Start one-time pulse vibration
371 VIBPulseState state_temp = pulse_state;
372 print_message("START ONE TIME PULSE VIB");
373 state_temp.repeat_num = 1;
374 (void)start_pulse_vib(&state_temp);
375 }
376 else if (Trg & PAD_BUTTON_B || tp_uptrg.touch)
377 { // Stop pulse vibration
378 print_message("STOP PULSE VIB");
379 stop_pulse_vib();
380 }
381 if (Trg & PAD_BUTTON_START)
382 { // Move scene to save/load pulse state
383 stop_pulse_vib();
384 dp_clear(LCD_TOP, 0, 22, 32);
385 dp_clear(LCD_TOP, 0, 23, 32);
386 print_usage(MM_SAVE);
387
388 // Read from backup
389 #ifdef USE_BACKUP
390 CARD_LockBackup(backup_lockid);
391 {
392 PulseStateBackup backup;
393
394 if (CARD_ReadEeprom(0, &backup, sizeof(PulseStateBackup)))
395 {
396 u32 check_sum = calc_sum(backup.pulse_state, sizeof(backup.pulse_state));
397 if (check_sum == backup.check_sum)
398 {
399 MI_CpuCopyFast(backup.pulse_state, save_slot, sizeof(backup.pulse_state));
400 OS_PutString("Read data from EEPROM.\n");
401 print_message("LOAD DATA FROM BACKUP");
402 }
403 else
404 {
405 OS_PutString("Read data checksum error.\n");
406 }
407 backup_is_enable = TRUE;
408 }
409 }
410 CARD_UnlockBackup(backup_lockid);
411 #endif
412
413 menu_mode = MM_SAVE;
414 line = 0;
415 }
416 }
417
418 // Process of save/load state scene
save_and_load_pulse_state(void)419 static void save_and_load_pulse_state(void)
420 {
421
422 if (Trg & PAD_KEY_UP)
423 { // Choose save/load slot
424 if (line == 0)
425 {
426 line = SAVE_SLOT_NUM;
427 }
428 else
429 {
430 line--;
431 }
432 }
433 else if (Trg & PAD_KEY_DOWN)
434 { // Choose save/load slot
435 if (line == SAVE_SLOT_NUM)
436 {
437 line = 0;
438 }
439 else
440 {
441 line++;
442 }
443 }
444 {
445 VIBPulseState *selected_state;
446
447 if (line == 0)
448 {
449 selected_state = &pulse_state;
450 }
451 else
452 {
453 selected_state = &save_slot[line - 1];
454 }
455
456 if (Trg & PAD_BUTTON_SELECT)
457 { // Load pulse state
458 if (line != 0)
459 {
460 if (backup_is_enable)
461 {
462 print_message("LOAD DATA FROM BACKUP");
463 dp_write_dec(line - 1, LCD_TOP, 23, 22);
464 }
465 else
466 {
467 print_message("LOAD DATA FROM SAVE");
468 dp_write_dec(line - 1, LCD_TOP, 21, 22);
469 }
470 pulse_state = *selected_state;
471 }
472 stop_pulse_vib();
473 menu_mode = MM_SET_STATE;
474 print_usage(MM_SET_STATE);
475 line = 0;
476 return;
477 }
478 else if (Trg & PAD_BUTTON_START)
479 { // Save pulse state
480 stop_pulse_vib();
481 dp_clear(LCD_TOP, 0, 22, 32);
482 dp_clear(LCD_TOP, 0, 23, 32);
483 print_usage(MM_SET_STATE);
484
485 if (line != 0)
486 {
487 *selected_state = pulse_state;
488
489 if (backup_is_enable)
490 {
491 PulseStateBackup backup;
492
493 MI_CpuCopyFast(save_slot, backup.pulse_state, sizeof(backup.pulse_state));
494 backup.check_sum = calc_sum(backup.pulse_state, sizeof(backup.pulse_state));
495
496 CARD_LockBackup(backup_lockid);
497 if (CARD_WriteAndVerifyEeprom(0, &backup, sizeof(PulseStateBackup)))
498 {
499 OS_PutString("Write data to EEPROM.\n");
500 }
501 CARD_UnlockBackup(backup_lockid);
502 print_message("SAVE CURRENT DATA TO BACKUP");
503 dp_write_dec(line - 1, LCD_TOP, 29, 22);
504 }
505 else
506 {
507 print_message("SAVE CURRENT DATA TO SAVE");
508 dp_write_dec(line - 1, LCD_TOP, 27, 22);
509 }
510 }
511
512 menu_mode = MM_SET_STATE;
513 line = 0;
514 return;
515 }
516
517 if ((Trg & PAD_BUTTON_A) || (tp_trg.touch && tp_trg.x > 128))
518 { // Start pulse vibration
519 if (line == 0)
520 {
521 print_message("START PULSE VIB");
522 }
523 else
524 {
525 print_message("START PULSE VIB SAVE");
526 dp_write_dec(line - 1, LCD_TOP, 22, 22);
527 }
528 (void)start_pulse_vib(selected_state);
529 }
530 else if (tp_trg.touch && tp_trg.x <= 128)
531 { // Start one-time pulse vibration
532 VIBPulseState state_temp = *selected_state;
533 if (line == 0)
534 {
535 print_message("START ONE TIME PULSE VIB");
536 }
537 else
538 {
539 print_message("START ONE TIME PULSE VIB SAVE");
540 dp_write_dec(line - 1, LCD_TOP, 31, 22);
541 }
542 state_temp.repeat_num = 1;
543 (void)start_pulse_vib(&state_temp);
544 }
545 else if (Trg & PAD_BUTTON_B || (tp_uptrg.touch && tp_uptrg.x > 128))
546 { // Stop pulse vibration
547 print_message("STOP PULSE VIB");
548 #ifdef USE_VIB
549 stop_pulse_vib();
550 #endif
551 }
552
553 write_pulse_state(selected_state); // Display current pulse state
554 }
555 dp_write("@", LCD_BOTTOM, 20, line + 1); // Display cursor
556 write_save_words(); // Display save slot words
557 }
558
559 // Display pulse state
write_pulse_state(VIBPulseState * state)560 static void write_pulse_state(VIBPulseState * state)
561 {
562
563 s32 i;
564
565 // Display on/off time length
566 for (i = 0; i < state->pulse_num; i++)
567 {
568 double time;
569 char buf[32];
570
571 time = (double)state->on_time[i];
572 time = time / 10;
573
574 (void)snprintf(buf, 32, "%6.1f", time);
575
576 if (state->on_time[i] > VIB_ON_TIME_MAX)
577 dp_set_pltt(1);
578 dp_write(buf, LCD_BOTTOM, 9, i * 2 + 1);
579 if (state->on_time[i] > VIB_ON_TIME_MAX)
580 dp_set_pltt(0);
581
582 time = (double)state->off_time[i];
583 time = time / 10;
584
585 (void)snprintf(buf, 32, "%6.1f", time);
586
587 if (state->on_time[i] > state->off_time[i])
588 dp_set_pltt(1);
589 dp_write(buf, LCD_BOTTOM, 9, i * 2 + 2);
590 if (state->on_time[i] > state->off_time[i])
591 dp_set_pltt(0);
592
593 dp_write(" ON :", LCD_BOTTOM, 3, i * 2 + 1);
594 dp_write("OFF :", LCD_BOTTOM, 3, i * 2 + 2);
595 dp_write_dec(i + 1, LCD_BOTTOM, 7, i * 2 + 1);
596 dp_write_dec(i + 1, LCD_BOTTOM, 7, i * 2 + 2);
597 dp_write("ms", LCD_BOTTOM, 15, i * 2 + 1);
598 dp_write("ms", LCD_BOTTOM, 15, i * 2 + 2);
599 }
600 dp_clear(LCD_BOTTOM, 0, (s32)state->pulse_num * 2, 32);
601
602 // Display rest time
603 {
604 double time;
605 char buf[32];
606
607 time = (double)state->rest_time;
608 time = time / 10;
609
610 (void)snprintf(buf, 32, "%6.1f", time);
611
612 dp_write(" REST:", LCD_BOTTOM, 3, 13);
613 if (state->rest_time < VIB_REST_TIME_MIN)
614 dp_set_pltt(1);
615 dp_write(buf, LCD_BOTTOM, 9, 13);
616 if (state->rest_time < VIB_REST_TIME_MIN)
617 dp_set_pltt(0);
618 dp_write("ms", LCD_BOTTOM, 15, 13);
619 }
620
621 // Display pulse num
622 dp_write_dec((s32)state->pulse_num, LCD_BOTTOM, 13, 16);
623 dp_write("PULSE NUM:", LCD_BOTTOM, 2, 16);
624 }
625
626 // Get pointer to pointed parameter by cursor
get_state_value_from_line(VIBPulseState * state,s32 line)627 static u32 *get_state_value_from_line(VIBPulseState * state, s32 line)
628 {
629
630 if (line == pulse_state.pulse_num * 2 - 1)
631 {
632 return &(state->rest_time);
633 }
634 else
635 {
636 if (line & 1)
637 {
638 return &(state->off_time[line >> 1]);
639 }
640 else
641 {
642 return &(state->on_time[line >> 1]);
643 }
644 }
645 }
646
647 // Display save slot words
write_save_words(void)648 static void write_save_words(void)
649 {
650
651 dp_write("CURRENT", LCD_BOTTOM, 22, 1);
652 dp_write("SAVE 0 ", LCD_BOTTOM, 22, 2);
653 dp_write("SAVE 1 ", LCD_BOTTOM, 22, 3);
654 dp_write("SAVE 2 ", LCD_BOTTOM, 22, 4);
655 dp_write("SAVE 3 ", LCD_BOTTOM, 22, 5);
656 dp_write("SAVE 4 ", LCD_BOTTOM, 22, 6);
657 dp_write("SAVE 5 ", LCD_BOTTOM, 22, 7);
658 dp_write("SAVE 6 ", LCD_BOTTOM, 22, 8);
659 dp_write("SAVE 7 ", LCD_BOTTOM, 22, 9);
660 }
661
662 // Display message text
print_message(char * str)663 static void print_message(char *str)
664 {
665 dp_clear(LCD_TOP, 0, 22, 32);
666 dp_clear(LCD_TOP, 0, 23, 32);
667 dp_write(str, LCD_TOP, 1, 22);
668 }
669
670 // Display usage
print_usage(MenuMode mode)671 static void print_usage(MenuMode mode)
672 {
673
674 dp_clear(LCD_TOP, 0, 3, 32 * 10);
675 dp_write("A: START PULSE VIB", LCD_TOP, 1, 3);
676 dp_write("B: STOP PULSE VIB", LCD_TOP, 1, 4);
677
678 switch (mode)
679 {
680 case MM_SET_STATE:
681 dp_write("Y: CHANGE PULSE NUM", LCD_TOP, 1, 5);
682 dp_write("X: PUSH TO SPEEDUP LEFT/RIGHT", LCD_TOP, 1, 6);
683 dp_write("R: PUSH TO SPEED+++ LEFT/RIGHT", LCD_TOP, 1, 7);
684 dp_write(" UP/DOWN: CHOOSE PARAM", LCD_TOP, 1, 8);
685 dp_write("LEFT/RIGHT: CHANGE PARAM NUM", LCD_TOP, 1, 9);
686 dp_write(" START: ENTER SAVE MENU", LCD_TOP, 1, 10);
687 break;
688 case MM_SAVE:
689 dp_write("UP/DOWN: CHOOSE SAVE SLOT", LCD_TOP, 1, 5);
690 dp_write(" START: SAVE DATA AND EXIT", LCD_TOP, 1, 6);
691 dp_write(" SELECT: LOAD DATA AND EXIT", LCD_TOP, 1, 7);
692 break;
693 }
694
695 dp_write("TOUCH RIGHT SIDE:", LCD_TOP, 1, 12);
696 dp_write(" CONTINUOUS PULSE VIB", LCD_TOP, 1, 13);
697 dp_write("TOUCH LEFT SIDE:", LCD_TOP, 1, 14);
698 dp_write(" ONE TIME PULSE VIB", LCD_TOP, 1, 15);
699 }
700
701 // Initialize variables
set_first_state(void)702 static void set_first_state(void)
703 {
704
705 u32 i;
706
707 pulse_state.pulse_num = 2;
708 pulse_state.rest_time = 500;
709 pulse_state.repeat_num = 0;
710
711 pulse_state.on_time[0] = 15;
712 pulse_state.on_time[1] = 15;
713 pulse_state.on_time[2] = 15;
714 pulse_state.on_time[3] = 15;
715 pulse_state.on_time[4] = 15;
716 pulse_state.on_time[5] = 15;
717
718 pulse_state.off_time[0] = 15;
719 pulse_state.off_time[1] = 15;
720 pulse_state.off_time[2] = 15;
721 pulse_state.off_time[3] = 15;
722 pulse_state.off_time[4] = 15;
723 pulse_state.off_time[5] = 15;
724
725 MI_CpuClearFast(save_slot, sizeof(save_slot));
726
727 for (i = 0; i < SAVE_SLOT_NUM; i++)
728 {
729 save_slot[i].pulse_num = VIB_PULSE_NUM_MAX;
730 save_slot[i].rest_time = 100;
731 save_slot[i].repeat_num = 0;
732
733 save_slot[i].on_time[0] = 10;
734 save_slot[i].on_time[1] = 10;
735 save_slot[i].on_time[2] = 10;
736 save_slot[i].on_time[3] = 10;
737 save_slot[i].on_time[4] = 10;
738 save_slot[i].on_time[5] = 10;
739
740 save_slot[i].off_time[0] = 10;
741 save_slot[i].off_time[1] = 10;
742 save_slot[i].off_time[2] = 10;
743 save_slot[i].off_time[3] = 10;
744 save_slot[i].off_time[4] = 10;
745 save_slot[i].off_time[5] = 10;
746 }
747 }
748
749 // Read Touch Panel data
read_tp(void)750 static void read_tp(void)
751 {
752
753 TPData tp_raw;
754
755 tp_pre = tp_last;
756
757 while (TP_RequestRawSampling(&tp_raw) != 0)
758 {
759 }
760 TP_GetCalibratedPoint(&tp_last, &tp_raw);
761
762 if (tp_last.validity != TP_VALIDITY_VALID)
763 {
764 tp_last = tp_pre;
765 tp_last.touch = 0;
766 }
767
768 if (tp_last.touch && (!tp_pre.touch))
769 {
770 tp_trg = tp_last;
771 }
772 else
773 {
774 tp_trg.touch = FALSE;
775 }
776
777 if ((!tp_last.touch) && tp_pre.touch)
778 {
779 tp_uptrg = tp_pre;
780 }
781 else
782 {
783 tp_uptrg.touch = FALSE;
784 }
785 }
786
787 // If Game Pak pulled out, display caution and set flag
cartridge_pullout_callback(void)788 static void cartridge_pullout_callback(void)
789 {
790
791 cartridge_pullout_flag = TRUE;
792 }
793
calc_sum(void * addr,u32 size)794 static u32 calc_sum(void *addr, u32 size)
795 {
796
797 u32 i;
798 u32 times = size / 4;
799 u32 *num_by_4byte = addr;
800 u32 sum = 0;
801
802 for (i = 0; i < times; i++)
803 {
804 sum += *num_by_4byte;
805 num_by_4byte++;
806 }
807
808 return sum;
809 }
810
start_pulse_vib(VIBPulseState * state)811 static BOOL start_pulse_vib(VIBPulseState * state)
812 {
813 int i;
814
815 /* Does the ON time exceed VIB_ON_TIME_MAX? */
816 for (i = 0; i < state->pulse_num; i++)
817 {
818 if (state->on_time[i] > VIB_ON_TIME_MAX)
819 {
820 VIB_StopPulse();
821 dp_set_pltt(1);
822 dp_write("ON time[", LCD_TOP, 1, 22);
823 dp_write_dec(i + 1, LCD_TOP, 9, 22);
824 dp_write("] is over", LCD_TOP, 10, 22);
825 dp_write("VIB_ON_TIME_MAX", LCD_TOP, 1, 23);
826 dp_set_pltt(0);
827 return FALSE;
828 }
829 }
830 /* Does the OFF time exceed the previous ON time? */
831 for (i = 0; i < state->pulse_num - 1; i++)
832 {
833 if (state->on_time[i] > state->off_time[i])
834 {
835 VIB_StopPulse();
836 dp_set_pltt(1);
837 dp_write("ON time[", LCD_TOP, 1, 22);
838 dp_write_dec(i + 1, LCD_TOP, 9, 22);
839 dp_write("] is over OFF time[", LCD_TOP, 10, 22);
840 dp_write_dec(i + 1, LCD_TOP, 29, 22);
841 dp_write("]", LCD_TOP, 30, 22);
842 dp_set_pltt(0);
843 return FALSE;
844 }
845 }
846 /* Is the REST time less than VIB_REST_TIME_MIN? */
847 if (state->rest_time < VIB_REST_TIME_MIN)
848 {
849 VIB_StopPulse();
850 dp_set_pltt(1);
851 dp_write("REST time is less than", LCD_TOP, 1, 22);
852 dp_write("VIB_REST_TIME_MIN", LCD_TOP, 1, 23);
853 dp_set_pltt(0);
854 return FALSE;
855 }
856
857 VIB_StartPulse(state);
858 return TRUE;
859 }
860
stop_pulse_vib(void)861 static void stop_pulse_vib(void)
862 {
863
864 VIB_StopPulse();
865 }
866
read_key_data(void)867 void read_key_data(void)
868 {
869
870 int i;
871 u16 keyData;
872 u16 bit;
873 static u8 keyrep_count[16];
874
875 //---- Load pad data
876 keyData = PAD_Read();
877 Trg = (u16)(keyData & (keyData ^ Cont));
878 Cont = keyData;
879 Rpt = 0;
880 for (i = 0; i < KEY_NUM; ++i)
881 {
882 if (!(Cont & (bit = (u16)(PAD_BUTTON_A << i))))
883 {
884 keyrep_count[i] = 0;
885 continue;
886 }
887 keyrep_count[i]++;
888 if (keyrep_count[i] == KEYREPEAT_FIRST)
889 {
890 Rpt |= bit;
891 continue;
892 }
893 if (keyrep_count[i] == KEYREPEAT_FIRST + KEYREPEAT_INTERVAL)
894 {
895 Rpt |= bit;
896 keyrep_count[i] = KEYREPEAT_FIRST;
897 }
898 }
899 }
900