diff --git a/fernandomartin.tap b/fernandomartin.tap new file mode 100644 index 0000000..4230123 Binary files /dev/null and b/fernandomartin.tap differ diff --git a/main.cpp b/main.cpp index 819d97d..50ed0e7 100644 --- a/main.cpp +++ b/main.cpp @@ -15,6 +15,40 @@ uint8_t memory[65536]; uint32_t time = 0; uint32_t t_states = 0; +namespace actions +{ + void exitMenu() + { + const uint8_t dt = z80::step(); + z80debug::cont(); + zxscreen::refresh(dt); + } + + int berserk(int value) + { + zx_tape::setberserk(!zx_tape::getberserk()); + return zx_tape::getberserk(); + } + + int decZoom(int value) + { + zxscreen::decZoom(); + return 0; + } + + int incZoom(int value) + { + zxscreen::incZoom(); + return 0; + } + + int fullscreen(int value) + { + zxscreen::toggleFullscreen(); + return zxscreen::getFullscreen(); + } +} + int main(int argc, char *argv[]) { FILE* f = fopen("48.rom", "rb"); @@ -29,14 +63,22 @@ int main(int argc, char *argv[]) zxscreen::init(); ui::menu::init(); + ui::menu::setexitcallback(actions::exitMenu); + int menu = ui::menu::addsubmenu("FILE"); ui::menu::addoption(menu, "LOAD TAPE", nullptr); ui::menu::addoption(menu, "SAVE TAPE", nullptr); ui::menu::addseparator(menu); ui::menu::addoption(menu, "LOAD STATE", nullptr); ui::menu::addoption(menu, "SAVE STATE", nullptr); - menu = ui::menu::addsubmenu("OPTIONS"); - ui::menu::addbooloption(menu, "BERSERK MODE", false, nullptr); + + menu = ui::menu::addsubmenu("TAPE"); + ui::menu::addbooloption(menu, "BERSERK MODE", zx_tape::getberserk(), actions::berserk); + + 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", zxscreen::getFullscreen(), actions::fullscreen); zx_ula::sound_init(); @@ -55,6 +97,7 @@ int main(int argc, char *argv[]) while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) { should_exit=true; break; } + if (e.type == SDL_MOUSEBUTTONUP && e.button.button==1) ui::setClicked(true); if ((e.type==SDL_WINDOWEVENT) && (e.window.event==SDL_WINDOWEVENT_CLOSE)) { should_exit=true; break; } @@ -115,7 +158,6 @@ int main(int argc, char *argv[]) z80debug::stop(); zxscreen::redraw(); } else if (e.key.keysym.scancode==SDL_SCANCODE_F12) { - zx_tape::go_berserk(); zx_tape::play(); } else if (e.key.keysym.scancode==SDL_SCANCODE_F11) { zx_tape::rewind(); @@ -134,7 +176,7 @@ int main(int argc, char *argv[]) t_states += dt; zx_tape::update(dt); - while (zx_tape::berserk()) + while (zx_tape::getplaying() && zx_tape::getberserk()) { zx_tape::update(z80::step()); } @@ -159,6 +201,7 @@ int main(int argc, char *argv[]) ui::menu::show(); zxscreen::present(); } + ui::setClicked(false); } return 0; diff --git a/ui.cpp b/ui.cpp index 323c462..4e695ff 100644 --- a/ui.cpp +++ b/ui.cpp @@ -29,6 +29,8 @@ namespace ui uint8_t offset_x = 0; uint8_t offset_y = 0; + bool clicked = false; + void init() { surf = SDL_LoadBMP("font.bmp"); @@ -79,4 +81,14 @@ namespace ui for (int i=0; i options; }; + void(*exit_callback)(void) = nullptr; std::vector menus; int visible_menu = -1; int menu_x = 0; @@ -41,10 +42,11 @@ namespace ui int mx, my; Uint32 mb = SDL_GetMouseState(&mx, &my); mx=mx/CHR_W; my=my/CHR_H; - ui::printrect(0, 0, 59, 1, COLOR_BLACK); + int w; + ui::printrect(0, 0, 320, 1, COLOR_BLACK); int opt_pos=1; int index=0; - for (auto menu : menus) + for (auto &menu : menus) { const int text_size = (menu.label.size()+2); uint8_t text_color = COLOR_WHITE; @@ -62,10 +64,10 @@ namespace ui if (visible_menu!=-1) { opt_pos=2; - menu_t m = menus[visible_menu]; + menu_t &m = menus[visible_menu]; ui::printrect(menu_x, 1, 22, m.options.size()+2, COLOR_BLACK); ui::box(menu_x, 1, 22, m.options.size()+2, COLOR_WHITE); - for (auto option : m.options) + for (auto &option : m.options) { if (option.type!=OPTION_TYPE_SEPARATOR) { @@ -75,6 +77,12 @@ namespace ui { ui::printrect(menu_x+1, opt_pos, 20, 1, COLOR_DARK_BLUE); text_color = COLOR_WHITE; + if (ui::getClicked()) + { + if (option.callback) option.value = option.callback(option.value); + if (exit_callback) exit_callback(); + return; + } } ui::printtxt(menu_x+1, opt_pos, option.label.c_str(), text_color); @@ -89,6 +97,11 @@ namespace ui } } + void setexitcallback(void(*callback)(void)) + { + exit_callback = callback; + } + const int addsubmenu(const char *label) { menu_t m; diff --git a/ui_menu.h b/ui_menu.h index e2001ed..0c849ee 100644 --- a/ui_menu.h +++ b/ui_menu.h @@ -6,6 +6,7 @@ namespace ui { void init(); void show(); + void setexitcallback(void(*callback)(void)); const int addsubmenu(const char *label); void addoption(int menu, const char *label, int(*callback)(int)); void addbooloption(int menu, const char *label, bool default_value, int(*callback)(int)); diff --git a/zx_screen.cpp b/zx_screen.cpp index 941d3f4..6963736 100644 --- a/zx_screen.cpp +++ b/zx_screen.cpp @@ -175,7 +175,7 @@ namespace zxscreen void redraw(const bool present) { - if (zx_tape::berserk()) return; + if (zx_tape::getplaying() && zx_tape::getberserk()) return; Uint32* pixels; int pitch; @@ -192,7 +192,17 @@ namespace zxscreen // Pintem la textura a pantalla SDL_RenderCopy(ren, tex, NULL, &dest_rect); - if (present) SDL_RenderPresent(ren); + if (present) + SDL_RenderPresent(ren); + else + { + SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(ren, 0, 0, 0, 128); + SDL_Rect rect {0,0,352*zoom,296*zoom}; + if (fullscreen) SDL_GetWindowSize(win, &rect.w, &rect.h); + SDL_RenderFillRect(ren, &rect); + } + } void present() @@ -229,6 +239,11 @@ namespace zxscreen reinit(); } + const bool getFullscreen() + { + return fullscreen; + } + SDL_Renderer *getrenderer() { return ren; diff --git a/zx_screen.h b/zx_screen.h index 2b22d80..9967312 100644 --- a/zx_screen.h +++ b/zx_screen.h @@ -12,6 +12,7 @@ namespace zxscreen void incZoom(); void decZoom(); void toggleFullscreen(); + const bool getFullscreen(); SDL_Renderer *getrenderer(); } diff --git a/zx_tape.cpp b/zx_tape.cpp index 5c0cf63..0b842e2 100644 --- a/zx_tape.cpp +++ b/zx_tape.cpp @@ -219,7 +219,7 @@ namespace zx_tape zx_ula::set_ear(pulse_level); } - void go_berserk() { berserk_mode = true; } - const bool berserk() { return berserk_mode; } - + void setberserk(const bool value) { berserk_mode = value; } + const bool getberserk() { return berserk_mode; } + const bool getplaying() { return playing; } } diff --git a/zx_tape.h b/zx_tape.h index ed40e4b..f62629f 100644 --- a/zx_tape.h +++ b/zx_tape.h @@ -8,6 +8,7 @@ namespace zx_tape void stop(); void rewind(); void update(const uint8_t dt); - void go_berserk(); - const bool berserk(); + void setberserk(const bool value); + const bool getberserk(); + const bool getplaying(); }