diff --git a/source/graphics.cpp b/source/graphics.cpp index 0474a713..c3c65685 100644 --- a/source/graphics.cpp +++ b/source/graphics.cpp @@ -1444,30 +1444,61 @@ std::tuple Graphics::clip(int x, int y, int } -//map methods heavily based on tac08 implementation uint8_t Graphics::mget(int celx, int cely){ - if (celx < 0 || celx >= 128 || cely < 0 || cely >= 64) - return 0; + const bool bigMap = _memory->hwState.mapMemMapping >= 0x80; + const int mapW = _memory->hwState.widthOfTheMap; + const int idx = cely * mapW + celx; - if (cely < 32) { - return _memory->mapData[cely * 128 + celx]; + if (idx < 0) { + return 0; + } + + if (bigMap){ + const int mapLocation = _memory->hwState.mapMemMapping << 8; + const int mapSize = 0x10000 - mapLocation; + if (idx >= mapSize){ + return 0; + } + const int offset = 0x8000 - mapSize; + return _memory->userData[offset + idx]; } - else if (cely < 64){ - return _memory->spriteSheetData[cely* 128 + celx]; + else { + if (idx < 4096) { + return _memory->mapData[idx]; + } + else if (idx < 8192){ + return _memory->spriteSheetData[idx]; + } } return 0; } void Graphics::mset(int celx, int cely, uint8_t snum){ - if (celx < 0 || celx >= 128 || cely < 0 || cely >= 64) + const bool bigMap = _memory->hwState.mapMemMapping >= 0x80; + const int mapW = _memory->hwState.widthOfTheMap; + const int idx = cely * mapW + celx; + + if (idx < 0) { return; + } - if (cely < 32) { - _memory->mapData[cely * 128 + celx] = snum; + if (bigMap){ + const int mapLocation = _memory->hwState.mapMemMapping << 8; + const int mapSize = 0x10000 - mapLocation; + if (idx >= mapSize){ + return; + } + const int offset = 0x8000 - mapSize; + _memory->userData[offset + idx] = snum; } - else if (cely < 64){ - _memory->spriteSheetData[cely* 128 + celx] = snum; + else { + if (idx < 4096) { + _memory->mapData[idx] = snum; + } + else if (idx < 8192) { + _memory->spriteSheetData[idx] = snum; + } } } diff --git a/test/graphicstests.cpp b/test/graphicstests.cpp index 1f31fe68..4cd016c5 100644 --- a/test/graphicstests.cpp +++ b/test/graphicstests.cpp @@ -2192,7 +2192,6 @@ TEST_CASE("graphics class behaves as expected") { checkPoints(graphics, expectedPoints); } - SUBCASE("Remap screen to spritesheet"){ graphics->cls(); graphics->sset(125,125,4); @@ -2233,6 +2232,142 @@ TEST_CASE("graphics class behaves as expected") { checkPoints(graphics, expectedPoints); } + SUBCASE("change map width"){ + picoRam.data[0x5f57] = 4; + + for(int y = 0; y < 8; y++){ + for(int x = 0; x < 32; x++) { + graphics->sset(x,y,(x/8) + 1); + } + } + + graphics->mset(0, 0, 1); + graphics->mset(0, 1, 2); + graphics->mset(1, 0, 2); + graphics->mset(1, 1, 1); + + graphics->mset(2, 2046, 2); + graphics->mset(2, 2047, 3); + graphics->mset(3, 2046, 3); + graphics->mset(3, 2047, 2); + + graphics->cls(); + + graphics->map(0, 0, 0, 0, 4, 8); + graphics->map(0, 2040, 64, 64, 4, 8); + + CHECK_EQ(picoRam.hwState.widthOfTheMap, 4); + CHECK_EQ(graphics->mget(0,0), 1); + CHECK_EQ(graphics->mget(3,2047), 2); + + std::vector expectedPoints = { + {6,6,2}, + {14,6,3}, + {6,14,3}, + {14,14,2}, + + {82,118,3}, + {90,118,4}, + {82,126,4}, + {90,126,3}, + }; + + checkPoints(graphics, expectedPoints); + } +SUBCASE("use extended ram for big map"){ + picoRam.data[0x5f56] = 0x80; + + for(int y = 0; y < 8; y++){ + for(int x = 64; x < 96; x++) { + graphics->sset(x,y,(x/8) + 1); + } + } + + graphics->mset(0, 0, 8); + graphics->mset(0, 1, 9); + graphics->mset(1, 0, 9); + graphics->mset(1, 1, 8); + + graphics->mset(126, 254, 9); + graphics->mset(126, 255, 10); + graphics->mset(127, 254, 10); + graphics->mset(127, 255, 9); + + graphics->cls(); + + graphics->map(0, 0, 8, 8, 2, 2); + graphics->map(126, 254, 112, 112, 2, 2); + + CHECK_EQ(picoRam.hwState.mapMemMapping, 0x80); + CHECK_EQ(graphics->mget(0,0), 8); + CHECK_EQ(picoRam.data[0x8000], 8); + CHECK_EQ(picoRam.userData[0], 8); + CHECK_EQ(graphics->mget(127,255), 9); + CHECK_EQ(picoRam.data[0xFFFF], 9); + CHECK_EQ(picoRam.userData[0x7FFF], 9); + + std::vector expectedPoints = { + {12,12,9}, + {20,12,10}, + {12,20,10}, + {20,20,9}, + + {116,116,10}, + {124,116,11}, + {116,124,11}, + {124,124,10}, + }; + + checkPoints(graphics, expectedPoints); + } + SUBCASE("use only part of extended ram for big map"){ + picoRam.data[0x5f56] = 0xb6; + //18944 total map bytes, 148 lines (using default 128 width) + + for(int y = 0; y < 8; y++){ + for(int x = 64; x < 96; x++) { + graphics->sset(x,y,(x/8) + 3); + } + } + + graphics->mset(0, 0, 8); + graphics->mset(0, 1, 9); + graphics->mset(1, 0, 9); + graphics->mset(1, 1, 8); + + graphics->mset(126, 146, 9); + graphics->mset(126, 147, 10); + graphics->mset(127, 146, 10); + graphics->mset(127, 147, 9); + + graphics->cls(); + + graphics->map(0, 0, 8, 8, 2, 2); + graphics->map(126, 146, 112, 112, 2, 2); + + CHECK_EQ(picoRam.hwState.mapMemMapping, 0xb6); + CHECK_EQ(picoRam.data[0x5f56], 0xb6); + CHECK_EQ(graphics->mget(0,0), 8); + CHECK_EQ(picoRam.data[0xb600], 8); + CHECK_EQ(graphics->mget(127,147), 9); + CHECK_EQ(picoRam.data[0xFFFF], 9); + + std::vector expectedPoints = { + {12,12,11}, + {20,12,12}, + {12,20,12}, + {20,20,11}, + + {116,116,12}, + {124,116,13}, + {116,124,13}, + {124,124,12}, + }; + + checkPoints(graphics, expectedPoints); + } + + //general teardown