mirror of
https://github.com/mlaux/gb6.git
synced 2025-01-29 09:31:23 +00:00
render objs, fix bug with SRL, tetris is playable
This commit is contained in:
parent
580c349fc7
commit
0f43ebf4cc
@ -59,7 +59,7 @@ GLuint make_output_texture() {
|
|||||||
return image_texture;
|
return image_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char default_palette[] = { 0, 0x55, 0xaa, 0xff };
|
unsigned char default_palette[] = { 0xff, 0xaa, 0x55, 0x00 };
|
||||||
|
|
||||||
void convert_output(struct lcd *lcd) {
|
void convert_output(struct lcd *lcd) {
|
||||||
int x, y;
|
int x, y;
|
||||||
|
12
src/cpu.c
12
src/cpu.c
@ -213,7 +213,7 @@ static u8 srl(struct cpu *cpu, u8 value)
|
|||||||
}
|
}
|
||||||
clear_flag(cpu, FLAG_SIGN);
|
clear_flag(cpu, FLAG_SIGN);
|
||||||
clear_flag(cpu, FLAG_HALF_CARRY);
|
clear_flag(cpu, FLAG_HALF_CARRY);
|
||||||
return 0;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 swap(struct cpu *cpu, u8 value)
|
static u8 swap(struct cpu *cpu, u8 value)
|
||||||
@ -761,7 +761,7 @@ void cpu_step(struct cpu *cpu)
|
|||||||
case 0xd2: // JP NC,a16
|
case 0xd2: // JP NC,a16
|
||||||
temp16 = read16(cpu, cpu->pc);
|
temp16 = read16(cpu, cpu->pc);
|
||||||
cpu->pc += 2;
|
cpu->pc += 2;
|
||||||
if (flag_isset(cpu, FLAG_CARRY)) {
|
if (!flag_isset(cpu, FLAG_CARRY)) {
|
||||||
cpu->pc = temp16;
|
cpu->pc = temp16;
|
||||||
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
|
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
|
||||||
}
|
}
|
||||||
@ -772,6 +772,14 @@ 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 0xda: // JP C, u16
|
||||||
|
temp16 = read16(cpu, cpu->pc);
|
||||||
|
cpu->pc += 2;
|
||||||
|
if (flag_isset(cpu, FLAG_CARRY)) {
|
||||||
|
cpu->pc = temp16;
|
||||||
|
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x80: add(cpu, cpu->b, 0); break;
|
case 0x80: add(cpu, cpu->b, 0); break;
|
||||||
case 0x81: add(cpu, cpu->c, 0); break;
|
case 0x81: add(cpu, cpu->c, 0); break;
|
||||||
|
116
src/dmg.c
116
src/dmg.c
@ -95,11 +95,9 @@ void dmg_write(void *_dmg, u16 address, u8 data)
|
|||||||
struct dmg *dmg = (struct dmg *) _dmg;
|
struct dmg *dmg = (struct dmg *) _dmg;
|
||||||
if (address < 0x4000) {
|
if (address < 0x4000) {
|
||||||
printf("warning: writing 0x%04x in rom\n", address);
|
printf("warning: writing 0x%04x in rom\n", address);
|
||||||
dmg->rom->data[address] = data;
|
|
||||||
} else if (address < 0x8000) {
|
} else if (address < 0x8000) {
|
||||||
// TODO switchable rom bank
|
// TODO switchable rom bank
|
||||||
printf("warning: writing 0x%04x in rom\n", address);
|
printf("warning: writing 0x%04x in rom\n", address);
|
||||||
dmg->rom->data[address] = data;
|
|
||||||
} else if (address < 0xa000) {
|
} else if (address < 0xa000) {
|
||||||
dmg->video_ram[address - 0x8000] = data;
|
dmg->video_ram[address - 0x8000] = data;
|
||||||
} else if (address < 0xc000) {
|
} else if (address < 0xc000) {
|
||||||
@ -135,6 +133,82 @@ void dmg_request_interrupt(struct dmg *dmg, int nr)
|
|||||||
dmg->interrupt_requested |= nr;
|
dmg->interrupt_requested |= nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO move to lcd.c, it needs to be able to access dmg_read though
|
||||||
|
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 tilebase = use_unsigned ? 0x8000 : 0x9000;
|
||||||
|
|
||||||
|
//printf("%04x %04x %04x\n", bg_base, window_base, tilebase);
|
||||||
|
|
||||||
|
int k = 0, off = 0;
|
||||||
|
int tile_y = 0, tile_x = 0;
|
||||||
|
for (tile_y = 0; tile_y < 32; tile_y++) {
|
||||||
|
for (tile_x = 0; tile_x < 32; tile_x++) {
|
||||||
|
off = 256 * 8 * tile_y + 8 * tile_x;
|
||||||
|
int tile = dmg_read(dmg, bg_base + (tile_y * 32 + tile_x));
|
||||||
|
int eff_addr;
|
||||||
|
if (use_unsigned) {
|
||||||
|
eff_addr = tilebase + 16 * tile;
|
||||||
|
} else {
|
||||||
|
eff_addr = tilebase + 16 * (signed char) tile;
|
||||||
|
}
|
||||||
|
int b, i;
|
||||||
|
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;
|
||||||
|
off++;
|
||||||
|
}
|
||||||
|
off += 248;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct oam_entry {
|
||||||
|
u8 pos_y;
|
||||||
|
u8 pos_x;
|
||||||
|
u8 tile;
|
||||||
|
u8 attrs;
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: only ten per scanline, priority
|
||||||
|
static void render_objs(struct dmg *dmg)
|
||||||
|
{
|
||||||
|
struct oam_entry *oam = (struct oam_entry *) dmg->lcd->oam;
|
||||||
|
int k, lcd_x, lcd_y, off;
|
||||||
|
for (k = 0; k < 40; k++, oam++) {
|
||||||
|
if (oam->pos_y == 0 || oam->pos_y >= 160) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (oam->pos_x == 0 || oam->pos_y >= 168) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
lcd_x = oam->pos_x - 8;
|
||||||
|
lcd_y = oam->pos_y - 16;
|
||||||
|
|
||||||
|
off = 256 * lcd_y + lcd_x;
|
||||||
|
int eff_addr = 0x8000 + 16 * oam->tile;
|
||||||
|
int b, i;
|
||||||
|
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;
|
||||||
|
off++;
|
||||||
|
}
|
||||||
|
off += 248;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void dmg_step(void *_dmg)
|
void dmg_step(void *_dmg)
|
||||||
{
|
{
|
||||||
struct dmg *dmg = (struct dmg *) _dmg;
|
struct dmg *dmg = (struct dmg *) _dmg;
|
||||||
@ -165,6 +239,7 @@ void dmg_step(void *_dmg)
|
|||||||
lcd_set_mode(dmg->lcd, 1);
|
lcd_set_mode(dmg->lcd, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: do all of this per-scanline instead of everything in vblank
|
||||||
if (next_scanline == 144) {
|
if (next_scanline == 144) {
|
||||||
// vblank has started, draw all the stuff from ram into the lcd
|
// vblank has started, draw all the stuff from ram into the lcd
|
||||||
dmg_request_interrupt(dmg, INT_VBLANK);
|
dmg_request_interrupt(dmg, INT_VBLANK);
|
||||||
@ -173,37 +248,16 @@ void dmg_step(void *_dmg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int lcdc = lcd_read(dmg->lcd, REG_LCDC);
|
int lcdc = lcd_read(dmg->lcd, REG_LCDC);
|
||||||
int bg_base = (lcdc & LCDC_BG_TILE_MAP) ? 0x9c00 : 0x9800;
|
if (lcdc & LCDC_ENABLE_BG) {
|
||||||
int window_base = (lcdc & LCDC_WINDOW_TILE_MAP) ? 0x9c00 : 0x9800;
|
render_background(dmg, lcdc);
|
||||||
int use_unsigned = lcdc & LCDC_BG_TILE_DATA;
|
}
|
||||||
int tilebase = use_unsigned ? 0x8000 : 0x9000;
|
|
||||||
|
|
||||||
//printf("%04x %04x %04x\n", bg_base, window_base, tilebase);
|
if (lcdc & LCDC_ENABLE_WINDOW) {
|
||||||
|
// printf("window\n");
|
||||||
|
}
|
||||||
|
|
||||||
int k = 0, off = 0;
|
if (lcdc & LCDC_ENABLE_OBJ) {
|
||||||
int tile_y = 0, tile_x = 0;
|
render_objs(dmg);
|
||||||
for (tile_y = 0; tile_y < 32; tile_y++) {
|
|
||||||
for (tile_x = 0; tile_x < 32; tile_x++) {
|
|
||||||
off = 256 * 8 * tile_y + 8 * tile_x;
|
|
||||||
int tile = dmg_read(dmg, bg_base + (tile_y * 32 + tile_x));
|
|
||||||
int eff_addr;
|
|
||||||
if (use_unsigned) {
|
|
||||||
eff_addr = tilebase + 16 * tile;
|
|
||||||
} else {
|
|
||||||
eff_addr = tilebase + 16 * (signed char) tile;
|
|
||||||
}
|
|
||||||
int b, i;
|
|
||||||
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;
|
|
||||||
off++;
|
|
||||||
}
|
|
||||||
off += 248;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// now copy 256x256 buf to 160x144 based on window registers
|
// now copy 256x256 buf to 160x144 based on window registers
|
||||||
|
Loading…
x
Reference in New Issue
Block a user