pizza: some basic ATTR stuff now working
This commit is contained in:
parent
46568bf1ec
commit
ea32862199
|
@ -53,6 +53,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy
|
|||
|
||||
if (_sgb)
|
||||
VsyncNumerator = TICKSPERSECOND_SGB;
|
||||
|
||||
Console.WriteLine("Pizza Initialized: CGB {0} SGB {1}", IsCGBMode(), IsSGBMode());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "interrupt.h"
|
||||
#include "mmu.h"
|
||||
#include "utils.h"
|
||||
#include "sgb.h"
|
||||
|
||||
/* Gameboy OAM 4 bytes data */
|
||||
typedef struct gpu_oam_s
|
||||
|
@ -183,6 +184,11 @@ void gpu_draw_frame()
|
|||
(gpu.frame_counter & 0x0003) != 0))
|
||||
return;*/
|
||||
|
||||
if (global_sgb)
|
||||
{
|
||||
sgb_take_frame(gpu.frame_buffer);
|
||||
}
|
||||
|
||||
/* call the callback */
|
||||
if (gpu_frame_ready_cb)
|
||||
(*gpu_frame_ready_cb)();
|
||||
|
|
|
@ -25,6 +25,28 @@ typedef struct
|
|||
|
||||
// palettes
|
||||
uint32_t palette[8][16];
|
||||
uint32_t auxpalette[512][4];
|
||||
|
||||
// frame data
|
||||
uint8_t frame[160 * 144]; // the most recent obtained full frame
|
||||
uint8_t frozenframe[160 * 144]; // the most recent saved full frame (MASK_EN)
|
||||
uint8_t attr[20 * 18]; // current attr map for the GB screen
|
||||
uint8_t auxattr[45][20 * 18]; // 45 attr files
|
||||
|
||||
// MASK_EN
|
||||
uint8_t waiting_mask; // true if waiting to capture a mask
|
||||
uint8_t active_mask; // true if mask is currently being used
|
||||
|
||||
// transfers
|
||||
uint32_t waiting_transfer;
|
||||
#define TRN_NONE 0
|
||||
#define TRN_SOUND 1
|
||||
#define TRN_PAL 2
|
||||
#define TRN_CHR_LOW 3
|
||||
#define TRN_CHR_HI 4
|
||||
#define TRN_PCT 5
|
||||
#define TRN_ATTR 6
|
||||
int32_t transfer_countdown; // number of frames until transfer. not entirely accurate
|
||||
} sgb_t;
|
||||
|
||||
static sgb_t sgb;
|
||||
|
@ -34,13 +56,33 @@ static uint32_t makecol(uint16_t c)
|
|||
return c >> 7 & 0xf8 | c >> 12 & 0x07 | c << 6 & 0xf800 | c << 1 & 0x0700 | c << 19 & 0xf80000 | c << 14 & 0x070000 | 0xff000000;
|
||||
}
|
||||
|
||||
static void cmd_trn(uint32_t which)
|
||||
{
|
||||
if ((sgb.command[0] & 7) == 1)
|
||||
{
|
||||
if (sgb.waiting_transfer == TRN_NONE)
|
||||
{
|
||||
sgb.waiting_transfer = which;
|
||||
sgb.transfer_countdown = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
utils_log("SGB: TRN already queued!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
utils_log("SGB: cmd_trn bad length");
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_pal(int a, int b)
|
||||
{
|
||||
if ((sgb.command[0] & 7) == 1)
|
||||
{
|
||||
uint32_t c[7];
|
||||
for (int i = 0; i < 7; i++)
|
||||
c[i] = makecol(sgb.command[1 + i] | sgb.command[2 + i] << 8);
|
||||
c[i] = makecol(sgb.command[i * 2 + 1] | sgb.command[i * 2 + 2] << 8);
|
||||
sgb.palette[0][0] = c[0];
|
||||
sgb.palette[a][1] = c[1];
|
||||
sgb.palette[a][2] = c[2];
|
||||
|
@ -55,6 +97,193 @@ static void cmd_pal(int a, int b)
|
|||
}
|
||||
}
|
||||
|
||||
static void cmd_pal_set(void)
|
||||
{
|
||||
if ((sgb.command[0] & 7) == 1)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int p = sgb.command[i * 2 + 1] | sgb.command[i * 2 + 2] << 8 & 0x100;
|
||||
for (int j = 0; j < 4; j++)
|
||||
sgb.palette[i][j] = sgb.auxpalette[p][j];
|
||||
}
|
||||
if (sgb.command[9] & 0x80) // change attribute
|
||||
{
|
||||
int attr = sgb.command[9] & 0x3f;
|
||||
if (attr >= 45)
|
||||
attr = 44;
|
||||
memcpy(sgb.attr, sgb.auxattr[attr], sizeof(sgb.attr));
|
||||
}
|
||||
if (sgb.command[9] & 0x40) // cancel mask
|
||||
{
|
||||
sgb.waiting_mask = 0;
|
||||
sgb.active_mask = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
utils_log("SGB: cmd_pal bad length");
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_attr_blk()
|
||||
{
|
||||
}
|
||||
|
||||
static void cmd_attr_lin()
|
||||
{
|
||||
int nset = sgb.command[1];
|
||||
if (nset <= 0 || nset >= 111)
|
||||
{
|
||||
utils_log("SGB: cmd_attr_lin bad nset");
|
||||
return;
|
||||
}
|
||||
int npacket = (nset + 17) / 16;
|
||||
if ((sgb.command[0] & 7) != npacket)
|
||||
{
|
||||
utils_log("SGB: cmd_attr_lin bad length");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < nset; i++)
|
||||
{
|
||||
uint8_t v = sgb.command[i + 2];
|
||||
int line = v & 31;
|
||||
int a = v >> 5 & 3;
|
||||
if (v & 0x80) // horizontal
|
||||
{
|
||||
if (line > 17)
|
||||
line = 17;
|
||||
memset(sgb.attr + line * 20, a, 20);
|
||||
}
|
||||
else // vertical
|
||||
{
|
||||
if (line > 19)
|
||||
line = 19;
|
||||
uint8_t *dst = sgb.attr + line;
|
||||
for (int i = 0; i < 18; i++, dst += 20)
|
||||
dst[0] = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_attr_div()
|
||||
{
|
||||
if ((sgb.command[0] & 7) == 1)
|
||||
{
|
||||
uint8_t v = sgb.command[1];
|
||||
|
||||
int c = v & 3;
|
||||
int a = v >> 2 & 3;
|
||||
int b = v >> 4 & 3;
|
||||
|
||||
int pos = sgb.command[2];
|
||||
uint8_t *dst = sgb.attr;
|
||||
if (v & 0x40) // horizontal
|
||||
{
|
||||
if (pos > 17)
|
||||
pos = 17;
|
||||
int i;
|
||||
for (i = 0; i < pos; i++, dst += 20)
|
||||
memset(dst, a, 20);
|
||||
memset(dst, b, 20);
|
||||
i++, dst += 20;
|
||||
for (; i < 18; i++, dst += 20)
|
||||
memset(dst, c, 20);
|
||||
}
|
||||
else // vertical
|
||||
{
|
||||
if (pos > 19)
|
||||
pos = 19;
|
||||
for (int j = 0; j < 18; j++)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < pos; i++)
|
||||
*dst++ = a;
|
||||
*dst++ = b;
|
||||
i++;
|
||||
for (; i < 20; i++)
|
||||
*dst++ = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
utils_log("SGB: cmd_attr_div bad length");
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_attr_chr()
|
||||
{
|
||||
int x = sgb.command[1];
|
||||
int y = sgb.command[2];
|
||||
int n = sgb.command[3] | sgb.command[4] << 8;
|
||||
if (n > 360)
|
||||
{
|
||||
utils_log("SGB: cmd_attr_chr bad n");
|
||||
return;
|
||||
}
|
||||
int npacket = (n + 87) / 64;
|
||||
if ((sgb.command[0] & 7) != npacket)
|
||||
{
|
||||
utils_log("SGB: cmd_attr_chr bad length");
|
||||
return;
|
||||
}
|
||||
uint8_t *dst = sgb.attr;
|
||||
if (x > 19)
|
||||
x = 19;
|
||||
if (y > 17)
|
||||
y = 17;
|
||||
int vertical = sgb.command[5];
|
||||
for (int i = 0; i < 360; i++)
|
||||
{
|
||||
uint8_t v = i / 4 + 6;
|
||||
int a = v >> (2 * (3 - (i & 3))) & 3;
|
||||
dst[y * 20 + x] = a;
|
||||
if (vertical)
|
||||
{
|
||||
y++;
|
||||
if (y == 18)
|
||||
{
|
||||
y = 0;
|
||||
x++;
|
||||
if (x == 20)
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x++;
|
||||
if (x == 20)
|
||||
{
|
||||
x = 0;
|
||||
y++;
|
||||
if (y == 18)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_attr_set()
|
||||
{
|
||||
if ((sgb.command[0] & 7) == 1)
|
||||
{
|
||||
int attr = sgb.command[1] & 0x3f;
|
||||
if (attr >= 45)
|
||||
attr = 44;
|
||||
memcpy(sgb.attr, sgb.auxattr[attr], sizeof(sgb.attr));
|
||||
if (sgb.command[1] & 0x40)
|
||||
{
|
||||
sgb.waiting_mask = 0;
|
||||
sgb.active_mask = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
utils_log("SGB: cmd_attr_set bad length");
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_mlt_req(void)
|
||||
{
|
||||
if ((sgb.command[0] & 7) == 1)
|
||||
|
@ -83,6 +312,33 @@ static void cmd_mlt_req(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void cmd_mask(void)
|
||||
{
|
||||
if ((sgb.command[0] & 7) == 1)
|
||||
{
|
||||
switch (sgb.command[1] & 3)
|
||||
{
|
||||
case 0:
|
||||
sgb.waiting_mask = 0;
|
||||
sgb.active_mask = 0;
|
||||
break;
|
||||
case 1:
|
||||
sgb.waiting_mask = 1;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
sgb.waiting_mask = 0;
|
||||
sgb.active_mask = 1;
|
||||
memset(sgb.frozenframe, 0, sizeof(sgb.frozenframe));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
utils_log("SGB: cmd_mask bad length");
|
||||
}
|
||||
}
|
||||
|
||||
static void do_command(void)
|
||||
{
|
||||
const int command = sgb.command[0] >> 3;
|
||||
|
@ -108,6 +364,36 @@ static void do_command(void)
|
|||
utils_log("SGB: PAL12");
|
||||
cmd_pal(1, 2);
|
||||
break;
|
||||
case 0x0a: // PAL_SET
|
||||
utils_log("SGB: PAL_SET");
|
||||
cmd_pal_set();
|
||||
break;
|
||||
|
||||
case 0x04: // ATTR_BLK
|
||||
utils_log("SGB: ATTR_BLK");
|
||||
cmd_attr_blk();
|
||||
break;
|
||||
case 0x05: // ATTR_LIN
|
||||
utils_log("SGB: ATTR_LIN");
|
||||
cmd_attr_lin();
|
||||
break;
|
||||
case 0x06: // ATTR_DIV
|
||||
utils_log("SGB: ATTR_DIV");
|
||||
cmd_attr_div();
|
||||
break;
|
||||
case 0x07: // ATTR_CHR
|
||||
utils_log("SGB: ATTR_CHR");
|
||||
cmd_attr_chr();
|
||||
break;
|
||||
case 0x16: // ATTR_SET
|
||||
utils_log("SGB: ATTR_SET");
|
||||
cmd_attr_set();
|
||||
break;
|
||||
|
||||
case 0x17: // MASK_EN
|
||||
utils_log("SGB: MASK_EN");
|
||||
cmd_mask();
|
||||
break;
|
||||
|
||||
// unknown functions
|
||||
case 0x0c: // ATRC_EN
|
||||
|
@ -125,10 +411,13 @@ static void do_command(void)
|
|||
break;
|
||||
|
||||
// unimplementable functions
|
||||
case 0x10: // DATA_TRN
|
||||
// TODO: Is it possible for this to write data to
|
||||
case 0x0f: // DATA_SND
|
||||
// TODO: Is it possible for this (and DATA_TRN) to write data to
|
||||
// memory areas used for the attribute file, etc?
|
||||
// If so, do games do this?
|
||||
utils_log("SGB: DATA_SND!!");
|
||||
break;
|
||||
case 0x10: // DATA_TRN
|
||||
utils_log("SGB: DATA_TRN!!");
|
||||
break;
|
||||
case 0x12: // JUMP
|
||||
|
@ -140,6 +429,28 @@ static void do_command(void)
|
|||
utils_log("SGB: MLT_REQ");
|
||||
cmd_mlt_req();
|
||||
break;
|
||||
|
||||
// all vram transfers
|
||||
case 0x09: // SOU_TRN
|
||||
utils_log("SGB: SOU_TRN");
|
||||
cmd_trn(TRN_SOUND);
|
||||
break;
|
||||
case 0x0b: // PAL_TRN
|
||||
utils_log("SGB: PAL_TRN");
|
||||
cmd_trn(TRN_PAL);
|
||||
break;
|
||||
case 0x13: // CHR_TRN
|
||||
utils_log("SGB: CHR_TRN");
|
||||
cmd_trn(sgb.command[1] & 1 ? TRN_CHR_HI : TRN_CHR_LOW);
|
||||
break;
|
||||
case 0x14: // PCT_TRN
|
||||
utils_log("SGB: PCT_TRN");
|
||||
cmd_trn(TRN_PCT);
|
||||
break;
|
||||
case 0x15: // ATTR_TRN
|
||||
utils_log("SGB: ATTR_TRN");
|
||||
cmd_trn(TRN_ATTR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,7 +487,7 @@ void sgb_write_ff00(uint8_t val, uint64_t time)
|
|||
{
|
||||
val &= 0x30;
|
||||
|
||||
utils_log("ZZ: %02x, %llu", val, time);
|
||||
//utils_log("ZZ: %02x, %llu", val, time);
|
||||
const int p14_fell = (val & 0x10) < (sgb.last_write_value & 0x10);
|
||||
const int p15_fell = (val & 0x20) < (sgb.last_write_value & 0x20);
|
||||
const int p14_rose = (val & 0x10) > (sgb.last_write_value & 0x10);
|
||||
|
@ -224,7 +535,7 @@ void sgb_write_ff00(uint8_t val, uint64_t time)
|
|||
sgb.joypad_has_been_read = 0;
|
||||
sgb.joypad_index++;
|
||||
sgb.joypad_index &= sgb.num_joypads - 1;
|
||||
utils_log("SGB: joypad index to %u", sgb.joypad_index);
|
||||
//utils_log("SGB: joypad index to %u", sgb.joypad_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -252,7 +563,7 @@ uint8_t sgb_read_ff00(uint64_t time)
|
|||
|
||||
if (!p14 && !p15)
|
||||
{
|
||||
utils_log("SGB: SCAN%u", ji);
|
||||
//utils_log("SGB: SCAN%u", ji);
|
||||
// scan id
|
||||
return ret | (15 - ji);
|
||||
}
|
||||
|
@ -264,7 +575,7 @@ uint8_t sgb_read_ff00(uint64_t time)
|
|||
ret |= j >> 4;
|
||||
if (p15)
|
||||
ret |= j & 0x0f;
|
||||
utils_log("SGB: READ%u %02x", ji, ret ^ 0x0f);
|
||||
//utils_log("SGB: READ%u %02x", ji, ret ^ 0x0f);
|
||||
return ret ^ 0x0f;
|
||||
}
|
||||
}
|
||||
|
@ -276,3 +587,146 @@ void sgb_set_controller_data(const uint8_t *buttons)
|
|||
{
|
||||
memcpy(sgb.joypad_data, buttons, sizeof(sgb.joypad_data));
|
||||
}
|
||||
|
||||
static void trn_pal(const uint8_t *data)
|
||||
{
|
||||
const uint16_t *src = (const uint16_t *)data;
|
||||
uint32_t *dst = (uint32_t *)sgb.auxpalette;
|
||||
for (int i = 0; i < 2048; i++)
|
||||
dst[i] = makecol(src[i]);
|
||||
}
|
||||
|
||||
static void trn_attr(const uint8_t *data)
|
||||
{
|
||||
uint8_t *dst = (uint8_t *)sgb.auxattr;
|
||||
for (int n = 0; n < 45 * 90; n++)
|
||||
{
|
||||
uint8_t s = *data++;
|
||||
*dst++ = s >> 6 & 3;
|
||||
*dst++ = s >> 4 & 3;
|
||||
*dst++ = s >> 2 & 3;
|
||||
*dst++ = s >> 0 & 3;
|
||||
}
|
||||
}
|
||||
|
||||
#include "mmu.h"
|
||||
static void do_vram_transfer(void)
|
||||
{
|
||||
uint8_t vram[4096];
|
||||
for (int tilenum = 0; tilenum < 256; tilenum++)
|
||||
{
|
||||
const int ty = tilenum / 20;
|
||||
const int tx = tilenum % 20;
|
||||
const uint8_t *src = sgb.frame + ty * 8 * 160 + tx * 8;
|
||||
uint8_t *dst = vram + 16 * tilenum;
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
uint32_t a = 0, b = 0;
|
||||
a |= (src[7] & 1) << 0;
|
||||
a |= (src[6] & 1) << 1;
|
||||
a |= (src[5] & 1) << 2;
|
||||
a |= (src[4] & 1) << 3;
|
||||
a |= (src[3] & 1) << 4;
|
||||
a |= (src[2] & 1) << 5;
|
||||
a |= (src[1] & 1) << 6;
|
||||
a |= (src[0] & 1) << 7;
|
||||
|
||||
b |= (src[7] & 2) >> 1;
|
||||
b |= (src[6] & 2) << 0;
|
||||
b |= (src[5] & 2) << 1;
|
||||
b |= (src[4] & 2) << 2;
|
||||
b |= (src[3] & 2) << 3;
|
||||
b |= (src[2] & 2) << 4;
|
||||
b |= (src[1] & 2) << 5;
|
||||
b |= (src[0] & 2) << 6;
|
||||
*dst++ = a;
|
||||
*dst++ = b;
|
||||
src += 160;
|
||||
}
|
||||
}
|
||||
|
||||
switch (sgb.waiting_transfer)
|
||||
{
|
||||
case TRN_SOUND:
|
||||
break;
|
||||
case TRN_PAL:
|
||||
trn_pal(vram);
|
||||
break;
|
||||
case TRN_CHR_LOW:
|
||||
break;
|
||||
case TRN_CHR_HI:
|
||||
break;
|
||||
case TRN_PCT:
|
||||
break;
|
||||
case TRN_ATTR:
|
||||
trn_attr(vram);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 160x144 32bpp pixel data
|
||||
// assumed to contain exact pixel values 00, 55, aa, ff
|
||||
void sgb_take_frame(uint32_t *vbuff)
|
||||
{
|
||||
for (int i = 0; i < 160 * 144; i++)
|
||||
{
|
||||
sgb.frame[i] = 3 - (vbuff[i] >> 6 & 3); // 0, 1, 2, or 3 for each pixel
|
||||
}
|
||||
if (sgb.waiting_transfer != TRN_NONE)
|
||||
{
|
||||
if (!--sgb.transfer_countdown)
|
||||
{
|
||||
do_vram_transfer();
|
||||
sgb.waiting_transfer = TRN_NONE;
|
||||
}
|
||||
}
|
||||
if (sgb.waiting_mask)
|
||||
{
|
||||
memcpy(sgb.frozenframe, sgb.frame, sizeof(sgb.frame));
|
||||
sgb.waiting_mask = 0;
|
||||
sgb.active_mask = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void sgb_render_frame_gb(uint32_t *vbuff)
|
||||
{
|
||||
/*sgb.palette[0][0] = 0xff000000;
|
||||
sgb.palette[0][1] = 0xff550055;
|
||||
sgb.palette[0][2] = 0xffaa00aa;
|
||||
sgb.palette[0][3] = 0xffff00ff;
|
||||
|
||||
sgb.palette[1][0] = 0xff00003f;
|
||||
sgb.palette[1][1] = 0xff00007f;
|
||||
sgb.palette[1][2] = 0xff0000bf;
|
||||
sgb.palette[1][3] = 0xff0000ff;
|
||||
|
||||
sgb.palette[2][0] = 0xff003f00;
|
||||
sgb.palette[2][1] = 0xff007f00;
|
||||
sgb.palette[2][2] = 0xff00bf00;
|
||||
sgb.palette[2][3] = 0xff00ff00;
|
||||
|
||||
sgb.palette[3][0] = 0xff3f0000;
|
||||
sgb.palette[3][1] = 0xff7f0000;
|
||||
sgb.palette[3][2] = 0xffbf0000;
|
||||
sgb.palette[3][3] = 0xffff0000;*/
|
||||
|
||||
const uint8_t *attr = sgb.attr;
|
||||
const uint8_t *src = sgb.active_mask ? sgb.frozenframe : sgb.frame;
|
||||
uint32_t *dst = vbuff + ((224 - 144) / 2 * 256 + (256 - 160) / 2);
|
||||
|
||||
for (int j = 0; j < 144; j++)
|
||||
{
|
||||
const uint8_t *attr_line = attr + j / 8 * 20;
|
||||
for (int i = 0; i < 160; i++)
|
||||
{
|
||||
const int attr_index = i / 8;
|
||||
*dst++ = sgb.palette[attr_line[attr_index]][*src++];
|
||||
}
|
||||
dst += 256 - 160;
|
||||
}
|
||||
}
|
||||
|
||||
void sgb_render_frame(uint32_t *vbuff)
|
||||
{
|
||||
sgb_render_frame_gb(vbuff);
|
||||
}
|
||||
|
|
|
@ -8,3 +8,7 @@ uint8_t sgb_read_ff00(uint64_t time);
|
|||
void sgb_set_controller_data(const uint8_t* buttons);
|
||||
|
||||
void sgb_init(void);
|
||||
|
||||
void sgb_take_frame(uint32_t* vbuff);
|
||||
|
||||
void sgb_render_frame(uint32_t* vbuff);
|
||||
|
|
|
@ -86,8 +86,8 @@ EXPORT int Init(const void *rom, int romlen, int sgb)
|
|||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t* VideoBuffer;
|
||||
int16_t* SoundBuffer;
|
||||
uint32_t *VideoBuffer;
|
||||
int16_t *SoundBuffer;
|
||||
int64_t Cycles;
|
||||
int32_t Width;
|
||||
int32_t Height;
|
||||
|
@ -96,13 +96,13 @@ typedef struct
|
|||
uint32_t Keys;
|
||||
} MyFrameInfo;
|
||||
|
||||
static uint32_t* current_vbuff;
|
||||
static uint32_t *current_vbuff;
|
||||
static uint64_t overflow;
|
||||
|
||||
EXPORT void FrameAdvance(MyFrameInfo* frame)
|
||||
EXPORT void FrameAdvance(MyFrameInfo *frame)
|
||||
{
|
||||
if (global_sgb)
|
||||
sgb_set_controller_data((uint8_t*)&frame->Keys);
|
||||
sgb_set_controller_data((uint8_t *)&frame->Keys);
|
||||
else
|
||||
input_set_keys(frame->Keys);
|
||||
current_vbuff = frame->VideoBuffer;
|
||||
|
@ -115,8 +115,16 @@ EXPORT void FrameAdvance(MyFrameInfo* frame)
|
|||
overflow = cycles.sampleclock - target;
|
||||
|
||||
frame->Samples = sound_output_read(frame->SoundBuffer);
|
||||
frame->Width = 160;
|
||||
frame->Height = 144;
|
||||
if (global_sgb)
|
||||
{
|
||||
frame->Width = 256;
|
||||
frame->Height = 224;
|
||||
}
|
||||
else
|
||||
{
|
||||
frame->Width = 160;
|
||||
frame->Height = 144;
|
||||
}
|
||||
current_vbuff = NULL;
|
||||
}
|
||||
|
||||
|
@ -130,7 +138,7 @@ EXPORT void SetInputCallback(void (*callback)(void))
|
|||
// TODO
|
||||
}
|
||||
|
||||
EXPORT void GetMemoryAreas(MemoryArea* m)
|
||||
EXPORT void GetMemoryAreas(MemoryArea *m)
|
||||
{
|
||||
m[0].Data = mmu.memory;
|
||||
m[0].Name = "Fake System Bus";
|
||||
|
@ -140,7 +148,14 @@ EXPORT void GetMemoryAreas(MemoryArea* m)
|
|||
|
||||
void frame_cb()
|
||||
{
|
||||
memcpy(current_vbuff, gpu.frame_buffer, sizeof(gpu.frame_buffer));
|
||||
if (global_sgb)
|
||||
{
|
||||
sgb_render_frame(current_vbuff);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(current_vbuff, gpu.frame_buffer, sizeof(gpu.frame_buffer));
|
||||
}
|
||||
}
|
||||
|
||||
void connected_cb()
|
||||
|
|
Loading…
Reference in New Issue