📄 uifltk-menu.cpp
字号:
/*************************************************************************** DSemu - The Next Generation ** Fltk user interface: Menu item handlers [uifltk-menu.cpp] ** Copyright Imran Nazar, 2005; released under the BSD public licence. ** Fltk used under the terms of the LGPL. ***************************************************************************/#include <map>#include <FL/Fl.h>#include <FL/fl_draw.H>#include "uifltk.h"#include "plugin.h"#include "log.h"#include "w32compile.h"//---Menubar and handlers--------------------------------------------------// Initial state of the menuconst Fl_Menu_Item UIFltk::UI::menuInit[]={ {"&File", 0, 0, 0, FL_SUBMENU, 0, 0, 11}, {"@#8|> Open &GBA...", FL_CTRL+'o', UIFltk::UI::cbOpenGBA, 0, 0, 0, 0, 11}, {"@#8|> Open &DS...", FL_CTRL+'o', UIFltk::UI::cbOpenDS, 0, 0, 0, 0, 11}, {"@#-2square &Close", 0, UIFltk::UI::cbClose, 0, FL_MENU_INACTIVE|FL_MENU_DIVIDER, 0, 0, 11}, {"E&xit", FL_ALT+'x', UIFltk::UI::cbExit, 0, 0, 0, 0, 11}, {0}, {"&Debug", 0, 0, 0, FL_SUBMENU|FL_MENU_INACTIVE, 0, 0, 11}, {"@#> &Run", FL_F+4, UIFltk::UI::cbRun, 0, 0, 0, 0, 11}, {"@#<< Re&set", FL_F+6, UIFltk::UI::cbReset, 0, FL_MENU_DIVIDER, 0, 0, 11}, {"&Breakpoints...", FL_F+2, UIFltk::UI::cbBkpt, 0, 0, 0, 0, 11}, {"&Step into", FL_F+7, UIFltk::UI::cbStep, 0, 0, 0, 0, 11}, {"Animate Step", FL_SHIFT+FL_F+7, UIFltk::UI::cbAStep, 0, FL_MENU_DIVIDER, 0, 0, 11}, {"CPU view mode", 0, 0, 0, FL_SUBMENU, 0, 0, 11}, {"ARM", 0, UIFltk::UI::cbCpuStatARM, 0, FL_MENU_RADIO, 0, 0, 11}, {"Thumb", 0, UIFltk::UI::cbCpuStatThumb, 0, FL_MENU_RADIO, 0, 0, 11}, {"Automatic", 0, UIFltk::UI::cbCpuStatAuto, 0, FL_MENU_RADIO|FL_MENU_VALUE, 0, 0, 11}, {0}, {"MMU view mode", 0, 0, 0, FL_SUBMENU, 0, 0, 11}, {"Bytes", 0, UIFltk::UI::cbMmuDumpB, 0, FL_MENU_RADIO, 0, 0, 11}, {"Halfwords", 0, UIFltk::UI::cbMmuDumpH, 0, FL_MENU_RADIO|FL_MENU_VALUE, 0, 0, 11}, {"Words", 0, UIFltk::UI::cbMmuDumpW, 0, FL_MENU_RADIO, 0, 0, 11}, {0}, {"MMU view address...", 0, UIFltk::UI::cbMmuAddr, 0, 0, 0, 0, 11}, {0}, {"&View", 0, 0, 0, FL_SUBMENU, 0, 0, 11}, {"Event &Log", 0, UIFltk::UI::cbLog, 0, FL_MENU_TOGGLE, 0, 0, 11}, {0}, {"&Options", 0, 0, 0, FL_SUBMENU, 0, 0, 11}, {"&Configuration...", 0, /*UIFltk::UI::cbConf*/0, 0, FL_MENU_INACTIVE, 0, 0, 11}, {0}, {"&Help", 0, 0, 0, FL_SUBMENU, 0, 0, 11}, {"&About", FL_F+1, UIFltk::UI::cbAbout, 0, 0, 0, 0, 11}, {0}, {0}};// Actual menu, updated on the fly as a vector of Itemsstd::vector<Fl_Menu_Item> UIFltk::UI::menu(menuInit, menuInit+sizeof(menuInit)/sizeof(*menuInit));//---File menu-------------------------------------------------------------void UIFltk::UI::cbOpenGBA(Fl_Widget *w, void *in) { ((UIFltk::UI*)in)->cbOpenGBAI(); }inline void UIFltk::UI::cbOpenGBAI(){ static char str[128]; std::string filename; std::pair<int, int> CPUdbgsize; // Let the user choose a ROM Fl_File_Chooser fc(".", "GBA binary files (*.{bin,gba,agb})", Fl_File_Chooser::SINGLE, "Open GBA Rom"); fc.show(); while(fc.shown()) Fl::wait(); if(!fc.value()) return; if(ROMpath.length()) if(loaded) cbCloseI(); ROMpath = fc.value(); if(!ROMpath.length()) return; // Allocate output buffer outbuf = new u8[240*160*4]; if(!outbuf) throw Exception(ERR_GUI_INIT, "FLTK", "Allocation of output memory failed"); Logger::log(pluginName) << "Memory allocated."; // Resize the window to 240x160 + menu + status, and fix it size(240, 196); size_range(240, 196, 240, 196); Logger::log(pluginName) << "Opening file " << ROMpath; // Load plugins mmu = (MMU32Plugin*)pRequest("GBA_CPU0.mmu"); cpu = (CPUPlugin*)pRequest("GBA_CPU0.main"); gpu = (GPUPlugin*)pRequest("GBA_GPU"); timer = (Plugin*)pRequest("GBA_Timer"); apu = (APUPlugin*)pRequest("GBA_APU"); events.clear(); timestamp=0; DSmode=0; Logger::log(pluginName) << "Plugins loaded."; // Load the ROM, and register key I/O with the MMU mmu->load(ROMpath); mmu->mmioReg(0x13, keyRdB, keyRdH, keyRdW, keyWrB, keyWrH, keyWrW); // Reset everything cpu->reset(); Logger::log(pluginName) << "CPU debugger initialised."; memset(outbuf, 0, 240*160*4); gpu->setDisplay(outbuf); gpu->reset(); apu->reset(); // Show the Debug menu options menu[MENU_FILE_CLOSE].flags &= ~FL_MENU_INACTIVE; menu[MENU_DEBUG_RUN].text = "@#> &Run"; menu[MENU_DEBUG].flags &= ~FL_MENU_INACTIVE; mbar->copy(&menu[0]); loaded=1; running=0; frames=0; keys=0x03FF; // Change the window title #ifdef WIN32 filename = ROMpath.substr(ROMpath.rfind('\\', std::string::npos)+1); #else filename = ROMpath.substr(ROMpath.rfind('/', std::string::npos)+1); #endif sprintf(str, "%s: %s", filename.c_str(), DSEMU_VERSION_STR); label(str); sbarr->label("ROM loaded."); sbarl->label("Reset"); redraw(); // And we're done. Logger::log(pluginName) << "File open.";}void UIFltk::UI::cbOpenDS(Fl_Widget *w, void *in) { ((UIFltk::UI*)in)->cbOpenDSI(); }inline void UIFltk::UI::cbOpenDSI(){ static char str[128]; std::string filename; std::pair<int, int> CPUdbgsize; // Let the user choose a ROM Fl_File_Chooser fc(".", "DS binary files (*.{nds})", Fl_File_Chooser::SINGLE, "Open DS Rom"); fc.show(); while(fc.shown()) Fl::wait(); if(!fc.value()) return; if(ROMpath.length()) if(loaded) cbCloseI(); ROMpath = fc.value(); if(!ROMpath.length()) return; // Allocate output buffer outbuf = new u8[256*384*4]; if(!outbuf) throw Exception(ERR_GUI_INIT, "FLTK", "Allocation of output memory failed"); memset(outbuf, 0, 256*384*4); Logger::log(pluginName) << "Memory allocated."; // Resize the window to 256x384 + menu + status, and fix it size(256, 420); size_range(256, 420, 256, 420); Logger::log(pluginName) << "Opening file " << ROMpath; // Load plugins mmu = (MMU32Plugin*)pRequest("DS_CPU0.mmu"); cpu = (CPUPlugin*)pRequest("DS_CPU0.main"); mmuSub = (MMU32Plugin*)pRequest("DS_CPU1.mmu"); cpuSub = (CPUPlugin*)pRequest("DS_CPU1.main"); gpu = (GPUPlugin*)pRequest("DS_GPU"); timer = (Plugin*)pRequest("DS_Timer"); apu = (APUPlugin*)pRequest("DS_APU"); events.clear(); timestamp=0; DSmode=1; Logger::log(pluginName) << "Plugins loaded."; // Reset everything cpu->reset(); cpuSub->reset(); Logger::log(pluginName) << "CPU debugger initialised."; memset(outbuf, 0, 240*160*4); gpu->setDisplay(outbuf); gpu->reset(); apu->reset(); // Load the ROM, and register key I/O with the MMU mmu->load(ROMpath); mmuSub->load(ROMpath); mmu->mmioReg(0x13, keyRdB, keyRdH, keyRdW, keyWrB, keyWrH, keyWrW); cpu->status(cpuStatMode,0); cpuSub->status(cpuStatMode,0); // Show the Debug menu options menu[MENU_FILE_CLOSE].flags &= ~FL_MENU_INACTIVE; menu[MENU_DEBUG_RUN].text = "@#> &Run"; menu[MENU_DEBUG].flags &= ~FL_MENU_INACTIVE; mbar->copy(&menu[0]); loaded=1; running=0; frames=0; keys=0x03FF; // Change the window title #ifdef WIN32 filename = ROMpath.substr(ROMpath.rfind('\\', std::string::npos)+1); #else filename = ROMpath.substr(ROMpath.rfind('/', std::string::npos)+1); #endif sprintf(str, "%s: %s", filename.c_str(), DSEMU_VERSION_STR); label(str); sbarr->label("ROM loaded."); sbarl->label("Reset"); redraw(); // And we're done. Logger::log(pluginName) << "File open.";}void UIFltk::UI::cbClose(Fl_Widget *w, void *in) { ((UIFltk::UI*)in)->cbCloseI(); }inline void UIFltk::UI::cbCloseI(){ Logger::log(pluginName) << "Close initiated."; if(!loaded) return; if(bkptVisible) cbBkptI(); // Shut down all the subwindows for(std::map<int, SubWindow*>::iterator i=subwindows.begin(); i!=subwindows.end(); ++i) { (*i).second->hide(); delete (*i).second; subwindows.erase(i); } // Unload all the plugins if(DSmode) { pUnrequest("DS_APU",1); apu=NULL; pUnrequest("DS_GPU",1); gpu=NULL; pUnrequest("DS_Timer",1); timer=NULL; pUnrequest("DS_CPU1.main",1); cpuSub=NULL; pUnrequest("DS_CPU1.mmu",1); mmuSub=NULL; pUnrequest("DS_CPU0.main",1); cpu=NULL; pUnrequest("DS_CPU0.mmu",1); mmu=NULL; } else { pUnrequest("GBA_APU",1); apu=NULL; pUnrequest("GBA_GPU",1); gpu=NULL; pUnrequest("GBA_Timer",1); timer=NULL; pUnrequest("GBA_CPU0.main",1); cpu=NULL; pUnrequest("GBA_CPU0.mmu",1); mmu=NULL; } // Turn the Debug menu off menu.clear(); menu.assign(menuInit, menuInit+sizeof(menuInit)/sizeof(*menuInit)); mbar->copy(&menu[0]); loaded=0; running=0; ROMpath.erase(0); events.clear(); timestamp=0; if(outbuf) { delete[] outbuf; outbuf=NULL; } // Bring the window back down to 240x37 size(240, 37); size_range(240, 37, 240, 37); // Reset the window title label(DSEMU_VERSION_STR); sbarr->label("ROM closed."); sbarl->label(""); // And we're closed down. Logger::log(pluginName) << "File closed.";}void UIFltk::UI::cbExit(Fl_Widget *w, void *in) { ((UIFltk::UI*)in)->cbExitI(); }inline void UIFltk::UI::cbExitI(){ // Exit is just close with the hiding of the main window. if(loaded) cbCloseI(); //if(logVisible) cbLogI(); Logger::log(pluginName) << "Exit requested."; hide();}//---Debug menu------------------------------------------------------------void UIFltk::UI::cbRun(Fl_Widget *w, void *in) { ((UIFltk::UI*)in)->cbRunI(); }inline void UIFltk::UI::cbRunI(){ if(loaded) { switch(running) { // Start running. If we're already stepping, we actually need // to pause instead. case 0: if(stepping) { running=1; cbRunI(); } else { // Start the FPS counter updating Fl::add_timeout(1.0, cbFPScount, this); running=1; // Change the menu to reflect that we're running menu[MENU_DEBUG_RUN].text="@#|| &Pause"; menu[MENU_DEBUG_BKPT].flags |= FL_MENU_INACTIVE; menu[MENU_DEBUG_STEP].flags |= FL_MENU_INACTIVE; menu[MENU_DEBUG_ASTEP].flags |= FL_MENU_INACTIVE; mbar->copy(&menu[0]); apu->togglePause(); sbarl->label("Running"); } break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -