diff --git a/Makefile b/Makefile index 2572283..9794455 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ DEP = $(patsubst %.o,%.d,$(SRC)) res = $(subst pokered/,res/,$(patsubst %.$(1),%.$(1).o,$(wildcard $(2)*.$(1)))) res_png = $(subst pokered/,res/,$(patsubst %.png,%.$(1).o,$(wildcard $(2)*.png))) -GFX_TILESETS = $(call res_png,4bpp,pokered/gfx/tilesets/) +GFX_TILESETS = $(call res_png,2bpp,pokered/gfx/tilesets/) GFX_BLOCKSETS = $(call res,bst,pokered/gfx/blocksets/) MAPS_BLOCKS = $(call res,blk,pokered/maps/) @@ -28,14 +28,14 @@ endef generated: $(GENERATED) -res/%.4bpp: pokered/%.png +res/%.2bpp: pokered/%.png @mkdir -p $(dir $@) - python tools/png_to_4bpp.py $< $@ + python tools/png_to_nbpp.py $< 2 $@ -%.4bpp.h: +%.2bpp.h: $(BUILD_BINARY_H) -%.4bpp.o: %.4bpp %.4bpp.h +%.2bpp.o: %.2bpp %.2bpp.h $(BUILD_BINARY_O) res/%.blk: pokered/%.blk diff --git a/main.cpp b/main.cpp index 79a7ef1..586918d 100644 --- a/main.cpp +++ b/main.cpp @@ -23,12 +23,28 @@ void palette_data() uint32_t cell_data(const start_size_t& buf, const uint32_t top) { // round to nearest multiple of 32 - const uint32_t table_size = (buf.size + 0x20 - 1) & (-0x20); + const uint32_t table_size = ((buf.size * 2) + 0x20 - 1) & (-0x20); const uint32_t base_address = top - table_size; // in bytes - copy(&vdp2.vram.u32[(base_address / 4)], - reinterpret_cast(buf.start), - buf.size); + uint32_t * vram = &vdp2.vram.u32[(base_address / 4)]; + for (uint32_t ix = 0; ix < buf.size / 4; ix += 1) { + const uint32_t pixels = reinterpret_cast(buf.start)[ix]; + const uint32_t px0 = pixels >> 16 & 0xffff; + const uint32_t px1 = pixels >> 0 & 0xffff; + +#define lshift(n) ((7 - n) * 2) +#define rshift(n) ((7 - n) * 4) +#define px(p, n) (((p >> lshift(n)) & 0b11) << rshift(n)) +#define p0(n) (px(px0, n)) +#define p1(n) (px(px1, n)) + vram[ix * 2 + 0] = p0(7) | p0(6) | p0(5) | p0(4) | p0(3) | p0(2) | p0(1) | p0(0); + vram[ix * 2 + 1] = p1(7) | p1(6) | p1(5) | p1(4) | p1(3) | p1(2) | p1(1) | p1(0); +#undef p1 +#undef p0 +#undef px +#undef lshift +#undef rshift + } return base_address; } @@ -115,7 +131,7 @@ void main() vdp2.reg.MPABN0 = MPABN0__N0MPB(0) | MPABN0__N0MPA(plane_a); // bits 5~0 vdp2.reg.MPCDN0 = MPABN0__N0MPD(0) | MPABN0__N0MPC(0); // bits 5~0 - uint32_t top = (sizeof (union vdp2_vram));// - ((sizeof (union vdp2_vram)) / 8); + uint32_t top = (sizeof (union vdp2_vram)); palette_data(); uint32_t base_address = top = cell_data(tilesets[tileset_t::overworld].tileset, top); uint32_t base_pattern = base_address / 32; diff --git a/tools/png_to_4bpp.py b/tools/png_to_4bpp.py deleted file mode 100644 index 281948a..0000000 --- a/tools/png_to_4bpp.py +++ /dev/null @@ -1,39 +0,0 @@ -import sys - -from PIL import Image - -def two_bpp_index(px): - indices = {0x00: 0, 0x55: 1, 0xaa: 2, 0xff: 3} - assert px in indices, px - return indices[px] - -def convert(image): - assert image.mode == 'L', image.mode - width, height = image.size - - buf = bytearray(width * height // 2) - - for cell_y in range(height//8): - for cell_x in range(width//8): - for y in range(8): - for x in range(8): - px = im.getpixel((cell_x * 8 + x, cell_y * 8 + y)) - index = two_bpp_index(px) - buf_ix = x//2 + (4 * (cell_x * 8 + (cell_y * width) + y)) - buf[buf_ix] |= (index << 4 * (1 - (x % 2))) - return buf - -def debug(buf): - for row in range(len(buf) // 4): - for x in range(4): - px = buf[row * 4 + x] - print((px >> 4) & 0xf, end='') - print((px >> 0) & 0xf, end='') - print() - if (row % 8 == 7): - print() - -im = Image.open(sys.argv[1]) -buf = convert(im) -with open(sys.argv[2], 'wb') as f: - f.write(buf) diff --git a/tools/png_to_nbpp.py b/tools/png_to_nbpp.py new file mode 100644 index 0000000..a30c81c --- /dev/null +++ b/tools/png_to_nbpp.py @@ -0,0 +1,59 @@ +import os +import sys + +from PIL import Image + +def intensity_to_index(px): + indices = {0x00: 0, 0x55: 1, 0xaa: 2, 0xff: 3} + assert px in indices, px + return indices[px] + +def convert(image, bpp): + assert bpp in {8, 4, 2}, bpp + px_per_byte = 8 // bpp + px_per_row = 8 + bits_per_byte = 8 + bytes_per_row = (px_per_row // (bits_per_byte // bpp)) + + assert image.mode == 'L', image.mode + width, height = image.size + + buf = bytearray(width * height // px_per_byte) + + for cell_y in range(height//8): + for cell_x in range(width//8): + for y in range(8): + for x in range(8): + px = im.getpixel((cell_x * 8 + x, cell_y * 8 + y)) + index = intensity_to_index(px) + buf_ix = x//px_per_byte + (bytes_per_row * (cell_x * 8 + (cell_y * width) + y)) + buf[buf_ix] |= (index << bpp * ((px_per_byte - 1) - (x % px_per_byte))) + return buf + +def debug(buf, bpp): + assert bpp in {8, 4, 2}, bpp + px_per_byte = 8 // bpp + px_per_row = 8 + bits_per_byte = 8 + bytes_per_row = (px_per_row // (bits_per_byte // bpp)) + bit_mask = (2 ** bpp) - 1 + + for row in range(len(buf) // bytes_per_row): + for x in range(bytes_per_row): + px = buf[row * bytes_per_row + x] + for shift in reversed(range(0, px_per_row, bpp)): + print((px >> shift) & bit_mask, end='') + print() + if (row % 8 == 7): + print() + +in_path = sys.argv[1] +bpp = int(sys.argv[2]) +out_path = sys.argv[3] + +im = Image.open(in_path) +buf = convert(im, bpp) +if 'NBPP_DEBUG' in os.environ: + debug(buf, bpp) +with open(out_path, 'wb') as f: + f.write(buf)