📄 writer.cpp
字号:
// Writer.cpp
//
/////////////////////////////////////////////////////////////////////////////
#include <cstring>
#include "GameState.h"
#include "Game.h"
#include "Writer.h"
// 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -