mirror of
https://github.com/joncampbell123/dosbox-x.git
synced 2025-06-11 13:56:33 +08:00
add support for save files etc
This commit is contained in:
parent
7f1fce4689
commit
a00a4ff910
14
CHANGELOG
14
CHANGELOG
@ -13,10 +13,18 @@
|
||||
"core=dynamic_x86" or "core=dynamic_rec" for either
|
||||
the dynamic_x86 core or the dynamic_rec core. Also
|
||||
thank joncampbell123 for the 64-bit fix. (Wengier)
|
||||
- You can now use your own save file (in addition to
|
||||
save slots! There are now a "Use save file" toggle
|
||||
item and "Browse save file..." for browsing save
|
||||
files on your computer. A new menu item "Display
|
||||
state information" is added as well to display the
|
||||
information of the saved state. (Wengier)
|
||||
- Save state feature now allows users to optionally
|
||||
enter remarks when saving a state. A toggle menu
|
||||
item "No remark when saving state" (in "Capture")
|
||||
is added to disable input of remarks. (Wengier)
|
||||
enter remarks when saving a state. A submenu group
|
||||
"Save/load option" is added (under "Capture") where
|
||||
you can toggle menu items "No remark when saving
|
||||
state" (for disabling input of remarks when saving)
|
||||
and "force load state mode". (Wengier)
|
||||
- DOSBox-X will now use native dialog box to display
|
||||
quit warnings and save state errors. (Wengier)
|
||||
- Updated the Windows installer to default to the
|
||||
|
@ -299,7 +299,7 @@ public:
|
||||
void load (size_t slot) const; //throw (Error)
|
||||
bool isEmpty(size_t slot) const;
|
||||
void removeState(size_t slot) const;
|
||||
std::string getName(size_t slot) const;
|
||||
std::string getName(size_t slot, bool nl=false) const;
|
||||
|
||||
//initialization: register relevant components on program startup
|
||||
struct Component
|
||||
|
@ -310,6 +310,8 @@ unsigned long long update_clockdom_from_now(ClockDomain &dst) {
|
||||
|
||||
#include "paging.h"
|
||||
|
||||
extern std::string savefilename;
|
||||
extern bool use_save_file;
|
||||
extern bool rom_bios_vptable_enable;
|
||||
extern bool rom_bios_8x8_cga_font;
|
||||
extern bool allow_port_92_reset;
|
||||
@ -783,7 +785,11 @@ void notifyError(const std::string& message, bool log=true)
|
||||
{
|
||||
if (log) LOG_MSG("%s",message.c_str());
|
||||
#if !defined(HX_DOS)
|
||||
MAPPER_ReleaseAllKeys();
|
||||
GFX_LosingFocus();
|
||||
tinyfd_messageBox("Error",message.c_str(),"ok","error", 1);
|
||||
MAPPER_ReleaseAllKeys();
|
||||
GFX_LosingFocus();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -5095,7 +5101,7 @@ void SaveState::save(size_t slot) { //throw (Error)
|
||||
std::stringstream slotname;
|
||||
slotname << slot+1;
|
||||
temp=path;
|
||||
std::string save=temp+slotname.str()+".sav";
|
||||
std::string save=use_save_file&&savefilename.size()?savefilename:temp+slotname.str()+".sav";
|
||||
remove(save.c_str());
|
||||
std::ofstream file (save.c_str());
|
||||
file << "";
|
||||
@ -5224,7 +5230,11 @@ delete_all:
|
||||
void savestatecorrupt(const char* part) {
|
||||
LOG_MSG("Save state corrupted! Program in inconsistent state! - %s", part);
|
||||
#if !defined(HX_DOS)
|
||||
MAPPER_ReleaseAllKeys();
|
||||
GFX_LosingFocus();
|
||||
tinyfd_messageBox("Error","Save state corrupted! Program may not work.","ok","error", 1);
|
||||
MAPPER_ReleaseAllKeys();
|
||||
GFX_LosingFocus();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -5276,12 +5286,12 @@ void SaveState::load(size_t slot) const { //throw (Error)
|
||||
temp = path;
|
||||
std::stringstream slotname;
|
||||
slotname << slot+1;
|
||||
std::string save=temp+slotname.str()+".sav";
|
||||
std::string save=use_save_file&&savefilename.size()?savefilename:temp+slotname.str()+".sav";
|
||||
std::ifstream check_slot;
|
||||
check_slot.open(save.c_str(), std::ifstream::in);
|
||||
if(check_slot.fail()) {
|
||||
LOG_MSG("No saved slot - %d (%s)",(int)slot+1,save.c_str());
|
||||
notifyError("The selected save slot is an empty slot.", false);
|
||||
notifyError(use_save_file&&savefilename.size()?"The selected save file is currently empty.":"The selected save slot is an empty slot.", false);
|
||||
load_err=true;
|
||||
return;
|
||||
}
|
||||
@ -5548,7 +5558,7 @@ void SaveState::removeState(size_t slot) const {
|
||||
}
|
||||
}
|
||||
|
||||
std::string SaveState::getName(size_t slot) const {
|
||||
std::string SaveState::getName(size_t slot, bool nl) const {
|
||||
if (slot >= SLOT_COUNT*MAX_PAGE) return "[Empty slot]";
|
||||
std::string path;
|
||||
bool Get_Custom_SaveDir(std::string& savedir);
|
||||
@ -5570,10 +5580,10 @@ std::string SaveState::getName(size_t slot) const {
|
||||
temp = path;
|
||||
std::stringstream slotname;
|
||||
slotname << slot+1;
|
||||
std::string save=temp+slotname.str()+".sav";
|
||||
std::string save=nl&&use_save_file&&savefilename.size()?savefilename:temp+slotname.str()+".sav";
|
||||
std::ifstream check_slot;
|
||||
check_slot.open(save.c_str(), std::ifstream::in);
|
||||
if (check_slot.fail()) return "[Empty slot]";
|
||||
if (check_slot.fail()) return nl?"(Empty state)":"[Empty slot]";
|
||||
my_miniunz((char **)save.c_str(),"Program_Name",temp.c_str());
|
||||
std::ifstream check_title;
|
||||
int length = 8;
|
||||
@ -5591,7 +5601,7 @@ std::string SaveState::getName(size_t slot) const {
|
||||
check_title.close();
|
||||
remove(tempname.c_str());
|
||||
buffer1[length]='\0';
|
||||
std::string ret="[Program: "+std::string(buffer1)+"]";
|
||||
std::string ret=nl?"Program: "+(!strlen(buffer1)?"-":std::string(buffer1))+"\n":"[Program: "+std::string(buffer1)+"]";
|
||||
my_miniunz((char **)save.c_str(),"Time_Stamp",temp.c_str());
|
||||
length=18;
|
||||
tempname = temp+"Time_Stamp";
|
||||
@ -5608,7 +5618,7 @@ std::string SaveState::getName(size_t slot) const {
|
||||
check_title.close();
|
||||
remove(tempname.c_str());
|
||||
buffer2[length]='\0';
|
||||
if (strlen(buffer2)) ret+=" ("+std::string(buffer2);
|
||||
if (strlen(buffer2)) ret+=nl?"Timestamp: "+(!strlen(buffer2)?"-":std::string(buffer2))+"\n":" ("+std::string(buffer2);
|
||||
my_miniunz((char **)save.c_str(),"Save_Remark",temp.c_str());
|
||||
length=30;
|
||||
tempname = temp+"Save_Remark";
|
||||
@ -5625,6 +5635,6 @@ std::string SaveState::getName(size_t slot) const {
|
||||
check_title.close();
|
||||
remove(tempname.c_str());
|
||||
buffer3[length]='\0';
|
||||
if (strlen(buffer3)) ret+=" - "+std::string(buffer3)+")";
|
||||
if (strlen(buffer3)) ret+=nl?"Remark: "+(!strlen(buffer3)?"-":std::string(buffer3))+"\n":" - "+std::string(buffer3)+")";
|
||||
return ret;
|
||||
}
|
||||
|
@ -567,11 +567,13 @@ static const char *def_menu_capture[] =
|
||||
"mapper_caprawmidi",
|
||||
"--",
|
||||
#endif
|
||||
"noremark_savestate",
|
||||
"force_loadstate",
|
||||
"saveoptionmenu",
|
||||
"mapper_savestate",
|
||||
"mapper_loadstate",
|
||||
"saveslotmenu",
|
||||
"usesavefile",
|
||||
"browsesavefile",
|
||||
"showstate",
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -589,6 +591,14 @@ static const char *def_menu_capture_format[] =
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Save/load options */
|
||||
static const char *save_load_options[] =
|
||||
{
|
||||
"noremark_savestate",
|
||||
"force_loadstate",
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Save slots */
|
||||
static const char *def_save_slots[] =
|
||||
{
|
||||
@ -1417,6 +1427,7 @@ void ConstructMenu(void) {
|
||||
ConstructSubMenu(mainMenu.get_item("CaptureFormatMenu").get_master_id(), def_menu_capture_format);
|
||||
# endif
|
||||
#endif
|
||||
ConstructSubMenu(mainMenu.get_item("saveoptionmenu").get_master_id(), save_load_options);
|
||||
ConstructSubMenu(mainMenu.get_item("saveslotmenu").get_master_id(), def_save_slots);
|
||||
|
||||
/* Drive menu */
|
||||
|
@ -45,7 +45,7 @@ extern bool noremark_save_state;
|
||||
extern bool force_load_state;
|
||||
extern bool use_quick_reboot;
|
||||
extern bool enable_config_as_shell_commands;
|
||||
bool winrun=false;
|
||||
bool winrun=false, use_save_file=false;
|
||||
bool direct_mouse_clipboard=false;
|
||||
#if defined(WIN32)
|
||||
extern int dos_clipboard_device_access;
|
||||
@ -814,7 +814,7 @@ extern bool keep_private_area_on_boot;
|
||||
extern bool dos_kernel_disabled;
|
||||
bool guest_machine_power_on = false;
|
||||
|
||||
std::string custom_savedir;
|
||||
std::string custom_savedir, savefilename = "";
|
||||
|
||||
void SHELL_Run();
|
||||
void DisableINT33();
|
||||
@ -8446,6 +8446,53 @@ bool force_loadstate_menu_callback(DOSBoxMenu * const menu, DOSBoxMenu::item * c
|
||||
return true;
|
||||
}
|
||||
|
||||
bool browse_save_file_menu_callback(DOSBoxMenu * const menu, DOSBoxMenu::item * const menuitem) {
|
||||
(void)menu;//UNUSED
|
||||
const char *mname = menuitem->get_name().c_str();
|
||||
if (!strcmp(mname, "browsesavefile")&&!use_save_file) return false;
|
||||
|
||||
#if !defined(HX_DOS)
|
||||
char CurrentDir[512];
|
||||
char * Temp_CurrentDir = CurrentDir;
|
||||
getcwd(Temp_CurrentDir, 512);
|
||||
const char *lFilterPatterns[] = {"*.sav","*.SAV"};
|
||||
const char *lFilterDescription = "Save files (*.sav)";
|
||||
char const * lTheSaveFileName = tinyfd_saveFileDialog("Select an save file","",2,lFilterPatterns,lFilterDescription);
|
||||
if (lTheSaveFileName!=NULL) {
|
||||
savefilename = std::string(lTheSaveFileName);
|
||||
mainMenu.get_item("usesavefile").set_text("Use save file"+(savefilename.size()?" ("+savefilename+")":"")).refresh_item(mainMenu);
|
||||
}
|
||||
chdir( Temp_CurrentDir );
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool use_save_file_menu_callback(DOSBoxMenu * const menu, DOSBoxMenu::item * const menuitem) {
|
||||
(void)menu;//UNUSED
|
||||
(void)menuitem;//UNUSED
|
||||
if (use_save_file) use_save_file=false;
|
||||
else if (savefilename.size()) use_save_file=true;
|
||||
else {
|
||||
browse_save_file_menu_callback(menu, menuitem);
|
||||
if (savefilename.size()) use_save_file=true;
|
||||
}
|
||||
mainMenu.get_item("usesavefile").check(use_save_file).refresh_item(mainMenu);
|
||||
mainMenu.get_item("browsesavefile").enable(use_save_file).refresh_item(mainMenu);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool show_save_state_menu_callback(DOSBoxMenu * const menu, DOSBoxMenu::item * const menuitem) {
|
||||
(void)menu;//UNUSED
|
||||
(void)menuitem;//UNUSED
|
||||
MAPPER_ReleaseAllKeys();
|
||||
GFX_LosingFocus();
|
||||
std::string message = "Save to: "+(use_save_file&&savefilename.size()?"File "+savefilename:"Slot "+std::to_string(GetGameState_Run()+1))+"\n"+SaveState::instance().getName(GetGameState_Run(), true);
|
||||
bool ret=tinyfd_messageBox("Saved state information", message.c_str(), "ok","info", 1);
|
||||
MAPPER_ReleaseAllKeys();
|
||||
GFX_LosingFocus();
|
||||
return true;
|
||||
}
|
||||
|
||||
void refresh_slots() {
|
||||
mainMenu.get_item("current_page").set_text("Current page: "+to_string(page+1)+"/10").refresh_item(mainMenu);
|
||||
for (unsigned int i=0; i<SaveState::SLOT_COUNT; i++) {
|
||||
@ -9829,9 +9876,17 @@ int main(int argc, char* argv[]) SDL_MAIN_NOEXCEPT {
|
||||
}
|
||||
# endif
|
||||
{
|
||||
DOSBoxMenu::item &item = mainMenu.alloc_item(DOSBoxMenu::submenu_type_id,"saveoptionmenu");
|
||||
item.set_text("Save/load option");
|
||||
}
|
||||
{
|
||||
DOSBoxMenu::item &item = mainMenu.alloc_item(DOSBoxMenu::submenu_type_id,"saveslotmenu");
|
||||
item.set_text("Select save slot");
|
||||
|
||||
}
|
||||
{
|
||||
mainMenu.alloc_item(DOSBoxMenu::item_type_id, "usesavefile").set_text("Use save file").set_callback_function(use_save_file_menu_callback).check(use_save_file);
|
||||
mainMenu.alloc_item(DOSBoxMenu::item_type_id, "browsesavefile").set_text("Browse save file...").set_callback_function(browse_save_file_menu_callback).enable(use_save_file);
|
||||
mainMenu.alloc_item(DOSBoxMenu::item_type_id, "showstate").set_text("Display state information").set_callback_function(show_save_state_menu_callback);
|
||||
{
|
||||
mainMenu.alloc_item(DOSBoxMenu::item_type_id,"current_page").set_text("Current page: 1/10").enable(false).set_callback_function(refresh_slots_menu_callback);
|
||||
mainMenu.alloc_item(DOSBoxMenu::item_type_id,"prev_page").set_text("Previous page").set_callback_function(prev_page_menu_callback);
|
||||
|
Loading…
x
Reference in New Issue
Block a user