Commit b64a7710 authored by Jack's avatar Jack
Browse files

added pal behavior with secondary palette and reset, fixed map layering mask,...

added pal behavior with secondary palette and reset, fixed map layering mask, fixed tile map address computation
parent b28f77d4
......@@ -7,7 +7,10 @@
#include "vm/machine.h"
#include <unordered_set>
using namespace retro8;
using namespace retro8::gfx;
TEST_CASE("cursor([x,] [y,] [col])")
{
......@@ -24,6 +27,36 @@ TEST_CASE("cursor([x,] [y,] [col])")
}
}
TEST_CASE("tilemap")
{
Machine m;
SECTION("tilemap address space never overlap")
{
std::unordered_set<const sprite_index_t*> addresses;
for (size_t y = 0; y < TILE_MAP_HEIGHT; ++y)
{
for (size_t x = 0; x < TILE_MAP_WIDTH; ++x)
{
const sprite_index_t* address = m.memory().spriteInTileMap(x, y);
addresses.insert(address);
}
}
REQUIRE(addresses.size() == TILE_MAP_WIDTH * TILE_MAP_HEIGHT);
}
SECTION("tilemap halves are inverted compared to theie coordinates")
{
REQUIRE(m.memory().spriteInTileMap(0, 32) - m.memory().base() == address::TILE_MAP_LOW);
REQUIRE(m.memory().spriteInTileMap(0, 0) - m.memory().base() == address::TILE_MAP_HIGH);
REQUIRE(address::TILE_MAP_HIGH > address::TILE_MAP_LOW);
}
}
int testMain(int argc, char* argv[])
{
int result = Catch::Session().run(argc, argv);
......
......@@ -169,30 +169,35 @@ else
}
{
/*SDL_Surface* tilemap = SDL_CreateRGBSurface(0, 1024, 512, 32, 0x00000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
SDL_FillRect(tilemap, nullptr, 0x00000000);
uint32_t* base = static_cast<uint32_t*>(tilemap->pixels);
for (r8::coord_t ty = 0; ty < r8::gfx::TILE_MAP_HEIGHT; ++ty)
{
for (r8::coord_t tx = 0; tx < r8::gfx::TILE_MAP_WIDTH; ++tx)
/*static SDL_Surface* tilemap = nullptr;
if (!tilemap)
{
tilemap = SDL_CreateRGBSurface(0, 1024, 512, 32, 0x00000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
SDL_FillRect(tilemap, nullptr, 0x00000000);
uint32_t* base = static_cast<uint32_t*>(tilemap->pixels);
for (r8::coord_t ty = 0; ty < r8::gfx::TILE_MAP_HEIGHT; ++ty)
{
r8::sprite_index_t index = *machine.memory().spriteInTileMap(tx, ty);
for (r8::coord_t y = 0; y < r8::gfx::SPRITE_HEIGHT; ++y)
for (r8::coord_t x = 0; x < r8::gfx::SPRITE_WIDTH; ++x)
{
auto* dest = base + x + tx * r8::gfx::SPRITE_WIDTH + (y + ty * r8::gfx::SPRITE_HEIGHT) * tilemap->h;
const r8::gfx::color_byte_t& pixels = machine.memory().spriteAt(index)->byteAt(x, y);
RASTERIZE_PIXEL_PAIR(machine, dest, &pixels);
}
for (r8::coord_t tx = 0; tx < r8::gfx::TILE_MAP_WIDTH; ++tx)
{
r8::sprite_index_t index = *machine.memory().spriteInTileMap(tx, ty);
for (r8::coord_t y = 0; y < r8::gfx::SPRITE_HEIGHT; ++y)
for (r8::coord_t x = 0; x < r8::gfx::SPRITE_WIDTH; ++x)
{
auto* dest = base + x + tx * r8::gfx::SPRITE_WIDTH + (y + ty * r8::gfx::SPRITE_HEIGHT) * tilemap->h;
const r8::gfx::color_byte_t& pixels = machine.memory().spriteAt(index)->byteAt(x, y);
RASTERIZE_PIXEL_PAIR(machine, dest, &pixels);
}
}
}
}
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, tilemap);
SDL_Rect destr = { (1024 - 286) , 200, 256, 128 };
SDL_Rect destr = { (1024 - 286) , 256, 256, 128 };
SDL_RenderCopy(renderer, texture, nullptr, &destr);
SDL_DestroyTexture(texture);
SDL_FreeSurface(tilemap);*/
//SDL_FreeSurface(tilemap);*/
}
}
......
......@@ -30,6 +30,7 @@ namespace retro8
using sprite_index_t = uint8_t;
using sprite_flags_t = uint8_t;
using color_index_t = uint8_t;
using palette_index_t = size_t;
using address_t = int32_t;
struct point_t { coord_t x, y; };
}
......
......@@ -134,20 +134,37 @@ int spr(lua_State* L)
int x = lua_tonumber(L, 2);
int y = lua_tonumber(L, 3);
machine.spr(idx, x, y);
if (lua_gettop(L) > 3)
{
float w = 1.0f, h = 1.0f;
bool fx = false, fy = false;
machine.spr(idx, x, y);
}
else
/* optimized path */
machine.spr(idx, x, y);
return 0;
}
int pal(lua_State* L)
{
int c0 = lua_tonumber(L, 1);
int c1 = lua_tonumber(L, 2);
//TODO: third parameter to decide which palette
/* no arguments, reset palette */
if (lua_gettop(L) == 0)
{
machine.memory().paletteAt(gfx::DRAW_PALETTE_INDEX)->reset();
}
else
{
int c0 = lua_tonumber(L, 1);
int c1 = lua_tonumber(L, 2);
palette_index_t index = gfx::DRAW_PALETTE_INDEX;
machine.pal(static_cast<color_t>(c0), static_cast<color_t>(c1));
if (lua_gettop(L) == 3)
index = lua_tonumber(L, 3);
machine.pal(static_cast<color_t>(c0), static_cast<color_t>(c1), index);
}
return 0;
}
......
......@@ -201,9 +201,9 @@ void Machine::print(const std::string& string, coord_t x, coord_t y, color_t col
}
}
void Machine::pal(color_t c0, color_t c1)
void Machine::pal(color_t c0, color_t c1, palette_index_t index)
{
gfx::palette_t* palette = _memory.paletteAt(gfx::DRAW_PALETTE_INDEX);
gfx::palette_t* palette = _memory.paletteAt(index);
palette->set(c0, c1);
}
......@@ -211,14 +211,17 @@ void Machine::pal(color_t c0, color_t c1)
void Machine::map(coord_t cx, coord_t cy, coord_t x, coord_t y, amount_t cw, amount_t ch, sprite_flags_t layer)
{
for (amount_t ty = 0; ty < ch; ++ty)
{
for (amount_t tx = 0; tx < cw; ++tx)
{
const sprite_index_t index = *_memory.spriteInTileMap(cx + tx, cy + ty);
/* don't draw if index is 0 or layer is not zero and sprite flags are not correcly masked to it */
if (index != 0 && (!layer || (layer & *_memory.spriteFlagsFor(index)) != layer))
if (index != 0 && (!layer || (layer & *_memory.spriteFlagsFor(index)) == layer))
spr(index, x + tx * gfx::SPRITE_WIDTH, y + ty * gfx::SPRITE_HEIGHT);
}
printf("\n");
}
}
......
......@@ -33,7 +33,7 @@ namespace retro8
static constexpr address_t SCREEN_DATA = 0x6000;
static constexpr address_t TILE_MAP_LOWER = 0x1000;
static constexpr address_t TILE_MAP_LOW = 0x1000;
static constexpr address_t TILE_MAP_HIGH = 0x2000;
};
......@@ -61,6 +61,8 @@ namespace retro8
*cursor() = { 0, 0 };
}
uint8_t* base() { return memory; }
gfx::color_byte_t* penColor() { return reinterpret_cast<gfx::color_byte_t*>(&memory[address::PEN_COLOR]); }
gfx::cursor_t* cursor() { return as<gfx::cursor_t>(address::CURSOR); }
gfx::camera_t* camera() { return as<gfx::camera_t>(address::CAMERA); }
......@@ -82,11 +84,11 @@ namespace retro8
sprite_index_t *addr;
if (y >= ROWS_PER_TILE_MAP_HALF)
addr = as<sprite_index_t>(address::TILE_MAP_LOWER) + x + (y - ROWS_PER_TILE_MAP_HALF) * gfx::TILE_MAP_WIDTH * sizeof(sprite_index_t);
addr = as<sprite_index_t>(address::TILE_MAP_LOW) + x + (y - ROWS_PER_TILE_MAP_HALF) * gfx::TILE_MAP_WIDTH * sizeof(sprite_index_t);
else
addr = as<sprite_index_t>(address::TILE_MAP_HIGH) + x + y * gfx::TILE_MAP_WIDTH * sizeof(sprite_index_t);
assert((addr >= memory + address::TILE_MAP_LOWER && addr <= memory + address::TILE_MAP_LOWER * gfx::TILE_MAP_WIDTH * gfx::TILE_MAP_HEIGHT * sizeof(sprite_index_t)));
assert((addr >= memory + address::TILE_MAP_LOW && addr <= memory + address::TILE_MAP_LOW * gfx::TILE_MAP_WIDTH * gfx::TILE_MAP_HEIGHT * sizeof(sprite_index_t)));
return addr;
}
......@@ -96,7 +98,7 @@ namespace retro8
+ (index % gfx::SPRITES_PER_SPRITE_SHEET_ROW) * gfx::SPRITE_BYTES_PER_SPRITE_ROW]
+ (index / gfx::SPRITES_PER_SPRITE_SHEET_ROW) * gfx::SPRITE_SHEET_WIDTH_IN_BYTES * gfx::SPRITE_HEIGHT
); }
gfx::palette_t* paletteAt(size_t index) { return reinterpret_cast<gfx::palette_t*>(&memory[address::PALETTES + index * BYTES_PER_PALETTE]); }
gfx::palette_t* paletteAt(palette_index_t index) { return reinterpret_cast<gfx::palette_t*>(&memory[address::PALETTES + index * BYTES_PER_PALETTE]); }
template<typename T> T* as(address_t addr) { return reinterpret_cast<T*>(&memory[addr]); }
};
......@@ -135,7 +137,7 @@ namespace retro8
void circ(coord_t x, coord_t y, amount_t r, color_t color);
void circfill(coord_t x, coord_t y, amount_t r, color_t color);
void pal(color_t c0, color_t c1);
void pal(color_t c0, color_t c1, palette_index_t index);
void map(coord_t cx, coord_t cy, coord_t x, coord_t y, amount_t cw, amount_t ch, sprite_flags_t layer);
void spr(index_t idx, coord_t x, coord_t y);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment