00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "menuBottom.h"
00021 #include "spriteObject.h"
00022 #include "gameManager.h"
00023
00024 const char *menuBottom::_SRAMID = "MDUEL";
00025
00031 menuBottom::menuBottom(u8 newScreen) : spriteManager(newScreen), menuTop(NULL), gameBottom(NULL), gameTop(NULL),
00032 playerPallete1(NULL), playerPallete2(NULL), playerPallete3(NULL), playerPallete4(NULL),
00033 playerSprite1(NULL), playerSprite2(NULL), playerSprite3(NULL),
00034 navFunction(NULL), renderFunction(NULL), actionFunction(NULL),
00035 playerPal1(0), playerPal2(0), playerPal3(0), playerPal4(0),
00036 editingName(0), selectedItem(0), menuColSize(0), cursor(NULL), selectedItem2(0), settingsPlayer(0),
00037 settingsPage(0), menuRepeater(0)
00038 {
00039
00040 }
00041
00042 menuBottom::~menuBottom()
00043 {
00044
00045 }
00046
00056 void menuBottom::gameTick()
00057 {
00058 spriteManager::gameTick();
00059
00060 #ifdef __WITHSOUND
00061 u8 oldSelItem = selectedItem;
00062 #endif
00063
00064
00065 bool stylusActivated = false;
00066 bool stylusTouched = false;
00067
00068 if (Stylus.Newpress)
00069 {
00070 s8 touchedItem = touchingWhichItem(Stylus.X, Stylus.Y);
00071 if (touchedItem == selectedItem) {
00072 stylusActivated = true;
00073 }
00074 if (touchedItem != -1) {
00075 selectedItem = touchedItem;
00076
00077 stylusTouched = true;
00078 }
00079 }
00080
00081
00082 if (navFunction != NULL)
00083 (this->*navFunction)();
00084
00085 #ifdef __WITHSOUND
00086 if (oldSelItem != selectedItem)
00087 playSound(menuMove.data, menuMove.size);
00088 #endif
00089
00090
00091 if (cursor != NULL)
00092 {
00093 cursor->setPos(menuItems[selectedItem].cursorx, menuItems[selectedItem].cursory);
00094 if (selectedItem > menuColSize-1 && menuColSize != 0)
00095 cursor->setFrame(2);
00096 else
00097 cursor->setFrame(1);
00098 }
00099
00100 for (u8 i=0; i < menuItems.size(); ++i)
00101 {
00102 normalRender(i);
00103 if (renderFunction != NULL)
00104 (this->*renderFunction)(i);
00105 }
00106
00107
00108 if (actionFunction != NULL)
00109 (this->*actionFunction)(stylusTouched, stylusActivated);
00110
00111 if (menuRepeater == 0)
00112 menuRepeater = menuRepeatDelay;
00113 menuRepeater--;
00114 }
00115
00116
00117
00118
00120 void menuBottom::normalNav()
00121 {
00122 if (Pad.Newpress.Up)
00123 --selectedItem;
00124 else if (Pad.Newpress.Down)
00125 ++selectedItem;
00126 else if (Pad.Newpress.Left && menuColSize > 0)
00127 selectedItem -= menuColSize;
00128 else if (Pad.Newpress.Right && menuColSize > 0)
00129 selectedItem += menuColSize;
00130 if (selectedItem < 0)
00131 (menuColSize > 0 ? selectedItem += menuColSize*2 : selectedItem = menuItems.size()-1);
00132 selectedItem %= menuItems.size();
00133 }
00135 void menuBottom::statsNav()
00136 {
00137 #ifdef __WITHSOUND
00138 u8 oldSelectedItem2 = selectedItem2;
00139 #endif
00140
00141 if (Pad.Newpress.Up)
00142 --selectedItem;
00143 else if (Pad.Newpress.Down)
00144 ++selectedItem;
00145 else if (Pad.Newpress.Left)
00146 --selectedItem2;
00147 else if (Pad.Newpress.Right)
00148 ++selectedItem2;
00149
00150 if (selectedItem < 0)
00151 selectedItem = 6;
00152 else if (selectedItem > 6)
00153 selectedItem = 0;
00154
00155 if (selectedItem2 < 0)
00156 selectedItem2 = 3;
00157 else if (selectedItem2 > 3)
00158 selectedItem2 = 0;
00159
00160 if (selectedItem == 0 && selectedItem2 == 3)
00161 selectedItem2 = 0;
00162 drawStatsFor(selectedItem, selectedItem2);
00163
00164 #ifdef __WITHSOUND
00165 if (oldSelectedItem2 != selectedItem2)
00166 playSound(menuMove.data, menuMove.size);
00167 #endif
00168 }
00170 void menuBottom::miscNav()
00171 {
00172 if (Pad.Newpress.Up)
00173 --selectedItem;
00174 else if (Pad.Newpress.Down)
00175 ++selectedItem;
00176 if (selectedItem < 0)
00177 (menuColSize > 0 ? selectedItem += menuColSize*2 : selectedItem = menuItems.size()-1);
00178 selectedItem %= menuItems.size();
00179 }
00181 void menuBottom::charNav()
00182 {
00183 if (Pad.Newpress.Up)
00184 --selectedItem;
00185 else if (Pad.Newpress.Down)
00186 ++selectedItem;
00187 else if (Pad.Newpress.Left)
00188 {
00189 #ifdef __WITHSOUND
00190 playSound(menuMove.data, menuMove.size);
00191 #endif
00192 selectPlayer(selectedItem, 1);
00193 } else if (Pad.Newpress.Right)
00194 {
00195 #ifdef __WITHSOUND
00196 playSound(menuMove.data, menuMove.size);
00197 #endif
00198 selectPlayer(selectedItem, 2);
00199 }
00200 if (selectedItem < 0)
00201 (menuColSize > 0 ? selectedItem += menuColSize*2 : selectedItem = menuItems.size()-1);
00202 selectedItem %= menuItems.size();
00203
00204 if (playerPals[player1id-1] == playerPals[player2id-1])
00205 playerColorCycle(selectedItem);
00206 }
00208 void menuBottom::charNameNav()
00209 {
00210 if (Pad.Held.Up && menuRepeater == 0 || Pad.Newpress.Up)
00211 {
00212 #ifdef __WITHSOUND
00213 playSound(menuMove.data, menuMove.size);
00214 #endif
00215 alterPlayerName(editingName, selectedItem, -1);
00216 } else if (Pad.Held.Down && menuRepeater == 0 || Pad.Newpress.Down)
00217 {
00218 #ifdef __WITHSOUND
00219 playSound(menuMove.data, menuMove.size);
00220 #endif
00221 alterPlayerName(editingName, selectedItem, 1);
00222 }
00223 else if (Pad.Newpress.Left)
00224 --selectedItem;
00225 else if (Pad.Newpress.Right)
00226 ++selectedItem;
00227 if (selectedItem < 0)
00228 selectedItem = menuItems.size()-1;
00229 selectedItem %= menuItems.size();
00230 PA_OutputText(screen, 12, 9, "________\n%s\n--------", macros::getPlayerName(editingName, playerNames, false).c_str());
00231 }
00233 void menuBottom::roundsNav()
00234 {
00235 if ((Pad.Held.Up && menuRepeater == 0 || Pad.Newpress.Up) && roundNum < 50)
00236 {
00237 #ifdef __WITHSOUND
00238 playSound(menuMove.data, menuMove.size);
00239 #endif
00240 ++roundNum;
00241 } else if ((Pad.Held.Down && menuRepeater == 0 || Pad.Newpress.Down) && roundNum > 1)
00242 {
00243 #ifdef __WITHSOUND
00244 playSound(menuMove.data, menuMove.size);
00245 #endif
00246 --roundNum;
00247 }
00248 PA_OutputText(screen, 14, 10, "-%d- ", roundNum);
00249 gameTop->pointsToWin = roundNum;
00250 }
00251
00256 void menuBottom::normalRender(u8 i)
00257 {
00258 if (menuItems[i].text != "")
00259 PA_OutputSimpleText(screen, menuItems[i].textx, menuItems[i].texty, const_cast<char*>(menuItems[i].text.c_str()));
00260 if (menuItems[i].obj != NULL)
00261 menuItems[i].obj->setPos(menuItems[i].objx, menuItems[i].objy);
00262 }
00267 void menuBottom::statsRender(u8 i)
00268 {
00269 if (i > 6)
00270 {
00271 if (selectedItem == 0 && i==10)
00272 PA_OutputSimpleText(screen, menuItems[i].textx, menuItems[i].texty, " ");
00273 if (selectedItem2 == i-7)
00274 menuItems[i].obj->setPos(menuItems[i].objx, menuItems[i].objy);
00275 else
00276 menuItems[i].obj->setPos(OFFX, OFFY);
00277 }
00278 }
00283 void menuBottom::pickupsRender(u8 i)
00284 {
00285
00286
00287 if (cursor != NULL)
00288 {
00289 if (selectedItem > menuColSize-1 && menuColSize != 0)
00290 cursor->setFrame(1);
00291 else
00292 cursor->setFrame(2);
00293 }
00294
00295 if (pickupSelected(i))
00296 menuItems[i].obj2->setPos(menuItems[i].objx, menuItems[i].objy);
00297 else
00298 menuItems[i].obj2->setPos(OFFX, OFFY);
00299 }
00304 void menuBottom::charRender(u8 i)
00305 {
00306 if (i == (u8)(player1id-1))
00307 {
00308 menuItems[i].obj->setFrame(0);
00309 menuItems[i].obj->setPos(120, menuItems[i].obj->gety());
00310 } else if (i == (u8)(player2id-1))
00311 {
00312 menuItems[i].obj->setFrame(0);
00313 menuItems[i].obj->setPos(224, menuItems[i].obj->gety());
00314 } else
00315 {
00316 menuItems[i].obj->setFrame(6);
00317 menuItems[i].obj->setPos(172, menuItems[i].obj->gety());
00318 }
00319 }
00324 void menuBottom::charNameRender(u8 i)
00325 {
00326 if (cursor != NULL && cursor->getFrame() != 0)
00327 cursor->setFrame(0);
00328 }
00329
00335 void menuBottom::mainAction(bool stylusTouched, bool stylusActivated)
00336 {
00337 #ifdef __WITHSOUND
00338 if (Pad.Released.A || stylusTouched)
00339 playSound(menuOk.data, menuOk.size);
00340 #endif
00341 switch (selectedItem)
00342 {
00343 case 0:
00344 #ifdef __MDDEBUG //file logging seems to slow the menu down to the point where button hits dont register
00345 if (Pad.Held.A || stylusTouched)
00346 #else
00347 if (Pad.Released.A || stylusTouched)
00348 #endif
00349 {
00350 menuTop->deactivate();
00351 deactivate();
00352 PA_WaitForVBL();
00353 gameTop->activate();
00354 for (u8 i=0; i < _NUMPICKUPS; ++i)
00355 {
00356 if (pickupSelected(i))
00357 gameTop->pickupMask.push_back(i);
00358 }
00359 gameTop->pointsToWin = roundNum;
00360 loadPlayerGFX(player1id, 1);
00361 loadPlayerGFX(player2id, 2);
00362 gameBottom->activate();
00363 }
00364 break;
00365 case 1:
00366 if (Pad.Released.A || stylusTouched)
00367 characterMenu();
00368 break;
00369 case 2:
00370 if (Pad.Released.A || stylusTouched)
00371 pickupMenu();
00372 break;
00373 case 3:
00374 if (Pad.Released.A || stylusTouched)
00375 roundsMenu();
00376 break;
00377 case 4:
00378 if (Pad.Released.A || stylusTouched)
00379 miscMenu();
00380 break;
00381 case 5:
00382 if (Pad.Released.A || stylusTouched)
00383 statsMenu();
00384 break;
00385 case 6:
00386 if (Pad.Released.A || stylusTouched)
00387 controlsMenu();
00388 break;
00389 case 7:
00390 if (Pad.Released.A || stylusTouched)
00391 creditsMenu();
00392 break;
00393 default:
00394 break;
00395 }
00396 }
00402 void menuBottom::charAction(bool stylusTouched, bool stylusActivated)
00403 {
00404 if (Pad.Released.A)
00405 {
00406 #ifdef __WITHSOUND
00407 playSound(menuOk.data, menuOk.size);
00408 #endif
00409 saveSRAM(false, 1);
00410 } else if (Pad.Released.B) {
00411 #ifdef __WITHSOUND
00412 playSound(menuCancel.data, menuCancel.size);
00413 #endif
00414 loadSRAM();
00415 mainMenu(1);
00416 } else if (Pad.Released.X || stylusActivated) {
00417 #ifdef __WITHSOUND
00418 playSound(menuOk.data, menuOk.size);
00419 #endif
00420 editingName = selectedItem+1;
00421 playerRenameMenu(selectedItem);
00422 } else if (Pad.Released.R) {
00423 #ifdef __WITHSOUND
00424 playSound(menuMove.data, menuMove.size);
00425 #endif
00426 playerColorCycle(selectedItem);
00427 } else if (Pad.Released.L) {
00428 #ifdef __WITHSOUND
00429 playSound(menuMove.data, menuMove.size);
00430 #endif
00431 playerGFXCycle(selectedItem);
00432 }
00433 }
00439 void menuBottom::pickupsAction(bool stylusTouched, bool stylusActivated)
00440 {
00441 if (Pad.Released.A)
00442 {
00443 #ifdef __WITHSOUND
00444 playSound(menuOk.data, menuOk.size);
00445 #endif
00446 saveSRAM(false, 2);
00447 } else if (Pad.Released.B) {
00448 #ifdef __WITHSOUND
00449 playSound(menuCancel.data, menuCancel.size);
00450 #endif
00451 loadSRAM();
00452 mainMenu(2);
00453 } else if (Pad.Released.X || stylusTouched) {
00454 #ifdef __WITHSOUND
00455 playSound(menuMove.data, menuMove.size);
00456 #endif
00457 pickupToggle(selectedItem);
00458 }
00459 }
00465 void menuBottom::roundsAction(bool stylusTouched, bool stylusActivated)
00466 {
00467 if (Pad.Released.A)
00468 {
00469 #ifdef __WITHSOUND
00470 playSound(menuOk.data, menuOk.size);
00471 #endif
00472 saveSRAM(false, 3);
00473 } else if (Pad.Released.B) {
00474 #ifdef __WITHSOUND
00475 playSound(menuCancel.data, menuCancel.size);
00476 #endif
00477 loadSRAM();
00478 mainMenu(3);
00479 }
00480 }
00486 void menuBottom::sramAction(bool stylusTouched, bool stylusActivated)
00487 {
00488 if (Pad.Released.A || Stylus.Newpress)
00489 {
00490 #ifdef __WITHSOUND
00491 playSound(menuOk.data, menuOk.size);
00492 #endif
00493 saveSRAM(true);
00494 } else if (Pad.Released.B) {
00495 #ifdef __WITHSOUND
00496 playSound(menuCancel.data, menuCancel.size);
00497 #endif
00498 mainMenu(0);
00499 }
00500 }
00506 void menuBottom::controlsAction(bool stylusTouched, bool stylusActivated)
00507 {
00508 if (Pad.Released.A || Stylus.Newpress)
00509 {
00510 #ifdef __WITHSOUND
00511 playSound(menuCancel.data, menuCancel.size);
00512 #endif
00513 resetBackground();
00514 resetText();
00515 mainMenu(6);
00516 }
00517 }
00523 void menuBottom::charNameAction(bool stylusTouched, bool stylusActivated)
00524 {
00525 if (Pad.Released.A)
00526 {
00527 #ifdef __WITHSOUND
00528 playSound(menuOk.data, menuOk.size);
00529 #endif
00530 erasePlayer(editingName);
00531 characterMenu();
00532 } else if (Pad.Released.B) {
00533 #ifdef __WITHSOUND
00534 playSound(menuCancel.data, menuCancel.size);
00535 #endif
00536 loadSRAM();
00537 characterMenu();
00538 }
00539 }
00545 void menuBottom::creditsAction(bool stylusTouched, bool stylusActivated)
00546 {
00547 if (Pad.Released.A || Stylus.Newpress)
00548 {
00549 #ifdef __WITHSOUND
00550 playSound(menuCancel.data, menuCancel.size);
00551 #endif
00552 mainMenu(7);
00553 }
00554 }
00560 void menuBottom::miscAction(bool stylusTouched, bool stylusActivated)
00561 {
00562 s8 temp;
00563
00564 if (Pad.Newpress.Left || Pad.Newpress.Right)
00565 {
00566 #ifdef __WITHSOUND
00567 playSound(menuMove.data, menuMove.size);
00568 #endif
00569 switch (selectedItem)
00570 {
00571 case 0:
00572 temp = numPickups;
00573 temp += Pad.Newpress.Right-Pad.Newpress.Left;
00574 numPickups = temp > MAXPICKUPSONSCREEN ? MAXPICKUPSONSCREEN : (temp < 0 ? 0 : temp);
00575 char data[24];
00576 sprintf(data, "Max pickups: %d ", numPickups);
00577 menuItems[selectedItem].text = data;
00578 break;
00579 case 1:
00580 showPickups = !showPickups;
00581 strcpy(data, "Pre-show pickups: ");
00582 strcat(data, (showPickups ? "ON " : "OFF"));
00583 menuItems[selectedItem].text = data;
00584 break;
00585 case 2:
00586 dieWhileDancing = !dieWhileDancing;
00587 strcpy(data, "Die while dancing: ");
00588 strcat(data, (dieWhileDancing ? "ON " : "OFF"));
00589 menuItems[selectedItem].text = data;
00590 break;
00591 }
00592 }
00593 if (Pad.Released.A)
00594 {
00595 #ifdef __WITHSOUND
00596 playSound(menuOk.data, menuOk.size);
00597 #endif
00598 saveSRAM(false, 4);
00599 }
00600 else if (Pad.Released.B) {
00601 #ifdef __WITHSOUND
00602 playSound(menuCancel.data, menuCancel.size);
00603 #endif
00604 loadSRAM();
00605 mainMenu(4);
00606 }
00607 }
00613 void menuBottom::statsAction(bool stylusTouched, bool stylusActivated)
00614 {
00615 if (Pad.Released.A)
00616 {
00617 #ifdef __WITHSOUND
00618 playSound(menuCancel.data, menuCancel.size);
00619 #endif
00620 mainMenu(5);
00621 }
00622 }
00623
00624
00625
00626
00630 void menuBottom::loadBackground()
00631 {
00632 PA_EasyBgLoad(screen, 3, ::menuBGbottom);
00633 }
00634
00639 void menuBottom::clearOutSprites(bool keepSound)
00640 {
00641 cursorSprite.palleteID = -1;
00642 pickupSprite.palleteID = -1;
00643 menuSprite.palleteID = -1;
00644 spriteManager::clearOutSprites(keepSound);
00645 }
00646
00647
00648
00650 void menuBottom::loadCursorSpriteSet(const unsigned short *p, const unsigned char *s)
00651 {
00652 loadSpriteSet(&cursorSprite, p, s);
00653 }
00654
00656 void menuBottom::loadPickupSpriteSet(const unsigned short *p, const unsigned char *s)
00657 {
00658 loadSpriteSet(&pickupSprite, p, s);
00659 }
00660
00662 void menuBottom::loadMenuSpriteSet(const unsigned short *p, const unsigned char *s)
00663 {
00664 loadSpriteSet(&menuSprite, p, s);
00665 }
00666
00667
00668
00674 void menuBottom::clearMenus()
00675 {
00676 menuItems.clear();
00677 PA_WaitForVBL();
00678
00679 clearOutSprites(true);
00680 PA_WaitForVBL();
00681 resetText();
00682 PA_WaitForVBL();
00683 loadBackground();
00684 loadCursorSpriteSet(cursorSprite.palleteData, cursorSprite.spriteData);
00685 loadMenuSpriteSet(menuSprite.palleteData, menuSprite.spriteData);
00686 PA_WaitForVBL();
00687 makeCursor();
00688 selectedItem = 0;
00689 selectedItem2 = 0;
00690 navFunction = &menuBottom::normalNav;
00691 renderFunction = NULL;
00692 actionFunction = NULL;
00693 }
00694
00698 void menuBottom::makeCursor()
00699 {
00700 cursor = new spriteObject(this);
00701 cursor->setPallete(cursorSprite.palleteID);
00702 cursor->giveSprite(cursorSprite.spriteData, OBJ_SIZE_16X16, 8, 8);
00703 cursor->setLayer(0);
00704 cursor->setFrame(1);
00705 }
00706
00707
00708
00714 void menuBottom::mainMenu(u8 prevScreen)
00715 {
00716 clearMenus();
00717 actionFunction = &menuBottom::mainAction;
00718 menuColSize = 0;
00719 selectedItem = prevScreen;
00720 struct menuItem temp1 = {60, 28, 9, 3, "Start 2P Game", 0,0,NULL,NULL};
00721 menuItems.push_back(temp1);
00722 struct menuItem temp2 = {44, 52, 7, 6, "Select Characters", 0,0,NULL,NULL};
00723 menuItems.push_back(temp2);
00724 struct menuItem temp3 = {60, 68, 9, 8, "Choose Pickups", 0,0,NULL,NULL};
00725 menuItems.push_back(temp3);
00726 struct menuItem temp4 = {60, 84, 9, 10, "Set Kill Limit", 0,0,NULL,NULL};
00727 menuItems.push_back(temp4);
00728 struct menuItem temp7 = {68, 100, 10, 12, "Misc Options", 0,0,NULL,NULL};
00729 menuItems.push_back(temp7);
00730 struct menuItem temp8 = {76, 124, 11, 15, "Statistics", 0,0,NULL,NULL};
00731 menuItems.push_back(temp8);
00732 struct menuItem temp5 = {60, 140, 9, 17, "View Controls", 0,0,NULL,NULL};
00733 menuItems.push_back(temp5);
00734 struct menuItem temp6 = {68, 156, 10, 19, "View Credits", 0,0,NULL,NULL};
00735 menuItems.push_back(temp6);
00736
00737 autoMenuClickRegions();
00738
00739
00740 makeInstructions(0, 128);
00741 }
00742
00744 void menuBottom::characterMenu()
00745 {
00746 clearMenus();
00747 navFunction = &menuBottom::charNav;
00748 renderFunction = &menuBottom::charRender;
00749 actionFunction = &menuBottom::charAction;
00750 menuColSize = 0;
00751
00752 playerPal1 = loadPallete((void*)playerPallete1);
00753 playerPal2 = loadPallete((void*)playerPallete2);
00754 playerPal3 = loadPallete((void*)playerPallete3);
00755 playerPal4 = loadPallete((void*)playerPallete4);
00756
00757 spriteObject *playerSpr1 = new spriteObject(this);
00758 playerSpr1->setPallete(getPlayerPalleteID(playerPals[0]));
00759 playerSpr1->giveSprite(getPlayerSpriteData(playerSprs[0]), OBJ_SIZE_32X32, 16, 16);
00760 spriteObject *playerSpr2 = new spriteObject(this);
00761 playerSpr2->setPallete(getPlayerPalleteID(playerPals[1]));
00762 playerSpr2->giveSprite(getPlayerSpriteData(playerSprs[1]), OBJ_SIZE_32X32, 16, 16);
00763 spriteObject *playerSpr3 = new spriteObject(this);
00764 playerSpr3->setPallete(getPlayerPalleteID(playerPals[2]));
00765 playerSpr3->giveSprite(getPlayerSpriteData(playerSprs[2]), OBJ_SIZE_32X32, 16, 16);
00766 spriteObject *playerSprA = new spriteObject(this);
00767 playerSprA->setPallete(getPlayerPalleteID(playerPals[3]));
00768 playerSprA->giveSprite(getPlayerSpriteData(playerSprs[3]), OBJ_SIZE_32X32, 16, 16);
00769
00770 spriteObject *playerSprB = new spriteObject(this);
00771 playerSprB->setPallete(getPlayerPalleteID(playerPals[4]));
00772 playerSprB->giveSprite(getPlayerSpriteData(playerSprs[4]), OBJ_SIZE_32X32, 16, 16);
00773
00774 spriteObject *playerSprC = new spriteObject(this);
00775 playerSprC->setPallete(getPlayerPalleteID(playerPals[5]));
00776 playerSprC->giveSprite(getPlayerSpriteData(playerSprs[5]), OBJ_SIZE_32X32, 16, 16);
00777
00778
00779 struct menuItem temp1 = {12, 36, 3, 4, macros::getPlayerName(1, playerNames, false).c_str(), 172, 36, playerSpr1, NULL};
00780 menuItems.push_back(temp1);
00781 struct menuItem temp2 = {12, 60, 3, 7, macros::getPlayerName(2, playerNames, false).c_str(), 172, 60, playerSpr2, NULL};
00782 menuItems.push_back(temp2);
00783 struct menuItem temp3 = {12, 84, 3, 10, macros::getPlayerName(3, playerNames, false).c_str(), 172, 84, playerSpr3, NULL};
00784 menuItems.push_back(temp3);
00785 struct menuItem tempA = {12, 108, 3, 13, macros::getPlayerName(4, playerNames, false).c_str(), 172, 108, playerSprA, NULL};
00786 menuItems.push_back(tempA);
00787 struct menuItem tempB = {12, 132, 3, 16, macros::getPlayerName(5, playerNames, false).c_str(), 172, 132, playerSprB, NULL};
00788 menuItems.push_back(tempB);
00789 struct menuItem tempC = {12, 156, 3, 19, macros::getPlayerName(6, playerNames, false).c_str(), 172, 156, playerSprC, NULL};
00790 menuItems.push_back(tempC);
00791
00792 autoMenuClickRegions();
00793
00794
00795 PA_OutputSimpleText(screen, 14, 1, "P1 OFF P2");
00796
00797
00798 makeInstructions(5, 32);
00799 makeInstructions(1, 96);
00800 makeInstructions(2, 160);
00801 makeInstructions(3, 224);
00802 }
00803
00805 void menuBottom::pickupMenu()
00806 {
00807 clearMenus();
00808 renderFunction = &menuBottom::pickupsRender;
00809 actionFunction = &menuBottom::pickupsAction;
00810 menuColSize = 9;
00811 loadPickupSpriteSet(pickupSprite.palleteData, pickupSprite.spriteData);
00812
00813 makePickupIcon("Skull", 0, 84, 12);
00814 makePickupIcon("1000V", 1, 84, 28);
00815 makePickupIcon("Invisibility", 2, 140, 44);
00816 makePickupIcon("Mine", 3, 76, 60);
00817 makePickupIcon("Gun", 4, 68, 76);
00818 makePickupIcon("TNT", 5, 68, 92);
00819 makePickupIcon("Boots", 6, 84, 108);
00820 makePickupIcon("Grenade", 7, 100, 124);
00821 makePickupIcon("Puck", 8, 76, 140);
00822 makePickupIcon("Parachut", 9, 148, 12);
00823 makePickupIcon("Hook", 10, 180, 28);
00824 makePickupIcon("Warp", 11, 180, 44);
00825 makePickupIcon("Magnet", 12, 164, 60);
00826 makePickupIcon("Net", 13, 188, 76);
00827 makePickupIcon("Shield", 14, 164, 92);
00828 makePickupIcon("Dunce Hat", 15, 140, 108);
00829 makePickupIcon("Weasel", 16, 164, 124);
00830 makePickupIcon("Boomerang", 17, 140, 140);
00831
00832 autoMenuClickRegions();
00833
00834
00835 makeInstructions(5, 96);
00836 makeInstructions(4, 160);
00837 }
00838
00847 void menuBottom::makePickupIcon(string text, u8 num, u16 curx, u16 cury)
00848 {
00849 spriteObject *icon = new spriteObject(this);
00850 icon->setPallete(pickupSprite.palleteID);
00851 icon->giveSprite(pickupSprite.spriteData, OBJ_SIZE_16X16, 8, 8);
00852 icon->setFrame(num+3);
00853 spriteObject *icons = new spriteObject(this);
00854 icons->setPallete(pickupSprite.palleteID);
00855 icons->giveSprite(pickupSprite.spriteData, OBJ_SIZE_16X16, 8, 8);
00856 icons->setAnim(0,2,spriteObject::ANIMSPEED);
00857
00858 if (num < 9)
00859 {
00860 struct menuItem temp = {curx, cury, 4, 1+num*2, text, 20, ((num+1)*16)-4, icon, icons};
00861 menuItems.push_back(temp);
00862 }
00863 else {
00864 struct menuItem temp = {curx, cury, 28-text.length(), 1+(num-9)*2, text, 236, ((num-8)*16)-4, icon, icons};
00865 menuItems.push_back(temp);
00866 }
00867 }
00868
00875 void menuBottom::makeInstructions(u8 frame, u8 xpos)
00876 {
00877 spriteObject *temp = new spriteObject(this);
00878 temp->setPallete(menuSprite.palleteID);
00879 temp->giveSprite(menuSprite.spriteData, OBJ_SIZE_64X32, 32, 16, 0, xpos, 192-8);
00880 temp->setLayer(0);
00881 temp->setFrame(frame);
00882 temp->makeStatic();
00883 }
00884
00892 bool menuBottom::pickupSelected(u8 pickupID)
00893 {
00894 u32 pickupNum = 1<<pickupID;
00895 return pickupMask & pickupNum;
00896 }
00897
00899 void menuBottom::roundsMenu()
00900 {
00901 clearMenus();
00902 navFunction = &menuBottom::roundsNav;
00903 actionFunction = &menuBottom::roundsAction;
00904 menuColSize = 0;
00905
00906 PA_OutputText(screen, 4, 4, "First player to reach\nthis many points wins:");
00907
00908 cursor->destroy();
00909 cursor = NULL;
00910
00911
00912 makeInstructions(5, 96);
00913 makeInstructions(6, 160);
00914 }
00915
00917 void menuBottom::saveWarningMenu()
00918 {
00919 clearMenus();
00920 actionFunction = &menuBottom::sramAction;
00921 menuColSize = 0;
00922 PA_OutputText(screen, 2, 4, " WARNING: SRAM has not been\n\nformatted for this game yet.\n\n\n\n\n\n\n Overwrite SRAM Save Data?");
00923
00924 cursor->destroy();
00925 cursor = NULL;
00926
00927
00928 makeInstructions(0, 128);
00929 }
00930
00932 void menuBottom::controlsMenu()
00933 {
00934 resetBackground();
00935 clearMenus();
00936 actionFunction = &menuBottom::controlsAction;
00937 menuColSize = 0;
00938
00939 cursor->destroy();
00940 cursor = NULL;
00941
00942
00943 PA_EasyBgLoad(screen, 3, ::controlsBG);
00944
00945
00946 makeInstructions(7, 224);
00947 }
00948
00950 void menuBottom::creditsMenu()
00951 {
00952 clearMenus();
00953 actionFunction = &menuBottom::creditsAction;
00954 menuColSize = 0;
00955
00956 cursor->destroy();
00957 cursor = NULL;
00958
00959 PA_OutputText(screen, 2, 2, " Marshmallow Duel DS\n\nby pospi - pospi.spadgos.com\n\n\n Based on Marshmallow Duel\n created in 1996\n by Duncan and Roger Gill\n\n Sounds and music by\n Liam Alexander\n\n Special thanks to Sam and\nMoles for their beta-testing\n help and support.");
00960
00961
00962 makeInstructions(7, 128);
00963 }
00964
00970 void menuBottom::playerRenameMenu(u8 playerID)
00971 {
00972 clearMenus();
00973 navFunction = &menuBottom::charNameNav;
00974 renderFunction = &menuBottom::charNameRender;
00975 actionFunction = &menuBottom::charNameAction;
00976 menuColSize = 0;
00977
00978 struct menuItem temp1 = {100, 84, 0, 0, "", 0, 0, NULL, NULL};
00979 menuItems.push_back(temp1);
00980 struct menuItem temp2 = {108, 84, 0, 0, "", 0, 0, NULL, NULL};
00981 menuItems.push_back(temp2);
00982 struct menuItem temp3 = {116, 84, 0, 0, "", 0, 0, NULL, NULL};
00983 menuItems.push_back(temp3);
00984 struct menuItem temp4 = {124, 84, 0, 0, "", 0, 0, NULL, NULL};
00985 menuItems.push_back(temp4);
00986 struct menuItem temp5 = {132, 84, 0, 0, "", 0, 0, NULL, NULL};
00987 menuItems.push_back(temp5);
00988 struct menuItem temp6 = {140, 84, 0, 0, "", 0, 0, NULL, NULL};
00989 menuItems.push_back(temp6);
00990 struct menuItem temp7 = {148, 84, 0, 0, "", 0, 0, NULL, NULL};
00991 menuItems.push_back(temp7);
00992 struct menuItem temp8 = {156, 84, 0, 0, "", 0, 0, NULL, NULL};
00993 menuItems.push_back(temp8);
00994
00995 PA_OutputText(screen, 1, 3, " Pressing A will erase \n this player's stats.\n\nPRESS B IF YOU DON'T WANT THIS");
00996
00997
00998 makeInstructions(0, 96);
00999 makeInstructions(6, 160);
01000 }
01001
01003 void menuBottom::miscMenu()
01004 {
01005 clearMenus();
01006 navFunction = &menuBottom::miscNav;
01007 actionFunction = &menuBottom::miscAction;
01008 menuColSize = 0;
01009
01010 char data[24];
01011 sprintf(data, "Max pickups: %d ", numPickups);
01012 struct menuItem temp2 = {12, 60, 3, 7, data, 0, 0, NULL, NULL};
01013 menuItems.push_back(temp2);
01014
01015 strcpy(data, "Pre-show pickups: ");
01016 strcat(data, (showPickups ? "ON " : "OFF"));
01017 struct menuItem temp3 = {12, 84, 3, 10, data, 0, 0, NULL, NULL};
01018 menuItems.push_back(temp3);
01019
01020 strcpy(data, "Die while dancing: ");
01021 strcat(data, (dieWhileDancing ? "ON " : "OFF"));
01022 struct menuItem tempA = {12, 108, 3, 13, data, 0, 0, NULL, NULL};
01023 menuItems.push_back(tempA);
01024
01025
01026 makeInstructions(5, 96);
01027 makeInstructions(6, 160);
01028 }
01029
01031 void menuBottom::statsMenu()
01032 {
01033 clearMenus();
01034 navFunction = &menuBottom::statsNav;
01035 renderFunction = &menuBottom::statsRender;
01036 actionFunction = &menuBottom::statsAction;
01037 menuColSize = 7;
01038
01039
01040 struct menuItem temp1 = {8, 52, 2, 6, "All", 0, 0, NULL, NULL};
01041 menuItems.push_back(temp1);
01042 struct menuItem temp2 = {8, 68, 2, 8, "P1", 0, 0, NULL, NULL};
01043 menuItems.push_back(temp2);
01044 struct menuItem temp3 = {8, 84, 2, 10, "P2", 0, 0, NULL, NULL};
01045 menuItems.push_back(temp3);
01046 struct menuItem temp4 = {8, 100, 2, 12, "P3", 0, 0, NULL, NULL};
01047 menuItems.push_back(temp4);
01048 struct menuItem temp5 = {8, 116, 2, 14, "P4", 0, 0, NULL, NULL};
01049 menuItems.push_back(temp5);
01050 struct menuItem temp6 = {8, 132, 2, 16, "P5", 0, 0, NULL, NULL};
01051 menuItems.push_back(temp6);
01052 struct menuItem temp7 = {8, 148, 2, 18, "P6", 0, 0, NULL, NULL};
01053 menuItems.push_back(temp7);
01054
01055
01056 for (u8 i=0; i<4; ++i)
01057 {
01058 spriteObject *icon = new spriteObject(this);
01059 icon->setPallete(cursorSprite.palleteID);
01060 icon->giveSprite(cursorSprite.spriteData, OBJ_SIZE_16X16, 8, 8);
01061 icon->setFrame(0);
01062 u16 x=0;
01063 u16 ix=0;
01064 string text;
01065 switch (i)
01066 {
01067 case 0:
01068 x=4; ix=60; text="General";
01069 break;
01070 case 1:
01071 x=13; ix=120; text="Time";
01072 break;
01073 case 2:
01074 x=19; ix=172; text="Kills";
01075 break;
01076 case 3:
01077 x=26; ix=232; text="Deaths";
01078 break;
01079 }
01080 struct menuItem temp = {0, 0, x, 0, text, ix, 4, icon, NULL};
01081 menuItems.push_back(temp);
01082 }
01083
01084 autoMenuClickRegions();
01085
01086
01087 makeInstructions(7, 96);
01088 makeInstructions(6, 160);
01089
01090
01091 settingsPlayer = 1;
01092 drawStatsFor(0, 0);
01093 }
01094
01098 void menuBottom::autoMenuClickRegions()
01099 {
01100 for (u8 i=0; i<menuItems.size(); ++i)
01101 {
01102 menuItems[i].x1 = menuItems[i].textx*8;
01103 menuItems[i].x2 = menuItems[i].x1 + (menuItems[i].text.length())*8;
01104 menuItems[i].y1 = menuItems[i].texty*8;
01105 menuItems[i].y2 = menuItems[i].y1+8;
01106 }
01107 }
01108
01116 s8 menuBottom::touchingWhichItem(u16 x, u16 y)
01117 {
01118 for (u8 i=0; i<menuItems.size(); ++i)
01119 {
01120 if (menuItems[i].x1 != 0 && menuItems[i].x2 != 0
01121 && menuItems[i].y1 != 0 && menuItems[i].y2 != 0
01122 && x > menuItems[i].x1 && x < menuItems[i].x2
01123 && y > menuItems[i].y1 && y < menuItems[i].y2)
01124 {
01125 return i;
01126 }
01127 }
01128 return -1;
01129 }
01130
01131
01132
01139 bool menuBottom::isSRAMSaved()
01140 {
01141 #ifdef __WITHSAVING
01142 char testStr[6];
01143 PA_LoadData(_SRAMIDOFFSET, testStr, 6);
01144 return PA_CompareText(testStr, const_cast<char*>(_SRAMID));
01145 #else
01146 return true;
01147 #endif
01148 }
01149
01156 void menuBottom::loadSRAM(bool firstLoad)
01157 {
01158 #ifdef __WITHSAVING
01159 if (isSRAMSaved())
01160 {
01161 pickupMask = PA_Load32bit(_PICKUPOFFSET);
01162 roundNum = PA_Load8bit(_ROUNDSOFFSET);
01163 gameTop->pointsToWin = roundNum;
01164 char pNames[49];
01165 PA_LoadString(_NAMESOFFSET, pNames);
01166 playerNames = pNames;
01167 player1id = PA_Load8bit(_PLAYER1IDOFFSET);
01168 player2id = PA_Load8bit(_PLAYER2IDOFFSET);
01169 PA_LoadData(_PLAYERSPRSOFFSET, &playerSprs, _NUMSAVESLOTS);
01170 PA_LoadData(_PLAYERPALSOFFSET, &playerPals, _NUMSAVESLOTS);
01171 u8 settings = PA_Load8bit(_SETTINGSOFFSET);
01172 dieWhileDancing = settings & 32;
01173 showPickups = settings & 64;
01174 numPickups = settings & 31;
01175 PA_LoadData(_STATSOFFSET, &statistics, _STATSLEN);
01176 } else if (firstLoad) {
01177 sramLoadDefaults();
01178 sramSavePrevVars();
01179 } else {
01180 sramLoadPrevVars();
01181 }
01182 #else
01183 if (firstLoad) {
01184 sramLoadDefaults();
01185 sramSavePrevVars();
01186 } else {
01187 sramLoadPrevVars();
01188 }
01189 #endif
01190 }
01191
01198 void menuBottom::saveSRAM(bool dontCheck, u8 menuNumber)
01199 {
01200 #ifdef __WITHSAVING
01201 if (isSRAMSaved() || dontCheck)
01202 {
01203 PA_SaveString(_SRAMIDOFFSET, const_cast<char*>(_SRAMID));
01204 PA_Save8bit(_ROUNDSOFFSET, roundNum);
01205 PA_Save32bit(_PICKUPOFFSET, pickupMask);
01206 PA_SaveString(_NAMESOFFSET, const_cast<char*>(playerNames.c_str()));
01207 PA_Save8bit(_PLAYER1IDOFFSET, player1id);
01208 PA_Save8bit(_PLAYER2IDOFFSET, player2id);
01209 PA_SaveData(_PLAYERSPRSOFFSET, playerSprs, _NUMSAVESLOTS);
01210 PA_SaveData(_PLAYERPALSOFFSET, playerPals, _NUMSAVESLOTS);
01211 u8 settings = numPickups + (dieWhileDancing*32) + (showPickups*64);
01212 PA_Save8bit(_SETTINGSOFFSET, settings);
01213 PA_SaveData(_STATSOFFSET, statistics, _STATSLEN);
01214 sramSavePrevVars();
01215 mainMenu(menuNumber);
01216 } else {
01217 saveWarningMenu();
01218 }
01219 #else
01220 sramSavePrevVars();
01221 #endif
01222 }
01223
01228 void menuBottom::sramSavePrevVars()
01229 {
01230 prevRoundNum = roundNum;
01231 prevPickupMask = pickupMask;
01232 prevPlayerNames = playerNames;
01233 prevPlayer1id = player1id;
01234 prevPlayer2id = player2id;
01235 prevDieWhileDancing = dieWhileDancing;
01236 prevShowPickups = showPickups;
01237 prevNumPickups = numPickups;
01238
01239 for (u8 i=0; i<_NUMSAVESLOTS; ++i) {
01240 prevPlayerSprs[i] = playerSprs[i];
01241 prevPlayerPals[i] = playerPals[i];
01242 }
01243 }
01244
01249 void menuBottom::sramLoadPrevVars()
01250 {
01251 roundNum = prevRoundNum;
01252 gameTop->pointsToWin = roundNum;
01253 pickupMask = prevPickupMask;
01254 playerNames = prevPlayerNames;
01255 player1id = prevPlayer1id;
01256 player2id = prevPlayer2id;
01257 dieWhileDancing = prevDieWhileDancing;
01258 showPickups = prevShowPickups;
01259 numPickups = prevNumPickups;
01260
01261 for (u8 i=0; i<_NUMSAVESLOTS; ++i) {
01262 playerSprs[i] = prevPlayerSprs[i];
01263 playerPals[i] = prevPlayerPals[i];
01264 }
01265 }
01266
01270 void menuBottom::sramLoadDefaults()
01271 {
01272 roundNum = 3;
01273 gameTop->pointsToWin = roundNum;
01274 pickupMask = _ALLPICKUPS;
01275 playerNames = "Percy Howard Mowbray CliffordStanley Beaufort";
01276 player1id = 1;
01277 player2id = 2;
01278 dieWhileDancing = false;
01279 showPickups = true;
01280 numPickups = 3;
01281
01282 playerSprs[0] = 1; playerPals[0] = 1;
01283 playerSprs[1] = 1; playerPals[1] = 3;
01284 playerSprs[2] = 2; playerPals[2] = 2;
01285 playerSprs[3] = 2; playerPals[3] = 2;
01286 playerSprs[4] = 3; playerPals[4] = 4;
01287 playerSprs[5] = 3; playerPals[5] = 4;
01288
01289 for (u16 i=0; i<_STATSLEN; ++i)
01290 statistics[i] = 0;
01291 }
01292
01293
01294
01301 void menuBottom::pickupToggle(u8 i)
01302 {
01303 u32 pickupNum = 1<<i;
01304
01305 if (pickupSelected(i))
01306 pickupMask &= ~pickupNum;
01307 else
01308 pickupMask |= pickupNum;
01309 }
01310
01319 void menuBottom::alterPlayerName(u8 playerID, u8 letterID, s8 modBy)
01320 {
01321 playerNames[(playerID-1)*8 + letterID] += modBy;
01322
01323
01324 if (playerNames[(playerID-1)*8 + letterID] == 31)
01325 playerNames[(playerID-1)*8 + letterID] = 122;
01326 else if (playerNames[(playerID-1)*8 + letterID] == 123)
01327 playerNames[(playerID-1)*8 + letterID] = 32;
01328 else if (playerNames[(playerID-1)*8 + letterID] >= 91 && playerNames[(playerID-1)*8 + letterID] <= 96)
01329 {
01330 if (modBy > 0)
01331 playerNames[(playerID-1)*8 + letterID] = 97;
01332 else
01333 playerNames[(playerID-1)*8 + letterID] = 90;
01334 }
01335 else if (playerNames[(playerID-1)*8 + letterID] == 38)
01336 {
01337 if (modBy > 0)
01338 playerNames[(playerID-1)*8 + letterID] = 39;
01339 else
01340 playerNames[(playerID-1)*8 + letterID] = 37;
01341 }
01342
01343 #ifdef __MDDEBUG
01344 PA_OutputText(screen, 5, 0, "%d ", playerNames[(playerID-1)*8 + letterID]);
01345 #endif
01346 }
01347
01353 void menuBottom::playerColorCycle(u8 i)
01354 {
01355 ++playerPals[i];
01356 if (playerPals[i] == 5)
01357 playerPals[i] = 1;
01358 updatePlayerIcon(i);
01359 }
01360
01366 void menuBottom::playerGFXCycle(u8 i)
01367 {
01368 ++playerSprs[i];
01369 if (playerSprs[i] == 4)
01370 playerSprs[i] = 1;
01371 updatePlayerIcon(i);
01372 }
01373
01379 void menuBottom::updatePlayerIcon(u8 i)
01380 {
01381 u8 tempx = menuItems[selectedItem].obj->getx();
01382 u8 tempy = menuItems[selectedItem].obj->gety();
01383 menuItems[selectedItem].obj->destroy();
01384
01385 menuItems[selectedItem].obj = new spriteObject(this);
01386 menuItems[selectedItem].obj->setPallete(getPlayerPalleteID(playerPals[i]));
01387 menuItems[selectedItem].obj->giveSprite(getPlayerSpriteData(playerSprs[i]), OBJ_SIZE_32X32, 16, 16, 0, tempx, tempy);
01388
01389
01390 }
01391
01398 void menuBottom::selectPlayer(u8 i, u8 playerNum)
01399 {
01400 if (player1id == i+1)
01401 player1id = player2id;
01402 else if (player2id == i+1)
01403 player2id = player1id;
01404
01405 if (playerNum == 1)
01406 player1id = i+1;
01407 else
01408 player2id = i+1;
01409 }
01410
01418 void menuBottom::loadPlayerGFX(u8 dataNum, u8 playerNum)
01419 {
01420 const unsigned char *sprite = getPlayerSpriteData(playerSprs[dataNum-1]);
01421 const unsigned short *pal = getPlayerPalleteData(playerPals[dataNum-1]);
01422
01423 if (playerNum == 1)
01424 gameTop->loadPlayer1SpriteSet(pal, sprite);
01425 else
01426 gameTop->loadPlayer2SpriteSet(pal, sprite);
01427 }
01428
01435 const unsigned char *menuBottom::getPlayerSpriteData(u8 idNum)
01436 {
01437 switch(idNum)
01438 {
01439 case 2: return playerSprite2;
01440 case 3: return playerSprite3;
01441 default: return playerSprite1;
01442 }
01443 }
01444
01451 const unsigned short *menuBottom::getPlayerPalleteData(u8 idNum)
01452 {
01453 switch(idNum)
01454 {
01455 case 2: return playerPallete2;
01456 case 3: return playerPallete3;
01457 case 4: return playerPallete4;
01458 default: return playerPallete1;
01459 }
01460 }
01461
01468 u8 menuBottom::getPlayerPalleteID(u8 idNum)
01469 {
01470 switch(idNum)
01471 {
01472 case 2: return playerPal2;
01473 case 3: return playerPal3;
01474 case 4: return playerPal4;
01475 default: return playerPal1;
01476 }
01477 }
01478
01479
01480
01481
01482
01490 void menuBottom::writeStatValueAt(u16 offset, u16 value)
01491 {
01492 u8 part1 = value>>8;
01493 u8 part2 = value&255;
01494
01495 statistics[offset] = part1;
01496 statistics[offset+1] = part2;
01497 saveStats();
01498 }
01499
01507 u16 menuBottom::readStatValueAt(u16 offset) const
01508 {
01509
01510 u16 good1 = statistics[offset]<<8;
01511 u16 good2 = statistics[offset+1];
01512 u16 good = good1 + good2;
01513
01514 return good;
01515 }
01516
01521 void menuBottom::saveStats()
01522 {
01523 if (isSRAMSaved())
01524 PA_SaveData(_STATSOFFSET, statistics, _STATSLEN);
01525 }
01526
01534 void menuBottom::scoreKill(u8 player, u8 weaponID)
01535 {
01536 player--;
01537 u16 location = GLOBALSLOTSIZE+(PLAYERSLOTSIZE*player)+(weaponID*2);
01538 writeStatValueAt(location, readStatValueAt(location)+1);
01539 }
01540
01548 void menuBottom::scoreDeath(u8 player, u8 weaponID)
01549 {
01550 player--;
01551 u16 location = GLOBALSLOTSIZE+(PLAYERSLOTSIZE*player)+(WEAPONBLOCKSIZE*2)+(weaponID*2);
01552 writeStatValueAt(location, readStatValueAt(location)+1);
01553
01554
01555 location = weaponID*2;
01556 writeStatValueAt(location, readStatValueAt(location)+1);
01557 }
01558
01566 void menuBottom::scoreTime(u8 player, u8 weaponID, u16 timeSecs)
01567 {
01568 player--;
01569 u16 location = GLOBALSLOTSIZE+(PLAYERSLOTSIZE*player)+WEAPONBLOCKSIZE+(weaponID*2);
01570 writeStatValueAt(location, readStatValueAt(location)+timeSecs);
01571
01572
01573 location = WEAPONBLOCKSIZE+weaponID*2;
01574 writeStatValueAt(location, readStatValueAt(location)+timeSecs);
01575 }
01576
01584 void menuBottom::scoreRound(u8 winner, u8 loser, bool tied)
01585 {
01586 winner--;
01587 loser--;
01588
01589 u16 winlocation = GLOBALSLOTSIZE+(PLAYERSLOTSIZE*winner)+(WEAPONBLOCKSIZE*3);
01590 u16 loselocation = GLOBALSLOTSIZE+(PLAYERSLOTSIZE*loser)+(WEAPONBLOCKSIZE*3)+2;
01591 if (tied)
01592 {
01593 winlocation += 4;
01594 loselocation += 2;
01595 }
01596
01597 writeStatValueAt(winlocation, readStatValueAt(winlocation)+1);
01598 writeStatValueAt(loselocation, readStatValueAt(loselocation)+1);
01599
01600
01601 u16 location = (WEAPONBLOCKSIZE*2);
01602 writeStatValueAt(location, readStatValueAt(location)+1);
01603 }
01604
01610 void menuBottom::erasePlayer(u8 player)
01611 {
01612 player--;
01613 u16 startPos = GLOBALSLOTSIZE+(PLAYERSLOTSIZE*player);
01614 for (u16 i=0; i < (WEAPONBLOCKSIZE*3)+6; ++i)
01615 {
01616 statistics[startPos+i] = 0;
01617
01618 }
01619 }
01620
01629 u16 menuBottom::getKillsForPlayer(s8 player, s8 weaponID) const
01630 {
01631 u16 location;
01632 if (player == -1)
01633 location = 0;
01634 else {
01635 player--;
01636 location = GLOBALSLOTSIZE+(PLAYERSLOTSIZE*player);
01637 }
01638
01639 if (weaponID != -1)
01640 return readStatValueAt(location+weaponID*2);
01641
01642 u16 total = 0;
01643 for (u8 i=0; i < WEAPONBLOCKSIZE; i+=2)
01644 {
01645 total += readStatValueAt(location+i);
01646 }
01647 return total;
01648 }
01649
01658 u16 menuBottom::getDeathsForPlayer(s8 player, s8 weaponID) const
01659 {
01660 u16 location;
01661 if (player == -1)
01662 return 0;
01663 else {
01664 player--;
01665 location = GLOBALSLOTSIZE+(PLAYERSLOTSIZE*player)+(WEAPONBLOCKSIZE*2);
01666 }
01667
01668 if (weaponID != -1)
01669 return readStatValueAt(location+weaponID*2);
01670
01671 u16 total = 0;
01672 for (u8 i=0; i < WEAPONBLOCKSIZE; i+=2)
01673 {
01674 total += readStatValueAt(location+i);
01675 }
01676 return total;
01677 }
01678
01687 u16 menuBottom::getTimeForPlayer(s8 player, s8 weaponID) const
01688 {
01689 u16 location;
01690 if (player == -1)
01691 location = WEAPONBLOCKSIZE;
01692 else {
01693 player--;
01694 location = GLOBALSLOTSIZE+(PLAYERSLOTSIZE*player)+WEAPONBLOCKSIZE;
01695 }
01696
01697 if (weaponID != -1)
01698 return readStatValueAt(location+weaponID*2);
01699
01700 u16 total = 0;
01701 for (u8 i=0; i < WEAPONBLOCKSIZE; i+=2)
01702 {
01703 total += readStatValueAt(location+i);
01704 }
01705 return total;
01706 }
01707
01714 u16 menuBottom::getWins(s8 player) const
01715 {
01716 u16 location;
01717 if (player == -1)
01718 location = WEAPONBLOCKSIZE*2;
01719 else {
01720 player--;
01721 location = GLOBALSLOTSIZE+(PLAYERSLOTSIZE*player)+(WEAPONBLOCKSIZE*3);
01722 }
01723 return readStatValueAt(location);
01724 }
01725
01732 u16 menuBottom::getLosses(s8 player) const
01733 {
01734 u16 location;
01735 if (player == -1)
01736 return 0;
01737 else {
01738 player--;
01739 location = GLOBALSLOTSIZE+(PLAYERSLOTSIZE*player)+(WEAPONBLOCKSIZE*3)+2;
01740 }
01741 return readStatValueAt(location);
01742 }
01743
01750 u16 menuBottom::getTies(s8 player) const
01751 {
01752 u16 location;
01753 if (player == -1)
01754 return 0;
01755 else {
01756 player--;
01757 location = GLOBALSLOTSIZE+(PLAYERSLOTSIZE*player)+(WEAPONBLOCKSIZE*3)+4;
01758 }
01759 return readStatValueAt(location);
01760 }
01761
01762
01773 void menuBottom::drawStatsFor(u8 player, u8 page)
01774 {
01775 if (settingsPlayer == player && settingsPage == page)
01776 return;
01777 settingsPlayer = player;
01778 settingsPage = page;
01779
01780
01781 resetText();
01782
01783
01784 if (player != 0)
01785 PA_OutputText(screen, 4, 2, "Player: %s", macros::getPlayerName(player, playerNames, false).c_str());
01786
01787 u8 playerSlot = (player==0 ? -1 : player);
01788
01789 char buf[21];
01790 u16 (menuBottom::*statFunction)(s8, s8) const = NULL;
01791
01792 switch (page)
01793 {
01794 case 0:
01795 sprintf(buf, "Total playtime: %5d", getTimeForPlayer(playerSlot, -1)/(player==0 ? 2 : 1));
01796
01797
01798 PA_OutputText(screen, 8, 5, buf);
01799 sprintf(buf, "Rounds played: %5d", (player==0 ? getWins(playerSlot) : getWins(playerSlot)+getLosses(playerSlot)+getTies(playerSlot)));
01800 PA_OutputText(screen, 8, 7, buf);
01801 sprintf(buf, "Total kills: %5d", getKillsForPlayer(playerSlot, -1));
01802 PA_OutputText(screen, 8, 9, buf);
01803 if (player != 0)
01804 {
01805 sprintf(buf, "Total deaths: %5d", getDeathsForPlayer(playerSlot, -1));
01806 PA_OutputText(screen, 8, 11, buf);
01807 sprintf(buf, "Number of wins: %5d", getWins(playerSlot));
01808 PA_OutputText(screen, 8, 13, buf);
01809 sprintf(buf, "Number of losses: %5d", getLosses(playerSlot));
01810 PA_OutputText(screen, 8, 15, buf);
01811 sprintf(buf, "Number of ties: %5d", getTies(playerSlot));
01812 PA_OutputText(screen, 8, 17, buf);
01813 }
01814 break;
01815 case 1:
01816 PA_OutputText(screen, 7, 5, "Skull N/A");
01817 sprintf(buf, "1000V %5d", getTimeForPlayer(playerSlot, 1));
01818 PA_OutputText(screen, 7, 7, buf);
01819 sprintf(buf, "Invis %5d", getTimeForPlayer(playerSlot, 2));
01820 PA_OutputText(screen, 7, 9, buf);
01821 sprintf(buf, " Mine %5d", getTimeForPlayer(playerSlot, 3));
01822 PA_OutputText(screen, 7, 11, buf);
01823 sprintf(buf, " Gun %5d", getTimeForPlayer(playerSlot, 4));
01824 PA_OutputText(screen, 7, 13, buf);
01825 PA_OutputText(screen, 7, 15, " TNT N/A");
01826 sprintf(buf, "Boots %5d", getTimeForPlayer(playerSlot, 6));
01827 PA_OutputText(screen, 7, 17, buf);
01828 sprintf(buf, " Gren %5d", getTimeForPlayer(playerSlot, 7));
01829 PA_OutputText(screen, 7, 19, buf);
01830 sprintf(buf, " Puck %5d", getTimeForPlayer(playerSlot, 8));
01831 PA_OutputText(screen, 7, 21, buf);
01832 sprintf(buf, " None %5d", getTimeForPlayer(playerSlot, 18));
01833 PA_OutputText(screen, 19, 3, buf);
01834 sprintf(buf, "Paracht %5d", getTimeForPlayer(playerSlot, 9));
01835 PA_OutputText(screen, 19, 5, buf);
01836 sprintf(buf, " Hook %5d", getTimeForPlayer(playerSlot, 10));
01837 PA_OutputText(screen, 19, 7, buf);
01838 sprintf(buf, " Warp %5d", getTimeForPlayer(playerSlot, 11));
01839 PA_OutputText(screen, 19, 9, buf);
01840 sprintf(buf, " Magnet %5d", getTimeForPlayer(playerSlot, 12));
01841 PA_OutputText(screen, 19, 11, buf);
01842 sprintf(buf, " Net %5d", getTimeForPlayer(playerSlot, 13));
01843 PA_OutputText(screen, 19, 13, buf);
01844 sprintf(buf, " Shield %5d", getTimeForPlayer(playerSlot, 14));
01845 PA_OutputText(screen, 19, 15, buf);
01846 sprintf(buf, " Dunce %5d", getTimeForPlayer(playerSlot, 15));
01847 PA_OutputText(screen, 19, 17, buf);
01848 sprintf(buf, " Weasel %5d", getTimeForPlayer(playerSlot, 16));
01849 PA_OutputText(screen, 19, 19, buf);
01850 sprintf(buf, "Boomrng %5d", getTimeForPlayer(playerSlot, 17));
01851 PA_OutputText(screen, 19, 21, buf);
01852 break;
01853
01854 case 2: case 3:
01855 if (page == 2)
01856 statFunction = &menuBottom::getKillsForPlayer;
01857 else
01858 statFunction = &menuBottom::getDeathsForPlayer;
01859
01860 sprintf(buf, "Skull %5d", (this->*statFunction)(playerSlot, 0));
01861 PA_OutputText(screen, 7, 5, buf);
01862 sprintf(buf, "1000V %5d", (this->*statFunction)(playerSlot, 1));
01863 PA_OutputText(screen, 7, 7, buf);
01864 sprintf(buf, "Invis %5d", (this->*statFunction)(playerSlot, 2));
01865 PA_OutputText(screen, 7, 9, buf);
01866 sprintf(buf, " Mine %5d", (this->*statFunction)(playerSlot, 3));
01867 PA_OutputText(screen, 7, 11, buf);
01868 sprintf(buf, " Gun %5d", (this->*statFunction)(playerSlot, 4));
01869 PA_OutputText(screen, 7, 13, buf);
01870 sprintf(buf, " TNT %5d", (this->*statFunction)(playerSlot, 5));
01871 PA_OutputText(screen, 7, 15, buf);
01872 PA_OutputText(screen, 7, 17, "Boots N/A");
01873 sprintf(buf, " Gren %5d", (this->*statFunction)(playerSlot, 7));
01874 PA_OutputText(screen, 7, 19, buf);
01875 sprintf(buf, " Puck %5d", (this->*statFunction)(playerSlot, 8));
01876 PA_OutputText(screen, 7, 21, buf);
01877 sprintf(buf, (page == 3 ? " FIDs %5d" : " Tackle %5d"), (this->*statFunction)(playerSlot, 18));
01878 PA_OutputText(screen, 19, 3, buf);
01879 PA_OutputText(screen, 19, 5, "Paracht N/A");
01880 PA_OutputText(screen, 19, 7, " Hook N/A");
01881 sprintf(buf, " Warp %5d", (this->*statFunction)(playerSlot, 11));
01882 PA_OutputText(screen, 19, 9, buf);
01883 sprintf(buf, " Magnet %5d", (this->*statFunction)(playerSlot, 12));
01884 PA_OutputText(screen, 19, 11, buf);
01885 sprintf(buf, " Net %5d", (this->*statFunction)(playerSlot, 13));
01886 PA_OutputText(screen, 19, 13, buf);
01887 sprintf(buf, " Shield %5d", (this->*statFunction)(playerSlot, 14));
01888 PA_OutputText(screen, 19, 15, buf);
01889 PA_OutputText(screen, 19, 17, " Dunce N/A");
01890 sprintf(buf, " Weasel %5d", (this->*statFunction)(playerSlot, 16));
01891 PA_OutputText(screen, 19, 19, buf);
01892 sprintf(buf, "Boomrng %5d", (this->*statFunction)(playerSlot, 17));
01893 PA_OutputText(screen, 19, 21, buf);
01894 break;
01895 }
01896 }