Decoupling video rendering (Part 1).
This commit is contained in:
parent
435e9ee2d7
commit
92757a347f
|
@ -235,10 +235,12 @@ void power()
|
|||
INT<RESET>();
|
||||
}
|
||||
|
||||
/* Start the execution */
|
||||
void run()
|
||||
/* Run the CPU for roughly a frame */
|
||||
void run_frame()
|
||||
{
|
||||
while (true)
|
||||
unsigned remaining = 29781;
|
||||
|
||||
while (remaining--)
|
||||
{
|
||||
exec();
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ class Flags
|
|||
void set_nmi(bool v = true);
|
||||
void set_irq(bool v = true);
|
||||
void power();
|
||||
void run();
|
||||
void run_frame();
|
||||
|
||||
|
||||
}
|
||||
|
|
16
src/gui.cpp
16
src/gui.cpp
|
@ -15,8 +15,6 @@ SDL_Renderer* renderer;
|
|||
SDL_Texture* texture;
|
||||
u8 const* keys;
|
||||
|
||||
u32 pixels[width * height]; // Video buffer.
|
||||
|
||||
/* Initialize SDL */
|
||||
void init()
|
||||
{
|
||||
|
@ -37,8 +35,8 @@ void init()
|
|||
signal(SIGINT, SIG_DFL);
|
||||
}
|
||||
|
||||
/* Get the keys state from SDL */
|
||||
u8 get_keys_state(int n)
|
||||
/* Get the joypad state from SDL */
|
||||
u8 get_joypad_state(int n)
|
||||
{
|
||||
u8 j = 0;
|
||||
SDL_PumpEvents();
|
||||
|
@ -57,14 +55,8 @@ u8 get_keys_state(int n)
|
|||
return j;
|
||||
}
|
||||
|
||||
/* Draw a pixel at the given coordinates */
|
||||
void draw_pixel(unsigned x, unsigned y, u32 rgb)
|
||||
{
|
||||
pixels[y*width + x] = rgb;
|
||||
}
|
||||
|
||||
/* Put the pixels on screen */
|
||||
void flush_screen()
|
||||
/* Send the rendered frame to the GUI */
|
||||
void new_frame(u32* pixels)
|
||||
{
|
||||
SDL_UpdateTexture(texture, NULL, pixels, width * sizeof(u32));
|
||||
SDL_RenderClear(renderer);
|
||||
|
|
|
@ -5,9 +5,9 @@ namespace GUI {
|
|||
|
||||
|
||||
void init();
|
||||
u8 get_keys_state(int n);
|
||||
u8 get_joypad_state(int n);
|
||||
void draw_pixel(unsigned x, unsigned y, u32 rgb);
|
||||
void flush_screen();
|
||||
void new_frame(u32* pixels);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ u8 read_state(int n)
|
|||
{
|
||||
// When strobe is high, it keeps reading A:
|
||||
if (strobe)
|
||||
return 0x40 | (GUI::get_keys_state(n) & 1);
|
||||
return 0x40 | (GUI::get_joypad_state(n) & 1);
|
||||
|
||||
// Get the status of a button and shift the register:
|
||||
u8 j = 0x40 | (joypad_bits[n] & 1);
|
||||
|
@ -24,7 +24,7 @@ void write_strobe(bool v)
|
|||
// Read the joypad data on strobe's transition 1 -> 0.
|
||||
if (strobe and !v)
|
||||
for (int i = 0; i < 2; i++)
|
||||
joypad_bits[i] = GUI::get_keys_state(i);
|
||||
joypad_bits[i] = GUI::get_joypad_state(i);
|
||||
|
||||
strobe = v;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@ int main(int argc, char *argv[])
|
|||
Cartridge::load(argv[1]);
|
||||
CPU::power();
|
||||
|
||||
CPU::run();
|
||||
while(true)
|
||||
CPU::run_frame();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ u8 ciRam[0x800]; // VRAM for nametables.
|
|||
u8 cgRam[0x20]; // VRAM for palettes.
|
||||
u8 oamMem[0x100]; // VRAM for sprite properties.
|
||||
Sprite oam[8], secOam[8]; // Sprite buffers.
|
||||
u32 pixels[256 * 240]; // Video buffer.
|
||||
|
||||
Addr vAddr, tAddr; // Loopy V, T.
|
||||
u8 fX; // Fine X.
|
||||
|
@ -254,7 +255,7 @@ void pixel()
|
|||
// Evaluate priority:
|
||||
if (objPalette && (palette == 0 || objPriority == 0)) palette = objPalette;
|
||||
|
||||
GUI::draw_pixel(x, scanline, nesRgb[rd(0x3F00 + (rendering() ? palette : 0))]);
|
||||
pixels[scanline*256 + x] = nesRgb[rd(0x3F00 + (rendering() ? palette : 0))];
|
||||
}
|
||||
// Perform background shifts:
|
||||
bgShiftL <<= 1; bgShiftH <<= 1;
|
||||
|
@ -268,7 +269,7 @@ template<Scanline s> void scanline_cycle()
|
|||
static u16 addr;
|
||||
|
||||
if (s == NMI and dot == 1) { status.vBlank = true; if (ctrl.nmi) CPU::set_nmi(); }
|
||||
else if (s == POST and dot == 0) GUI::flush_screen();
|
||||
else if (s == POST and dot == 0) GUI::new_frame(pixels);
|
||||
else if (s == VISIBLE or s == PRE)
|
||||
{
|
||||
// Sprites:
|
||||
|
|
Reference in a new issue