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::mode__intro__main: mode for first intro splashscreen
    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: #include <stdio.h> 
    38: 
    39: #include <dswifi9.h> 
    40: 
    41: #include <maxmod9.h> 
    42: 
    43: #include "dmc.h" 
    44: 
    45: #include "graphics.h" 
    46: 
    47: #include "input.h" 
    48: 
    49: #include "main.h" 
    50: 
    51: #include "mcp.h" 
    52: 
    53: #include "modes.h" 
    54: 
    55: #include "mode__intro__main.h" 
    56: 
    57: #include "network.h" 
    58: 
    59: #include "sound.h" 
    60: 
    61: #include "cloader/arm9_loader.h" 
    62: 
    63: 
    64: 
    65: #include "sounds.h" 
    66: 
    67: #include "sounds_bin.h" 
    68: 
    69: #include "resources/bitmaps/guitar-zyx.splash.main.h" 
    70: 
    71: #include "resources/bitmaps/dlava.h" 
    72: 
    73: #include "resources/bitmaps/mcpfont.h" 
    74: 
    75: 
    76: 
    77: 
    78: 
    79: 
    80: ConsoleFont mcpfont;
    81: 
    82: 
    83: 
    84: 
    85: void mode__intro__main___init(void) {
    86: 
    87:   // ooh, ahh, earcandy
    88:   mmEffectEx(&sounds[SFX_STARTUP]);
    89: 
    90:   // initialize main screen 
    91:   // edunote: had tried MODE_5_3D here, but after 3D was actually used,
    92:   //          it would interfere with the bitmap showing.  I think I'm
    93:   //          effectively bghiding all layers in intermode init, but
    94:   //          maybe I'm not, or maybe there is another way to hide the 3D
    95:   //          layer.  Probably I should figure out how to render 3D on 
    96:   //          top of a bitmap successfully.  Then the rest might follow.
    97:   videoSetMode(MODE_5_2D);
    98: 
    99:   // map main screen background fourth (128k) region to vram bank A
   100:   vramSetBankA(VRAM_A_MAIN_BG_0x06060000);
   101:   
   102:   // NOTE: current half educated assumption is that or-ing together
   103:   //       bg enabled layers here is nothing but effectively an
   104:   //       advanced call to bgShow, which is also a part of bgInit
   105:   // NOTE2: after some time, I'm convinced of the above, and about
   106:   //        to write a function bg_init_hidden()
   107:   videoSetModeSub(MODE_5_2D);
   108: 
   109:   // map sub screen background (only? 1/4?) to vram bank C
   110:   vramSetBankC(VRAM_C_SUB_BG);
   111: 
   112:   mcp_console_init(&bottom_screen, 
   113: 		   MCP_SUB_SCREEN,
   114: 		   0, 
   115: 		   1,
   116: 		   1,
   117: 		   BgType_Text4bpp, 
   118: 		   BgSize_T_256x256, 
   119: 		   31, 
   120: 		   0);
   121: 
   122:   // set printf sink
   123:   consoleSelect(&bottom_screen);
   124: 
   125:   // set console background layer to top priority
   126:   bgSetPriority(bottom_screen.bgId, 0);
   127: 
   128:   // note: this must be done _after_ consoleInit (as that resets it)
   129:   //       and _after_ loading our 8bit indexed bitmap reloads it
   130:   // set to black to allow renderer to really control
   131:   BG_PALETTE_SUB[255] = RGB15(0, 0, 0);
   132: 
   133:   // show the console layer
   134:   mcp_bg_show(MCP_SUB_SCREEN, 0);
   135: 
   136:   // default to fully faded (to black)
   137:   mcp_set_blend(MCP_MAIN_SCREEN, 
   138: 		MCP_MAX_BLEND_LEVEL);
   139:   mcp_set_blend(MCP_SUB_SCREEN, 
   140: 		MCP_MAX_BLEND_LEVEL);
   141: 
   142:   // fade the mainscreen background to/from black, layer 3
   143:   REG_BLDCNT = BLEND_FADE_BLACK | BLEND_SRC_BG3;
   144:   // fade the lava background to/from black, layer 3
   145:   REG_BLDCNT_SUB = BLEND_FADE_BLACK | BLEND_SRC_BG2;
   146: 
   147:   // init subscreen layer/background 3 
   148:   // the mapbase offset of 24 here means 24*16k which means utilizing
   149:   // the 4th of the possible main background memory regions that vram
   150:   // bank A can be mapped to.  I.e. above we mapped to the 4th.  Had
   151:   // we mapped to the 1st, we would have used offset 0.  
   152:   // note: vram bank A is 128k, i.e. 8 * 16k.
   153:   // note: *16k is because of bitmap type, else would be *2k
   154:   //  bg3 = bgInit(3, BgType_Bmp16, BgSize_B16_256x256, 24, 0);
   155:   bg3 = mcp_bg_init(MCP_MAIN_SCREEN,
   156: 		    3, 
   157: 		    MCP_BG_HIDE,
   158: 		    BgType_Bmp16, 
   159: 		    BgSize_B16_256x256, 
   160: 		    24, 
   161: 		    0);
   162:   // its initial priority, lowest (to emphasize lack of other enabled layers)
   163:   // note: priorities 0..3, 0 highest priority
   164:   bgSetPriority(bg3, 3);
   165: 
   166:   // mcp_bg_init covers this
   167:   // maybe this prevents flicker during decompress
   168:   //  bgHide(bg3);
   169: 
   170:   // load main splash screen into screen/background memory (bgs3)
   171:   decompress(guitar_zyx_splash_mainBitmap, 
   172: 	     (u16*)bgGetGfxPtr(bg3),  
   173: 	     LZ77Vram);
   174:   // maybe this prevents flicker during decompress
   175:   mcp_bg_show(MCP_MAIN_SCREEN, 3);
   176: 
   177:   // note: using offset=4, because 4 will be 64k offset, where 31 above is 62k
   178:   // (thus above using only 2k? seems plausible with tiles for console text chars
   179:   //  bgs2 = bgInitSub(2, BgType_Bmp8, BgSize_B8_256x256, 4, 0);
   180:   bgs2 = mcp_bg_init(MCP_SUB_SCREEN,
   181: 		     2,
   182: 		     MCP_BG_HIDE,
   183: 		     BgType_Bmp8, 
   184: 		     BgSize_B8_256x256, 
   185: 		     4, 
   186: 		     0);
   187:   // its initial priority, lowest (to emphasize lack of other enabled layers)
   188:   // priorities 0..3, 0 highest priority
   189:   bgSetPriority(bgs2, 2);
   190: 
   191:   // mcp_bg_init covers this
   192:   //  bgHide(bgs2);
   193: 
   194:   // note: as per libnds doc on dma, do the flush first
   195:   DC_FlushRange(dlavaBitmap, 256*256);
   196:   dmaCopy(dlavaBitmap, bgGetGfxPtr(bgs2), 256*256);
   197:   DC_FlushRange(dlavaPal, 256*2);
   198:   dmaCopy(dlavaPal, BG_PALETTE_SUB, 256*2);
   199:   
   200:   bgShow(bgs2);
   201: 
   202:   // reinitialize the text color
   203:   BG_PALETTE_SUB[255] = RGB15(0, 0, 0);
   204: 
   205:   /* bad experiment, but probably will use later anyway)
   206:   consoleInit(&bottom_screen_x, 
   207: 	      3, 
   208: 	      BgType_ExRotation,
   209: 	      BgSize_ER_256x256,
   210: 	      31, 
   211: 	      1, 
   212: 	      false,
   213: 	      false);
   214: 
   215:   // custom 8bpp font
   216:   mcpfont.asciiOffset = 32;
   217:   mcpfont.bpp = 8;
   218:   mcpfont.convertSingleColor = false;
   219:   mcpfont.gfx = (u16*)mcpfontTiles;
   220:   mcpfont.numChars = 95;
   221:   mcpfont.numColors =  mcpfontPalLen / 2;
   222:   mcpfont.pal = (u16*)mcpfontPal;
   223:   consoleSetFont(&bottom_screen, &mcpfont);
   224: 
   225:   // set console background layer to top priority
   226:   bgSetPriority(bottom_screen_x.bgId, 0);
   227:   bgShow(bottom_screen_x.bgId);
   228:   */
   229: 
   230: 
   231: }
   232: 
   233: void mode__intro__main___top_renderer(void) {
   234: 
   235:   int t_blend;
   236: 
   237:   // 
   238:   // initialize to unfaded values
   239:   // 
   240:   t_blend = 0;
   241: 
   242: 
   243:   // 
   244:   // do top background fade-in
   245:   // 
   246:   if (mode_ms < INTRO__MAIN__TOP_BG_FADE_IN_START_MS) {
   247:     t_blend = 31;
   248:   } else if (mode_ms < (INTRO__MAIN__TOP_BG_FADE_IN_START_MS + 
   249: 			INTRO__MAIN__TOP_BG_FADE_IN_DURATION_MS)) {
   250:     // main screen bg fade
   251:     t_blend = 31 - ((mode_ms - INTRO__MAIN__TOP_BG_FADE_IN_START_MS) * 31 / 
   252: 		     INTRO__MAIN__TOP_BG_FADE_IN_DURATION_MS);
   253: 
   254:   } 
   255: 
   256:   //
   257:   // handle fadeout
   258:   //
   259:   if (mode != next_mode) {
   260:     if ((mode_ms - exit_mode_ms) < INTRO__MAIN__TOP_BG_FADE_OUT_DURATION_MS) {
   261:       t_blend = ((mode_ms - exit_mode_ms) * 
   262: 		 31 / INTRO__MAIN__TOP_BG_FADE_OUT_DURATION_MS);
   263:     } else {
   264:       t_blend = 31;
   265:     }
   266:     // fadeouts should only be fading out
   267:     // i.e. this code may be executing right after an aborted fadein
   268:     //    t_blend = MAX(REG_BLDY, t_blend);
   269:     t_blend = MAX(t_blend, mcp_get_blend(MCP_MAIN_SCREEN));
   270:   } // end handle fadeout
   271: 
   272:   // actually set the blend register value
   273:   mcp_set_blend(MCP_MAIN_SCREEN,
   274: 		t_blend);
   275: 
   276: }
   277: 
   278: void mode__intro__main___bot_renderer(void) {
   279: 
   280:   unsigned char t_font_int;
   281:   int t_blend;
   282: 
   283: 
   284:   // 
   285:   // initialize to unfaded values
   286:   // 
   287:   t_blend = 0;
   288:   t_font_int = (unsigned char)((int)font_intensity * 1);
   289: 
   290:   // 
   291:   // do bg fade-in
   292:   // 
   293:   if (mode_ms < INTRO__MAIN__BOT_BG_FADE_IN_START_MS) {
   294:     // pre fade-in
   295:     t_blend = 31;
   296:   } else if (mode_ms < (INTRO__MAIN__BOT_BG_FADE_IN_START_MS + 
   297: 			INTRO__MAIN__BOT_BG_FADE_IN_DURATION_MS)) {
   298:     // main screen bg fade-in
   299:     t_blend = 31 - ((mode_ms - INTRO__MAIN__BOT_BG_FADE_IN_START_MS) * 31 / 
   300: 		    INTRO__MAIN__BOT_BG_FADE_IN_DURATION_MS);
   301: 
   302:   } 
   303: 
   304:   // 
   305:   // do text fade-in
   306:   // 
   307:   if (mode_ms < INTRO__MAIN__BOT_TXT_FADE_IN_START_MS) {
   308:     // pre fade-in
   309:     t_font_int = 0;
   310:   } else if (mode_ms < (INTRO__MAIN__BOT_TXT_FADE_IN_START_MS + 
   311: 			INTRO__MAIN__BOT_TXT_FADE_IN_DURATION_MS)) {
   312:     t_font_int = (unsigned char)((int)(font_intensity) * 
   313: 			       (mode_ms - INTRO__MAIN__BOT_TXT_FADE_IN_START_MS) / 
   314: 			       INTRO__MAIN__BOT_TXT_FADE_IN_DURATION_MS);
   315:   } 
   316: 
   317: 
   318:   //
   319:   // do fadeout, possibly overriding above
   320:   //
   321:   if (mode != next_mode) {
   322:     // fade-out
   323:     if ((mode_ms - exit_mode_ms) < INTRO__MAIN__BOT_BG_FADE_OUT_DURATION_MS) {
   324:       t_blend = ((mode_ms - exit_mode_ms) * 
   325: 		      31 / INTRO__MAIN__BOT_BG_FADE_OUT_DURATION_MS);
   326:     } else {
   327:       t_blend = 31;
   328:     }
   329:     // only fadeout
   330:     t_blend = MAX(t_blend, mcp_get_blend(MCP_SUB_SCREEN));
   331: 
   332:     if ((mode_ms - exit_mode_ms) < INTRO__MAIN__BOT_TXT_FADE_OUT_DURATION_MS) {
   333:       t_font_int = (unsigned char)((int)(font_intensity) * 
   334: 				 (INTRO__MAIN__BOT_TXT_FADE_OUT_DURATION_MS - (mode_ms - exit_mode_ms)) / 
   335: 				 INTRO__MAIN__BOT_TXT_FADE_OUT_DURATION_MS);
   336:     } else {
   337:       t_font_int = 0;
   338:     }
   339:     // only fadeout
   340:     t_font_int = MIN(t_font_int, RGB15_TO_G5(BG_PALETTE_SUB[255]));
   341:   }
   342: 
   343:   mcp_set_blend(MCP_SUB_SCREEN,
   344: 		t_blend);
   345:   // set the font color from the calculated intensity (greenish)
   346:   BG_PALETTE_SUB[255] = RGB15(t_font_int / 3,
   347: 			      t_font_int,
   348: 			      t_font_int / 3);
   349: 
   350: 
   351: 
   352:   // clear the console text
   353:   consoleClear();
   354: 
   355:   // tell user they can skip the intro
   356:   printf("\x1b[05;0H     ~~~~~~~~~~~~~~~~~~~~~~ ");
   357:   printf("\x1b[06;0H     ~~~~~~~~~~~~~~~~~~~~~~ ");
   358: 
   359:   printf("\x1b[08;0H       website - http://    ");
   360: 
   361:   printf("\x1b[10;0H      VirOS.org/GuitarZyX   ");
   362: 
   363:   printf("\x1b[12;0H     ~~~~~~~~~~~~~~~~~~~~~~ ");
   364:   printf("\x1b[13;0H     ~~~~~~~~~~~~~~~~~~~~~~ ");
   365: 
   366: 
   367:   printf("\x1b[17;0H       press 'A' to skip    ");
   368: 
   369: }
   370: 
   371: void mode__intro__main___input_handler(void) {
   372: 
   373:   //
   374:   // handle input
   375:   //
   376:   if ((heldkeys & KEY_L) && (heldkeys & KEY_R)) {
   377:     //
   378:     // held(L)+held(R)+something
   379:     //
   380: 
   381:   } else if (heldkeys & KEY_L) {
   382:     //
   383:     // held(L)+something
   384:     //
   385: 
   386:     if (downkeys & KEY_X) {
   387:       execz("/gzmcp/gzmcp-update.nds", 0, NULL);
   388:     }
   389: 
   390:     if (downkeys & KEY_Y) {
   391:       execz("/gzmcp/gzmcp-client.nds", 0, NULL);
   392:     }
   393: 
   394:     if (downkeys & KEY_A) {
   395:       execz("/data/apps/dso/DSOrganize.nds", 0, NULL);
   396:     }
   397: 
   398:     if (downkeys & KEY_B) {
   399:       execz("/gzmcp/gzmcp-update.bak", 0, NULL);
   400:     }
   401: 
   402:   } else if (heldkeys & KEY_R) {
   403:     //
   404:     // held(R)+something
   405:     //
   406: 
   407:   } else {
   408:     //
   409:     // no interesting modifer keys held
   410:     //
   411: 
   412:     if (downkeys & KEY_START) {
   413:     }
   414: 
   415:     if (downkeys & KEY_SELECT) {
   416:     }
   417: 
   418:     if (downkeys & KEY_X) {
   419:     }
   420: 
   421:     if (downkeys & KEY_Y) {
   422:     }
   423: 
   424:     if (downkeys & KEY_A) {
   425:       // if no ssid has been set, prompt the user
   426:       if (! strncmp(ap_ssid, "unset", strlen(ap_ssid))) {
   427: 	system_xmode_new(MODE_SSID__INPUT);
   428:       } else {
   429: 	system_xmode_new(MODE_TPW__JAM);
   430:       }
   431:     }
   432: 
   433:     if (downkeys & KEY_B) {
   434:     }
   435: 
   436:   }
   437: 
   438: 
   439:   // touchpad handling is independent of modifiers (at the moment)
   440:   if ((downkeys & KEY_TOUCH) || (heldkeys & KEY_TOUCH)) {
   441: 
   442:   }
   443: 
   444: }
   445: 
   446: void mode__intro__main___idle(void) {
   447:   //
   448:   // handle fadeout
   449:   //
   450:   if (mode != next_mode) {
   451:     if (((mode_ms - exit_mode_ms) > INTRO__MAIN__TOP_BG_FADE_OUT_DURATION_MS) &&
   452: 	((mode_ms - exit_mode_ms) > INTRO__MAIN__BOT_BG_FADE_OUT_DURATION_MS) &&
   453: 	((mode_ms - exit_mode_ms) > INTRO__MAIN__BOT_TXT_FADE_OUT_DURATION_MS)) {
   454:       /*
   455:       // XXX: this should get moved elsewhere, and use dma
   456:       // XXX: not even remotely sure it is necessary or helps, just a theory
   457:       
   458:       // clear background image memory bank
   459:       // 256 * 256 * 2 = 128k 
   460:       dmaFillHalfWords(0,
   461: 		       (u16*)bgGetGfxPtr(bg3),
   462: 		       256 * 256 * 2);
   463:       //      memptr = (u16*)bgGetGfxPtr(bg3);
   464:       //      for (i = 0 ; i < (256 * 256) ; i++) memptr[i] = (u16)0;
   465:       
   466:       dmaFillHalfWords(0,
   467: 		       (u16*)bgGetGfxPtr(bgs2),
   468: 		       256 * 256);
   469: 
   470:       dmaFillHalfWords(0,
   471: 		       (u16*)bgGetGfxPtr(bgs0),
   472: 		       256 * 256 / 2);
   473:       */
   474:       system_xmode_real();
   475:     }
   476:   }
   477: 
   478: 
   479:   if (mode == next_mode) {
   480:     //
   481:     // check for timed exit
   482:     //
   483:     if (mode_ms > (INTRO__MAIN__TOP_BG_FADE_IN_START_MS +
   484: 		   INTRO__MAIN__TOP_BG_FADE_IN_DURATION_MS +
   485: 		   INTRO__MAIN__TOP_BG_HOLD_DURATION_MS)) {
   486:       
   487:       // if no ssid has been set, prompt the user
   488:       if (! strncmp(ap_ssid, "unset", strlen(ap_ssid))) {
   489: 	system_xmode_new(MODE_SSID__INPUT);
   490:       } else {
   491: 	system_xmode_new(MODE_TPW__JAM);
   492:       }
   493:       
   494:     }
   495: 
   496:   }
   497: 
   498: }
   499: 
   500: 
   501: void mode__intro__main___exit(void) {
   502: 
   503: }
   504: 
   505: 
   506: