/
trilirium
/
Pacman
Обзор
Документация
Войти
/
trilirium
/
Pacman
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
Writer.cpp
248 строк
7 KB
Trilirium
first commit
19 июн 2026, 11:07
19 июн 2026, 11:07
d44591e
Код
Авторство
О чём код?
// Writer.cpp // ///////////////////////////////////////////////////////////////////////////// #include <cstring> #include "GameState.h" #include "Game.h" #include "Writer.h" using namespace Puckman; // string table Writer::stringEntry Writer::stringTable[0x37] = { { 0x83d4, "HIGH@SCORE", 0x8f, 0x80 }, { 0x803b, "CREDIT@@@", 0x8f, 0x80 }, { 0x803b, "FREE@PLAY", 0x8f, 0x80 }, { 0x028c, "PLAYER@ONE", 0x85, 0x80 }, { 0x028c, "PLAYER@TWO", 0x85, 0x80 }, { 0x0292, "GAME@@OVER", 0x81, 0x80 }, { 0x0252, "READY", 0x89, 0x90 }, { 0x02ee, "PUSH@START@BUTTON", 0x87, 0x80 }, { 0x02b2, "1@PLAYER@ONLY", 0x85, 0x80 }, { 0x02b2, "1@OR@2@PLAYERS", 0x85, 0x80 }, { 0x0396, "BONUS@PUCKMAN@FOR@@@000@\x5d\x5e\x5f", 0x8e, 0x80 }, { 0x02ba, "\x5c@\x28\x29\x2a\x2b\x2c\x2d\x2e@1980", 0x83, 0x80 }, // (c) NAMCO 1980 { 0x02c3, "CHARACTER:NICKNAME", 0x8f, 0x80 }, { 0x0165, "\x26""AKABEU\x26", 0x81, 0x80 }, { 0x0145, "\x26MACKY\x26", 0x81, 0x80 }, { 0x0148, "\x26PINKY\x26", 0x83, 0x80 }, { 0x0148, "\x26MICKY\x26", 0x83, 0x80 }, { 0x0276, "\x10@\x5d\x5e\x5f", 0x9f, 0x80 }, // small pill 10 PTS { 0x0278, "\x14@\x5d\x5e\x5f", 0x9f, 0x80 }, // big pill 50 PTS { 0x025d, "\x28\x29\x2a\x2b\x2c\x2d\x2e", 0x83, 0x80 }, // NAMCO { 0x02c5, "@OIKAKE\x3b\x3b\x3b\x3b", 0x81, 0x80 }, { 0x02c5, "@URCHIN\x3b\x3b\x3b\x3b", 0x81, 0x80 }, { 0x02c8, "@MACHIBUSE\x3b\x3b", 0x83, 0x80 }, { 0x02c8, "@TOMP\x3b\x3b\x3b\x3b\x3b", 0x83, 0x80 }, { 0x0000, "", 0x00, 0x00 }, { 0x0000, "", 0x00, 0x00 }, { 0x0000, "", 0x00, 0x00 }, { 0x0212, "\x81\x85", 0x83, 0x90 }, // 100 { 0x0232, "@\x82\x85@", 0x83, 0x90 }, // 300 { 0x0232, "@\x83\x85@", 0x83, 0x90 }, // 500 { 0x0232, "@\x84\x85@", 0x83, 0x90 }, // 700 { 0x0232, "@\x86\x8d\x8e", 0x83, 0x90 }, // 1000 { 0x0232, "\x87\x88\x8d\x8e", 0x83, 0x90 }, // 2000 { 0x0232, "\x89\x8a\x8d\x8e", 0x83, 0x90 }, // 3000 { 0x0232, "\x8b\x8c\x8d\x8e", 0x83, 0x90 }, // 5000 { 0x0304, "MEMORY@OK", 0x8f, 0x80 }, { 0x0304, "BAD@@@@R@M", 0x8f, 0x80 }, { 0x0308, "FREE@@PLAY@@@@@@@", 0x8f, 0x80 }, { 0x0308, "1@COIN@@1@CREDIT@", 0x8f, 0x80 }, { 0x0308, "1@COIN@@2@CREDITS", 0x8f, 0x80 }, { 0x0308, "2@COINS@1@CREDIT@", 0x8f, 0x80 }, { 0x030c, "PUCKMAN", 0x8f, 0x80 }, { 0x030a, "BONUS@@NONE", 0x8f, 0x80 }, { 0x030a, "BONUS@", 0x8f, 0x80 }, { 0x030e, "TABLE@@", 0x8f, 0x80 }, { 0x030e, "UPRIGHT", 0x8f, 0x80 }, { 0x020a, "000", 0x8f, 0x80 }, { 0x016b, "\x26""AOSUKE\x26", 0x85, 0x80 }, { 0x014b, "\x26MUCKY\x26", 0x85, 0x80 }, { 0x016e, "\x26GUZUTA\x26", 0x87, 0x80 }, { 0x014e, "\x26MOCKY\x26", 0x87, 0x80 }, { 0x02cb, "@KIMAGURE\x3b\x3b", 0x85, 0x80 }, { 0x02cb, "@STYLIST\x3b\x3b\x3b\x3b", 0x85, 0x80 }, { 0x02ce, "@OTOBOKE\x3b\x3b", 0x87, 0x80 }, { 0x02ce, "@CRYBABY\x3b\x3b\x3b\x3b\x3b", 0x87, 0x80 } }; ///////////////////////////////////////////////////////////////////////////// // printing methods ///////////////////////////////////////////////////////////////////////////// // prints or clear a string void Writer::printString(int stringNumber) { stringEntry *string = &stringTable[stringNumber & 0x7f]; int pos = string->position; // most significant bit of the position tells the increment we have to use int lineOffset = (pos & 0x8000) ? -0x01 : -0x20; // adjust position pos = pos & 0x3ff; // do we have to write the string or clear it? bool del = (stringNumber & 0x80) == 0x80; // iterate through the string for (unsigned int i = 0; i < strlen(string->string); i++){ // draw or clear current character theGame->VRAM[pos + i*lineOffset] = (del) ? 0x40 : string->string[i]; theGame->CRAM[pos + i*lineOffset] = (del) ? string->attrDelete : string->attrNormal; } } // prints a score void Writer::printScore(int score, int dest, int digits, int skipableDigits) { bool hasPrinted = false; int base = 1; for (int i = 1; i < digits; i++){ base = base*10; } for (int i = 0; i < digits; i++){ int currDigit = (score/base) % 10; // prints digit printDigit(currDigit, dest, hasPrinted, skipableDigits > 0); skipableDigits--; dest--; base = base/10; } } // print the current credit configuration void Writer::printCredits() { int credits = theGame->settings.credits; if (credits == 0xff){ // if free play is set, print it and exit Writer::printString(2); } else { // print CREDIT Writer::printString(1); // if there's MSB, print it if (((credits/10) % 10) != 0){ theGame->VRAM[0x034] = 0x30 + ((credits/10) % 10); } // print LSB theGame->VRAM[0x033] = 0x30 + (credits % 10); } } void Writer::printBonusLifeMSB() { int bonusLife = theGame->settings.bonusLife/1000; // print LSB theGame->VRAM[0x136] = (bonusLife % 10) + 0x30; // print MSB if it's not 0 if (((bonusLife/10) % 10) != 0){ theGame->VRAM[0x136 + 0x20] = 0x30 + ((bonusLife/10) % 10); } } // prints HIGH SCORE string, inits scores and print them void Writer::initAndPrintScores() { // print HIGH SCORE Writer::printString(0); // reset 1P & 2P score theGame->score1P = theGame->score2P = 0; theGame->gotBonusLife1P = theGame->gotBonusLife2P = false; // prints 1P & 2P score Writer::printScore(theGame->score1P, 0x3fc, 6, 4); Writer::printScore(theGame->score2P, 0x3e9, 6, (theGame->numberOfPlayers == 0) ? 6 : 4); } void Writer::showOrHide1UP2UP() { theGame->cntShowHide1P2P++; // if we're playing or about to play if ((theGame->state == PLAYING) || (theGame->states[PLAYING]->substate >= 2)){ if (theGame->currentPlayer == 0){ if ((theGame->cntShowHide1P2P & 0x10) == 0){ Writer::print1UP(); } else { Writer::hide1UP(); } } else { if ((theGame->cntShowHide1P2P & 0x10) == 0){ Writer::print2UP(); } else { Writer::hide2UP(); } } // if it's a one player game, hide 2UP if (theGame->numberOfPlayers == 0){ Writer::hide2UP(); } } else { Writer::print1UP(); Writer::print2UP(); } } ///////////////////////////////////////////////////////////////////////////// // helper methods ///////////////////////////////////////////////////////////////////////////// // print a digit void Writer::printDigit(int digit, int dest, bool &hasPrinted, bool skipable) { // ignore high bits digit = digit & 0x0f; if (digit != 0){ hasPrinted = true; } else { if (!hasPrinted && skipable){ digit = 0x40; } } // draw the digit or if skipable draw an empty space theGame->VRAM[dest] = digit; } void Writer::print1UP() { theGame->VRAM[0x3d8 + 0] = 'P'; theGame->VRAM[0x3d8 + 1] = 'U'; theGame->VRAM[0x3d8 + 2] = '1'; } void Writer::print2UP() { theGame->VRAM[0x3c5 + 0] = 'P'; theGame->VRAM[0x3c5 + 1] = 'U'; theGame->VRAM[0x3c5 + 2] = '2'; } void Writer::hide1UP() { theGame->VRAM[0x3d8 + 0] = 0x40; theGame->VRAM[0x3d8 + 1] = 0x40; theGame->VRAM[0x3d8 + 2] = 0x40; } void Writer::hide2UP() { theGame->VRAM[0x3c5 + 0] = 0x40; theGame->VRAM[0x3c5 + 1] = 0x40; theGame->VRAM[0x3c5 + 2] = 0x40; }