diff --git a/Makefile b/Makefile index 7b5b1d4..0fa2868 100644 --- a/Makefile +++ b/Makefile @@ -12,3 +12,6 @@ debug1: compile release: g++ -O3 *.cpp -lSDL2 -o gb + +profile: + g++ -g *.cpp -lSDL2 -o gb -pg diff --git a/gbscreen.cpp b/gbscreen.cpp index 3addeea..abb31dd 100644 --- a/gbscreen.cpp +++ b/gbscreen.cpp @@ -11,6 +11,11 @@ namespace gbscreen { + struct oam_entry_t + { + uint8_t y, x, tile, attr; + }; + uint32_t palette[4] = { //0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF 0xFFFFFF, 0xAAAAAA, 0x555555, 0x000000 @@ -35,11 +40,35 @@ namespace gbscreen uint32_t t_screen = 0; uint8_t gb_pixels[160*144]; - uint8_t *ptr_pixel = gb_pixels; uint16_t dots_in_scanline = 0; uint8_t line_buffer[160]; + uint8_t *_LCDC = nullptr; + uint8_t *_STAT = nullptr; + uint8_t *_SCY = nullptr; + uint8_t *_SCX = nullptr; + uint8_t *_LY = nullptr; + uint8_t *_LYC = nullptr; + uint8_t *_BGP = nullptr; + uint8_t *_WY = nullptr; + uint8_t *_WX = nullptr; + uint8_t *OBP = nullptr; + + oam_entry_t *oam = nullptr; + uint8_t *vram = nullptr; + + #define LCDC (*_LCDC) + #define STAT (*_STAT) + #define SCY (*_SCY) + #define SCX (*_SCX) + #define LY (*_LY) + #define LYC (*_LYC) + #define BGP (*_BGP) + #define WY (*_WY) + #define WX (*_WX) + + bool eventHandler(SDL_Event *e) { if (e->type==SDL_WINDOWEVENT) { @@ -117,6 +146,20 @@ namespace gbscreen dest_rect.h = 144 * zoom; } + _LCDC = mem::rawHram(0xff40); + _STAT = mem::rawHram(0xff41); + _SCY = mem::rawHram(0xff42); + _SCX = mem::rawHram(0xff43); + _LY = mem::rawHram(0xff44); + _LYC = mem::rawHram(0xff45); + _BGP = mem::rawHram(0xff47); + _WY = mem::rawHram(0xff4a); + _WX = mem::rawHram(0xff4b); + OBP = mem::rawHram(0xff48); + + oam = (oam_entry_t*)mem::rawHram(0xfe00); + vram = mem::rawVram(); + focus(); } @@ -133,34 +176,30 @@ namespace gbscreen redraw(); } } - - void fill_line_buffer_bkg(uint8_t LY) + + void fill_line_buffer_bkg() { - const uint8_t LCDC = mem::readMem(0xff40); if ((LCDC & 0x1) == 0) { for (int i=0; i<160; ++i) line_buffer[i]=0; return; } - const uint8_t SCY = mem::readMem(0xff42); - const uint8_t SCX = mem::readMem(0xff43); - const uint8_t BGP = mem::readMem(0xff47); const uint16_t ty = uint8_t(SCY+LY) >> 3; const uint8_t ly = uint8_t(SCY+LY) & 0x7; uint16_t tx = SCX >> 3; uint8_t ox = SCX & 0x7; - uint16_t base_tilemap_address = LCDC&0x8 ? 0x9c00 : 0x9800; + uint16_t base_tilemap_address = LCDC&0x8 ? 0x1c00 : 0x1800; int pi = 0; while(true) { uint16_t tilemap_address = base_tilemap_address + tx + (ty<<5); - uint16_t tile = mem::readMem(tilemap_address); - uint16_t base_tile_address = 0x8000; - if ( ((LCDC&0x10)==0) && (tile<128) ) base_tile_address = 0x9000; + uint16_t tile = vram[tilemap_address]; + uint16_t base_tile_address = 0x0000; + if ( ((LCDC&0x10)==0) && (tile<128) ) base_tile_address = 0x1000; uint16_t tile_address = base_tile_address + (tile<<4) + (ly*2); - uint8_t a = mem::readMem(tile_address); - uint8_t b = mem::readMem(tile_address+1); + uint8_t a = vram[tile_address]; + uint8_t b = vram[tile_address+1]; for (int i=0; i<8; ++i) { if (ox==0) { uint8_t index = (a&0x80 ? 1 : 0) + (b&0x80 ? 2 : 0 ); @@ -175,31 +214,27 @@ namespace gbscreen } } - void fill_line_buffer_win(uint8_t LY) + void fill_line_buffer_win() { - const uint8_t LCDC = mem::readMem(0xff40); if ((LCDC & 0x21) != 0x21) return; - const uint8_t WY = mem::readMem(0xff4a); if (LY> 3; const uint8_t ly = uint8_t(LY-WY) & 0x7; uint8_t ox = WX<7 ? 7-WX : 0; uint16_t tx = 0; - uint16_t base_tilemap_address = LCDC&0x40 ? 0x9c00 : 0x9800; + uint16_t base_tilemap_address = LCDC&0x40 ? 0x1c00 : 0x1800; int pi = WX<7 ? 0 : WX-7; while(true) { uint16_t tilemap_address = base_tilemap_address + tx + (ty<<5); - uint16_t tile = mem::readMem(tilemap_address); - uint16_t base_tile_address = 0x8000; - if ( ((LCDC&0x10)==0) && (tile<128) ) base_tile_address = 0x9000; + uint16_t tile = vram[tilemap_address]; + uint16_t base_tile_address = 0x0000; + if ( ((LCDC&0x10)==0) && (tile<128) ) base_tile_address = 0x1000; uint16_t tile_address = base_tile_address + (tile<<4) + (ly*2); - uint8_t a = mem::readMem(tile_address); - uint8_t b = mem::readMem(tile_address+1); + uint8_t a = vram[tile_address]; + uint8_t b = vram[tile_address+1]; for (int i=0; i<8; ++i) { if (ox==0) { uint8_t index = (a&0x80 ? 1 : 0) + (b&0x80 ? 2 : 0 ); @@ -214,19 +249,10 @@ namespace gbscreen } } - struct oam_entry_t + void fill_line_buffer_obj() { - uint8_t y, x, tile, attr; - }; - oam_entry_t *oam = nullptr; - - void fill_line_buffer_obj(uint8_t LY) - { - const uint8_t LCDC = mem::readMem(0xff40); - const uint8_t OBP[2] = { mem::readMem(0xff48), mem::readMem(0xff49) }; if ((LCDC & 0x2) == 0) return; - oam = (oam_entry_t*)mem::rawPtr(0xfe00); const uint8_t height = (LCDC & 0x4) ? 16 : 8; uint8_t obj_list[10] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; int num_obj_found=0; @@ -251,10 +277,10 @@ namespace gbscreen uint16_t tile = height==8 ? o->tile : o->tile & 0xFE; // si es dos tiles de alt, el primer sempre comença en numero parell uint8_t yflip = o->attr&0x40 ? (height-1)-ly : ly; // està invertit verticalment? - uint16_t tile_address = 0x8000 + (tile<<4) + (yflip*2); + uint16_t tile_address = 0x0000 + (tile<<4) + (yflip*2); - uint8_t a = mem::readMem(tile_address); - uint8_t b = mem::readMem(tile_address+1); + uint8_t a = vram[tile_address]; + uint8_t b = vram[tile_address+1]; for (int i=0; i<8; ++i) { // Per a cada pixel de la linea del tile... if (o->x+i>=168) break; // Si ja estem fora de la pantalla per la dreta, eixim del bucle @@ -285,19 +311,14 @@ namespace gbscreen void refresh(const uint32_t dt, const bool full) { - const uint8_t LCDC = mem::readMem(0xff40); if ((LCDC&0x80)==0) return; - uint8_t STAT = mem::readMem(0xff41); - uint8_t LY = mem::readMem(0xff44); - const uint8_t LYC = mem::readMem(0xff45); for (int i=0;i=t_states_total) { - t_screen=0; - ptr_pixel = gb_pixels; + t_screen-=t_states_total; redraw(); - //if (!full) sm83::interrupt(INTERRUPT_VBLANK); } } - mem::writeMem(0xff41, STAT); - mem::writeMem(0xff44, LY); } void fullrefresh() { uint32_t tmp = t_screen; t_screen = 0; - //uint8_t * tmp_ptr = ptr_pixel; - //ptr_pixel = gb_pixels; refresh(t_states_total, true); - //ptr_pixel = tmp_ptr; t_screen = tmp; } @@ -420,7 +427,7 @@ namespace gbscreen if (fullscreen) SDL_GetWindowSize(win, &rect.w, &rect.h); SDL_RenderFillRect(ren, &rect); } - audio_viewer::refresh(); + //audio_viewer::refresh(); } void present() diff --git a/main.cpp b/main.cpp index 804cc31..0ca1aa6 100644 --- a/main.cpp +++ b/main.cpp @@ -122,13 +122,13 @@ int main(int argc, char *argv[]) bool result = true; if (e.type == SDL_QUIT) { should_exit=true; break; } - if (e.type == SDL_MOUSEBUTTONDOWN) result = ui::window::sendEvent(e.button.windowID, &e); - if (e.type == SDL_MOUSEBUTTONUP) result = ui::window::sendEvent(e.button.windowID, &e); - if (e.type == SDL_MOUSEMOTION) result = ui::window::sendEvent(e.motion.windowID, &e); - if (e.type == SDL_WINDOWEVENT) result = ui::window::sendEvent(e.window.windowID, &e); - if (e.type == SDL_MOUSEWHEEL) result = ui::window::sendEvent(e.wheel.windowID, &e); - if (e.type == SDL_TEXTINPUT) result = ui::window::sendEvent(e.text.windowID, &e); - if (e.type == SDL_KEYDOWN) { + else if (e.type == SDL_MOUSEBUTTONDOWN) result = ui::window::sendEvent(e.button.windowID, &e); + else if (e.type == SDL_MOUSEBUTTONUP) result = ui::window::sendEvent(e.button.windowID, &e); + else if (e.type == SDL_MOUSEMOTION) result = ui::window::sendEvent(e.motion.windowID, &e); + else if (e.type == SDL_WINDOWEVENT) result = ui::window::sendEvent(e.window.windowID, &e); + else if (e.type == SDL_MOUSEWHEEL) result = ui::window::sendEvent(e.wheel.windowID, &e); + else if (e.type == SDL_TEXTINPUT) result = ui::window::sendEvent(e.text.windowID, &e); + else if (e.type == SDL_KEYDOWN) { if (e.key.keysym.scancode==SDL_SCANCODE_F5) { if (debug::debugging()) { debug::history::gototop(); @@ -177,8 +177,7 @@ int main(int argc, char *argv[]) } result = ui::window::sendEvent(e.key.windowID, &e); } - - if (e.type == SDL_MOUSEBUTTONUP && e.button.button==1) ui::setClicked(true); + else if (e.type == SDL_MOUSEBUTTONUP && e.button.button==1) ui::setClicked(true); if (!result) should_exit = true; break; diff --git a/mem.cpp b/mem.cpp index 91d8487..94abf55 100644 --- a/mem.cpp +++ b/mem.cpp @@ -186,7 +186,12 @@ namespace mem } - uint8_t *rawPtr(uint16_t address) + uint8_t *rawVram() + { + return vram; + } + + uint8_t *rawHram(uint16_t address) { return &hram[address-0xfe00]; } diff --git a/mem.h b/mem.h index 603b9eb..3bfc20a 100644 --- a/mem.h +++ b/mem.h @@ -36,7 +36,8 @@ namespace mem void saveState(FILE* f); void loadState(FILE* f); - uint8_t *rawPtr(uint16_t address); + uint8_t *rawVram(); + uint8_t *rawHram(uint16_t address); void init_dma_transfer(uint8_t source); void update_mapped(const uint32_t dt); diff --git a/sm83.cpp b/sm83.cpp index b5630ca..ed6e4fb 100644 --- a/sm83.cpp +++ b/sm83.cpp @@ -522,8 +522,8 @@ namespace sm83 void processInterrupts() { - uint8_t *IE = mem::rawPtr(0xffff); - uint8_t *IF = mem::rawPtr(0xff0f); + uint8_t *IE = mem::rawHram(0xffff); + uint8_t *IF = mem::rawHram(0xff0f); if ( (*IF & *IE) == 0 ) return; if (halted) { //exit_from_halt = true;