pizza: Save the last rendering of the border as well when MASK_EN is used. Seems to match real hardware?
This commit is contained in:
parent
8e1df5562a
commit
f972df72ea
Binary file not shown.
|
@ -75,7 +75,7 @@ typedef struct
|
|||
|
||||
// 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)
|
||||
uint32_t frozenframe[256 * 224]; // 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
|
||||
|
||||
|
@ -433,7 +433,8 @@ static void cmd_mask(void)
|
|||
case 2:
|
||||
case 3:
|
||||
sgb.active_mask = 1;
|
||||
memset(sgb.frozenframe, 0, sizeof(sgb.frozenframe));
|
||||
for (int i = 0; i < 256 * 224; i++)
|
||||
sgb.frozenframe[i] = sgb.palette[0][0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -862,32 +863,10 @@ static void do_vram_transfer(void)
|
|||
}
|
||||
}
|
||||
|
||||
// 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.active_mask)
|
||||
{
|
||||
memcpy(sgb.frozenframe, sgb.frame, sizeof(sgb.frame));
|
||||
}
|
||||
}
|
||||
|
||||
static void sgb_render_frame_gb(uint32_t *vbuff)
|
||||
{
|
||||
const uint8_t *attr = sgb.attr;
|
||||
const uint8_t *src = sgb.active_mask ? sgb.frozenframe : sgb.frame;
|
||||
const uint8_t *src = sgb.frame;
|
||||
uint32_t *dst = vbuff + ((224 - 144) / 2 * 256 + (256 - 160) / 2);
|
||||
|
||||
for (int j = 0; j < 144; j++)
|
||||
|
@ -951,12 +930,35 @@ static void sgb_render_border(uint32_t *vbuff)
|
|||
}
|
||||
}
|
||||
|
||||
// 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.active_mask)
|
||||
{
|
||||
// render the frame now
|
||||
for (int i = 0; i < 256 * 224; i++)
|
||||
sgb.frozenframe[i] = sgb.palette[0][0];
|
||||
sgb_render_frame_gb(sgb.frozenframe);
|
||||
sgb_render_border(sgb.frozenframe);
|
||||
}
|
||||
}
|
||||
|
||||
void sgb_render_frame(uint32_t *vbuff)
|
||||
{
|
||||
for (int i = 0; i < 256 * 224; i++)
|
||||
vbuff[i] = sgb.palette[0][0];
|
||||
sgb_render_frame_gb(vbuff);
|
||||
sgb_render_border(vbuff);
|
||||
memcpy(vbuff, sgb.frozenframe, sizeof(sgb.frozenframe));
|
||||
}
|
||||
|
||||
void sgb_render_audio(uint64_t time, void (*callback)(int16_t l, int16_t r, uint64_t time))
|
||||
|
|
|
@ -1,16 +1,36 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
// whenever a time is asked for, it is relative to a clock that ticks 35112 times
|
||||
// per nominal frame on the GB lcd, starts at 0 when emulation begins, and never resets/rebases
|
||||
|
||||
// write to MMIO ff00. only bits 4 and 5 are used
|
||||
void sgb_write_ff00(uint8_t val, uint64_t time);
|
||||
|
||||
// read from MMIO ff00. supplies data for all 8 bits
|
||||
uint8_t sgb_read_ff00(uint64_t time);
|
||||
|
||||
// set controller data to be used by subsequent controller reads
|
||||
// buttons[0] = controller 1, buttons[3] = controller 4
|
||||
// 7......0
|
||||
// DULRSsBA
|
||||
void sgb_set_controller_data(const uint8_t* buttons);
|
||||
|
||||
// initialize the SGB module. pass an SPC file that results from the real S-CPU initialization,
|
||||
// and the length of that file
|
||||
int sgb_init(const uint8_t* spc, int length);
|
||||
|
||||
// call whenever the gameboy has finished producing a video frame
|
||||
// data is 32bpp 160x144 screen data. for each pixel:
|
||||
//31 7 0
|
||||
// xxxxxxxx xxxxxxxx xxxxxxxx DDxxxxxx -- DD = 0, 1, 2, or 3. x = don't care
|
||||
void sgb_take_frame(uint32_t* vbuff);
|
||||
|
||||
// copy the finished video frame to an output buffer. pixel format is 32bpp xrgb
|
||||
// can be called at any time, including right after sgb_take_frame
|
||||
void sgb_render_frame(uint32_t* vbuff);
|
||||
|
||||
// call to finish a frame's worth of audio. should be called once every 35112 time units (some jitter is OK)
|
||||
// callback will be called with L and R sample values for various time points
|
||||
// between the last time sgb_render_audio was called and now
|
||||
void sgb_render_audio(uint64_t time, void(*callback)(int16_t l, int16_t r, uint64_t time));
|
||||
|
|
Loading…
Reference in New Issue