Skip to content

Commit

Permalink
fixed graphics glitches with PSX backgrounds
Browse files Browse the repository at this point in the history
  • Loading branch information
CommonLoon102 committed Apr 20, 2021
1 parent 25d5550 commit 59576f4
Show file tree
Hide file tree
Showing 13 changed files with 75 additions and 39 deletions.
14 changes: 9 additions & 5 deletions game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,7 @@ void Game::restartLevel() {
preloadLevelScreenData(screenNum, kNoScreen);
_andyObject->levelData0x2988 = _res->_resLevelData0x2988PtrTable[_andyObject->spriteNum];
memset(_video->_backgroundLayer, 0, Video::W * Video::H);
_video->clearYuvBackBuffer();
resetScreen();
if (_andyObject->screenNum != screenNum) {
preloadLevelScreenData(_andyObject->screenNum, kNoScreen);
Expand Down Expand Up @@ -1817,8 +1818,16 @@ void Game::drawPlasmaCannon() {
_plasmaCannonObject = 0;
}

void Game::updateBackgroundPsx(int num) {
if (_res->_isPsx) {
const LvlBackgroundData *lvl = &_res->_resLvlScreenBackgroundDataTable[_res->_currentScreenResourceNum];
_video->decodeBackgroundPsx(lvl->backgroundBitmapTable[num] + 4, -1, Video::W, Video::H);
}
}

void Game::drawScreen() {
memcpy(_video->_frontLayer, _video->_backgroundLayer, Video::W * Video::H);
_video->copyYuvBackBuffer();

// redraw background animation sprites
LvlBackgroundData *dat = &_res->_resLvlScreenBackgroundDataTable[_res->_currentScreenResourceNum];
Expand Down Expand Up @@ -2718,11 +2727,6 @@ int Game::displayHintScreen(int num, int pause) {
_video->_paletteChanged = true;
}
unmuteSound();
if (isPsx) { // restore level screen bitmap
LvlBackgroundData *lvl = &_res->_resLvlScreenBackgroundDataTable[_res->_currentScreenResourceNum];
const uint8_t *bmp = lvl->backgroundBitmapTable[lvl->currentBackgroundId];
_video->decodeBackgroundPsx(bmp + 4, -1, Video::W, Video::H);
}
return confirmQuit && quit == kQuitYes;
}

Expand Down
1 change: 1 addition & 0 deletions game.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ struct Game {
int restoreAndyCollidesLava();
int updateAndyLvlObject();
void drawPlasmaCannon();
void updateBackgroundPsx(int num);
void drawScreen();
void updateLvlObjectList(LvlObject **list);
void updateLvlObjectLists();
Expand Down
3 changes: 3 additions & 0 deletions level1_rock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ void Level_rock::postScreenUpdate_rock_screen0() {
++_screenCounterTable[0];
if (_screenCounterTable[0] > 25) {
_res->_screensState[0].s0 = 1;
_g->updateBackgroundPsx(1);
}
if (_screenCounterTable[0] == 2) {
_g->setShakeScreen(3, 12);
Expand Down Expand Up @@ -129,6 +130,7 @@ void Level_rock::postScreenUpdate_rock_screen4() {
_g->setupScreenMask(4);
} else if (_screenCounterTable[4] > 46) {
_res->_screensState[4].s0 = 1;
_g->updateBackgroundPsx(1);
}
if (_screenCounterTable[4] == 31) {
_g->setShakeScreen(2, 12);
Expand Down Expand Up @@ -168,6 +170,7 @@ void Level_rock::postScreenUpdate_rock_screen9() {
_checkpoint = 5;
}
_res->_screensState[9].s0 = 1;
_g->updateBackgroundPsx(1);
_g->setAndySprite(2);
_andyObject->xPos = 105;
_andyObject->yPos = 52;
Expand Down
1 change: 1 addition & 0 deletions level2_fort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ void Level_fort::postScreenUpdate_fort_screen1() {
_g->setupScreenMask(1);
} else if (_screenCounterTable[1] == 59) {
_res->_screensState[1].s0 = 1;
_g->updateBackgroundPsx(1);
_res->_resLvlScreenBackgroundDataTable[1].currentBackgroundId = 1;
}
}
Expand Down
6 changes: 5 additions & 1 deletion level3_pwr1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ void Level_pwr1::postScreenUpdate_pwr1_screen6() {
_res->_screensState[6].s0 = 1;
dat->currentMaskId = 1;
dat->currentBackgroundId = 1;
_g->updateBackgroundPsx(1);
if (_checkpoint == 0) {
_checkpoint = 1;
}
Expand All @@ -131,7 +132,8 @@ void Level_pwr1::postScreenUpdate_pwr1_screen6() {
++_screenCounterTable[6];
if (_screenCounterTable[6] >= 54) {
_res->_screensState[6].s0 = 2;
dat->currentBackgroundId = 1;
dat->currentBackgroundId = 2;
_g->updateBackgroundPsx(2);
}
break;
default: {
Expand Down Expand Up @@ -242,6 +244,7 @@ void Level_pwr1::postScreenUpdate_pwr1_screen23() {
_res->_resLvlScreenBackgroundDataTable[23].currentMaskId = 1;
_res->_resLvlScreenBackgroundDataTable[23].currentBackgroundId = 1;
_g->setupScreenMask(23);
_g->updateBackgroundPsx(1);
}
break;
case 0:
Expand All @@ -267,6 +270,7 @@ void Level_pwr1::postScreenUpdate_pwr1_screen27() {
++_screenCounterTable[27];
if (_screenCounterTable[27] == 37) {
_res->_screensState[27].s0 = 1;
_g->updateBackgroundPsx(1);
_res->_resLvlScreenBackgroundDataTable[27].currentMaskId = 1;
_res->_resLvlScreenBackgroundDataTable[27].currentBackgroundId = 1;
_g->setupScreenMask(27);
Expand Down
2 changes: 2 additions & 0 deletions level4_isld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ void Level_isld::postScreenUpdate_isld_screen1() {
++_screenCounterTable[1];
if (_screenCounterTable[1] > 21) {
_res->_screensState[1].s0 = 1;
_g->updateBackgroundPsx(1);
_res->_resLvlScreenBackgroundDataTable[1].currentBackgroundId = 1;
}
}
Expand Down Expand Up @@ -167,6 +168,7 @@ void Level_isld::postScreenUpdate_isld_screen15() {
++_screenCounterTable[15];
if (_screenCounterTable[15] >= 60) {
_res->_screensState[15].s0 = 1;
_g->updateBackgroundPsx(1);
}
break;
case 0:
Expand Down
1 change: 1 addition & 0 deletions level5_lava.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ void Level_lava::postScreenUpdate_lava_screen0() {
++_screenCounterTable[0];
if (_screenCounterTable[0] >= 11) {
_res->_screensState[0].s0 = 1;
_g->updateBackgroundPsx(1);
}
break;
case 0:
Expand Down
4 changes: 4 additions & 0 deletions level7_lar1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ void Level_lar1::postScreenUpdate_lar1_screen0() {
} else if (_screenCounterTable[0] >= 45) {
_res->_screensState[0].s0 = 1;
_res->_resLvlScreenBackgroundDataTable[0].currentBackgroundId = 1;
_g->updateBackgroundPsx(1);
} else if (_screenCounterTable[0] == 11) {
_g->setShakeScreen(3, 2);
} else if (_screenCounterTable[0] == 13) {
Expand All @@ -208,6 +209,7 @@ void Level_lar1::postScreenUpdate_lar1_screen0() {
_res->_resLvlScreenBackgroundDataTable[0].currentMaskId = 2;
_g->setupScreenMask(0);
_res->_screensState[0].s0 = 2;
_g->updateBackgroundPsx(2);
}
break;
}
Expand Down Expand Up @@ -354,6 +356,7 @@ void Level_lar1::postScreenUpdate_lar1_screen14() {
_g->setupScreenMask(14);
} else if (_screenCounterTable[14] >= 20) {
_res->_screensState[14].s0 = 1;
_g->updateBackgroundPsx(1);
} else if (_screenCounterTable[14] == 7 || _screenCounterTable[14] == 9 || _screenCounterTable[14] == 11 || _screenCounterTable[14] == 13 || _screenCounterTable[14] == 15) {
_g->setShakeScreen(3, 2);
}
Expand Down Expand Up @@ -441,6 +444,7 @@ void Level_lar1::postScreenUpdate_lar1_screen19() {
} else if (_screenCounterTable[19] >= 14) {
_res->_screensState[19].s0 = 1;
_res->_resLvlScreenBackgroundDataTable[19].currentBackgroundId = 1;
_g->updateBackgroundPsx(1);
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions level8_lar2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,8 +440,10 @@ void Level_lar2::preScreenUpdate_lar2_screen7() {
if (_res->_currentScreenResourceNum == 7) {
if (_checkpoint >= 4 && _checkpoint < 7) {
_res->_screensState[7].s0 = 1;
_g->updateBackgroundPsx(1);
} else {
_res->_screensState[7].s0 = 0;
_g->updateBackgroundPsx(0);
}
if (_checkpoint == 5) {
if (!_paf->_skipCutscenes) {
Expand Down
38 changes: 19 additions & 19 deletions mdec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ struct BitStream { // most significant 16 bits
_len += 16;
}
assert(_len >= count);
const int value = (_bits >> (_len - count)) & ((1 << count) - 1);
_len -= count;
const int value = (_bits >> _len) & ((1 << count) - 1);
return value;
}
int getSignedBits(int len) {
Expand Down Expand Up @@ -117,15 +117,15 @@ static void dequantizeBlock(int *coefficients, float *block, int scale) {
}
}

static const double _idct8x8[8][8] = {
{ 0.353553390593274, 0.490392640201615, 0.461939766255643, 0.415734806151273, 0.353553390593274, 0.277785116509801, 0.191341716182545, 0.097545161008064 },
{ 0.353553390593274, 0.415734806151273, 0.191341716182545, -0.097545161008064, -0.353553390593274, -0.490392640201615, -0.461939766255643, -0.277785116509801 },
{ 0.353553390593274, 0.277785116509801, -0.191341716182545, -0.490392640201615, -0.353553390593274, 0.097545161008064, 0.461939766255643, 0.415734806151273 },
{ 0.353553390593274, 0.097545161008064, -0.461939766255643, -0.277785116509801, 0.353553390593274, 0.415734806151273, -0.191341716182545, -0.490392640201615 },
{ 0.353553390593274, -0.097545161008064, -0.461939766255643, 0.277785116509801, 0.353553390593274, -0.415734806151273, -0.191341716182545, 0.490392640201615 },
{ 0.353553390593274, -0.277785116509801, -0.191341716182545, 0.490392640201615, -0.353553390593273, -0.097545161008064, 0.461939766255643, -0.415734806151273 },
{ 0.353553390593274, -0.415734806151273, 0.191341716182545, 0.097545161008064, -0.353553390593274, 0.490392640201615, -0.461939766255643, 0.277785116509801 },
{ 0.353553390593274, -0.490392640201615, 0.461939766255643, -0.415734806151273, 0.353553390593273, -0.277785116509801, 0.191341716182545, -0.097545161008064 }
static const int16_t _idct8x8[8][8] = {
{ 23170, 32138, 30273, 27245, 23170, 18204, 12539, 6392 },
{ 23170, 27245, 12539, -6393, -23171, -32139, -30274, -18205 },
{ 23170, 18204, -12540, -32139, -23171, 6392, 30273, 27245 },
{ 23170, 6392, -30274, -18205, 23170, 27245, -12540, -32139 },
{ 23170, -6393, -30274, 18204, 23170, -27246, -12540, 32138 },
{ 23170, -18205, -12540, 32138, -23171, -6393, 30273, -27246 },
{ 23170, -27246, 12539, 6392, -23171, 32138, -30274, 18204 },
{ 23170, -32139, 30273, -27246, 23170, -18205, 12539, -6393 }
};

static void idct(float *dequantData, float *result) {
Expand All @@ -135,7 +135,7 @@ static void idct(float *dequantData, float *result) {
for (int x = 0; x < 8; x++) {
float p = 0;
for (int i = 0; i < 8; ++i) {
p += dequantData[i] * _idct8x8[x][i];
p += dequantData[i] * _idct8x8[x][i] / 0x10000;
}
tmp[y + x * 8] = p;
}
Expand All @@ -147,7 +147,7 @@ static void idct(float *dequantData, float *result) {
for (int y = 0; y < 8; y++) {
float p = 0;
for (int i = 0; i < 8; ++i) {
p += u[i] * _idct8x8[y][i];
p += u[i] * _idct8x8[y][i] / 0x10000;
}
result[y * 8 + x] = p;
}
Expand Down Expand Up @@ -176,7 +176,7 @@ static void decodeBlock(BitStream *bs, int x8, int y8, uint8_t *dst, int dstPitc
}
}

int decodeMDEC(const uint8_t *src, int len, const uint8_t *mborder, int mblen, int w, int h, MdecOutput *out) {
int decodeMDEC(const uint8_t *src, int len, const uint8_t *mbOrder, int mbLength, int w, int h, MdecOutput *out) {
BitStream bs(src, len);
bs.getBits(16);
const uint16_t vlc = bs.getBits(16);
Expand All @@ -192,15 +192,15 @@ int decodeMDEC(const uint8_t *src, int len, const uint8_t *mborder, int mblen, i
const int yPitch = out->planes[kOutputPlaneY].pitch;
uint8_t *yPtr = out->planes[kOutputPlaneY].ptr + out->y * yPitch + out->x;
const int cbPitch = out->planes[kOutputPlaneCb].pitch;
uint8_t *cbPtr = out->planes[kOutputPlaneCb].ptr + (out->y * cbPitch + out->x) / 2;
uint8_t *cbPtr = out->planes[kOutputPlaneCb].ptr + (out->y / 2) * cbPitch + (out->x / 2);
const int crPitch = out->planes[kOutputPlaneCr].pitch;
uint8_t *crPtr = out->planes[kOutputPlaneCr].ptr + (out->y * crPitch + out->x) / 2;
uint8_t *crPtr = out->planes[kOutputPlaneCr].ptr + (out->y / 2) * crPitch + (out->x / 2);

int z = 0;
for (int x = 0, x2 = 0; x < blockW; ++x, x2 += 2) {
for (int y = 0, y2 = 0; y < blockH; ++y, y2 += 2) {
if (z < mblen) {
const uint8_t xy = mborder[z];
if (z < mbLength) {
const uint8_t xy = mbOrder[z];
if ((xy & 15) != x || (xy >> 4) != y) {
continue;
}
Expand All @@ -212,13 +212,13 @@ int decodeMDEC(const uint8_t *src, int len, const uint8_t *mborder, int mblen, i
decodeBlock(&bs, x2 + 1, y2, yPtr, yPitch, qscale, version);
decodeBlock(&bs, x2, y2 + 1, yPtr, yPitch, qscale, version);
decodeBlock(&bs, x2 + 1, y2 + 1, yPtr, yPitch, qscale, version);
if (mborder && z == mblen) {
if (mbOrder && z == mbLength) {
goto end;
}
}
}
end:
if (!mborder && bs.bitsAvailable() >= 11) {
if (!mbOrder && bs.bitsAvailable() >= 11) {
const int eof = bs.getBits(11);
assert(eof == 0x3FE || eof == 0x3FF);
}
Expand Down
2 changes: 1 addition & 1 deletion mdec.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ struct MdecOutput {
} planes[3];
};

int decodeMDEC(const uint8_t *src, int len, const uint8_t *mborder, int mblen, int w, int h, MdecOutput *out);
int decodeMDEC(const uint8_t *src, int len, const uint8_t *mbOrder, int mbLength, int w, int h, MdecOutput *out);

#endif // MDEC_H__
36 changes: 24 additions & 12 deletions video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Video::Video() {
_transformShadowBuffer = 0;
_transformShadowLayerDelta = 0;
memset(&_mdec, 0, sizeof(_mdec));
_backgroundPsx = 0;
}

Video::~Video() {
Expand Down Expand Up @@ -79,6 +80,17 @@ void Video::updateYuvDisplay() {
}

void Video::copyYuvBackBuffer() {
if (_backgroundPsx) {
_mdec.x = 0;
_mdec.y = 0;
_mdec.w = W;
_mdec.h = H;
decodeMDEC(_backgroundPsx, W * H * sizeof(uint16_t), 0, 0, W, H, &_mdec);
}
}

void Video::clearYuvBackBuffer() {
_backgroundPsx = 0;
}

void Video::updateScreen() {
Expand Down Expand Up @@ -476,15 +488,15 @@ uint8_t Video::findWhiteColor() const {
}

void Video::decodeBackgroundPsx(const uint8_t *src, int size, int w, int h, int x, int y) {
_mdec.x = x;
_mdec.y = y;
_mdec.w = w;
_mdec.h = h;
if (size < 0) { // size not available
size = w * h * sizeof(uint16_t);
if (size < 0) {
_backgroundPsx = src;
} else {
_mdec.x = x;
_mdec.y = y;
_mdec.w = w;
_mdec.h = h;
decodeMDEC(src, size, 0, 0, w, h, &_mdec);
}
decodeMDEC(src, size, 0, 0, w, h, &_mdec);
copyYuvBackBuffer();
}

void Video::decodeBackgroundOverlayPsx(const uint8_t *src, int x, int y) {
Expand All @@ -499,14 +511,14 @@ void Video::decodeBackgroundOverlayPsx(const uint8_t *src, int x, int y) {
const int len = READ_LE_UINT16(src + offset + 2);
_mdec.w = src[offset + 4] * 16;
_mdec.h = src[offset + 5] * 16;
const int mborderlen = src[offset + 6];
const int mborderalign = src[offset + 7];
const int mbOrderLength = src[offset + 6];
const int mbOrderOffset = src[offset + 7];
const uint8_t *data = &src[offset + 8];
if (mborderalign == 0) {
if (mbOrderOffset == 0) {
decodeMDEC(data, len - 8, 0, 0, _mdec.w, _mdec.h, &_mdec);
} else {
// different macroblocks order
decodeMDEC(data + mborderalign, len - 8 - mborderalign, data, mborderlen, _mdec.w, _mdec.h, &_mdec);
decodeMDEC(data + mbOrderOffset, len - 8 - mbOrderOffset, data, mbOrderLength, _mdec.w, _mdec.h, &_mdec);
}
offset += len;
}
Expand Down
4 changes: 3 additions & 1 deletion video.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct Video {
H = 192
};

static const uint8_t _fontCharactersTable[78];
static const uint8_t _fontCharactersTable[39 * 2];

uint8_t _palette[256 * 3];
uint16_t _displayPaletteBuffer[256 * 3];
Expand All @@ -48,6 +48,7 @@ struct Video {
} _drawLine;

MdecOutput _mdec;
const uint8_t *_backgroundPsx;

Video();
~Video();
Expand All @@ -58,6 +59,7 @@ struct Video {
void updateGameDisplay(uint8_t *buf);
void updateYuvDisplay();
void copyYuvBackBuffer();
void clearYuvBackBuffer();
void updateScreen();
void clearBackBuffer();
void clearPalette();
Expand Down

0 comments on commit 59576f4

Please sign in to comment.