/******************************************************************************** Ultra 64 MARIO Brothers Title BG drawing function. Copyright 1995 Nintendo co., ltd. All rights reserved This module was programmed by Y.Tanimoto 1996.4.25 *********************************************************************************/ #include "headers.h" #define TM_FIX_FRAME 45 static ushort* frameBuffer[3]; extern Gfx mario_screen_init[] ; extern Gfx mario_screen_reset[]; extern ushort dispFrame ; extern ushort drawFrame ; extern Gfx vibpack_draw[]; /* ============================================================================================ : Static Gfx and its records to initialize and draw title BG [ Fixed ]. =============================================================================================== */ extern Gfx titleBG_draw_init[] ; extern Gfx titleBG_draw_on[] ; extern Gfx titleBG_draw_tri0[] ; extern Gfx titleBG_draw_tri1[] ; extern Gfx titleBG_draw_tri2[] ; extern Gfx titleBG_draw_tri3[] ; extern Gfx titleBG_draw_reset[] ; extern Gfx titleTM_draw[] ; extern Gfx RCP_Nintendo[] ; extern Gfx wipe_gfx_init[] ; static Gfx* titleBG_draw[] = { titleBG_draw_tri0, titleBG_draw_tri1, titleBG_draw_tri2, titleBG_draw_tri3 }; /* ============================================================================================ : 2D coordinate data [ Fixed ]. =============================================================================================== */ static float Xo[] = { 0.0, 80.0, 160.0, 240.0, 0.0, 80.0, 160.0, 240.0, 0.0, 80.0, 160.0, 240.0 }; static float Yo[] = { 160.0, 160.0, 160.0, 160.0, 80.0, 80.0, 80.0, 80.0, 0.0, 0.0, 0.0, 0.0 }; /* ============================================================================================ : Ptr to real image data records and their record. =============================================================================================== */ extern ushort* titleBG_A[]; extern ushort* titleGm_O[]; static ushort** titleBG[] = { titleBG_A, titleGm_O }; /* ============================================================================================ : Back pattern data and its record. =============================================================================================== */ static char back_pattern_A[] = { 0, 0, 0, 0, // <--- Each is image No. 0, 0, 0, 0, 0, 0, 0, 0, }; static char* back_pattern_rec[] = { back_pattern_A }; static int gover_count ; static int gover_flag ; /* ============================================================================================ : Back pattern and its changing data for Game Over. =============================================================================================== */ static char back_pattern_GV[] = { 1, 1, 1, 1, // <--- Each is image No. 1, 1, 1, 1, 1, 1, 1, 1, }; static char back_change_proc[] = { 0, 1, 2, 3, 7, 11, 10, 9, 8, 4, 5, 6 }; /* ============================================================================================ : Back pattern data of multi-screen. =============================================================================================== */ static char pos[] = { 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,0,0,0,0,1,1, 1,1,0,0,0,0,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1 }; static char pos_proc[] = { 0,1,2,3,4,5,6,7,15,23,31,39,47,46,45,44,43,42,41,40,32,24,16, 8,9,10,11,12,13,14,22,30,38,37,36,35,34,33,25,17 }; static char pos_procFlag = 0 ; /* ============================================================================================ : Trademark drawing. =============================================================================================== */ static short logo_Count ; static int logo_Alpha ; extern float logo_start[]; extern float logo_end[] ; /* ------------------------------------------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------------------------------------------ */ /* ============================================================================================ : Title BG drawing function. =============================================================================================== */ extern ulong TitleLGDraw(int code, MapNode *node, void *data) { MapCProg* cprog = (MapCProg *)node ; Gfx* gfxPtr = NULL ; Gfx* gfxTmp = NULL ; Mtx* scale ; float* s_data = (float *)SegmentToVirtual(logo_start); float* e_data = (float *)SegmentToVirtual(logo_end); float sx_val ; float sy_val ; float sz_val ; if (code != MAP_CBACK_EXEC) { logo_Count = 0 ; }else if (code == MAP_CBACK_EXEC) { MapSetRenderMode(cprog, RM_SURF); scale = (Mtx *)AllocDynamic(sizeof(Mtx)); gfxPtr = (Gfx *)AllocDynamic(4*sizeof(Gfx)); gfxTmp = gfxPtr ; if (logo_Count >= 0 && logo_Count <= 19) { sx_val = s_data[3*logo_Count]; sy_val = s_data[3*logo_Count+1]; sz_val = s_data[3*logo_Count+2]; }else if (logo_Count >= 20 && logo_Count <= TM_FIX_FRAME+29) { sx_val = 1.0 ; sy_val = 1.0 ; sz_val = 1.0 ; }else if (logo_Count >= TM_FIX_FRAME+30 && logo_Count <= TM_FIX_FRAME+45) { sx_val = e_data[3*(logo_Count-(TM_FIX_FRAME+30))]; sy_val = e_data[3*(logo_Count-(TM_FIX_FRAME+30))+1]; sz_val = e_data[3*(logo_Count-(TM_FIX_FRAME+30))+2]; }else{ sx_val = 0.0 ; sy_val = 0.0 ; sz_val = 0.0 ; } guScale(scale, sx_val, sy_val, sz_val); gSPMatrix(gfxTmp++, scale, G_MTX_MODELVIEW|G_MTX_MUL|G_MTX_PUSH); gSPDisplayList(gfxTmp++, RCP_Nintendo); gSPPopMatrix(gfxTmp++, G_MTX_MODELVIEW); gSPEndDisplayList(gfxTmp); logo_Count++ ; } return((ulong)gfxPtr); } /* ============================================================================================ : Title trade mark drawing function. =============================================================================================== */ extern ulong TitleTMDraw(int code, MapNode *node, void *data) { MapCProg* cprog = (MapCProg *)node ; Gfx* gfxPtr = NULL ; Gfx* gfxTmp = NULL ; if (code != MAP_CBACK_EXEC) { logo_Alpha = 0 ; }else if (code == MAP_CBACK_EXEC) { gfxPtr = (Gfx *)AllocDynamic(5*sizeof(Gfx)); gfxTmp = gfxPtr ; gSPDisplayList(gfxTmp++, wipe_gfx_init); gDPSetEnvColor(gfxTmp++, 255, 255, 255, logo_Alpha); switch(logo_Alpha) { case 255 : MapSetRenderMode(cprog, RM_SURF); gDPSetRenderMode(gfxTmp++, G_RM_AA_OPA_SURF, G_RM_AA_OPA_SURF2); break ; default : MapSetRenderMode(cprog, RM_XSURF); gDPSetRenderMode(gfxTmp++, G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2); break ; } gSPDisplayList(gfxTmp++, titleTM_draw); gSPEndDisplayList(gfxTmp); if (logo_Count >= 19) { logo_Alpha += 26 ; if (logo_Alpha > 255) { logo_Alpha = 255 ; } } } return((ulong)gfxPtr); } /* ============================================================================================ : Draw one image in one position. =============================================================================================== */ static Gfx* TitleBGDrawEach(int positNo, char *ptrnXX) { Mtx* transM = (Mtx *)AllocDynamic(sizeof(Mtx)); Gfx* gfxPtr = (Gfx *)AllocDynamic(36*sizeof(Gfx)); Gfx* gfxTmp = gfxPtr ; ushort** image ; int i ; image = (ushort **)SegmentToVirtual(titleBG[(ptrnXX[positNo])]); guTranslate(transM, Xo[positNo], Yo[positNo], 0.0); gSPMatrix(gfxTmp++, transM, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_PUSH ); gSPDisplayList(gfxTmp++, titleBG_draw_on); for (i = 0 ; i < 4 ; i++) { gDPLoadTextureBlock(gfxTmp++, image[i], G_IM_FMT_RGBA, G_IM_SIZ_16b, 80, 20, 0, G_TX_CLAMP|G_TX_NOMIRROR, G_TX_CLAMP|G_TX_NOMIRROR, 7, 6, G_TX_NOLOD, G_TX_NOLOD); gSPDisplayList(gfxTmp++, titleBG_draw[i]); } gSPPopMatrix(gfxTmp++, G_MTX_MODELVIEW); gSPEndDisplayList(gfxTmp); return(gfxPtr); } /* ============================================================================================ : Title BG drawing function. =============================================================================================== */ extern ulong TitleBGDraw(int code, MapNode *node, void *data) { MapCProg* cprog = (MapCProg *)node ; int ptrnNo = (int)((cprog->refCon) & 0xff); char* ptrnXX = back_pattern_rec[ptrnNo]; Gfx* gfxPtr = NULL ; Gfx* gfxTmp = NULL ; int position ; if (code == MAP_CBACK_EXEC) { gfxPtr = (Gfx *)AllocDynamic(16*sizeof(Gfx)); gfxTmp = gfxPtr ; MapSetRenderMode(cprog, RM_SURF); gSPDisplayList(gfxTmp++, wipe_gfx_init); gSPDisplayList(gfxTmp++, titleBG_draw_init); for (position = 0 ; position < 12 ; position++) { gSPDisplayList(gfxTmp++, TitleBGDrawEach(position, ptrnXX)); } gSPDisplayList(gfxTmp++, titleBG_draw_reset); gSPEndDisplayList(gfxTmp); } return((ulong)gfxPtr); } /* ============================================================================================ : Game Over BG drawing function. =============================================================================================== */ extern ulong GOverBGDraw(int code, MapNode *node, void *data) { MapCProg* cprog = (MapCProg *)node ; Gfx* gfxPtr = NULL ; Gfx* gfxTmp = NULL ; int position, i ; if (code != MAP_CBACK_EXEC) { gover_count = 0 ; gover_flag = -2 ; for (i = 0 ; i < 12 ; i++) { back_pattern_GV[i] = 1 ; } }else{ gfxPtr = (Gfx *)AllocDynamic(16*sizeof(Gfx)); gfxTmp = gfxPtr ; if (gover_flag == -2) { if (gover_count == 180) { gover_flag++ ; gover_count = 0 ; } }else if (gover_flag != 11) { if ((gover_count % 2) == 0) { gover_flag++ ; back_pattern_GV[(back_change_proc[gover_flag])] = 0 ; } } if (gover_flag != 11) { gover_count++ ; } MapSetRenderMode(cprog, RM_SURF); gSPDisplayList(gfxTmp++, wipe_gfx_init); gSPDisplayList(gfxTmp++, titleBG_draw_init); for (position = 0 ; position < 12 ; position++) { gSPDisplayList(gfxTmp++, TitleBGDrawEach(position, back_pattern_GV)); } gSPDisplayList(gfxTmp++, titleBG_draw_reset); gSPEndDisplayList(gfxTmp); } return((ulong)gfxPtr); } /* -------------------------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------------------------- */ /* ============================================================================================ : Generate gSPTextureRectangle() commands. =============================================================================================== */ static void GenTextureRect(Gfx **gfxTmp) { int x, y ; for (y = 0 ; y < 6 ; y++) { for (x = 0 ; x < 8 ; x++) { if (pos[y*8+x]) { gSPTextureRectangle((*gfxTmp)++, ((40*x) << 2), ((40*y) << 2), ((40*x+39) << 2), ((40*y+39) << 2), 0, (0 << 5), (0 << 5), (4 << 10), (1 << 10) ); } } } } /* ============================================================================================ : Copy image data block by copy-mode. =============================================================================================== */ static Gfx* DrawImageBlock(ushort *image, int imgW, int imgH) { Gfx *gfxPtr ; Gfx *gfxTmp ; gfxPtr = (Gfx *)AllocDynamic(110*sizeof(Gfx)); if (gfxPtr == NULL) { return(gfxPtr) ; }else { gfxTmp = gfxPtr ; } gSPDisplayList(gfxTmp++, mario_screen_init); gDPLoadTextureBlock(gfxTmp++, K0_TO_PHYS(image), G_IM_FMT_RGBA, G_IM_SIZ_16b, imgW, imgH, 0, G_TX_CLAMP|G_TX_NOMIRROR, G_TX_CLAMP|G_TX_NOMIRROR, 6, 6, G_TX_NOLOD, G_TX_NOLOD); GenTextureRect(&(gfxTmp)); gSPDisplayList(gfxTmp++, mario_screen_reset); gSPEndDisplayList(gfxTmp++); return(gfxPtr); } /* ============================================================================================ : Get and shrink image data from the frame-buffer. =============================================================================================== */ static ushort* ShrinkImageData(int imgW, int imgH, int unitW, int unitH) { ushort* fb_image ; ushort* dt_image ; int fb_offset ; int dt_offset ; int sx, sy ; int i, j, p, q ; ushort r_short, g_short, b_short ; float r_float, g_float, b_float ; float r_total, g_total, b_total ; float devide ; fb_image = frameBuffer[drawFrame]; dt_image = (ushort *)AllocDynamic((imgW*imgH)*sizeof(ushort)); if (dt_image == NULL) { return(dt_image); } sx = 120 ; sy = 80 ; for (q = 0 ; q < imgH ; q++) { for (p = 0 ; p < imgW ; p++) { r_total = 0.0 ; g_total = 0.0 ; b_total = 0.0 ; for (j = 0 ; j < unitH ; j++) { for (i = 0 ; i < unitW ; i++) { fb_offset = 320*(sy + unitH*q + j) + (sx + unitW*p + i); r_short = fb_image[fb_offset]; g_short = fb_image[fb_offset]; b_short = fb_image[fb_offset]; r_float = (float)((r_short >> 11) & 0x1f); g_float = (float)((g_short >> 6) & 0x1f); b_float = (float)((b_short >> 1) & 0x1f); r_total += r_float ; g_total += g_float ; b_total += b_float ; } } devide = (float)(unitW*unitH); r_short = (((ushort)((r_total / devide) + 0.5)) << 11) & 0xf800 ; g_short = (((ushort)((g_total / devide) + 0.5)) << 6) & 0x07c0 ; b_short = (((ushort)((b_total / devide) + 0.5)) << 1) & 0x003e ; dt_offset = imgH*q + p ; dt_image[dt_offset] = r_short + g_short + b_short + 1 ; } } return(dt_image); } /* ============================================================================================ : Real time image change function. =============================================================================================== */ extern ulong ImageChangeFunc(int code, MapNode *node, void *data) { MapCProg* cprog ; ushort* imgPtr ; Gfx* gfxPtr = NULL ; int i ; if (code != MAP_CBACK_EXEC) { frameBuffer[0] = (ushort *)(frameMemoryA); frameBuffer[1] = (ushort *)(frameMemoryB); frameBuffer[2] = (ushort *)(frameMemoryC); for (i = 0 ; i < 48 ; i++) { pos[i] = 0 ; } }else if (code == MAP_CBACK_EXEC) { if (pos_procFlag == 0) { if (cont1p->trigger & CONT_BACK) { Na_FixSeFlagEntry(NA_SE2_SET); pos[0] ^= 1 ; pos_procFlag++ ; } }else{ (pos[(pos_proc[pos_procFlag])]) ^= 1 ; pos_procFlag++ ; if (pos_procFlag >= 40) { pos_procFlag = 0 ; } } if ((pos[0] == 1) || (pos[17] == 1)) { if ((imgPtr = ShrinkImageData(40, 40, 2, 2)) != NULL) { cprog = (MapCProg *)node ; MapSetRenderMode(cprog, RM_SURF); gfxPtr = DrawImageBlock(imgPtr, 40, 40); } } } return((ulong)gfxPtr); } /* -------------------------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------------------------- */ /* ============================================================================================ : Draw vibrate-pack logo. =============================================================================================== */ extern ulong VibLogoDraw(int code, MapNode *node, void *data) { MapCProg* cprog ; Gfx* gfxTmp ; Gfx* gfxPtr ; int flag ; char value ; if (code != MAP_CBACK_EXEC) { gfxPtr = NULL ; }else if (code == MAP_CBACK_EXEC) { cprog = (MapCProg *)node ; MapSetRenderMode(cprog, RM_SURF); flag = (int)((cprog->refCon) & 0xff); if (flag == 0) { value = back_pattern_A[6] ; }else if (flag == 1) { value = back_pattern_GV[6]; } if (value == 0) { gfxPtr = (Gfx *)AllocDynamic(3*sizeof(Gfx)); if (gfxPtr != NULL) { gfxTmp = gfxPtr ; gSPDisplayList(gfxTmp++, vibpack_draw); gSPEndDisplayList(gfxTmp); } }else{ gfxPtr = NULL ; } } return((ulong)gfxPtr); }