Implement ATTR_CHR
This commit is contained in:
parent
e7f6ac8828
commit
84e8e45b7b
47
Core/sgb.c
47
Core/sgb.c
@ -17,6 +17,7 @@ enum {
|
||||
ATTR_BLK = 0x04,
|
||||
ATTR_LIN = 0x05,
|
||||
ATTR_DIV = 0x06,
|
||||
ATTR_CHR = 0x07,
|
||||
PAL_SET = 0x0A,
|
||||
PAL_TRN = 0x0B,
|
||||
DATA_SND = 0x0F,
|
||||
@ -254,6 +255,52 @@ static void command_ready(GB_gameboy_t *gb)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ATTR_CHR: {
|
||||
struct __attribute__((packed)) {
|
||||
uint8_t x, y;
|
||||
uint16_t length;
|
||||
uint8_t direction;
|
||||
uint8_t data[];
|
||||
} *command = (void *)(gb->sgb->command + 1);
|
||||
|
||||
uint16_t count = command->length;
|
||||
#ifdef GB_BIG_ENDIAN
|
||||
count = __builtin_bswap16(count);
|
||||
#endif
|
||||
uint8_t x = command->x;
|
||||
uint8_t y = command->y;
|
||||
if (x >= 20 || y >= 18 || (count + 3) / 4 > sizeof(gb->sgb->command) - sizeof(*command) - 1) {
|
||||
/* TODO: Verify with the SFC BIOS */
|
||||
break;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
uint8_t palette = (command->data[i / 4] >> (((~i) & 3) << 1)) & 3;
|
||||
gb->sgb->attribute_map[x + 20 * y] = palette;
|
||||
if (command->direction) {
|
||||
y++;
|
||||
if (y == 18) {
|
||||
x++;
|
||||
y = 0;
|
||||
if (x == 20) {
|
||||
x = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
x++;
|
||||
if (x == 20) {
|
||||
y++;
|
||||
x = 0;
|
||||
if (y == 18) {
|
||||
y = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ATTR_LIN: {
|
||||
struct {
|
||||
uint8_t count;
|
||||
|
Loading…
Reference in New Issue
Block a user