diff --git a/engines/twine/renderer/renderer.cpp b/engines/twine/renderer/renderer.cpp index 62b8f8ca33a..0f5d8277940 100644 --- a/engines/twine/renderer/renderer.cpp +++ b/engines/twine/renderer/renderer.cpp @@ -44,6 +44,17 @@ namespace TwinE { Renderer::Renderer(TwinEEngine *engine) : _engine(engine), shadeAngleTab3(&shadeAngleTable[384]) { } +Renderer::~Renderer() { + free(_polyTab); + free(_polyTab2); +} + +void Renderer::init(int32 w, int32 h) { + _polyTabSize = _engine->height() * 2; + _polyTab = (int16*)malloc(_polyTabSize * sizeof(int16)); + _polyTab2 = (int16*)malloc(_polyTabSize * sizeof(int16)); +} + int32 Renderer::projectPositionOnScreen(int32 cX, int32 cY, int32 cZ) { if (isUsingOrhoProjection) { projPosX = ((cX - cZ) * 24) / BRICK_SIZE + orthoProjX; @@ -434,14 +445,15 @@ void Renderer::computePolygons(int16 polyRenderType, Vertex *vertices, int32 num cvalue = (oldVertexParam << 8) + ((vertexParam2 - oldVertexParam) << 8) % vsize; cdelta = ((vertexParam2 - oldVertexParam) << 8) / vsize; } - int16 *outPtr = &polyTab[ypos + (up ? _engine->height() : 0)]; // outPtr is the output ptr in the renderTab + const int32 polyTabIndex = ypos + (up ? _engine->height() : 0); + int16 *outPtr = &_polyTab[polyTabIndex]; // outPtr is the output ptr in the renderTab float slope = (float)hsize / (float)vsize; slope = up ? -slope : slope; for (int32 i = 0; i < vsize + 2; i++) { - if (outPtr - polyTab < ARRAYSIZE(polyTab)) { - if (outPtr - polyTab > 0) { + if (outPtr - _polyTab < _polyTabSize) { + if (outPtr - _polyTab > 0) { *outPtr = xpos; } } @@ -450,11 +462,11 @@ void Renderer::computePolygons(int16 polyRenderType, Vertex *vertices, int32 num } if (polyRenderType >= POLYGONTYPE_GOURAUD) { // we must compute the color progression - int16 *outPtr2 = &polyTab2[ypos + (up ? _engine->height() : 0)]; + int16 *outPtr2 = &_polyTab2[polyTabIndex]; for (int32 i = 0; i < vsize + 2; i++) { - if (outPtr2 - polyTab2 < ARRAYSIZE(polyTab2)) { - if (outPtr2 - polyTab2 > 0) { + if (outPtr2 - _polyTab2 < _polyTabSize) { + if (outPtr2 - _polyTab2 > 0) { *outPtr2 = cvalue; } } @@ -466,7 +478,7 @@ void Renderer::computePolygons(int16 polyRenderType, Vertex *vertices, int32 num } void Renderer::renderPolygonsCopper(uint8 *out, int vtop, int32 vsize, int32 color) const { - const int16 *ptr1 = &polyTab[vtop]; + const int16 *ptr1 = &_polyTab[vtop]; int32 currentLine = vtop; do { if (currentLine >= 0 && currentLine < _engine->height()) { @@ -503,7 +515,7 @@ void Renderer::renderPolygonsCopper(uint8 *out, int vtop, int32 vsize, int32 col } void Renderer::renderPolygonsBopper(uint8 *out, int vtop, int32 vsize, int32 color) const { - const int16 *ptr1 = &polyTab[vtop]; + const int16 *ptr1 = &_polyTab[vtop]; int32 currentLine = vtop; do { if (currentLine >= 0 && currentLine < _engine->height()) { @@ -529,7 +541,7 @@ void Renderer::renderPolygonsBopper(uint8 *out, int vtop, int32 vsize, int32 col } void Renderer::renderPolygonsFlat(uint8 *out, int vtop, int32 vsize, int32 color) const { - const int16 *ptr1 = &polyTab[vtop]; + const int16 *ptr1 = &_polyTab[vtop]; int32 currentLine = vtop; do { if (currentLine >= 0 && currentLine < _engine->height()) { @@ -553,7 +565,7 @@ void Renderer::renderPolygonsFlat(uint8 *out, int vtop, int32 vsize, int32 color } void Renderer::renderPolygonsTele(uint8 *out, int vtop, int32 vsize, int32 color) const { - const int16 *ptr1 = &polyTab[vtop]; + const int16 *ptr1 = &_polyTab[vtop]; int bx = (uint16)color << 16; int32 renderLoop = vsize; do { @@ -634,7 +646,7 @@ void Renderer::renderPolygonsTele(uint8 *out, int vtop, int32 vsize, int32 color // FIXME: buggy void Renderer::renderPolygonsTras(uint8 *out, int vtop, int32 vsize, int32 color) const { - const int16 *ptr1 = &polyTab[vtop]; + const int16 *ptr1 = &_polyTab[vtop]; do { unsigned short int bx; @@ -666,7 +678,7 @@ void Renderer::renderPolygonsTras(uint8 *out, int vtop, int32 vsize, int32 color // FIXME: buggy void Renderer::renderPolygonTrame(uint8 *out, int vtop, int32 vsize, int32 color) const { - const int16 *ptr1 = &polyTab[vtop]; + const int16 *ptr1 = &_polyTab[vtop]; unsigned char bh = 0; int32 currentLine = vtop; @@ -704,8 +716,8 @@ void Renderer::renderPolygonTrame(uint8 *out, int vtop, int32 vsize, int32 color } void Renderer::renderPolygonsGouraud(uint8 *out, int vtop, int32 vsize, int32 color) const { - const int16 *ptr1 = &polyTab[vtop]; - const int16 *ptr2 = &polyTab2[vtop]; + const int16 *ptr1 = &_polyTab[vtop]; + const int16 *ptr2 = &_polyTab2[vtop]; int32 renderLoop = vsize; int32 currentLine = vtop; do { @@ -796,8 +808,8 @@ void Renderer::renderPolygonsGouraud(uint8 *out, int vtop, int32 vsize, int32 co } void Renderer::renderPolygonsDither(uint8 *out, int vtop, int32 vsize, int32 color) const { - const int16 *ptr1 = &polyTab[vtop]; - const int16 *ptr2 = &polyTab2[vtop]; + const int16 *ptr1 = &_polyTab[vtop]; + const int16 *ptr2 = &_polyTab2[vtop]; int32 renderLoop = vsize; int32 currentLine = vtop; diff --git a/engines/twine/renderer/renderer.h b/engines/twine/renderer/renderer.h index c30d69c047f..36f030888f2 100644 --- a/engines/twine/renderer/renderer.h +++ b/engines/twine/renderer/renderer.h @@ -39,9 +39,6 @@ #define POLYGONTYPE_GOURAUD 7 #define POLYGONTYPE_DITHER 8 -// TODO: this depends on the actual used resolution -#define POLYTABSIZE (SCREEN_WIDTH * 2) - namespace Common { class MemoryReadStream; } @@ -366,9 +363,9 @@ private: RenderCommand _renderCmds[1000]; uint8 renderCoordinatesBuffer[10000]{0}; - int16 polyTab[POLYTABSIZE]{0}; - int16 polyTab2[POLYTABSIZE]{0}; - // end render polygon vars + int32 _polyTabSize = 0; + int16 *_polyTab = nullptr; + int16 *_polyTab2 = nullptr; bool isUsingOrhoProjection = false; @@ -392,6 +389,9 @@ private: public: Renderer(TwinEEngine *engine); + ~Renderer(); + + void init(int32 w, int32 h); int16 projPosXScreen = 0; // fullRedrawVar1 int16 projPosYScreen = 0; // fullRedrawVar2 diff --git a/engines/twine/scene/grid.cpp b/engines/twine/scene/grid.cpp index 0d58b7afe35..b03d7769729 100644 --- a/engines/twine/scene/grid.cpp +++ b/engines/twine/scene/grid.cpp @@ -51,6 +51,16 @@ Grid::~Grid() { } free(currentGrid); free(currentBll); + free(brickInfoBuffer); + free(bricksDataBuffer); +} + +void Grid::init(int32 w, int32 h) { + const int32 numbrickentries = (1 + (w + 24) / 24); + const size_t brickDataBufferSize = numbrickentries * MAXBRICKS * sizeof(BrickEntry); + bricksDataBuffer = (BrickEntry *)malloc(brickDataBufferSize); + _brickInfoBufferSize = numbrickentries * sizeof(int16); + brickInfoBuffer = (int16 *)malloc(_brickInfoBufferSize); } void Grid::copyGridMask(int32 index, int32 x, int32 y, const Graphics::ManagedSurface &buffer) { @@ -146,13 +156,17 @@ void Grid::copyGridMask(int32 index, int32 x, int32 y, const Graphics::ManagedSu } while (--vSize); } +const BrickEntry* Grid::getBrickEntry(int32 j, int32 i) const { + return &bricksDataBuffer[j * MAXBRICKS + i]; +} + void Grid::drawOverModelActor(int32 x, int32 y, int32 z) { const int32 copyBlockPhysLeft = ((_engine->_interface->textWindow.left + 24) / 24) - 1; const int32 copyBlockPhysRight = ((_engine->_interface->textWindow.right + 24) / 24); for (int32 j = copyBlockPhysLeft; j <= copyBlockPhysRight; j++) { for (int32 i = 0; i < brickInfoBuffer[j]; i++) { - const BrickEntry *currBrickEntry = &bricksDataBuffer[j][i]; + const BrickEntry *currBrickEntry = getBrickEntry(j, i); if (currBrickEntry->posY + 38 > _engine->_interface->textWindow.top && currBrickEntry->posY <= _engine->_interface->textWindow.bottom && currBrickEntry->y >= y) { if (currBrickEntry->x + currBrickEntry->z > z + x) { @@ -169,7 +183,7 @@ void Grid::drawOverSpriteActor(int32 x, int32 y, int32 z) { for (int32 j = copyBlockPhysLeft; j <= copyBlockPhysRight; j++) { for (int32 i = 0; i < brickInfoBuffer[j]; i++) { - BrickEntry *currBrickEntry = &bricksDataBuffer[j][i]; + const BrickEntry *currBrickEntry = getBrickEntry(j, i); if (currBrickEntry->posY + 38 > _engine->_interface->textWindow.top && currBrickEntry->posY <= _engine->_interface->textWindow.bottom && currBrickEntry->y >= y) { if (currBrickEntry->x == x && currBrickEntry->z == z) { @@ -639,7 +653,7 @@ void Grid::drawColumnGrid(int32 blockIdx, int32 brickBlockIdx, int32 x, int32 y, return; } - BrickEntry *currBrickEntry = &bricksDataBuffer[brickBuffIdx][brickInfoBuffer[brickBuffIdx]]; + BrickEntry *currBrickEntry = &bricksDataBuffer[brickBuffIdx * MAXBRICKS + brickInfoBuffer[brickBuffIdx]]; currBrickEntry->x = x; currBrickEntry->y = y; @@ -665,7 +679,7 @@ void Grid::redrawGrid() { _engine->_renderer->projPosXScreen = _engine->_renderer->projPosX; _engine->_renderer->projPosYScreen = _engine->_renderer->projPosY; - memset(brickInfoBuffer, 0, sizeof(brickInfoBuffer)); + memset(brickInfoBuffer, 0, _brickInfoBufferSize); if (!_engine->_scene->changeRoomVar10) { return; diff --git a/engines/twine/scene/grid.h b/engines/twine/scene/grid.h index 436a8820716..ae1c1dd682b 100644 --- a/engines/twine/scene/grid.h +++ b/engines/twine/scene/grid.h @@ -82,8 +82,6 @@ struct BrickEntry { #define BRICK_SIZE 512 #define BRICK_HEIGHT 256 -// TODO: this depends on the actual used resolution -#define NUMBRICKENTRIES (1 + (SCREEN_WIDTH + 24) / 24) #define MAXBRICKS 150 class TwinEEngine; @@ -164,9 +162,10 @@ private: int32 numberOfBll = 0; /** Brick data buffer */ - BrickEntry bricksDataBuffer[NUMBRICKENTRIES][MAXBRICKS]; + BrickEntry *bricksDataBuffer = nullptr; /** Brick info buffer */ - int16 brickInfoBuffer[NUMBRICKENTRIES]{0}; + int16 *brickInfoBuffer = nullptr; + int32 _brickInfoBufferSize = 0; /** Current brick pixel X position */ int32 brickPixelPosX = 0; @@ -178,12 +177,15 @@ private: uint8 *blockBuffer = nullptr; uint8 *getBlockBuffer(int32 x, int32 y, int32 z); + const BrickEntry* getBrickEntry(int32 j, int32 i) const; void updateCollisionCoordinates(int32 x, int32 y, int32 z); public: Grid(TwinEEngine *engine); ~Grid(); + void init(int32 w, int32 h); + /** Grid block entry types */ typedef struct BlockEntry blockMap[GRID_SIZE_X][GRID_SIZE_Z][GRID_SIZE_Y]; diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp index 7fd75c3a368..8e627affd76 100644 --- a/engines/twine/twine.cpp +++ b/engines/twine/twine.cpp @@ -309,10 +309,12 @@ void TwinEEngine::autoSave() { void TwinEEngine::allocVideoMemory(int32 w, int32 h) { const Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8(); - imageBuffer.create(SCREEN_WIDTH, SCREEN_HEIGHT, format); // original lba1 resolution for a lot of images. + imageBuffer.create(640, 480, format); // original lba1 resolution for a lot of images. workVideoBuffer.create(w, h, format); frontVideoBuffer.create(w, h, format); + _renderer->init(w, h); + _grid->init(w, h); } static int getLanguageTypeIndex(const char *languageName) { diff --git a/engines/twine/twine.h b/engines/twine/twine.h index 6bc09370272..c97803ce741 100644 --- a/engines/twine/twine.h +++ b/engines/twine/twine.h @@ -45,10 +45,6 @@ namespace TwinE { /** Definition for Modification version */ #define MODIFICATION_VERSION 2 -/** Original screen width */ -#define SCREEN_WIDTH 640 -/** Original screen height */ -#define SCREEN_HEIGHT 480 /** Default frames per second */ #define DEFAULT_FRAMES_PER_SECOND 20