1: /*
2: * Guitar-ZyX(tm)::MasterControlProgram - portable guitar F/X controller
3: * Copyright (C) 2009 Douglas McClendon
4: *
5: * This program is free software: you can redistribute it and/or modify
6: * it under the terms of the GNU General Public License as published by
7: * the Free Software Foundation, version 3 of the License.
8: *
9: * This program is distributed in the hope that it will be useful,
10: * but WITHOUT ANY WARRANTY; without even the implied warranty of
11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12: * GNU General Public License for more details.
13: *
14: * You should have received a copy of the GNU General Public License
15: * along with this program. If not, see <http://www.gnu.org/licenses/>.
16: */
17: /*
18: #############################################################################
19: #############################################################################
20: ##
21: ## gzmcpc::main: Guitar-ZyX Master Control Program
22: ##
23: #############################################################################
24: ##
25: ## Copyright 2008-2009 Douglas McClendon <dmc AT filteredperception DOT org>
26: ##
27: #############################################################################
28: #############################################################################
29: #
30: */
31:
32:
33:
34:
35: #include <nds.h>
36:
37:
38:
39: #include "main.h"
40:
41: #include "configfiles.h"
42:
43: #include "debug.h"
44:
45: #include "graphics.h"
46:
47: #include "input.h"
48:
49: #include "metrognome.h"
50:
51: #include "mcp.h"
52:
53: #include "modes.h"
54:
55: #include "network.h"
56:
57: #include "rak.h"
58:
59: #include "sound.h"
60:
61: #include "time.h"
62:
63:
64: #include "sounds.h"
65:
66: #include "sounds_bin.h"
67:
68:
69:
70:
71: unsigned char idle_rate = DEFAULT_IDLE_RATE;
72: time_val next_idle = {0, 0};
73:
74:
75:
76: int main() {
77:
78: // battery life is not a constraint right now :)
79: powerOn(POWER_ALL);
80:
81: // assumption is that we are loaded from something that starts with white
82: fade_in_from_white();
83:
84: // intialize rakarrack interface state
85: gzmcpc_init_rak();
86:
87: // read defaults from fat filesystem
88: gzmcpc_read_config();
89:
90: // initialize sound subsystem
91: gzmcpc_init_sound();
92:
93: // initialize application networking subsystem
94: gzmcpc_init_net();
95:
96: // initialize global timekeeping subsystem (ms accuracy)
97: gzmcpc_init_time();
98:
99: //
100: // input-polling/event-handling/state-machine/rendering loop
101: //
102: while (1) {
103:
104: //
105: // turn the cranks
106: //
107:
108: // network state is generally orthogonal to mode state
109: network_state = gzmcpc_net_next_state(network_state);
110:
111: // check for network mode state transition
112: if (network_state != last_network_state) {
113: // tell next network mode state it needs to init
114: nsm_init = 0;
115: last_network_state = network_state;
116: }
117:
118: // check for mode state transition
119: if (new_mode != mode) {
120:
121: // execute per mode cleanup function (for previous mode)
122: if (mode != MODE_NUM_MODES) modes[mode].goodbye();
123:
124: // record time of mode start
125: mode_start = num_ticks;
126:
127: // set current and last mode
128: last_mode = mode;
129: mode = new_mode;
130:
131: // reset system state that modes expect initialized
132: system_xmode_reinit();
133:
134: // execute per mode initialization function
135: modes[mode].hello();
136:
137: }
138:
139: // calculate a frequently used value
140: mode_ms = ms_since(mode_start);
141:
142: // poll for user input
143: if (ms_since(next_input_poll) > 0) {
144:
145: // get new input data
146: gzmcpc_poll_input();
147:
148: // call global input handler
149: global_input_processor();
150:
151: // call per mode input handler
152: modes[mode].input_processor();
153:
154: // set alarm for next polling cycle
155: next_input_poll = time_val_add_ms(next_input_poll, 1000 / input_poll_rate);
156:
157: } // end polling for user input
158:
159:
160: // render top screen
161: if (ms_since(next_top_render) > 0) {
162: modes[mode].icandy_top_reindeer();
163: next_top_render = time_val_add_ms(next_top_render, 1000 / top_render_rate);
164: }
165:
166: // render bottom screen
167: if (ms_since(next_bottom_render) > 0) {
168: modes[mode].icandy_bot_reindeer();
169: next_bottom_render =
170: time_val_add_ms(next_bottom_render, 1000 / bottom_render_rate);
171: }
172:
173: // synchronize server
174: if (ms_since(next_sync_with_server) > 0) {
175: sync_with_server();
176: next_sync_with_server =
177: time_val_add_ms(next_sync_with_server, 1000 / network_event_rate);
178: }
179:
180: // metrognome
181: if (ms_since(next_metrognome_play) > 0) {
182: play_metrognome();
183: // XXX? worthwhile optimization ?= calculate at astrobe_bpm
184: // modification time, tradeoff would extra variable (or
185: // just replace astrobe_bpm with astrobe_b_ms_period)
186: next_metrognome_play =
187: time_val_add_ms(next_metrognome_play, 1000 * 60 / astrobe_bpm);
188: }
189:
190: // run idle function
191: if (ms_since(next_idle) > 0) {
192: mcp_fade_update();
193: modes[mode].slacker_funk();
194: next_idle = time_val_add_ms(next_idle, 1000 / idle_rate);
195: }
196:
197: // done with frame loop, wait for vblank, etc...
198: gzmcpc_flush_frame();
199:
200: } // end while(1)
201:
202: // execution never reaches here
203: return 0;
204:
205: } // end main()
206:
207:
208:
209:
210: void fade_in_from_white(void) {
211: lcdMainOnTop();
212: videoSetMode(MODE_5_2D);
213: vramSetBankA(VRAM_A_MAIN_BG_0x06060000);
214: videoSetModeSub(MODE_5_2D);
215: vramSetBankC(VRAM_C_SUB_BG);
216: int bg = bgInit(3, BgType_Bmp8, BgSize_B8_256x256, 0, 0);
217: int bgs = bgInitSub(3, BgType_Bmp8, BgSize_B8_256x256, 0, 0);
218: dmaFillWords(0xFFFFFFFF, BG_PALETTE, 256*2);
219: dmaFillWords(0x00000000, bgGetGfxPtr(bg), 256*256);
220: dmaFillWords(0xFFFFFFFF, BG_PALETTE_SUB, 256*2);
221: dmaFillWords(0x00000000, bgGetGfxPtr(bgs), 256*256);
222: int counter, i;
223:
224: for (counter = 31; counter >= 0; counter--) {
225: BG_PALETTE[0] = RGB15(counter, counter, counter);
226: BG_PALETTE_SUB[0] = RGB15(counter, counter, counter);
227: for (i = 0; i < 2; i++) {
228: swiWaitForVBlank();
229: }
230: }
231: }
232: