support x and y flip, try to support 8x16 but i need to change the rendering to per-scanline

This commit is contained in:
Matthew Laux 2022-08-03 01:22:22 -05:00
parent a9ecd14598
commit e32535b016
3 changed files with 44 additions and 8 deletions

View File

@ -782,6 +782,24 @@ void cpu_step(struct cpu *cpu)
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles; cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
} }
break; break;
case 0xd4: // CALL NC, u16
temp16 = read16(cpu, cpu->pc);
cpu->pc += 2;
if (!flag_isset(cpu, FLAG_CARRY)) {
push(cpu, cpu->pc);
cpu->pc = temp16;
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
}
break;
case 0xdc: // CALL C, u16
temp16 = read16(cpu, cpu->pc);
cpu->pc += 2;
if (flag_isset(cpu, FLAG_CARRY)) {
push(cpu, cpu->pc);
cpu->pc = temp16;
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
}
break;
case 0xd0: // RET NC case 0xd0: // RET NC
if (!flag_isset(cpu, FLAG_CARRY)) { if (!flag_isset(cpu, FLAG_CARRY)) {
cpu->pc = pop(cpu); cpu->pc = pop(cpu);

View File

@ -188,16 +188,18 @@ struct oam_entry {
u8 attrs; u8 attrs;
}; };
// TODO: only ten per scanline, priority // TODO: only ten per scanline, priority, attributes, move to lcd.c
static void render_objs(struct dmg *dmg) static void render_objs(struct dmg *dmg)
{ {
struct oam_entry *oam = (struct oam_entry *) dmg->lcd->oam; struct oam_entry *oam = (struct oam_entry *) dmg->lcd->oam;
int k, lcd_x, lcd_y, off; int k, lcd_x, lcd_y, off;
int tall = lcd_isset(dmg->lcd, REG_LCDC, LCDC_OBJ_SIZE);
for (k = 0; k < 40; k++, oam++) { for (k = 0; k < 40; k++, oam++) {
if (oam->pos_y == 0 || oam->pos_y >= 160) { if (oam->pos_y == 0 || oam->pos_y >= 160) {
continue; continue;
} }
if (oam->pos_x == 0 || oam->pos_y >= 168) { if (oam->pos_x == 0 || oam->pos_x >= 168) {
continue; continue;
} }
@ -206,17 +208,28 @@ static void render_objs(struct dmg *dmg)
off = 160 * lcd_y + lcd_x; off = 160 * lcd_y + lcd_x;
int eff_addr = 0x8000 + 16 * oam->tile; int eff_addr = 0x8000 + 16 * oam->tile;
int b, i; int b, i, limit = 16;
for (b = 0; b < 16; b += 2) { if (tall) {
int data1 = dmg_read(dmg, eff_addr + b); limit = 32;
int data2 = dmg_read(dmg, eff_addr + b + 1); }
for (b = 0; b < limit; b += 2) {
int use_tile = b;
if (oam->attrs & OAM_ATTR_MIRROR_Y) {
use_tile = (limit - 2) - b;
}
int data1 = dmg_read(dmg, eff_addr + use_tile);
int data2 = dmg_read(dmg, eff_addr + use_tile + 1);
for (i = 7; i >= 0; i--) { for (i = 7; i >= 0; i--) {
if (off < 0 || off >= 160 * 144) { if (off < 0 || off >= 160 * 144) {
// terrible clipping. need to not have an if per-pixel // terrible clipping. need to not have an if per-pixel
continue; continue;
} }
dmg->lcd->pixels[off] = ((data1 & (1 << i)) ? 1 : 0) << 1; int use_index = i;
dmg->lcd->pixels[off] |= (data2 & (1 << i)) ? 1 : 0; if (oam->attrs & OAM_ATTR_MIRROR_X) {
use_index = 7 - i;
}
dmg->lcd->pixels[off] = ((data1 & (1 << use_index)) ? 1 : 0) << 1;
dmg->lcd->pixels[off] |= (data2 & (1 << use_index)) ? 1 : 0;
off++; off++;
} }
off += 152; off += 152;

View File

@ -39,6 +39,11 @@
#define LCDC_WINDOW_TILE_MAP (1 << 6) #define LCDC_WINDOW_TILE_MAP (1 << 6)
#define LCDC_ENABLE (1 << 7) #define LCDC_ENABLE (1 << 7)
#define OAM_ATTR_PALETTE (1 << 4)
#define OAM_ATTR_MIRROR_X (1 << 5)
#define OAM_ATTR_MIRROR_Y (1 << 6)
#define OAM_ATTR_BEHIND_BG (1 << 7)
struct lcd { struct lcd {
u8 oam[0xa0]; u8 oam[0xa0];
u8 regs[0x0c]; u8 regs[0x0c];