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: