diff --git a/cli/imgui_example.cpp b/cli/imgui_example.cpp index a25a2ad..ab50efd 100644 --- a/cli/imgui_example.cpp +++ b/cli/imgui_example.cpp @@ -62,7 +62,16 @@ GLuint make_output_texture() { return image_texture; } -unsigned char default_palette[] = { 0xff, 0xaa, 0x55, 0x00 }; +unsigned int default_palette[] = { 0x9ff4e5, 0x00b9be, 0x005f8c, 0x002b59 }; +// ugly evenly spaced: { 0xffffff, 0xaaaaaa, 0x555555, 0x000000 }; +// bgb default: {0xe0f8d0, 0x88c070, 0x346856, 0x081820}; + +// https://lospec.com/palette-list/blk-aqu4 +// { 0x9ff4e5, 0x00b9be, 0x005f8c, 0x002b59 }; + +// https://lospec.com/palette-list/velvet-cherry-gb +// { 0x9775a6, 0x683a68, 0x412752, 0x2d162c }; + void convert_output(struct lcd *lcd) { int x, y; @@ -72,9 +81,9 @@ void convert_output(struct lcd *lcd) { int val = lcd->buf[y * 256 + x]; int fill = default_palette[val]; //int fill = val ? 255 : 0; - output_image[out_index++] = fill; - output_image[out_index++] = fill; - output_image[out_index++] = fill; + output_image[out_index++] = (fill >> 16) & 0xff; + output_image[out_index++] = (fill >> 8) & 0xff; + output_image[out_index++] = fill & 0xff; output_image[out_index++] = 255; } } @@ -83,9 +92,9 @@ void convert_output(struct lcd *lcd) { for (x = 0; x < 160; x++) { int val = lcd->pixels[y * 160 + x]; int fill = default_palette[val]; - visible_pixels[out_index++] = fill; - visible_pixels[out_index++] = fill; - visible_pixels[out_index++] = fill; + visible_pixels[out_index++] = (fill >> 16) & 0xff; + visible_pixels[out_index++] = (fill >> 8) & 0xff; + visible_pixels[out_index++] = fill & 0xff; visible_pixels[out_index++] = 255; } } diff --git a/src/dmg.c b/src/dmg.c index 977cbf0..b87bb73 100644 --- a/src/dmg.c +++ b/src/dmg.c @@ -150,6 +150,7 @@ static void render_background(struct dmg *dmg, int lcdc) int bg_base = (lcdc & LCDC_BG_TILE_MAP) ? 0x9c00 : 0x9800; int window_base = (lcdc & LCDC_WINDOW_TILE_MAP) ? 0x9c00 : 0x9800; int use_unsigned = lcdc & LCDC_BG_TILE_DATA; + int palette = lcd_read(dmg->lcd, REG_BGP); int tilebase = use_unsigned ? 0x8000 : 0x9000; //printf("%04x %04x %04x\n", bg_base, window_base, tilebase); @@ -166,13 +167,14 @@ static void render_background(struct dmg *dmg, int lcdc) } else { eff_addr = tilebase + 16 * (signed char) tile; } - int b, i; + int b, i, col_index; for (b = 0; b < 16; b += 2) { int data1 = dmg_read(dmg, eff_addr + b); int data2 = dmg_read(dmg, eff_addr + b + 1); for (i = 7; i >= 0; i--) { - dmg->lcd->buf[off] = ((data1 & (1 << i)) ? 1 : 0) << 1; - dmg->lcd->buf[off] |= (data2 & (1 << i)) ? 1 : 0; + col_index = (data1 & (1 << i)) ? 1 : 0; + col_index |= ((data2 & (1 << i)) ? 1 : 0) << 1; + dmg->lcd->buf[off] = (palette >> (col_index << 1)) & 3; off++; } off += 248; @@ -202,23 +204,26 @@ static void render_objs(struct dmg *dmg) if (oam->pos_x == 0 || oam->pos_x >= 168) { continue; } + int first_tile = 0x8000 + 16 * oam->tile; + int palette = oam->attrs & OAM_ATTR_PALETTE + ? lcd_read(dmg->lcd, REG_OBP1) + : lcd_read(dmg->lcd, REG_OBP0); lcd_x = oam->pos_x - 8; lcd_y = oam->pos_y - 16; off = 160 * lcd_y + lcd_x; - int eff_addr = 0x8000 + 16 * oam->tile; - int b, i, limit = 16; + int b, i, tile_bytes = 16; if (tall) { - limit = 32; + tile_bytes = 32; } - for (b = 0; b < limit; b += 2) { + for (b = 0; b < tile_bytes; b += 2) { int use_tile = b; if (oam->attrs & OAM_ATTR_MIRROR_Y) { - use_tile = (limit - 2) - b; + use_tile = (tile_bytes - 2) - b; } - int data1 = dmg_read(dmg, eff_addr + use_tile); - int data2 = dmg_read(dmg, eff_addr + use_tile + 1); + int data1 = dmg_read(dmg, first_tile + use_tile); + int data2 = dmg_read(dmg, first_tile + use_tile + 1); for (i = 7; i >= 0; i--) { if (off < 0 || off >= 160 * 144) { // terrible clipping. need to not have an if per-pixel @@ -228,10 +233,10 @@ static void render_objs(struct dmg *dmg) if (oam->attrs & OAM_ATTR_MIRROR_X) { use_index = 7 - i; } - int color = ((data1 & (1 << use_index)) ? 1 : 0) << 1 - | ((data2 & (1 << use_index)) ? 1 : 0); - if (color) { - dmg->lcd->pixels[off] = color; + int col_index = ((data1 & (1 << use_index)) ? 1 : 0) + | ((data2 & (1 << use_index)) ? 1 : 0) << 1; + if (col_index) { + dmg->lcd->pixels[off] = (palette >> (col_index << 1)) & 3; } off++; }