diff --git a/examples/debug/peanut-debug.c b/examples/debug/peanut-debug.c index 4f21c6d..bdfe2e7 100644 --- a/examples/debug/peanut-debug.c +++ b/examples/debug/peanut-debug.c @@ -14,6 +14,7 @@ #include "SDL.h" +#define PEANUT_GB_USE_NIBBLE_FOR_PALETTE 1 #define ENABLE_LCD 1 #define ENABLE_SOUND 0 diff --git a/examples/sdl2/peanut_sdl.c b/examples/sdl2/peanut_sdl.c index 09ae9b4..f6cb6ce 100644 --- a/examples/sdl2/peanut_sdl.c +++ b/examples/sdl2/peanut_sdl.c @@ -17,6 +17,8 @@ # include "minigb_apu/minigb_apu.h" #endif +#define PEANUT_GB_USE_NIBBLE_FOR_PALETTE 1 + #include "../../peanut_gb.h" enum { diff --git a/peanut_gb.h b/peanut_gb.h index 1907397..dc9d435 100644 --- a/peanut_gb.h +++ b/peanut_gb.h @@ -94,6 +94,27 @@ # define PEANUT_GB_12_COLOUR 1 #endif +/** + * If PEANUT_GB_USE_DOUBLE_WIDTH_PALETTE is enabled, the pixel colour data will be + * duplicated into both nibbles. This allows for faster scaling when rendering to + * a 4 bit per pixel destination. + * + * PEANUT_GB_USE_NIBBLE_FOR_PALETTE must also be defined for this to work. + */ +#ifndef PEANUT_GB_USE_DOUBLE_WIDTH_PALETTE +# define PEANUT_GB_USE_DOUBLE_WIDTH_PALETTE 0 +#endif + +/** + * If PEANUT_GB_USE_NIBBLE_FOR_PALETTE is enabled, the pixel colour data will be + * packed into the four least significant bits of a byte (or nibble). This + * allows for a smaller look-up table (LUT) to be used directly, in comparison + * to performing bit shifts or using a larger LUT. + */ +#ifndef PEANUT_GB_USE_NIBBLE_FOR_PALETTE +# define PEANUT_GB_USE_NIBBLE_FOR_PALETTE PEANUT_GB_USE_DOUBLE_WIDTH_PALETTE +#endif + /* Adds more code to improve LCD rendering accuracy. */ #ifndef PEANUT_GB_HIGH_LCD_ACCURACY # define PEANUT_GB_HIGH_LCD_ACCURACY 1 @@ -464,20 +485,29 @@ struct count_s #define LCD_COLOUR 0x03 # if PEANUT_GB_12_COLOUR - /** - * Bit mask for whether a pixel is OBJ0, OBJ1, or BG. Each may have a different - * palette when playing a DMG game on CGB. - */ - #define LCD_PALETTE_OBJ 0x04 - #define LCD_PALETTE_BG 0x08 - /** - * Bit mask for the two bits listed above. - * LCD_PALETTE_ALL == 0b00 --> OBJ0 - * LCD_PALETTE_ALL == 0b01 --> OBJ1 - * LCD_PALETTE_ALL == 0b10 --> BG - * LCD_PALETTE_ALL == 0b11 --> NOT POSSIBLE - */ - #define LCD_PALETTE_ALL 0x0c +# if PEANUT_GB_USE_NIBBLE_FOR_PALETTE + /** + * Bit mask for whether a pixel is OBJ0, OBJ1, or BG. Each may have a different + * palette when playing a DMG game on CGB. + */ + #define LCD_PALETTE_OBJ 0x04 + #define LCD_PALETTE_BG 0x08 + /** + * Bit mask for the two bits listed above. + * LCD_PALETTE_ALL == 0b00 --> OBJ0 + * LCD_PALETTE_ALL == 0b01 --> OBJ1 + * LCD_PALETTE_ALL == 0b10 --> BG + * LCD_PALETTE_ALL == 0b11 --> NOT POSSIBLE + */ + #define LCD_PALETTE_ALL 0x0c +# else +# if PEANUT_GB_USE_DOUBLE_WIDTH_PALETTE +# error PEANUT_GB_USE_NIBBLE_FOR_PALETTE must be enabled for PEANUT_GB_USE_DOUBLE_WIDTH_PALETTE to work +# endif + #define LCD_PALETTE_OBJ 0x10 + #define LCD_PALETTE_BG 0x20 + #define LCD_PALETTE_ALL 0x30 +# endif # else #define LCD_PALETTE_OBJ 0 #define LCD_PALETTE_BG 0 @@ -1140,11 +1170,12 @@ void __gb_write(struct gb_s *gb, uint_fast16_t addr, uint8_t val) gb->display.bg_palette[1] = ((gb->hram_io[IO_BGP] >> 2) & 0x03) | LCD_PALETTE_BG; gb->display.bg_palette[2] = ((gb->hram_io[IO_BGP] >> 4) & 0x03) | LCD_PALETTE_BG; gb->display.bg_palette[3] = ((gb->hram_io[IO_BGP] >> 6) & 0x03) | LCD_PALETTE_BG; - +#if PEANUT_GB_USE_DOUBLE_WIDTH_PALETTE gb->display.bg_palette[0] |= gb->display.bg_palette[0] << 4; gb->display.bg_palette[1] |= gb->display.bg_palette[1] << 4; gb->display.bg_palette[2] |= gb->display.bg_palette[2] << 4; gb->display.bg_palette[3] |= gb->display.bg_palette[3] << 4; +#endif return; case 0x48: @@ -1153,11 +1184,12 @@ void __gb_write(struct gb_s *gb, uint_fast16_t addr, uint8_t val) gb->display.sp_palette[1] = ((gb->hram_io[IO_OBP0] >> 2) & 0x03); gb->display.sp_palette[2] = ((gb->hram_io[IO_OBP0] >> 4) & 0x03); gb->display.sp_palette[3] = ((gb->hram_io[IO_OBP0] >> 6) & 0x03); - +#if PEANUT_GB_USE_DOUBLE_WIDTH_PALETTE gb->display.sp_palette[0] |= gb->display.sp_palette[0] << 4; gb->display.sp_palette[1] |= gb->display.sp_palette[1] << 4; gb->display.sp_palette[2] |= gb->display.sp_palette[2] << 4; gb->display.sp_palette[3] |= gb->display.sp_palette[3] << 4; +#endif return; case 0x49: @@ -1166,11 +1198,12 @@ void __gb_write(struct gb_s *gb, uint_fast16_t addr, uint8_t val) gb->display.sp_palette[5] = ((gb->hram_io[IO_OBP1] >> 2) & 0x03) | LCD_PALETTE_OBJ; gb->display.sp_palette[6] = ((gb->hram_io[IO_OBP1] >> 4) & 0x03) | LCD_PALETTE_OBJ; gb->display.sp_palette[7] = ((gb->hram_io[IO_OBP1] >> 6) & 0x03) | LCD_PALETTE_OBJ; - +#if PEANUT_GB_USE_DOUBLE_WIDTH_PALETTE gb->display.sp_palette[4] |= gb->display.sp_palette[4] << 4; gb->display.sp_palette[5] |= gb->display.sp_palette[5] << 4; gb->display.sp_palette[6] |= gb->display.sp_palette[6] << 4; gb->display.sp_palette[7] |= gb->display.sp_palette[7] << 4; +#endif return; /* Window Position Registers */