/*************************************************************************************************** Message Function programed by Iwamoto Daiki [1996 June 17] ****************************************************************************************************/ #define WORDS 30 #define PUSH 1 #define NOPUSH 2 #define MESSAG 0 #define SELECT 1 #include "Font_dot.h" /*----- Message Struct -----*/ typedef struct { int code; char line; short posx; short posy; unsigned char *string; } Message; extern Message* Messagelist[]; extern Message *Selectlist[]; static char message_flag = 0 ; //----------------------------------- //message_flag --> 0 window open // 1 font indication // 2 font change // 3 window close //------------------------------------- static float theta = 90; static short delta; static float win_sc = 19; static short font_tr = 0; static char message_type = 0; static short messageNo = -1; static short mess_first_pointer = 0; static short message_go = 0; static char cursor_no = 1; static char cursor_line; static char cursor_flag = 0; static int message_value; // Variable Number static unsigned short font_alpha; static unsigned char sticktrg = 0; static unsigned char trg_count = 0; /*----------*/ int messageAnsNo = 0; /*================================================================================================= Draw font Function File Include ===================================================================================================*/ #include "../drawfont.c" /*================================================================================================ Cursor Event ================================================================================================*/ /**************************************************************************************************/ /* Cursor Event */ /**************************************************************************************************/ extern void ContCursorEvent(char side_code ,char* cursol,char start,char end) { unsigned char str = 0x00; if (side_code == 1) { //Tate if (contOr->sticky > 60) str += 0x01; if (contOr->sticky < -60) str += 0x02; } else if (side_code == 2) { //Yoko if (contOr->stickx > 60) str += 0x02; if (contOr->stickx < -60) str += 0x01; } if (((str^sticktrg) & str) == 0x02) { if (*cursol == end) *cursol = end; else { Na_FixSeFlagEntry(NA_SYS_CURSOR); (*cursol) ++; } } if (((str^sticktrg) & str) == 0x01) { if (*cursol == start) *cursol == start; else { Na_FixSeFlagEntry(NA_SYS_CURSOR); (*cursol)--; } } if (trg_count == 10) { trg_count = 8; sticktrg = 0; } else { trg_count++; sticktrg = str; } if ( (str & 0x03) == 0) trg_count = 0; } /********************************************************************************/ /* CCenterling */ /********************************************************************************/ extern short CharCentering(short posx,unsigned char *font,float width) { short i=0; float dot_len = 0.; unsigned short idx; while (font[i] != 0xff || font[i+1]!=0xff) { idx = ((unsigned short)font[i]) << 8 | font[i+1]; if (idx<256) dot_len += (float)dot_tbl[idx]; else dot_len += 16.; i += 2; } return( posx - (short)(dot_len/2.)); } /********************************************************************************/ /* Message String Length */ /********************************************************************************/ extern short MessageLength(unsigned char* font) { short i=0; short dot_len = 0; unsigned short idx; while (font[i] != 0xff || font[i+1]!=0xff) { idx = ((unsigned short)font[i]) << 8 | font[i+1]; if (idx<256) dot_len += dot_tbl[idx]; else dot_len += 16; i += 2; } return((short)dot_len); } /********************************************************************************/ /* Draw Course Coin Number . */ /********************************************************************************/ extern void DrawCoinScore(int mode,char player,char course,short posx,short posy) { unsigned char coin_num[8]; short coin; static unsigned char se16_coinnum1[] = {0x33, 0xff}; //coin num static unsigned char se16_coinnum2[] = {0x32, 0xff}; //* num if (mode == 0) coin = BuGetHiScore(course); else coin = BuGetNumCoins(player,course); if (coin != 0) { Draw16bitFont(2,posx,posy,se16_coinnum1); Draw16bitFont(2,posx+16,posy,se16_coinnum2); I_itochar_16(coin,coin_num); Draw16bitFont(2,posx+32,posy,coin_num); } } /********************************************************************************/ /* Draw Course Star Number . */ /********************************************************************************/ extern void DrawCourseStar(char player,char course,short posx,short posy) { unsigned char star_num[8]; short star; unsigned char se16_coinnum1[] = {0x35, 0xff}; //star num unsigned char se16_coinnum2[] = {0x32, 0xff}; //* num star = BuGetCourseStars(player,course); if (star != 0) { Draw16bitFont(2,posx,posy,se16_coinnum1); Draw16bitFont(2,posx+16,posy,se16_coinnum2); I_itochar_16(star,star_num); Draw16bitFont(2,posx+32,posy,star_num); } } /********************************************************************************/ /* Convert Integer to char . */ /********************************************************************************/ extern void I_itochar_16(int num,unsigned char* font) { int n100; int n10; int n1; char i = 0; if (num > 999) { font[0] = 0; font[1] = 0xff; return;} n100 = (int)(num/100); n10 = (int)((num - n100*100)/10); n1 = (int)(num - n100*100 - n10*10); if (n100 != 0) {font[i] = n100; i++;} if (n10 != 0 || n100 != 0) {font[i] = n10 ; i++;} {font[i] = n1 ; i++;} font[i] = 0xff; } extern void I_itochar(int num,unsigned char* font) { int n100; int n10; int n1; char i = 0; if (num > 999) { font[0] = 0; font[1] = 0; font[2] = 0xff; font[3]=0xff; return;} n100 = (int)(num/100); n10 = (int)((num - n100*100)/10); n1 = (int)(num - n100*100 - n10*10); if (n100 != 0) {font[i]=0; i++; font[i] = n100; i++;} if (n10 != 0 || n100 != 0) {font[i]=0; i++; font[i] = n10 ; i++;} {font[i]=0; i++; font[i] = n1 ; i++;} font[i] = 0xff; i++; font[i] = 0xff; } /*================================================================================================= ===================================================================================================*/ /*************************************************************************************************** Get Message No ****************************************************************************************************/ extern short GetMessageNo(void) { return(messageNo); } /*************************************************************************************************** Call Message Normal ****************************************************************************************************/ extern void CallMessage(short callNo) { if (messageNo == -1) { messageNo = callNo; message_type = 0; } } /*************************************************************************************************** Call Message with Integer ****************************************************************************************************/ extern void CallMessageInt(short callNo,int num) { if (messageNo == -1) { messageNo = callNo; message_value = num; message_type = 0; } } /*************************************************************************************************** Call Message for Tatefuda ****************************************************************************************************/ extern void CallMessageFuda(short callNo) { if (messageNo == -1) { messageNo = callNo; message_type = 1; } } /*************************************************************************************************** Call Message Normal ****************************************************************************************************/ extern void CallMessageYesNo(short callNo) { if (messageNo == -1) { messageNo = callNo; message_type = 0; cursor_flag = 1; } } /*************************************************************************************************** Call Message Normal ****************************************************************************************************/ extern void MessageEnforcedDestroy(void) { FreezeGame(0,NULL); //Window Close! if (message_type == 1) ViewingCam(VIEW_OFF); win_sc = 19; theta = 90; message_flag = 0; messageNo = -1; message_go = 0; cursor_flag = 0; mess_first_pointer = 0; messageAnsNo = 0; } /*************************************************************************************************** Message Window ****************************************************************************************************/ static void DrawMessageWindow(Message *message,char line) { Mtx* matrix; iTranslate(NOPUSH,message->posx,message->posy,0); switch (message_type) { case 0: if (message_flag == 0 || message_flag == 3) { iScale(NOPUSH,1./win_sc ,1./win_sc, 1.); iRotate(NOPUSH,theta*4,0., 0. , 1.0); } gDPSetEnvColor(graphPtr++,0,0,0,150); break; case 1: if (message_flag == 0 || message_flag == 3) { iTranslate(NOPUSH,(65.-65./win_sc),(40./win_sc-40),0); iScale(NOPUSH,1./win_sc,1./win_sc,1.); } gDPSetEnvColor(graphPtr++,255,255,255,150); break; } iTranslate(PUSH,-7,5,0); iScale(NOPUSH,1+0.1 ,(float)(line+1)/5+0.1 ,1.); gSPDisplayList(graphPtr++, RCP_Mess_window); gSPPopMatrix(graphPtr++,G_MTX_MODELVIEW); } /*************************************************************************************************** Set Font Color ****************************************************************************************************/ static void SetFontColor(char code ,char line) { unsigned char color; if (code == SELECT) { // CURSOL MESSAGE if (line == 1) { gDPSetEnvColor(graphPtr++,255,255,255,255); } else { if (line == cursor_no){ color = 200 + sin(delta)*50; gDPSetEnvColor(graphPtr++,color,color,color,255); } else { gDPSetEnvColor(graphPtr++,200,200,200,255); } } } else { switch(message_type) { case 0: break; case 1: gDPSetEnvColor(graphPtr++,0,0,0,255); break; } } } /*************************************************************************************************** Kaigyou ****************************************************************************************************/ static void KaigyouEvent(char line, char end_line,char *end_flag,char *space,short *words) { gSPPopMatrix(graphPtr++,G_MTX_MODELVIEW); if (line == end_line) { *end_flag = 1; return; } iTranslate(PUSH, 0., 2-(line*20),0); *words = 0; *space = 1; } /*************************************************************************************************** Variable Event ****************************************************************************************************/ static void VariableEvent(char *space,short *words) { char ten_v = (char)(message_value/10); char one_v = (char)(message_value - ten_v*10); if (ten_v != 0) { if (*space != 1) iTranslate(NOPUSH,dot_tbl[0x9e]*(*space),0,0); DrawMessageTexture(ten_v); iTranslate(NOPUSH,dot_tbl[ten_v],0,0); *space=1; (*words)++; } else { // (*space)++; } if (*space != 1) iTranslate(NOPUSH,dot_tbl[0x9e]*(*space-1),0,0); DrawMessageTexture(one_v); iTranslate(NOPUSH,dot_tbl[one_v],0,0); (*words)++; *space=1; } /*************************************************************************************************** Draw String Font ****************************************************************************************************/ static void DrawFontStrings(char code,char line, short* words, char page_line,char space,char draw_line) { char i; unsigned char str[][5] = { { 03, 0x37,0x2b,0x28, }, //code 0 -->the { 03, 0x3c,0x32,0x38, }, //code 1 -->you }; if (line >= draw_line && line <= draw_line+page_line) { if (*words != 0 || space != 1) iTranslate(NOPUSH,dot_tbl[0x9e]*(space-1),0,0); for (i=0; istring)); char line = 1; char end_line; char end_flag = 0; char daku_flag = 0; char space = 1; char page_line = message->line; short mesp; short words = 0; if (message_flag == 2) end_line = page_line*2 - 1; else end_line = page_line; gSPDisplayList(graphPtr++, RCP_mess_font_on); mesp = message_go; if (message_flag == 2) iTranslate(NOPUSH,0,font_tr ,0); iTranslate(PUSH, 0., 2-(line*20),0); while (end_flag == 0) { SetFontColor(code,line); //num = stringPtr[mesp]; b1 = stringPtr[mesp]; b2 = stringPtr[mesp+1]; idx = ((unsigned short)b1)<<8 | b2 ; switch (idx) { case 0xffff: // end of message end_flag = 2; gSPPopMatrix(graphPtr++,G_MTX_MODELVIEW); break; case 0xfffe: // new line line++; KaigyouEvent(line, end_line,&end_flag,&space,&words); break; case 0xfffd: // 2 space space+=2; words+=2; break; //TODO: English letters /*daku*/ case 0xfff0 : daku_flag = 1; break; /*maru*/ case 0xfff1 : daku_flag = 2; break; /*space*/ case 0xff9e : space++; words++; break; /*space*/ case 0xffd0 : space+=2; words+=2; break; /*the*/ case 0xffd1 : DrawFontStrings(0,line, &words,page_line,space,draw_line); space=1; break; /*you*/ case 0xffd2 : DrawFontStrings(1,line, &words,page_line,space,draw_line); space=1; break; /*value*/ case 0xffe0 : VariableEvent(&space,&words); break; default: if (idx>255) { idx = 2 * (idx-255) - 1 + 255; if (line >= draw_line && line <=draw_line+page_line) { if (words != 0 || space != 1) iTranslate(NOPUSH,dot_tbl[0x9e]*(space-1),0,0); DrawMessageTexture_zh(idx); iTranslate(NOPUSH, 8, 0, 0); DrawMessageTexture_zh(idx+1); iTranslate(NOPUSH, 8, 0, 0); space = 1; words++; } } else { //TODO: old encoding stuff, delete eventually if (line >= draw_line && line <= draw_line+page_line) { if (words != 0 || space != 1) iTranslate(NOPUSH,dot_tbl[0x9e]*(space-1),0,0); DrawMessageTexture(idx); iTranslate(NOPUSH,dot_tbl[idx],0,0); space = 1; words++; } } break; } mesp += 2; } gSPDisplayList(graphPtr++, RCP_mess_font_off); if (message_flag == 1) { if (end_flag == 2) mess_first_pointer = -1; else mess_first_pointer = mesp; } cursor_line = line; } #else static void DrawMessageFont(char code,Message *message,char draw_line) { int i,k; unsigned char num; unsigned char* stringPtr = (uchar *)(SegmentToVirtual(message->string)); char line = 1; char end_line; char end_flag = 0; char daku_flag = 0; char space = 1; char page_line = message->line; short mesp; short words = 0; if (message_flag == 2) end_line = page_line*2 + 1; else end_line = page_line + 1; gSPDisplayList(graphPtr++, RCP_mess_font_on); mesp = message_go; if (message_flag == 2) iTranslate(NOPUSH,0,font_tr ,0); iTranslate(PUSH, 0., 2-(line*16),0); while (end_flag == 0) { SetFontColor(code,line); num = stringPtr[mesp]; switch (num) { /*end*/ case 0xff : end_flag = 2; gSPPopMatrix(graphPtr++,G_MTX_MODELVIEW); break; /*kaigyou*/ case 0xfe : line++; KaigyouEvent(line, end_line,&end_flag,&space,&words); break; /*daku*/ case 0xf0 : daku_flag = 1; break; /*maru*/ case 0xf1 : daku_flag = 2; break; /*space*/ case 0x9e : space++; words++; break; /*space*/ case 0xd0 : space+=2; words+=2; break; /*the*/ case 0xd1 : DrawFontStrings(0,line, &words,page_line,space,draw_line); space=1; break; /*you*/ case 0xd2 : DrawFontStrings(1,line, &words,page_line,space,draw_line); space=1; break; /*value*/ case 0xe0 : VariableEvent(&space,&words); break; default : if (line >= draw_line && line <= draw_line+page_line) { if (words != 0 || space != 1) iTranslate(NOPUSH,dot_tbl[0x9e]*(space-1),0,0); DrawMessageTexture(num); iTranslate(NOPUSH,dot_tbl[num],0,0); space = 1; words++; } } mesp++; } gSPDisplayList(graphPtr++, RCP_mess_font_off); if (message_flag == 1) { if (end_flag == 2) mess_first_pointer = -1; else mess_first_pointer = mesp; } cursor_line = line; } #endif /*************************************************************************************************** Draw Select Cursor ****************************************************************************************************/ static void DrawCursor(void) { if (message_flag == 1) ContCursorEvent(2 ,&cursor_no,1,2); iTranslate(NOPUSH, (cursor_no-1)*(58), 2-(cursor_line*20),0); if (message_type == 0) { gDPSetEnvColor(graphPtr++,255,255,255,255); } else { gDPSetEnvColor(graphPtr++, 0, 0, 0,255); } gSPDisplayList(graphPtr++, RCP_mess_cursor); } /*************************************************************************************************** Draw Okuri ****************************************************************************************************/ static void DrawOkuri(char line) { ulong counter = frameCounter; if ((counter & 0x000000008)) return; iTranslate(PUSH,118,-18*line+5,0); iScale(NOPUSH,0.8 ,0.8, 1.); iRotate(NOPUSH,-90. ,0., 0. , 1.0); if (message_type == 0) { gDPSetEnvColor(graphPtr++,255,255,255,255); } else { gDPSetEnvColor(graphPtr++, 0, 0, 0,255); } gSPDisplayList(graphPtr++, RCP_mess_cursor); gSPPopMatrix(graphPtr++,G_MTX_MODELVIEW); } /*************************************************************************************************** Message Special Sound ****************************************************************************************************/ static void MessageSpecialSound(short message_no) { short mess_boss[] = {17,114,128,117,150}; short mess_race[] = { 5,9,55,164}; short mess_switch[] = {10,11,12,13,14}; short mess_bossStop[] = {17,115,116,118,152}; short i; for (i=0; i<5; i++) { if (mess_boss[i] == message_no) { Na_MusicMuteOff(); Na_MusicStart(NA_MUS_HANDLE,NA_BOSS_BGM,0); return; } } for (i=0; i<4; i++) { if (mess_race[i] == message_no && cursor_no == 1) { Na_RaceFanfareBgm(); return; } } for (i=0; i<5; i++) { if (mess_switch[i] == message_no && cursor_no == 1) { Na_FixSeFlagEntry(NA_SE2_SET); return; } } for (i=0; i<5; i++) { if (mess_bossStop[i] == message_no) { Na_BossBgmStop(); return; } } } /*************************************************************************************************** Message Event ****************************************************************************************************/ static void MessageOnlyEvent(void) { Message** mlist = (Message **)(SegmentToVirtual(Messagelist)); Message* message = (Message *)(SegmentToVirtual(mlist[messageNo])); char draw_line; if (message == SegmentToVirtual(NULL)) { rmonpf(("Message not defined. (%d)\n",messageNo)); messageNo = -1; return; } switch(message_flag) { case 0: if (theta == 90) { // FreezeGame(-1,NULL); //Window Open! Na_MessageSound(messageNo); Na_FixSeFlagEntry(NA_SYS_WIN_OPEN); } if (message_type == 0) { theta -= 7.5; win_sc -=1.5; } else { theta -= 10.; win_sc -=2.; } if (theta == 0) { message_flag = 1; cursor_no = 1; } draw_line = 1; break; case 1: theta = 0; //Message Draw! if (contOr->trigger & CONT_A || contOr->trigger & CONT_B) { if (mess_first_pointer == -1) { MessageSpecialSound(messageNo); message_flag = 3; } else { message_flag = 2; Na_FixSeFlagEntry(NA_SYS_MESSAGEPASS); } } draw_line = 1; break; case 2: font_tr += 2*(message->line); //Next Message! if (font_tr >= 16*(message->line)) { message_go = mess_first_pointer; message_flag = 1; font_tr = 0; } draw_line = (font_tr/16) + 1; break; case 3: if (theta == 20) { FreezeGame(0,NULL); //Window Close! Na_FixSeFlagEntry(NA_SYS_WIN_CLOSE); if (message_type == 1) ViewingCam(VIEW_OFF); messageAnsNo = cursor_no; } theta += 10; win_sc +=2; if (theta == 90) { message_flag = 0; messageNo = -1; message_go = 0; cursor_flag = 0; mess_first_pointer = 0; messageAnsNo = 0; } draw_line = 1; break; } DrawMessageWindow(message,message->line); gDPSetScissor(graphPtr++,G_SC_NON_INTERLACE,ZeroRe(message->posx),ZeroRe(SCREEN_HEIGHT - message->posy), ZeroRe(message->posx+132),ZeroRe(SCREEN_HEIGHT - message->posy+(80*(message->line+1)/5))); DrawMessageFont(MESSAG,message,draw_line); if (mess_first_pointer == -1 && cursor_flag == 1) DrawCursor(); gDPSetScissor(graphPtr++, G_SC_NON_INTERLACE, 2, 2, SCREEN_WIDTH-4, SCREEN_HEIGHT-4); if (mess_first_pointer != -1 && message_flag == 1) DrawOkuri(message->line); } /***************************************************************************************************/ /***************************************************************************************************/ /***************************************************************************************************/ /***************************************************************************************************/ static short selectNo = -1; /*************************************************************************************************** Call Select Message ****************************************************************************************************/ extern void CallSelectMessage(short callNo) { if (selectNo == -1) { selectNo = callNo; } } #if 0 /*************************************************************************************************** Draw Select Cursor ****************************************************************************************************/ extern void DrawSelectCursor(char line_min,char line_max) { unsigned char str = 0x00; if (contOr->sticky > 60) str += 0x08; if (contOr->sticky < -60) str += 0x04; if (contOr->stickx > 60) str += 0x02; if (contOr->stickx < -60) str += 0x01; if (((str^sticktrg) & str) == 0x08) { cursor_no--; if (cursor_no < line_min) cursor_no = line_min; else Na_FixSeFlagEntry(NA_SYS_CURSOR); //Sound CURSOL } if (((str^sticktrg) & str) == 0x04) { cursor_no++; if (cursor_no > line_max) cursor_no = line_max; else Na_FixSeFlagEntry(NA_SYS_CURSOR); //Sound CURSOL } if (trg_count == 10) { trg_count = 8; sticktrg = 0; } else { trg_count++; sticktrg = str; } if ( (str & 0x0c) == 0) trg_count = 0; iTranslate(PUSH, 5., 2-(cursor_no*20),0); gDPSetEnvColor(graphPtr++,255,255,255,255); gSPDisplayList(graphPtr++, RCP_mess_cursor); gSPPopMatrix(graphPtr++,G_MTX_MODELVIEW); } /*************************************************************************************************** Message Select Event ****************************************************************************************************/ extern short SelectMessageEvent(void) { short ret_num; Message** mlist = (Message **)(SegmentToVirtual(Selectlist)); Message* message = (Message *)(SegmentToVirtual(mlist[selectNo])); if (message == NULL) { rmonpf(("Message not defined. (%d)\n",selectNo)); selectNo = -1; return(NULL); } switch(message_flag) { case 0: if (theta == 70) { FreezeGame(-1,NULL); //Window Open! Na_FixSeFlagEntry(NA_SYS_PAUSE_ON); //Sound ON } theta -= 10; win_sc -= 2; if (theta == 0) { message_flag = 1; cursor_no = 2; } break; case 1: theta = 0; //Message Draw! if (contOr->trigger & CONT_A || contOr->trigger & CONT_START) { Na_FixSeFlagEntry(NA_SYS_ENTER); //Sound Enter message_flag = 3; } break; case 3: if (theta == 20) { FreezeGame(0,NULL); //Window Close! Na_FixSeFlagEntry(NA_SYS_PAUSE_OFF); //Sound ON } theta += 10; win_sc += 2; if (theta == 90) { message_flag = 0; selectNo = -1; message_go = 0; ret_num = cursor_no - 1; return(ret_num); } break; } DrawMessageWindow(message,message->line); DrawSelectCursor(2,message->line); DrawMessageFont(SELECT,message); return(NULL); } #endif /*=================================================================================================*/ #include "../endingmess.c" #include "../pausemess.c" #if DEBUGSW #include "../mess_Debug.c" #endif /*================================================================================================= Message Function Main ===================================================================================================*/ /*************************************************************************************************** Message Event ****************************************************************************************************/ extern short MessageEvent(void) { short ret_num = 0; #if DEBUGSW message_test(); #endif MakeSelectProjection(); if (selectNo != -1) { switch (selectNo) { case 0 : ret_num = PauseSceneEvent(); break; case 1 : ret_num = PauseSceneEvent(); break; case 2 : ret_num = SaveSceneEvent(); break; case 3 : ret_num = SaveSceneEvent(); break; // default: ret_num = SelectMessageEvent(); } delta += 0x1000; } else if (messageNo != -1) { if (messageNo == 20) { OpeningMessageEvent(); return(ret_num); } MessageOnlyEvent(); delta += 0x1000; } return(ret_num); }