/* --------------------------------------------------------------------- ** Project: Tetixx (a Tetris clone) ** File: hiscore.c ** StartDate: 14.03.1999 ** Autor: Robert Jurziga */ #include #include #include "tetixx.h" // --------------------------------------------------------------------- // D E F I N E S // --------------------------------------------------------------------- #define HS_RANK_LOC 0 #define HS_NAME_LOC 58 #define HS_SCORE_LOC 58+88+10 #define HS_LINES_LOC 58+88+108 #define HS_STONES_LOC 58+88+108+68+10 #define HS_TIME_LOC 58+88+108+68+108-10 // --------------------------------------------------------------------- // P R O T O T Y P E S // --------------------------------------------------------------------- void DoHiscore(int mode); static void _ComeHiscoreLogo(); static void _GoHiscoreLogo(); static void HiscoreVSync(); static void ShowHiscoreList(); static void _InitializeHiscore(); static void _hsinit_HeadSprite(char *str, GsSPRITE *sprite, int x, int y); static int SetHiscoreBlock(int n); asm int itoacz(int n); asm void itoa(int n); asm void ttoa(int n); asm void clearhiscore(void); asm int check_hs_entry(void); asm void remap_hiscore(int n); static int _init_hssprites(GsSPRITE *spr, char *str, int count, int x, int y, short cx, short cy); static void HilightEntryLine(void); static void AlterEntryChar(short flager); static void SetEntryLineStandardRGB(); // --------------------------------------------------------------------- // H I S C O R E L I S T // --------------------------------------------------------------------- HISCORE_ENTRY HiscoreList[64]={ 600000, 0, 0, 0, "GENELEX ", 550000, 0, 0, 0, "DATAREG ", 500000, 0, 0, 0, "GENELEX ", 450000, 0, 0, 0, "DATAREG ", 400000, 0, 0, 0, "GENELEX ", 350000, 0, 0, 0, "DATAREG ", 300000, 0, 0, 0, "GENELEX ", 290000, 0, 0, 0, "DATAREG ", 280000, 0, 0, 0, "GENELEX ", 270000, 0, 0, 0, "DATAREG ", 260000, 0, 0, 0, "GENELEX ", 250000, 0, 0, 0, "DATAREG ", 240000, 0, 0, 0, "GENELEX ", 230000, 0, 0, 0, "DATAREG ", 220000, 0, 0, 0, "GENELEX ", 210000, 0, 0, 0, "DATAREG ", 200000, 0, 0, 0, "GENELEX ", 190000, 0, 0, 0, "DATAREG ", 180000, 0, 0, 0, "GENELEX ", 170000, 0, 0, 0, "DATAREG ", 160000, 0, 0, 0, "GENELEX ", 150000, 0, 0, 0, "DATAREG ", 140000, 0, 0, 0, "GENELEX ", 130000, 0, 0, 0, "DATAREG ", 120000, 0, 0, 0, "GENELEX ", 110000, 0, 0, 0, "DATAREG ", 100000, 0, 0, 0, "GENELEX ", 95000, 0, 0, 0, "DATAREG ", 90000, 0, 0, 0, "GENELEX ", 85000, 0, 0, 0, "DATAREG ", 80000, 0, 0, 0, "GENELEX ", 75000, 0, 0, 0, "DATAREG ", 70000, 0, 0, 0, "GENELEX ", 65000, 0, 0, 0, "DATAREG ", 60000, 0, 0, 0, "GENELEX ", 55000, 0, 0, 0, "DATAREG ", 50000, 0, 0, 0, "GENELEX ", 45000, 0, 0, 0, "DATAREG ", 40000, 0, 0, 0, "GENELEX ", 38000, 0, 0, 0, "DATAREG ", 36000, 0, 0, 0, "GENELEX ", 34000, 0, 0, 0, "DATAREG ", 32000, 0, 0, 0, "GENELEX ", 30000, 0, 0, 0, "DATAREG ", 29000, 0, 0, 0, "GENELEX ", 28000, 0, 0, 0, "DATAREG ", 27000, 0, 0, 0, "GENELEX ", 26000, 0, 0, 0, "DATAREG ", 25000, 0, 0, 0, "GENELEX ", 24000, 0, 0, 0, "DATAREG ", 23000, 0, 0, 0, "GENELEX ", 22000, 0, 0, 0, "DATAREG ", 21000, 0, 0, 0, "GENELEX ", 20000, 0, 0, 0, "DATAREG ", 19000, 0, 0, 0, "GENELEX ", 18000, 0, 0, 0, "DATAREG ", 17000, 0, 0, 0, "GENELEX ", 16000, 0, 0, 0, "DATAREG ", 15000, 0, 0, 0, "GENELEX ", 14000, 0, 0, 0, "DATAREG ", 13000, 0, 0, 0, "GENELEX ", 12000, 0, 0, 0, "DATAREG ", 11000, 0, 0, 0, "GENELEX ", 10000, 0, 0, 0, "DATAREG "}; HISCORE_ENTRY HiscoreListClear[64]={ 600000, 0, 0, 0, "GENELEX ", 550000, 0, 0, 0, "DATAREG ", 500000, 0, 0, 0, "GENELEX ", 450000, 0, 0, 0, "DATAREG ", 400000, 0, 0, 0, "GENELEX ", 350000, 0, 0, 0, "DATAREG ", 300000, 0, 0, 0, "GENELEX ", 290000, 0, 0, 0, "DATAREG ", 280000, 0, 0, 0, "GENELEX ", 270000, 0, 0, 0, "DATAREG ", 260000, 0, 0, 0, "GENELEX ", 250000, 0, 0, 0, "DATAREG ", 240000, 0, 0, 0, "GENELEX ", 230000, 0, 0, 0, "DATAREG ", 220000, 0, 0, 0, "GENELEX ", 210000, 0, 0, 0, "DATAREG ", 200000, 0, 0, 0, "GENELEX ", 190000, 0, 0, 0, "DATAREG ", 180000, 0, 0, 0, "GENELEX ", 170000, 0, 0, 0, "DATAREG ", 160000, 0, 0, 0, "GENELEX ", 150000, 0, 0, 0, "DATAREG ", 140000, 0, 0, 0, "GENELEX ", 130000, 0, 0, 0, "DATAREG ", 120000, 0, 0, 0, "GENELEX ", 110000, 0, 0, 0, "DATAREG ", 100000, 0, 0, 0, "GENELEX ", 95000, 0, 0, 0, "DATAREG ", 90000, 0, 0, 0, "GENELEX ", 85000, 0, 0, 0, "DATAREG ", 80000, 0, 0, 0, "GENELEX ", 75000, 0, 0, 0, "DATAREG ", 70000, 0, 0, 0, "GENELEX ", 65000, 0, 0, 0, "DATAREG ", 60000, 0, 0, 0, "GENELEX ", 55000, 0, 0, 0, "DATAREG ", 50000, 0, 0, 0, "GENELEX ", 45000, 0, 0, 0, "DATAREG ", 40000, 0, 0, 0, "GENELEX ", 38000, 0, 0, 0, "DATAREG ", 36000, 0, 0, 0, "GENELEX ", 34000, 0, 0, 0, "DATAREG ", 32000, 0, 0, 0, "GENELEX ", 30000, 0, 0, 0, "DATAREG ", 29000, 0, 0, 0, "GENELEX ", 28000, 0, 0, 0, "DATAREG ", 27000, 0, 0, 0, "GENELEX ", 26000, 0, 0, 0, "DATAREG ", 25000, 0, 0, 0, "GENELEX ", 24000, 0, 0, 0, "DATAREG ", 23000, 0, 0, 0, "GENELEX ", 22000, 0, 0, 0, "DATAREG ", 21000, 0, 0, 0, "GENELEX ", 20000, 0, 0, 0, "DATAREG ", 19000, 0, 0, 0, "GENELEX ", 18000, 0, 0, 0, "DATAREG ", 17000, 0, 0, 0, "GENELEX ", 16000, 0, 0, 0, "DATAREG ", 15000, 0, 0, 0, "GENELEX ", 14000, 0, 0, 0, "DATAREG ", 13000, 0, 0, 0, "GENELEX ", 12000, 0, 0, 0, "DATAREG ", 11000, 0, 0, 0, "GENELEX ", 10000, 0, 0, 0, "DATAREG "}; // --------------------------------------------------------------------- // V A R I A B L E S // --------------------------------------------------------------------- static int _ActiBuf; static GsSPRITE hs_HEAD_SPR[5+5+6+6+7+5]; static GsSPRITE hs_BarSprite[2]; static GsSPRITE hs_EntriesSprites[44*8]; char hs_RANK[]="RANK"; char hs_NAME[]="NAME"; char hs_SCORE[]="SCORE"; char hs_LINES[]="LINES"; char hs_STONES[]="STONES"; char hs_TIME[]="TIME"; char hs_strbuf[11]; char hs_playtimestr[9]; unsigned long poweroften[10]={1000000000,100000000,10000000,1000000, 100000,10000,1000,100,10,1}; static short hs_EntriesSpritesUsed; static int hs_blocknumber; static short ready; unsigned long ScoreCols_RANK[] = {0x477d0000,0x02131efa,0x00000400,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000}; unsigned long ScoreCols_NAME[] = {0x2fb40000,0x026a0b4f,0x00000400,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000}; unsigned long ScoreCols_SCORE[] = {0x768b0000,0x4d4069e2,0x00000400,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000}; unsigned long ScoreCols_LINES[] = {0x75d80000,0x4c0d6852,0x00000400,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000}; unsigned long ScoreCols_STONES[] = {0x69dd0000,0x3c13593a,0x00000400,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000}; unsigned long ScoreCols_TIME[] = {0x43440000,0x19803667,0x00000400,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000}; char HiscoreLastName[8]="........"; GsSPRITE *entrylinesprites; GsSPRITE *entrynamesprites; int entryrank; int entrylinesprcount; int entrynamesprndx; int entrylinesprnull; int entrynamesprpos; int entrynamecharpos; unsigned char blinkwave[27]={0x80,0x90,0xA0,0xB0,0xC0,0xD0,0xE0, 0xD0,0xC0,0xB0,0xA0,0x90,0x80,0x70,0x60, 0x50,0x40,0x30,0x20,0x10,0x10,0x20,0x030,0x040, 0x050,0x60,0x70}; short blinkwavendx =0; short hilightwait =0; HISCORE_ENTRY *hiscoreentryptr; /* --------------------------------------------------------------------- // Function: DoHiscore // Description: If the parameter hiscoreentry is NULL then // the hiscore browser will appear. // Else the hiscoreentry parameter will be sorted into // the hiscore and the playername has to be edited. */ void DoHiscore(int mode) { hiscoremode = mode; ready=0; if (!hiscoreinit) _InitializeHiscore(); ResetYXM(&ScoreMod, 0); hs_blocknumber=0; if (!(SetHiscoreBlock(hs_blocknumber))) { _ComeHiscoreLogo(); ready=1; ShowHiscoreList(); ready=0; _GoHiscoreLogo(); } StopYXM(&ScoreMod); } /* --------------------------------------------------------------------- // Function: _ComeHiscoreLogo // Description: */ static void _ComeHiscoreLogo() { HLLeft.y = -78; HLRight.y = -78; while (HLLeft.y < 0) { HLLeft.y = HLRight.y +=4; HiscoreVSync(); } } /* --------------------------------------------------------------------- // Function: _GoHiscoreLogo // Description: */ static void _GoHiscoreLogo() { while (HLLeft.y > -78) { HLLeft.y = HLRight.y -=4; HiscoreVSync(); } } /* --------------------------------------------------------------------- ** Function: HiscoreVSync ** Discription: Display the basic sprites like background and the. ** hiscore logo. */ static void HiscoreVSync() { GsSPRITE *spr; short i; unsigned char mask; _ActiBuf = GsGetActiveBuff(); PadBits=(~(*(pport0+2) | *(pport0+3) << 8 )); mask = *(pport0+1) >> 4; if (*pport0 == 0xff || mask != 0x4) InsertStandardController(&ScoreMod); GsSetWorkBase((PACKET*)GPU_WorkArea[_ActiBuf]); GsClearOt(0, 0, &WorldOT[_ActiBuf]); if (ready) { if (!hiscoremode) GsSortFastSprite(&hs_ctrl0Sprite,&WorldOT[_ActiBuf],11); else GsSortFastSprite(&hs_ctrl1Sprite,&WorldOT[_ActiBuf],11); spr=&hs_EntriesSprites[0]; for(i=0; i< hs_EntriesSpritesUsed; i++, spr++) GsSortFastSprite(spr,&WorldOT[_ActiBuf],11); spr=&hs_HEAD_SPR[0]; for(i=0; i<34; i++, spr++) GsSortFastSprite(spr,&WorldOT[_ActiBuf],12); GsSortFastSprite(&hs_BarSprite[0],&WorldOT[_ActiBuf],13); GsSortFastSprite(&hs_BarSprite[1],&WorldOT[_ActiBuf],13); } GsSortFastSprite(&BGLeft,&WorldOT[_ActiBuf],15); // render background GsSortFastSprite(&BGRight,&WorldOT[_ActiBuf],15); GsSortFastSprite(&HLRight,&WorldOT[_ActiBuf],14); // render hiscore logo GsSortFastSprite(&HLLeft,&WorldOT[_ActiBuf],14); PlayYXM(&ScoreMod); DrawSync(0); VSync(0); GsSwapDispBuff(); GsSortClear(0x0, 0x0, 0x0, &WorldOT[_ActiBuf]); GsDrawOt(&WorldOT[_ActiBuf]); } /* --------------------------------------------------------------------- // Function: _InitializeHiscore // Description: Initalize all sprites and..... */ void _InitializeHiscore() { GsIMAGE tim; RECT rect; u_long *ptr; // allocate HeadSprites _hsinit_HeadSprite(hs_RANK, &hs_HEAD_SPR[0], HS_RANK_LOC, 82); _hsinit_HeadSprite(hs_NAME, &hs_HEAD_SPR[5], HS_NAME_LOC, 82); _hsinit_HeadSprite(hs_SCORE, &hs_HEAD_SPR[10], HS_SCORE_LOC, 82); _hsinit_HeadSprite(hs_LINES, &hs_HEAD_SPR[16], HS_LINES_LOC, 82); _hsinit_HeadSprite(hs_STONES, &hs_HEAD_SPR[22], HS_STONES_LOC, 82); _hsinit_HeadSprite(hs_TIME, &hs_HEAD_SPR[29], HS_TIME_LOC, 82); // initalize Bar Sprite ptr=(u_long *)Bar; ptr++; GsGetTimInfo(ptr, &tim); rect.x = tim.px; rect.y = tim.py; rect.w = tim.pw; rect.h = tim.ph; LoadImage(&rect, tim.pixel); DrawSync(0); rect.x = tim.cx; rect.y = tim.cy; rect.w = tim.cw; rect.h = tim.ch; LoadImage(&rect, tim.clut); DrawSync(0); hs_BarSprite[0].attribute = hs_BarSprite[1].attribute = 0; hs_BarSprite[0].x =0; hs_BarSprite[1].x = 256; hs_BarSprite[0].y = hs_BarSprite[1].y = 82+18; hs_BarSprite[0].w = hs_BarSprite[1].w = 256; hs_BarSprite[0].h = hs_BarSprite[1].h = 6; hs_BarSprite[0].tpage =hs_BarSprite[1].tpage = GetTPage(0, 0, tim.px, tim.py); hs_BarSprite[0].u = hs_BarSprite[1].u = 0; hs_BarSprite[0].v = hs_BarSprite[1].v = tim.py; hs_BarSprite[0].cx =hs_BarSprite[1].cx = tim.cx; hs_BarSprite[0].cy = hs_BarSprite[1].cy = tim.cy; hs_BarSprite[0].r = hs_BarSprite[0].g = hs_BarSprite[0].b = 128; hs_BarSprite[1].r = hs_BarSprite[1].g = hs_BarSprite[1].b = 128; hs_BarSprite[0].mx = hs_BarSprite[1].my = 0; hs_BarSprite[0].scalex = hs_BarSprite[1].scaley = ONE; hs_BarSprite[0].rotate = hs_BarSprite[1].rotate= 0; // Load control sprites hs_ctrl0Sprite.x = 512 - 212; hs_ctrl0Sprite.y = 256 - 20; hs_ctrl0Sprite.r = hs_ctrl0Sprite.g = hs_ctrl0Sprite.b = 192; hs_ctrl1Sprite.x = 512 - 240; hs_ctrl1Sprite.y = 256 - 24; hs_ctrl1Sprite.r = hs_ctrl1Sprite.g = hs_ctrl1Sprite.b = 192; hiscoreinit=1; } /* ----------------- // Function: _hsinit_HeadSprite */ static void _hsinit_HeadSprite(char *str, GsSPRITE *sprite, int x, int y) { GsSPRITE *spr; GsSPRITE *srcspr; char *ptr; int c; short i; int xloc, yloc; xloc = x; yloc = y; spr = (GsSPRITE *)sprite; ptr = str; while(*ptr != 0) { c = *ptr; i=0; while(ScoreFontCharTab[i] != c) {i++;} if (i==38) goto nxchar; srcspr = &ScoreFontCharSprites[i]; spr->attribute = 0; spr->x = xloc; spr->y = yloc; spr->w = srcspr->w; spr->h = srcspr->h; spr->tpage = srcspr->tpage; spr->u = srcspr->u; spr->v = srcspr->v; spr->cx = srcspr->cx; spr->cy = srcspr->cy; spr->r = spr->g = spr->b = 128; spr->mx = spr->my = 0; spr->scalex = spr->scaley = ONE; spr->rotate = 0; spr++; nxchar: ptr++; xloc+=10; } } /* --------------------------------------------------------------------- ** Function: ShowHiscoreList go** Discription: Show the hiscores. ** Rank: Score: Name: Lines: Stones: Time: */ void ShowHiscoreList() { short pressed=0; short done; done = 0; while (!done) { if (pressed) { if (!(PadBits &0xffff)) pressed^=1; } else { if (!hiscoremode) { if (PAD_Triangle & PadBits) { SsUtKeyOn(ChooseSoundVabID, 0, SFX_GO_BACK, 50, 0, 127, 127); done =1; break;} if (PAD_Left & PadBits) { pressed^=1; hs_blocknumber--; if (hs_blocknumber < 0) {hs_blocknumber=0; goto contx;} SsUtKeyOn(ChooseSoundVabID, 0, SFX_WOOD_BLOCK, 50, 0, 127, 127); SetHiscoreBlock(hs_blocknumber); goto contx; } if (PAD_Right & PadBits) { pressed^=1; hs_blocknumber++; if (hs_blocknumber > 7) {hs_blocknumber=7; goto contx;} SsUtKeyOn(ChooseSoundVabID, 0, SFX_WOOD_BLOCK, 50, 0, 127, 127); SetHiscoreBlock(hs_blocknumber); goto contx; } if (PAD_Circle & PadBits) { pressed^=1; SsUtKeyOn(ChooseSoundVabID, 0, SFX_CLEAR, 50, 0, 127, 127); clearhiscore(); hs_blocknumber=0; SetHiscoreBlock(hs_blocknumber); goto contx; } } else { if (PAD_Cross & PadBits) { hiscoremode = 0; strncpy(HiscoreLastName, &hiscoreentryptr->he_name[0],8); SetEntryLineStandardRGB(); SsUtKeyOn(GameSfxVabID, 0, GSFX_NEW_SCORE, 48, 0, 127, 127); } if (PAD_Right & PadBits) { entrynamesprpos++; if (entrynamesprpos >= 8) entrynamesprpos = 0; pressed ^=1; SsUtKeyOn(GameSfxVabID, 0, GSFX_FLIP, 42, 0, 127, 127); } if (PAD_Left & PadBits) { entrynamesprpos--; if (entrynamesprpos < 0) entrynamesprpos = 7; pressed ^=1; SsUtKeyOn(GameSfxVabID, 0, GSFX_FLIP, 42, 0, 127, 127); } if (PAD_Up & PadBits) { AlterEntryChar(1); pressed ^=1; SsUtKeyOn(GameSfxVabID, 0, GSFX_FLIP, 50, 0, 127, 127); } if (PAD_Down & PadBits) { AlterEntryChar(0); pressed ^=1; SsUtKeyOn(GameSfxVabID, 0, GSFX_FLIP, 50, 0, 127, 127); } } } if (hiscoremode) { if (!hilightwait) HilightEntryLine(); hilightwait ^= 1; } // Draw Hiscore Screen contx: // if (PadBits & PAD_Select) dumpScreen(0, 0, 511, 256); HiscoreVSync(); } } /* --------------------------------------------------------------------- ** Function: ShowHiscoreBlock ** Discription: Show the hiscores. ** Rank: Name: Score: Lines: Stones: Time: */ static int SetHiscoreBlock(int n) { short rank; short i; GsSPRITE *spr; HISCORE_ENTRY *hsentry; int yloc; int howmany; int crc; spr=&hs_EntriesSprites[0]; rank = n; yloc = 82+22; hs_EntriesSpritesUsed=0; if (hiscoremode) { crc = check_hs_entry(); if (!crc) {hiscoremode=0; return(1);} rank = (crc-1) >> 3; entryrank = crc; strncpy(CurrentGameHS.he_name,HiscoreLastName,8); remap_hiscore(entryrank); } rank<<=3; hs_blocknumber = rank>>3; hsentry=&HiscoreList[rank]; for(i=rank+1; i <= rank+8; i++) { if (hiscoremode) { if (i == entryrank) { entrylinesprites = spr; entrylinesprnull = hs_EntriesSpritesUsed; hiscoreentryptr = hsentry; } } crc = itoacz(i); howmany = _init_hssprites(spr, &hs_strbuf[0], 0, HS_RANK_LOC+((3-crc)*10), yloc, HS_RANK_COLSX, HS_RANK_COLSY); spr+=howmany; hs_EntriesSpritesUsed+=howmany; if (hiscoremode) { if (i == entryrank) { entrynamesprites = spr; entrynamesprndx = hs_EntriesSpritesUsed; entrynamesprpos = 0; } } howmany = _init_hssprites(spr,&hsentry->he_name[0], 8, HS_NAME_LOC, yloc, HS_NAME_COLSX, HS_NAME_COLSY); spr+=howmany; hs_EntriesSpritesUsed+=howmany; crc = itoacz(hsentry->he_score); howmany = _init_hssprites(spr,&hs_strbuf[0], 0, HS_SCORE_LOC+((7-crc)*10), yloc,HS_SCORE_COLSX, HS_SCORE_COLSY); spr+=howmany; hs_EntriesSpritesUsed+=howmany; crc = itoacz(hsentry->he_lines); howmany = _init_hssprites(spr,&hs_strbuf[0], 0, HS_LINES_LOC+((5-crc)*10), yloc,HS_LINES_COLSX, HS_LINES_COLSY); spr+=howmany; hs_EntriesSpritesUsed+=howmany; crc = itoacz(hsentry->he_stones); howmany = _init_hssprites(spr,&hs_strbuf[0], 0, HS_STONES_LOC+((6-crc)*10), yloc, HS_STONES_COLSX, HS_STONES_COLSY); spr+=howmany; hs_EntriesSpritesUsed+=howmany; ttoa(hsentry->he_playtime); howmany = _init_hssprites(spr,&hs_playtimestr[0], 8, HS_TIME_LOC,yloc,HS_TIME_COLSX, HS_TIME_COLSY); spr+=howmany; hs_EntriesSpritesUsed+=howmany; if (hiscoremode) { if (i == entryrank) entrylinesprcount = hs_EntriesSpritesUsed; } yloc+=16; hsentry++; } return(0); } /* --------------------------------------------------------------------- ** Function: _init_hssprite ** Discription: ** */ static int _init_hssprites(GsSPRITE *spr, char *str, int count, int x, int y, short cx, short cy) { int sprcount,retcount; char *ptr; GsSPRITE *tempspr; GsSPRITE *srcspr; int c,i,j; int xloc; retcount = 0; sprcount = count; tempspr = spr; xloc = x; if (sprcount == 0) { ptr = str; while (*ptr != 0) { sprcount++; ptr++; } } ptr =str; for(i = 0; i< sprcount; i++, ptr++) { c = *ptr; j=0; while(ScoreFontCharTab[j] != c && j < 38) { j++; } if (!hiscoremode) { if (j >= 38) goto nxchrs; } srcspr = &ScoreFontCharSprites[j]; tempspr->attribute = 0; tempspr->x = xloc; tempspr->y = y; tempspr->w = srcspr->w; tempspr->h = srcspr->h; tempspr->tpage = srcspr->tpage; tempspr->u = srcspr->u; tempspr->v = srcspr->v; tempspr->cx = cx; tempspr->cy = cy; tempspr->r = tempspr->g = tempspr->b = 128; tempspr->mx = tempspr->my = 0; tempspr->scalex = tempspr->scaley = ONE; tempspr->rotate = 0; retcount++; tempspr++; nxchrs: xloc+=10; } return(retcount); } /* --------------------------------------------------------------------- ** Function: HilightEntryLine ** Discription: ** */ static void HilightEntryLine() { GsSPRITE *spr; int i; spr = entrylinesprites; // flash the current line for(i=entrylinesprnull; ir = spr->g = spr->b = 255; else { if (i >= entrynamesprndx && i < entrynamesprndx+8) spr->r= spr->g =spr->b = 128; else spr->r =spr->g = spr->b = blinkwave[blinkwavendx]; } } blinkwavendx++; if (blinkwavendx >= 27) blinkwavendx = 0; // if the entry rank is 1 the flash HiscorelOgo if (entryrank == 1) { if (HLLeft.r <= 64) { HLLeft.r = HLLeft.g = HLLeft.b = 255; HLRight.r = HLRight.g = HLRight.b = 255; } else { HLLeft.r = HLLeft.g = HLLeft.b-=8; HLRight.r = HLRight.g = HLRight.b-=8; } } } /* --------------------------------------------------------------------- ** Function: SetEntryLineStandardRGB ** Discription: ** */ static void SetEntryLineStandardRGB() { GsSPRITE *spr; int i; spr = entrylinesprites; for(i=entrylinesprnull; ir= spr->g =spr->b = 128; } HLLeft.r = HLLeft.g = HLLeft.b = 128; HLRight.r = HLRight.g = HLRight.b = 128; } /* --------------------------------------------------------------------- ** Function: ALterEntryChar ** Discription: Brows to the prefered chars in hiscore entry -name ** */ static void AlterEntryChar(short flager) { char *currchar; int j,c; GsSPRITE *nuspr; GsSPRITE *thisspr; currchar = &hiscoreentryptr->he_name[0]; currchar+=entrynamesprpos; c = *currchar; j = 0; while (c != ScoreFontCharTab[j]) {j++;} if (flager) { j++; if (j >= 39) j = 0; } else { j--; if (j < 0) j = 38; } *currchar = ScoreFontCharTab[j]; nuspr = &ScoreFontCharSprites[j]; thisspr = entrynamesprites; thisspr+=entrynamesprpos; thisspr->u = nuspr->u; thisspr->v = nuspr->v; } /* --------------------------------------------------------------------- ** Function: itoacz ** Discription: Convert iteger to ascII. ** The 32bit unsigned integer is placed in A0 ** Ignore the leading zeros */ int asm itoacz(int n) { .set reorder la t0, poweroften // get power of ten table address la a1,hs_strbuf // get destination string buffer address // at least 10 bytes li t1, 10 // counter li a2,0 // set flag loops1: lw t3,0(t0) // get divisor divu a0,t3 // divide nop nop mflo t4 // quotient mfhi a0 // a0 = reminder bne t4,$0,go0 beq a2,$0,go1 go0: addiu a2,a2,1 // set flag and count size addiu t4, t4, 0x30 // convert quotient to AscII (+'0') sb t4,0(a1) // store into strbuffer addiu a1,a1,1 // update strbuffer go1: addiu t0,t0,4 // next lower power of ten addiu t1,t1,-1 // couter -- bgtz t1,loops1 // as long as couter > 0 loops1 bgtz a2,go2 li a2,1 li t4,0x30 sb t4,0(a1) addiu a1,a1,1 go2: sb $0,0(a1) addu v0,$0,a2 jr ra // return form sub } /* --------------------------------------------------------------------- ** Function: itoa ** Discription: Convert iteger to ascII. ** The 32bit unsigned integer is placed in A0 ** */ void asm itoa(int n) { .set reorder la t0, poweroften // get power of ten table address la a1,hs_strbuf // get destination string buffer address // at least 10 bytes li t1, 10 // counter loops1: lw t3,0(t0) // get divisor divu a0,t3 // divide nop nop mflo t4 // quotient mfhi a0 // a0 = reminder addiu t4, t4, 0x30 // convert quotient to AscII (+'0') sb t4,0(a1) // store into strbuffer addiu a1,a1,1 // update strbuffer addiu t0,t0,4 // next lower power of ten addiu t1,t1,-1 // couter -- bgtz t1,loops1 // as long as couter > 0 loops1 sb $0,0(a1) jr ra // return form sub } /* --------------------------------------------------------------------- ** Function: ttoa ** Discription: n is the number of played frames. ** This function calcuates the play time, and ** stores the AscII at timestr. ** HH:MM:SS */ void asm ttoa(int n) { .set reorder addu t6,$0,ra // save the return address la t5,hs_playtimestr li t0,50 // 50fps divu a0,t0 // nop nop mflo t7 // t7 = frames# / 50fps li t0,3600 // 3600 seconds = 1hour divu t7,t0 nop nop mflo a0 // a0 = hours mfhi t7 // t6 = seconds below hour jal itoa // convert hours to String la t4,hs_strbuf // get address xx lbu t3,8(t4) // copy byte 1 lbu t8,9(t4) // sb t3,0(t5) // store byte 1 sb t8,1(t5) li t3,0x3a sb t3,2(t5) // store ":" li t0,60 divu t7,t0 nop nop mflo a0 mfhi t7 jal itoa la t4,hs_strbuf lbu t3,8(t4) // copy byte 1 lbu t8,9(t4) // sb t3,3(t5) // store byte 1 sb t8,4(t5) li t3,0x3a sb t3,5(t5) // store ":" addu a0,$0,t7 jal itoa la t4,hs_strbuf lbu t3,8(t4) // copy byte 1 lbu t8,9(t4) // sb t3,6(t5) // store byte 1 sb t8,7(t5) sb $0,8(t5) addu ra,$0,t6 // restore the retrun address jr ra } /* --------------------------------------------------------------------- ** Function: clearhiscore ** Discription: Clear hiscore list. ** */ void asm clearhiscore() { .set reorder la t1, HiscoreList la t0, HiscoreListClear li t2, 64 clearl: lw t3, 0(t0) // score lw t4, 4(t0) // lines lw t5, 8(t0) // stones lw t6, 12(t0) // frames lw t7, 16(t0) // 1st 4 byte lw t8, 20(t0) // 2nd 4 byte sw t3, 0(t1) sw t4, 4(t1) sw t5, 8(t1) sw t6, 12(t1) sw t7, 16(t1) sw t8, 20(t1) addiu t0, t0, 24 addiu t1, t1, 24 addi t2, t2, -1 bne t2, $0, clearl nop jr ra } /* --------------------------------------------------------------------- ** Function: check_hs_entry ** Discription: find out where the player is to place in the HiscoreList ** */ asm int check_hs_entry() { .set reorder la t0,HiscoreList la t1,CurrentGameHS li t2,63*24 // t0 = last hiscore entry addu t0,t0,t2 // t1 = Current Game HS li t2,64 // t2 = counter lw t4,0(t1) // t4 = current score beq t4,$0,noentry // null score means no entry findscore: lw t3,0(t0) // t3 = Hiscore Entry Score beq t3,t4,cmp_lines // if Equal decide by lines sltu at,t3,t4 // if Hiscore Entry Score < Current Game score beq at,$0,found // entry found addiu t2,t2,-1 addiu t0,t0,-24 bgtz t2,findscore li v0,1 // new hiscore jr ra // return found: addu v0,$0,t2 testentry: addiu v0,v0,1 sltiu at,v0,65 bne at,$0,leave addu v0,$0,$0 leave: jr ra noentry: // return zero addu v0,$0,$0 jr ra downentry: // addiu v0,t2,1 addu v0,$0,t2 b testentry replace: addiu v0,t2,-1 b testentry cmp_lines: lw t4,4(t1) // t4 = current llines lw t3,4(t0) // t3 = HiscoreEntry Lines beq t3,$0,replace beq t3,t4,cmp_stones // if EQUAL decide by stones sltu at,t3,t4 bne at,$0,replace b downentry cmp_stones: lw t4,8(t1) // t4 = current stones lw t3,8(t0) // t3 = HiscoreEntry Stones beq t3,$0,replace beq t3,t4,cmp_playtime sltu at,t3,t4 bne at,$0,replace b downentry cmp_playtime: lw t4,12(t1) // t4 = current playtime lw t3,12(t0) beq t3,$0,replace beq t3,t4,downentry sltu at,t3,t4 bne at,$0,downentry b replace } /* --------------------------------------------------------------------- ** Function: remap_hiscore ** Discription: insert the hisore at that place ** */ asm void remap_hiscore(int n) { .set reorder la t0,HiscoreList li t7,63*24 addiu t6,t7,-24 addu t1,t0,t6 // t1 = source ptr addu t0,t0,t7 // t2 = dest ptr li t2,64 // sub t2,t2,a0 // t2 = how many to copy slti at,t2,1 bne at,$0,setonly copyloop: lw t3,0(t1) lw t4,4(t1) lw t5,8(t1) lw t6,12(t1) lw t7,16(t1) lw t8,20(t1) sw t3,0(t0) sw t4,4(t0) sw t5,8(t0) sw t6,12(t0) sw t7,16(t0) sw t8,20(t0) addiu t0,t0,-24 addiu t1,t1,-24 addiu t2,t2,-1 bgtz t2,copyloop setonly: la t1,CurrentGameHS // copy lw t3,0(t1) lw t4,4(t1) lw t5,8(t1) lw t6,12(t1) lw t7,16(t1) lw t8,20(t1) sw t3,0(t0) sw t4,4(t0) sw t5,8(t0) sw t6,12(t0) sw t7,16(t0) sw t8,20(t0) jr ra }