Compare commits

...

2 Commits

Author SHA1 Message Date
JailDoctor 88a02d49f7 - [CHG] Separat mòdul "gbscreen" en mòduls "ppu" i "display"
- [CHG] Constants de interrupcions tretes a la seua propia capçalera
- [CHG] Renombrat mòdul APU a apu
2026-06-03 12:10:42 +02:00
JailDoctor 816b12e3b8 - [FIX] Més neteja: llevats els refresh de gbscreen que no s'usaven 2026-06-03 11:37:46 +02:00
12 changed files with 304 additions and 329 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
#include "APU.h"
#include "apu.h"
#include <SDL2/SDL.h>
//#include "audio_viewer.h"
namespace APU
namespace apu
{
#define SAMPLING_FREQ 44100
#define AUDIO_BUFFER_SIZE 2048
+1 -1
View File
@@ -1,7 +1,7 @@
#pragma once
#include <stdint.h>
namespace APU
namespace apu
{
uint8_t readRegister(uint16_t address);
void writeRegister(uint16_t address, uint8_t value);
+13 -13
View File
@@ -4,11 +4,12 @@
#include "sm83.h"
#include "sm83dis.h"
#include "mem.h"
#include "APU.h"
#include "ppu.h"
#include "apu.h"
//#include "z80analyze.h"
#include "ui.h"
#include "ui_window.h"
#include "gbscreen.h"
#include "display.h"
#define RESIZING_NONE 0
#define RESIZING_MEMORY 1
@@ -107,10 +108,10 @@ namespace debug
con_y = win_h - con_h;
sym_h = win_h - sym_y;
debug::refresh();
gbscreen::redraw();
display::redraw();
} else if (e->window.event == SDL_WINDOWEVENT_CLOSE) {
hide();
gbscreen::focus();
display::focus();
}
}
if (e->type == SDL_MOUSEWHEEL) {
@@ -350,7 +351,7 @@ namespace debug
void pause()
{
APU::silence();
apu::silence();
is_paused = true;
breakpoints[sm83::getPC()] &= ~8;
}
@@ -358,20 +359,19 @@ namespace debug
void stop()
{
//history::gototop();
gbscreen::setTitle(" (stopped)");
display::setTitle(" (stopped)");
pause();
is_debugging = true;
show();
gbscreen::redraw(true);
//if ( gbscreen::getFullRefresh()) gbscreen::fullrefresh();
display::redraw(true);
}
void cont() {
gbscreen::setTitle("");
display::setTitle("");
is_debugging = is_paused = false;
refresh();
gbscreen::focus();
APU::resume();
display::focus();
apu::resume();
}
const bool debugging() { return is_debugging; }
@@ -780,8 +780,8 @@ namespace debug
uint8_t dt = sm83::step();
//zx_tape::update(dt);
//zx_ula::sound_update(dt);
gbscreen::refresh(dt);
gbscreen::redraw();
ppu::refresh(dt);
display::redraw();
//z80analyze::refresh();
} else if (strcmp(cmd, "c")==0 || strcmp(cmd, "cont")==0) {
sm83::step();
+216
View File
@@ -0,0 +1,216 @@
#include "display.h"
#include <cstring>
#include "sm83.h"
#include "ppu.h"
#include <SDL2/SDL.h>
#include "ui_window.h"
#include "debug.h"
#include "ui.h"
namespace display
{
uint32_t palette[2][4] = {
{ 0xFFFFFF, 0xAAAAAA, 0x555555, 0x000000 },
{ 0xA0AA05, 0x749527, 0x487F49, 0x2E4326/*0x1D6A6B*/ }
};
SDL_Window *win = nullptr;
SDL_Renderer *ren = nullptr;
SDL_Texture *tex = nullptr;
SDL_Texture *uitex = nullptr;
uint8_t zoom = 3;
uint8_t use_palette=1;
bool fullscreen = false;
int fullscreen_scale = 1;
SDL_Rect dest_rect;
bool eventHandler(SDL_Event *e)
{
if (e->type==SDL_WINDOWEVENT) {
if (e->window.event==SDL_WINDOWEVENT_CLOSE) {
return false;
} else if ((e->window.event==SDL_WINDOWEVENT_SHOWN) || (e->window.event==SDL_WINDOWEVENT_EXPOSED)) {
redraw();
}
}
if (!debug::debugging()) {
if (debug::paused()) {
if (e->type == SDL_KEYDOWN) {
if (e->key.keysym.scancode==SDL_SCANCODE_ESCAPE) {
const uint8_t dt = sm83::step();
debug::cont();
ppu::refresh(dt);
}
}
} else {
if (e->type == SDL_KEYDOWN) {
if (e->key.keysym.scancode==SDL_SCANCODE_ESCAPE) {
debug::pause();
display::redraw();
} else if (e->key.keysym.scancode==SDL_SCANCODE_F1) {
display::decZoom();
} else if (e->key.keysym.scancode==SDL_SCANCODE_F2) {
display::incZoom();
} else if (e->key.keysym.scancode==SDL_SCANCODE_F3) {
display::toggleFullscreen();
} else if (e->key.keysym.scancode==SDL_SCANCODE_F6) {
//zx_tape::play();
} else if (e->key.keysym.scancode==SDL_SCANCODE_F7) {
//zx_tape::rewind();
} else if (e->key.keysym.scancode==SDL_SCANCODE_Q && e->key.keysym.mod & KMOD_CTRL) {
return false;
}
}
}
}
if (e->type == SDL_MOUSEMOTION) {
SDL_ShowCursor(true);
}
return true;
}
void reinit()
{
if (win) ui::window::unregisterWindow(SDL_GetWindowID(win));
if (tex) SDL_DestroyTexture(tex);
if (uitex) SDL_DestroyTexture(uitex);
if (ren) SDL_DestroyRenderer(ren);
if (win) SDL_DestroyWindow(win);
const int z = fullscreen ? 1 : zoom;
win = SDL_CreateWindow("Gameboy Screen", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 160*z, 144*z, fullscreen?SDL_WINDOW_FULLSCREEN_DESKTOP:SDL_WINDOW_SHOWN);
ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 160, 144);
uitex = ui::createtexture(ren);
ui::window::registerWindow(SDL_GetWindowID(win), eventHandler);
if (fullscreen)
{
int w, h;
SDL_GetWindowSize(win, &w, &h);
fullscreen_scale = h/144;
dest_rect.w = 160 * fullscreen_scale;
dest_rect.h = 144 * fullscreen_scale;
dest_rect.x = (w - dest_rect.w)/2;
dest_rect.y = (h - dest_rect.h)/2;
}
else
{
dest_rect.x = dest_rect.y = 0;
dest_rect.w = 160 * zoom;
dest_rect.h = 144 * zoom;
}
focus();
}
void init()
{
reinit();
}
void focus()
{
if (win)
{
SDL_RaiseWindow(win);
redraw();
}
}
void redraw(const bool present)
{
//if (zx_tape::getplaying() && zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD)) return;
ui::setrenderer(ren, uitex);
const uint8_t *ppu_pixels = ppu::getpixels();
Uint32* pixels;
int pitch;
SDL_LockTexture(tex, NULL, (void**)&pixels, &pitch);
for (int i=0; i<160*144;++i) *(pixels++) = palette[use_palette][ppu_pixels[i]];
SDL_UnlockTexture(tex);
if (fullscreen)
{
SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
SDL_RenderClear(ren);
}
// Pintem la textura a pantalla
SDL_RenderCopy(ren, tex, NULL, &dest_rect);
// Pintem les ralles dels pixels
if (zoom>2 || fullscreen) {
SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(ren, 160, 170, 5, 96);
const float scale = fullscreen ? fullscreen_scale : zoom;
for (int i=0;i<144;++i) SDL_RenderDrawLine(ren, dest_rect.x, dest_rect.y+i*scale, dest_rect.x+159*scale, dest_rect.y+i*scale);
for (int i=0;i<160;++i) SDL_RenderDrawLine(ren, dest_rect.x+i*scale, dest_rect.y, dest_rect.x+i*scale, dest_rect.y+143*scale);
}
if (present)
SDL_RenderPresent(ren);
else
{
SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(ren, 0, 0, 0, 128);
SDL_Rect rect {0,0,160*zoom,144*zoom};
if (fullscreen) SDL_GetWindowSize(win, &rect.w, &rect.h);
SDL_RenderFillRect(ren, &rect);
}
}
void present()
{
SDL_RenderPresent(ren);
}
void setTitle(const char* title)
{
char tmp[256];
strcpy(tmp, "Gameboy Screen");
strcat(tmp, title);
SDL_SetWindowTitle(win, tmp);
}
void setZoom(const int value)
{
if (fullscreen) return;
if (value < 1) return;
SDL_DisplayMode dm;
SDL_GetCurrentDisplayMode(0, &dm);
if (160*value > dm.w) return;
if (144*value > dm.h) return;
zoom = value;
reinit();
}
void incZoom()
{
if (fullscreen) return;
setZoom(zoom+1);
}
void decZoom()
{
if (fullscreen) return;
setZoom(zoom-1);
}
void toggleFullscreen()
{
fullscreen = !fullscreen;
reinit();
}
const bool getFullscreen()
{
return fullscreen;
}
}
+16
View File
@@ -0,0 +1,16 @@
#pragma once
namespace display
{
void init();
void reinit();
void focus();
void redraw(const bool present=true);
void present();
void setTitle(const char* title);
void incZoom();
void decZoom();
void toggleFullscreen();
const bool getFullscreen();
}
-25
View File
@@ -1,25 +0,0 @@
#pragma once
#include <SDL2/SDL.h>
namespace gbscreen
{
void init(int mode);
void reinit();
void focus();
void refresh(const uint32_t dt, const bool full=false);
void fullrefresh();
void debugrefresh();
void redraw(const bool present=true);
void present();
void setTitle(const char* title);
void incZoom();
void decZoom();
void toggleFullscreen();
const bool getFullscreen();
void toggleFullRefresh();
const bool getFullRefresh();
//SDL_Renderer *getrenderer();
}
+7
View File
@@ -0,0 +1,7 @@
#pragma once
#define INTERRUPT_VBLANK 0x01
#define INTERRUPT_LCD 0x02
#define INTERRUPT_TIMER 0x04
#define INTERRUPT_SERIAL 0x08
#define INTERRUPT_JOYPAD 0x10
+22 -29
View File
@@ -3,9 +3,10 @@
#include "sm83.h"
#include "mem.h"
#include "ppu.h"
#include "sm83dis.h"
#include "debug.h"
#include "gbscreen.h"
#include "display.h"
#include <SDL2/SDL.h>
#include <string.h>
#include "ui.h"
@@ -21,31 +22,25 @@ namespace actions
{
const uint8_t dt = sm83::step();
debug::cont();
gbscreen::refresh(dt);
ppu::refresh(dt);
}
int decZoom(int value)
{
gbscreen::decZoom();
display::decZoom();
return 0;
}
int incZoom(int value)
{
gbscreen::incZoom();
display::incZoom();
return 0;
}
int fullscreen(int value)
{
gbscreen::toggleFullscreen();
return gbscreen::getFullscreen();
}
int fullrefresh(int value)
{
gbscreen::toggleFullRefresh();
return gbscreen::getFullRefresh();
display::toggleFullscreen();
return display::getFullscreen();
}
int showAnalyzer(int value)
@@ -78,7 +73,8 @@ int main(int argc, char *argv[])
sm83dis::loadSymbols();
sm83::reset();
gbscreen::init(0);
ppu::init();
display::init();
debug::init();
ui::menu::init();
@@ -94,9 +90,7 @@ int main(int argc, char *argv[])
menu = ui::menu::addsubmenu("SCREEN");
ui::menu::addoption(menu, "DEC ZOOM", actions::decZoom);
ui::menu::addoption(menu, "INC ZOOM", actions::incZoom);
ui::menu::addbooloption(menu, "FULLSCREEN", gbscreen::getFullscreen(), actions::fullscreen);
ui::menu::addseparator(menu);
ui::menu::addbooloption(menu, "FULL REFRESH", gbscreen::getFullRefresh(), actions::fullrefresh);
ui::menu::addbooloption(menu, "FULLSCREEN", display::getFullscreen(), actions::fullscreen);
menu = ui::menu::addsubmenu("EMULATION");
ui::menu::addbooloption(menu, "STOP ON INVALID OP", sm83::getOption(SM83_OPTION_STOP_ON_INVALID), actions::decZoom);
@@ -131,12 +125,12 @@ int main(int argc, char *argv[])
debug::history::gototop();
const uint8_t dt = sm83::step();
debug::cont();
gbscreen::refresh(dt);
ppu::refresh(dt);
}
} else if (e.key.keysym.scancode==SDL_SCANCODE_F8) {
if (!debug::debugging()) {
debug::stop();
gbscreen::redraw();
display::redraw();
} else {
debug::show();
}
@@ -146,9 +140,8 @@ int main(int argc, char *argv[])
debug::history::gototop();
const uint8_t dt = sm83::step();
debug::refresh();
//gbscreen::fullrefresh();
gbscreen::refresh(dt);
gbscreen::redraw();
ppu::refresh(dt);
display::redraw();
//z80analyze::refresh();
}
} else if (e.key.keysym.scancode==SDL_SCANCODE_F11) {
@@ -157,8 +150,8 @@ int main(int argc, char *argv[])
debug::history::gototop();
const uint8_t dt = debug::next();
debug::refresh();
gbscreen::refresh(dt);
gbscreen::redraw();
ppu::refresh(dt);
display::redraw();
//z80analyze::refresh();
}
} else if (e.key.keysym.scancode==SDL_SCANCODE_F12) {
@@ -167,8 +160,8 @@ int main(int argc, char *argv[])
debug::history::gototop();
const uint8_t dt = debug::stepout();
debug::refresh();
gbscreen::refresh(dt);
gbscreen::redraw();
ppu::refresh(dt);
display::redraw();
//z80analyze::refresh();
}
}
@@ -187,13 +180,13 @@ int main(int argc, char *argv[])
for (int i=0;i<20;++i) {
if (debug::isbreak(sm83::getPC(), 9)) {
debug::stop();
gbscreen::redraw();
display::redraw();
break;
} else {
uint8_t dt = sm83::step();
t_states += dt;
//zx_ula::sound_update(dt);
gbscreen::refresh(dt);
ppu::refresh(dt);
if (debug::debugging()) break;
}
}
@@ -209,9 +202,9 @@ int main(int argc, char *argv[])
} else if (!debug::debugging() && debug::paused()) {
gbscreen::redraw(false);
display::redraw(false);
ui::menu::show();
gbscreen::present();
display::present();
}
ui::setClicked(false);
}
+7 -7
View File
@@ -3,7 +3,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <SDL2/SDL.h>
#include "APU.h"
#include "apu.h"
#include "mbc_none.h"
#include "mbc1.h"
@@ -86,7 +86,7 @@ namespace mem
break;
};
APU::init();
apu::init();
}
void reset()
@@ -105,7 +105,7 @@ namespace mem
for (int i=0; i<65536; ++i) { tags[i] = MEMTAG_NONE; }
resetMbc();
APU::reset();
apu::reset();
}
uint8_t getKeypad(uint8_t value)
@@ -144,7 +144,7 @@ namespace mem
} else {
if (address==0xFF00) {
hram[address - 0XFE00] = getKeypad(hram[address - 0XFE00]);
} else if (address>=0xFF10 && address<=0xFF3F) { return APU::readRegister(address); }
} else if (address>=0xFF10 && address<=0xFF3F) { return apu::readRegister(address); }
return hram[address - 0XFE00];
}
}
@@ -174,7 +174,7 @@ namespace mem
sm83::processInterrupts();
return;
} else if (address>=0xFF10 && address<=0xFF3F) { // APU
APU::writeRegister(address, value);
apu::writeRegister(address, value);
return;
} else if ( (address==0xFF46) ) { // OAM DMA
mem::init_dma_transfer(value);
@@ -235,7 +235,7 @@ namespace mem
div_counter -= 256;
bool bitset = DIV&0x10;
DIV++;
if (bitset && !(DIV&0x10)) APU::incDIVAPU();
if (bitset && !(DIV&0x10)) apu::incDIVAPU();
}
// Timer
@@ -255,7 +255,7 @@ namespace mem
}
// APU
APU::update(dt);
apu::update(dt);
// OAM DMA
if (dma_pos<160) {
+10 -246
View File
@@ -1,46 +1,22 @@
#include "gbscreen.h"
#include <cstring>
#include "sm83.h"
#include "ppu.h"
#include "mem.h"
#include "audio_viewer.h"
//#include "zx_ula.h"
#include <SDL2/SDL.h>
#include "ui_window.h"
#include "debug.h"
#include "ui.h"
#include "interrupts.h"
#include "display.h"
namespace gbscreen
namespace ppu
{
struct oam_entry_t
{
uint8_t y, x, tile, attr;
};
uint32_t palette[2][4] = {
{ 0xFFFFFF, 0xAAAAAA, 0x555555, 0x000000 },
{ 0xA0AA05, 0x749527, 0x487F49, 0x2E4326/*0x1D6A6B*/ }
};
SDL_Window *win = nullptr;
SDL_Renderer *ren = nullptr;
SDL_Texture *tex = nullptr;
SDL_Texture *uitex = nullptr;
uint32_t t_states_total = 70224;
uint32_t t_states_per_scanline = 456;
uint32_t vsync_lines = 10;
uint8_t zoom = 3;
uint8_t use_palette=1;
bool fullscreen = false;
bool full_refresh = true;
int fullscreen_scale = 1;
SDL_Rect dest_rect;
//uint32_t time=0;
uint32_t t_screen = 0;
uint8_t gb_pixels[160*144];
uint8_t pixels[160*144];
uint16_t dots_in_scanline = 0;
uint8_t line_buffer[160];
@@ -72,85 +48,8 @@ namespace gbscreen
#define IF 0xff0f
bool last_interrupt_lcd_state = false;
bool eventHandler(SDL_Event *e)
void init()
{
if (e->type==SDL_WINDOWEVENT) {
if (e->window.event==SDL_WINDOWEVENT_CLOSE) {
return false;
} else if ((e->window.event==SDL_WINDOWEVENT_SHOWN) || (e->window.event==SDL_WINDOWEVENT_EXPOSED)) {
redraw();
}
}
if (!debug::debugging()) {
if (debug::paused()) {
if (e->type == SDL_KEYDOWN) {
if (e->key.keysym.scancode==SDL_SCANCODE_ESCAPE) {
const uint8_t dt = sm83::step();
debug::cont();
gbscreen::refresh(dt);
}
}
} else {
if (e->type == SDL_KEYDOWN) {
if (e->key.keysym.scancode==SDL_SCANCODE_ESCAPE) {
debug::pause();
gbscreen::redraw();
} else if (e->key.keysym.scancode==SDL_SCANCODE_F1) {
gbscreen::decZoom();
} else if (e->key.keysym.scancode==SDL_SCANCODE_F2) {
gbscreen::incZoom();
} else if (e->key.keysym.scancode==SDL_SCANCODE_F3) {
gbscreen::toggleFullscreen();
} else if (e->key.keysym.scancode==SDL_SCANCODE_F6) {
//zx_tape::play();
} else if (e->key.keysym.scancode==SDL_SCANCODE_F7) {
//zx_tape::rewind();
} else if (e->key.keysym.scancode==SDL_SCANCODE_Q && e->key.keysym.mod & KMOD_CTRL) {
return false;
}
}
}
}
if (e->type == SDL_MOUSEMOTION) {
SDL_ShowCursor(true);
}
return true;
}
void reinit()
{
if (win) ui::window::unregisterWindow(SDL_GetWindowID(win));
if (tex) SDL_DestroyTexture(tex);
if (uitex) SDL_DestroyTexture(uitex);
if (ren) SDL_DestroyRenderer(ren);
if (win) SDL_DestroyWindow(win);
const int z = fullscreen ? 1 : zoom;
win = SDL_CreateWindow("Gameboy Screen", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 160*z, 144*z, fullscreen?SDL_WINDOW_FULLSCREEN_DESKTOP:SDL_WINDOW_SHOWN);
ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 160, 144);
uitex = ui::createtexture(ren);
ui::window::registerWindow(SDL_GetWindowID(win), eventHandler);
if (fullscreen)
{
int w, h;
SDL_GetWindowSize(win, &w, &h);
fullscreen_scale = h/144;
dest_rect.w = 160 * fullscreen_scale;
dest_rect.h = 144 * fullscreen_scale;
dest_rect.x = (w - dest_rect.w)/2;
dest_rect.y = (h - dest_rect.h)/2;
}
else
{
dest_rect.x = dest_rect.y = 0;
dest_rect.w = 160 * zoom;
dest_rect.h = 144 * zoom;
}
_LCDC = mem::rawHram(0xff40);
_STAT = mem::rawHram(0xff41);
_SCY = mem::rawHram(0xff42);
@@ -164,24 +63,8 @@ namespace gbscreen
oam = (oam_entry_t*)mem::rawHram(0xfe00);
vram = mem::rawVram();
focus();
}
void init(int mode)
{
reinit();
}
void focus()
{
if (win)
{
SDL_RaiseWindow(win);
redraw();
}
}
void fill_line_buffer_bkg()
{
if ((LCDC & 0x1) == 0) {
@@ -324,8 +207,7 @@ namespace gbscreen
if ( (STAT&0x3)==3) {
uint16_t current_pixel = dots_in_scanline-80;
if (current_pixel<160) {
//uint8_t pixel = gb_pixels[current_pixel+LY*160];
gb_pixels[current_pixel+LY*160] = line_buffer[current_pixel];// > line_buffer[current_pixel] ? pixel-1 : line_buffer[current_pixel];
pixels[current_pixel+LY*160] = line_buffer[current_pixel];
}
}
@@ -388,131 +270,13 @@ namespace gbscreen
if (t_screen>=t_states_total)
{
t_screen-=t_states_total;
redraw();
display::redraw();
}
}
}
void fullrefresh()
const uint8_t *getpixels()
{
uint32_t tmp = t_screen;
t_screen = 0;
refresh(t_states_total, true);
t_screen = tmp;
return pixels;
}
void debugrefresh(const uint32_t dt)
{
/*if (full_refresh) fullrefresh(); else*/ refresh(dt);
redraw();
}
void redraw(const bool present)
{
//if (zx_tape::getplaying() && zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD)) return;
ui::setrenderer(ren, uitex);
Uint32* pixels;
int pitch;
SDL_LockTexture(tex, NULL, (void**)&pixels, &pitch);
for (int i=0; i<160*144;++i) *(pixels++) = palette[use_palette][gb_pixels[i]];
SDL_UnlockTexture(tex);
if (fullscreen)
{
SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
SDL_RenderClear(ren);
}
// Pintem la textura a pantalla
SDL_RenderCopy(ren, tex, NULL, &dest_rect);
// Pintem les ralles dels pixels
if (zoom>2 || fullscreen) {
SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(ren, 160, 170, 5, 96);
const float scale = fullscreen ? fullscreen_scale : zoom;
for (int i=0;i<144;++i) SDL_RenderDrawLine(ren, dest_rect.x, dest_rect.y+i*scale, dest_rect.x+159*scale, dest_rect.y+i*scale);
for (int i=0;i<160;++i) SDL_RenderDrawLine(ren, dest_rect.x+i*scale, dest_rect.y, dest_rect.x+i*scale, dest_rect.y+143*scale);
}
if (present)
SDL_RenderPresent(ren);
else
{
SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(ren, 0, 0, 0, 128);
SDL_Rect rect {0,0,160*zoom,144*zoom};
if (fullscreen) SDL_GetWindowSize(win, &rect.w, &rect.h);
SDL_RenderFillRect(ren, &rect);
}
//audio_viewer::refresh();
}
void present()
{
SDL_RenderPresent(ren);
}
void setTitle(const char* title)
{
char tmp[256];
strcpy(tmp, "Gameboy Screen");
strcat(tmp, title);
SDL_SetWindowTitle(win, tmp);
}
void setZoom(const int value)
{
if (fullscreen) return;
if (value < 1) return;
SDL_DisplayMode dm;
SDL_GetCurrentDisplayMode(0, &dm);
if (160*value > dm.w) return;
if (144*value > dm.h) return;
zoom = value;
reinit();
}
void incZoom()
{
if (fullscreen) return;
setZoom(zoom+1);
}
void decZoom()
{
if (fullscreen) return;
setZoom(zoom-1);
}
void toggleFullscreen()
{
fullscreen = !fullscreen;
reinit();
}
const bool getFullscreen()
{
return fullscreen;
}
void toggleFullRefresh()
{
full_refresh = !full_refresh;
}
const bool getFullRefresh()
{
return full_refresh;
}
//SDL_Renderer *getrenderer()
//{
// return ren;
//}
}
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include <stdint.h>
namespace ppu
{
void init();
void refresh(const uint32_t dt, const bool full=false);
const uint8_t *getpixels();
}
+1 -6
View File
@@ -1,15 +1,10 @@
#pragma once
#include <stdint.h>
#include "interrupts.h"
namespace sm83
{
#define INTERRUPT_VBLANK 0x01
#define INTERRUPT_LCD 0x02
#define INTERRUPT_TIMER 0x04
#define INTERRUPT_SERIAL 0x08
#define INTERRUPT_JOYPAD 0x10
#define SM83_OPTION_STOP_ON_INVALID 0
#define SM83_OPTION_BREAK_ON_INTERRUPT 1
#define SM83_OPTION_BREAK_ON_RET 2