- [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
This commit is contained in:
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
#include "APU.h"
|
#include "apu.h"
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
//#include "audio_viewer.h"
|
//#include "audio_viewer.h"
|
||||||
namespace APU
|
namespace apu
|
||||||
{
|
{
|
||||||
#define SAMPLING_FREQ 44100
|
#define SAMPLING_FREQ 44100
|
||||||
#define AUDIO_BUFFER_SIZE 2048
|
#define AUDIO_BUFFER_SIZE 2048
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace APU
|
namespace apu
|
||||||
{
|
{
|
||||||
uint8_t readRegister(uint16_t address);
|
uint8_t readRegister(uint16_t address);
|
||||||
void writeRegister(uint16_t address, uint8_t value);
|
void writeRegister(uint16_t address, uint8_t value);
|
||||||
@@ -4,11 +4,12 @@
|
|||||||
#include "sm83.h"
|
#include "sm83.h"
|
||||||
#include "sm83dis.h"
|
#include "sm83dis.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "APU.h"
|
#include "ppu.h"
|
||||||
|
#include "apu.h"
|
||||||
//#include "z80analyze.h"
|
//#include "z80analyze.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "ui_window.h"
|
#include "ui_window.h"
|
||||||
#include "gbscreen.h"
|
#include "display.h"
|
||||||
|
|
||||||
#define RESIZING_NONE 0
|
#define RESIZING_NONE 0
|
||||||
#define RESIZING_MEMORY 1
|
#define RESIZING_MEMORY 1
|
||||||
@@ -107,10 +108,10 @@ namespace debug
|
|||||||
con_y = win_h - con_h;
|
con_y = win_h - con_h;
|
||||||
sym_h = win_h - sym_y;
|
sym_h = win_h - sym_y;
|
||||||
debug::refresh();
|
debug::refresh();
|
||||||
gbscreen::redraw();
|
display::redraw();
|
||||||
} else if (e->window.event == SDL_WINDOWEVENT_CLOSE) {
|
} else if (e->window.event == SDL_WINDOWEVENT_CLOSE) {
|
||||||
hide();
|
hide();
|
||||||
gbscreen::focus();
|
display::focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (e->type == SDL_MOUSEWHEEL) {
|
if (e->type == SDL_MOUSEWHEEL) {
|
||||||
@@ -350,7 +351,7 @@ namespace debug
|
|||||||
|
|
||||||
void pause()
|
void pause()
|
||||||
{
|
{
|
||||||
APU::silence();
|
apu::silence();
|
||||||
is_paused = true;
|
is_paused = true;
|
||||||
breakpoints[sm83::getPC()] &= ~8;
|
breakpoints[sm83::getPC()] &= ~8;
|
||||||
}
|
}
|
||||||
@@ -358,19 +359,19 @@ namespace debug
|
|||||||
void stop()
|
void stop()
|
||||||
{
|
{
|
||||||
//history::gototop();
|
//history::gototop();
|
||||||
gbscreen::setTitle(" (stopped)");
|
display::setTitle(" (stopped)");
|
||||||
pause();
|
pause();
|
||||||
is_debugging = true;
|
is_debugging = true;
|
||||||
show();
|
show();
|
||||||
gbscreen::redraw(true);
|
display::redraw(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cont() {
|
void cont() {
|
||||||
gbscreen::setTitle("");
|
display::setTitle("");
|
||||||
is_debugging = is_paused = false;
|
is_debugging = is_paused = false;
|
||||||
refresh();
|
refresh();
|
||||||
gbscreen::focus();
|
display::focus();
|
||||||
APU::resume();
|
apu::resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool debugging() { return is_debugging; }
|
const bool debugging() { return is_debugging; }
|
||||||
@@ -779,8 +780,8 @@ namespace debug
|
|||||||
uint8_t dt = sm83::step();
|
uint8_t dt = sm83::step();
|
||||||
//zx_tape::update(dt);
|
//zx_tape::update(dt);
|
||||||
//zx_ula::sound_update(dt);
|
//zx_ula::sound_update(dt);
|
||||||
gbscreen::refresh(dt);
|
ppu::refresh(dt);
|
||||||
gbscreen::redraw();
|
display::redraw();
|
||||||
//z80analyze::refresh();
|
//z80analyze::refresh();
|
||||||
} else if (strcmp(cmd, "c")==0 || strcmp(cmd, "cont")==0) {
|
} else if (strcmp(cmd, "c")==0 || strcmp(cmd, "cont")==0) {
|
||||||
sm83::step();
|
sm83::step();
|
||||||
|
|||||||
+216
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
|
|
||||||
namespace gbscreen
|
namespace display
|
||||||
{
|
{
|
||||||
void init(int mode);
|
void init();
|
||||||
void reinit();
|
void reinit();
|
||||||
void focus();
|
void focus();
|
||||||
void refresh(const uint32_t dt, const bool full=false);
|
|
||||||
void redraw(const bool present=true);
|
void redraw(const bool present=true);
|
||||||
void present();
|
void present();
|
||||||
void setTitle(const char* title);
|
void setTitle(const char* title);
|
||||||
@@ -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
|
||||||
@@ -3,9 +3,10 @@
|
|||||||
|
|
||||||
#include "sm83.h"
|
#include "sm83.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
#include "ppu.h"
|
||||||
#include "sm83dis.h"
|
#include "sm83dis.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "gbscreen.h"
|
#include "display.h"
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
@@ -21,25 +22,25 @@ namespace actions
|
|||||||
{
|
{
|
||||||
const uint8_t dt = sm83::step();
|
const uint8_t dt = sm83::step();
|
||||||
debug::cont();
|
debug::cont();
|
||||||
gbscreen::refresh(dt);
|
ppu::refresh(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
int decZoom(int value)
|
int decZoom(int value)
|
||||||
{
|
{
|
||||||
gbscreen::decZoom();
|
display::decZoom();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int incZoom(int value)
|
int incZoom(int value)
|
||||||
{
|
{
|
||||||
gbscreen::incZoom();
|
display::incZoom();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fullscreen(int value)
|
int fullscreen(int value)
|
||||||
{
|
{
|
||||||
gbscreen::toggleFullscreen();
|
display::toggleFullscreen();
|
||||||
return gbscreen::getFullscreen();
|
return display::getFullscreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
int showAnalyzer(int value)
|
int showAnalyzer(int value)
|
||||||
@@ -72,7 +73,8 @@ int main(int argc, char *argv[])
|
|||||||
sm83dis::loadSymbols();
|
sm83dis::loadSymbols();
|
||||||
sm83::reset();
|
sm83::reset();
|
||||||
|
|
||||||
gbscreen::init(0);
|
ppu::init();
|
||||||
|
display::init();
|
||||||
debug::init();
|
debug::init();
|
||||||
|
|
||||||
ui::menu::init();
|
ui::menu::init();
|
||||||
@@ -88,7 +90,7 @@ int main(int argc, char *argv[])
|
|||||||
menu = ui::menu::addsubmenu("SCREEN");
|
menu = ui::menu::addsubmenu("SCREEN");
|
||||||
ui::menu::addoption(menu, "DEC ZOOM", actions::decZoom);
|
ui::menu::addoption(menu, "DEC ZOOM", actions::decZoom);
|
||||||
ui::menu::addoption(menu, "INC ZOOM", actions::incZoom);
|
ui::menu::addoption(menu, "INC ZOOM", actions::incZoom);
|
||||||
ui::menu::addbooloption(menu, "FULLSCREEN", gbscreen::getFullscreen(), actions::fullscreen);
|
ui::menu::addbooloption(menu, "FULLSCREEN", display::getFullscreen(), actions::fullscreen);
|
||||||
|
|
||||||
menu = ui::menu::addsubmenu("EMULATION");
|
menu = ui::menu::addsubmenu("EMULATION");
|
||||||
ui::menu::addbooloption(menu, "STOP ON INVALID OP", sm83::getOption(SM83_OPTION_STOP_ON_INVALID), actions::decZoom);
|
ui::menu::addbooloption(menu, "STOP ON INVALID OP", sm83::getOption(SM83_OPTION_STOP_ON_INVALID), actions::decZoom);
|
||||||
@@ -123,12 +125,12 @@ int main(int argc, char *argv[])
|
|||||||
debug::history::gototop();
|
debug::history::gototop();
|
||||||
const uint8_t dt = sm83::step();
|
const uint8_t dt = sm83::step();
|
||||||
debug::cont();
|
debug::cont();
|
||||||
gbscreen::refresh(dt);
|
ppu::refresh(dt);
|
||||||
}
|
}
|
||||||
} else if (e.key.keysym.scancode==SDL_SCANCODE_F8) {
|
} else if (e.key.keysym.scancode==SDL_SCANCODE_F8) {
|
||||||
if (!debug::debugging()) {
|
if (!debug::debugging()) {
|
||||||
debug::stop();
|
debug::stop();
|
||||||
gbscreen::redraw();
|
display::redraw();
|
||||||
} else {
|
} else {
|
||||||
debug::show();
|
debug::show();
|
||||||
}
|
}
|
||||||
@@ -138,8 +140,8 @@ int main(int argc, char *argv[])
|
|||||||
debug::history::gototop();
|
debug::history::gototop();
|
||||||
const uint8_t dt = sm83::step();
|
const uint8_t dt = sm83::step();
|
||||||
debug::refresh();
|
debug::refresh();
|
||||||
gbscreen::refresh(dt);
|
ppu::refresh(dt);
|
||||||
gbscreen::redraw();
|
display::redraw();
|
||||||
//z80analyze::refresh();
|
//z80analyze::refresh();
|
||||||
}
|
}
|
||||||
} else if (e.key.keysym.scancode==SDL_SCANCODE_F11) {
|
} else if (e.key.keysym.scancode==SDL_SCANCODE_F11) {
|
||||||
@@ -148,8 +150,8 @@ int main(int argc, char *argv[])
|
|||||||
debug::history::gototop();
|
debug::history::gototop();
|
||||||
const uint8_t dt = debug::next();
|
const uint8_t dt = debug::next();
|
||||||
debug::refresh();
|
debug::refresh();
|
||||||
gbscreen::refresh(dt);
|
ppu::refresh(dt);
|
||||||
gbscreen::redraw();
|
display::redraw();
|
||||||
//z80analyze::refresh();
|
//z80analyze::refresh();
|
||||||
}
|
}
|
||||||
} else if (e.key.keysym.scancode==SDL_SCANCODE_F12) {
|
} else if (e.key.keysym.scancode==SDL_SCANCODE_F12) {
|
||||||
@@ -158,8 +160,8 @@ int main(int argc, char *argv[])
|
|||||||
debug::history::gototop();
|
debug::history::gototop();
|
||||||
const uint8_t dt = debug::stepout();
|
const uint8_t dt = debug::stepout();
|
||||||
debug::refresh();
|
debug::refresh();
|
||||||
gbscreen::refresh(dt);
|
ppu::refresh(dt);
|
||||||
gbscreen::redraw();
|
display::redraw();
|
||||||
//z80analyze::refresh();
|
//z80analyze::refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,13 +180,13 @@ int main(int argc, char *argv[])
|
|||||||
for (int i=0;i<20;++i) {
|
for (int i=0;i<20;++i) {
|
||||||
if (debug::isbreak(sm83::getPC(), 9)) {
|
if (debug::isbreak(sm83::getPC(), 9)) {
|
||||||
debug::stop();
|
debug::stop();
|
||||||
gbscreen::redraw();
|
display::redraw();
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
uint8_t dt = sm83::step();
|
uint8_t dt = sm83::step();
|
||||||
t_states += dt;
|
t_states += dt;
|
||||||
//zx_ula::sound_update(dt);
|
//zx_ula::sound_update(dt);
|
||||||
gbscreen::refresh(dt);
|
ppu::refresh(dt);
|
||||||
if (debug::debugging()) break;
|
if (debug::debugging()) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,9 +202,9 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
|
|
||||||
} else if (!debug::debugging() && debug::paused()) {
|
} else if (!debug::debugging() && debug::paused()) {
|
||||||
gbscreen::redraw(false);
|
display::redraw(false);
|
||||||
ui::menu::show();
|
ui::menu::show();
|
||||||
gbscreen::present();
|
display::present();
|
||||||
}
|
}
|
||||||
ui::setClicked(false);
|
ui::setClicked(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include "APU.h"
|
#include "apu.h"
|
||||||
|
|
||||||
#include "mbc_none.h"
|
#include "mbc_none.h"
|
||||||
#include "mbc1.h"
|
#include "mbc1.h"
|
||||||
@@ -86,7 +86,7 @@ namespace mem
|
|||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
APU::init();
|
apu::init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
@@ -105,7 +105,7 @@ namespace mem
|
|||||||
for (int i=0; i<65536; ++i) { tags[i] = MEMTAG_NONE; }
|
for (int i=0; i<65536; ++i) { tags[i] = MEMTAG_NONE; }
|
||||||
|
|
||||||
resetMbc();
|
resetMbc();
|
||||||
APU::reset();
|
apu::reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t getKeypad(uint8_t value)
|
uint8_t getKeypad(uint8_t value)
|
||||||
@@ -144,7 +144,7 @@ namespace mem
|
|||||||
} else {
|
} else {
|
||||||
if (address==0xFF00) {
|
if (address==0xFF00) {
|
||||||
hram[address - 0XFE00] = getKeypad(hram[address - 0XFE00]);
|
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];
|
return hram[address - 0XFE00];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,7 +174,7 @@ namespace mem
|
|||||||
sm83::processInterrupts();
|
sm83::processInterrupts();
|
||||||
return;
|
return;
|
||||||
} else if (address>=0xFF10 && address<=0xFF3F) { // APU
|
} else if (address>=0xFF10 && address<=0xFF3F) { // APU
|
||||||
APU::writeRegister(address, value);
|
apu::writeRegister(address, value);
|
||||||
return;
|
return;
|
||||||
} else if ( (address==0xFF46) ) { // OAM DMA
|
} else if ( (address==0xFF46) ) { // OAM DMA
|
||||||
mem::init_dma_transfer(value);
|
mem::init_dma_transfer(value);
|
||||||
@@ -235,7 +235,7 @@ namespace mem
|
|||||||
div_counter -= 256;
|
div_counter -= 256;
|
||||||
bool bitset = DIV&0x10;
|
bool bitset = DIV&0x10;
|
||||||
DIV++;
|
DIV++;
|
||||||
if (bitset && !(DIV&0x10)) APU::incDIVAPU();
|
if (bitset && !(DIV&0x10)) apu::incDIVAPU();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timer
|
// Timer
|
||||||
@@ -255,7 +255,7 @@ namespace mem
|
|||||||
}
|
}
|
||||||
|
|
||||||
// APU
|
// APU
|
||||||
APU::update(dt);
|
apu::update(dt);
|
||||||
|
|
||||||
// OAM DMA
|
// OAM DMA
|
||||||
if (dma_pos<160) {
|
if (dma_pos<160) {
|
||||||
|
|||||||
+10
-217
@@ -1,46 +1,22 @@
|
|||||||
#include "gbscreen.h"
|
#include "ppu.h"
|
||||||
#include <cstring>
|
|
||||||
#include "sm83.h"
|
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "audio_viewer.h"
|
#include "interrupts.h"
|
||||||
//#include "zx_ula.h"
|
#include "display.h"
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
#include "ui_window.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "ui.h"
|
|
||||||
|
|
||||||
namespace gbscreen
|
namespace ppu
|
||||||
{
|
{
|
||||||
struct oam_entry_t
|
struct oam_entry_t
|
||||||
{
|
{
|
||||||
uint8_t y, x, tile, attr;
|
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_total = 70224;
|
||||||
uint32_t t_states_per_scanline = 456;
|
uint32_t t_states_per_scanline = 456;
|
||||||
uint32_t vsync_lines = 10;
|
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;
|
uint32_t t_screen = 0;
|
||||||
|
|
||||||
uint8_t gb_pixels[160*144];
|
uint8_t pixels[160*144];
|
||||||
|
|
||||||
uint16_t dots_in_scanline = 0;
|
uint16_t dots_in_scanline = 0;
|
||||||
uint8_t line_buffer[160];
|
uint8_t line_buffer[160];
|
||||||
@@ -72,85 +48,8 @@ namespace gbscreen
|
|||||||
#define IF 0xff0f
|
#define IF 0xff0f
|
||||||
bool last_interrupt_lcd_state = false;
|
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);
|
_LCDC = mem::rawHram(0xff40);
|
||||||
_STAT = mem::rawHram(0xff41);
|
_STAT = mem::rawHram(0xff41);
|
||||||
_SCY = mem::rawHram(0xff42);
|
_SCY = mem::rawHram(0xff42);
|
||||||
@@ -164,22 +63,6 @@ namespace gbscreen
|
|||||||
|
|
||||||
oam = (oam_entry_t*)mem::rawHram(0xfe00);
|
oam = (oam_entry_t*)mem::rawHram(0xfe00);
|
||||||
vram = mem::rawVram();
|
vram = mem::rawVram();
|
||||||
|
|
||||||
focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
void init(int mode)
|
|
||||||
{
|
|
||||||
reinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void focus()
|
|
||||||
{
|
|
||||||
if (win)
|
|
||||||
{
|
|
||||||
SDL_RaiseWindow(win);
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill_line_buffer_bkg()
|
void fill_line_buffer_bkg()
|
||||||
@@ -324,8 +207,7 @@ namespace gbscreen
|
|||||||
if ( (STAT&0x3)==3) {
|
if ( (STAT&0x3)==3) {
|
||||||
uint16_t current_pixel = dots_in_scanline-80;
|
uint16_t current_pixel = dots_in_scanline-80;
|
||||||
if (current_pixel<160) {
|
if (current_pixel<160) {
|
||||||
//uint8_t pixel = gb_pixels[current_pixel+LY*160];
|
pixels[current_pixel+LY*160] = line_buffer[current_pixel];
|
||||||
gb_pixels[current_pixel+LY*160] = line_buffer[current_pixel];// > line_buffer[current_pixel] ? pixel-1 : line_buffer[current_pixel];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,102 +270,13 @@ namespace gbscreen
|
|||||||
if (t_screen>=t_states_total)
|
if (t_screen>=t_states_total)
|
||||||
{
|
{
|
||||||
t_screen-=t_states_total;
|
t_screen-=t_states_total;
|
||||||
redraw();
|
display::redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void redraw(const bool present)
|
const uint8_t *getpixels()
|
||||||
{
|
{
|
||||||
//if (zx_tape::getplaying() && zx_tape::getOption(ZXTAPE_OPTION_FAST_LOAD)) return;
|
return pixels;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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,15 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "interrupts.h"
|
||||||
|
|
||||||
namespace sm83
|
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_STOP_ON_INVALID 0
|
||||||
#define SM83_OPTION_BREAK_ON_INTERRUPT 1
|
#define SM83_OPTION_BREAK_ON_INTERRUPT 1
|
||||||
#define SM83_OPTION_BREAK_ON_RET 2
|
#define SM83_OPTION_BREAK_ON_RET 2
|
||||||
|
|||||||
Reference in New Issue
Block a user