|
16 | 16 | #include "main.h" |
17 | 17 | #include "throttle.h" |
18 | 18 | #include "config.h" |
| 19 | +#include "menu.h" |
19 | 20 |
|
20 | 21 | #include "../common/cheat.h" |
21 | 22 | #include "../../fceu.h" |
@@ -90,6 +91,18 @@ bool swapDuty; |
90 | 91 | // originally in src/drivers/common/vidblit.cpp |
91 | 92 | bool paldeemphswap = 0; |
92 | 93 |
|
| 94 | + |
| 95 | + |
| 96 | +char *load_state_file = NULL; |
| 97 | +std::string load_state_file_string; |
| 98 | +static char *prog_name; |
| 99 | +char *mRomName = NULL; |
| 100 | +char *mRomPath = NULL; |
| 101 | +static char *quick_save_file_extension = "quicksave"; |
| 102 | +char *quick_save_file = NULL; |
| 103 | +int mQuickSaveAndPoweroff=0; |
| 104 | + |
| 105 | + |
93 | 106 | char* DriverUsage = "\ |
94 | 107 | Option Value Description\n\ |
95 | 108 | --pal {0|1} Use PAL timing.\n\ |
@@ -265,6 +278,55 @@ int CloseGame() { |
265 | 278 |
|
266 | 279 | void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count); |
267 | 280 |
|
| 281 | +/* Handler for SIGUSR1, caused by closing the console */ |
| 282 | +void handle_sigusr1(int sig) |
| 283 | +{ |
| 284 | + printf("Caught signal USR1 %d\n", sig); |
| 285 | + |
| 286 | + /* Exit menu if it was launched */ |
| 287 | + stop_menu_loop = 1; |
| 288 | + |
| 289 | + /* Signal to quick save and poweoff after next loop */ |
| 290 | + mQuickSaveAndPoweroff = 1; |
| 291 | +} |
| 292 | + |
| 293 | +/* Quick save and turn off the console */ |
| 294 | +void quick_save_and_poweroff() |
| 295 | +{ |
| 296 | + /* Vars */ |
| 297 | + char shell_cmd[2048]; |
| 298 | + FILE *fp; |
| 299 | + |
| 300 | + /* Send command to kill any previously scheduled shutdown */ |
| 301 | + sprintf(shell_cmd, "pkill %s", SHELL_CMD_SCHEDULE_POWERDOWN); |
| 302 | + fp = popen(shell_cmd, "r"); |
| 303 | + if (fp == NULL) { |
| 304 | + printf("Failed to run command %s\n", shell_cmd); |
| 305 | + } |
| 306 | + |
| 307 | + /* Save */ |
| 308 | + FCEUI_SaveState(quick_save_file); |
| 309 | + |
| 310 | + /* Write quick load file */ |
| 311 | + sprintf(shell_cmd, "%s SDL_NOMOUSE=1 \"%s\" --loadStateFile \"%s\" \"%s\"", |
| 312 | + SHELL_CMD_WRITE_QUICK_LOAD_CMD, prog_name, quick_save_file, mRomName); |
| 313 | + printf("Cmd write quick load file:\n %s\n", shell_cmd); |
| 314 | + fp = popen(shell_cmd, "r"); |
| 315 | + if (fp == NULL) { |
| 316 | + printf("Failed to run command %s\n", shell_cmd); |
| 317 | + } |
| 318 | + |
| 319 | + /* Clean Poweroff */ |
| 320 | + sprintf(shell_cmd, "%s", SHELL_CMD_POWERDOWN); |
| 321 | + fp = popen(shell_cmd, "r"); |
| 322 | + if (fp == NULL) { |
| 323 | + printf("Failed to run command %s\n", shell_cmd); |
| 324 | + } |
| 325 | + |
| 326 | + /* Exit Emulator */ |
| 327 | + CloseGame(); |
| 328 | +} |
| 329 | + |
268 | 330 | static void DoFun(int fskip) { |
269 | 331 | uint8 *gfx; |
270 | 332 | int32 *sound; |
@@ -451,7 +513,7 @@ void FCEUD_TraceInstruction() { |
451 | 513 | } |
452 | 514 |
|
453 | 515 | /** |
454 | | - * Convert FCM movie to FM2 . |
| 516 | + * Convert FCM movie to FM2 . |
455 | 517 | * Returns 1 on success, otherwise 0. |
456 | 518 | */ |
457 | 519 | int FCEUD_ConvertMovie(const char *name, char *outname) { |
@@ -486,7 +548,7 @@ int FCEUD_ConvertMovie(const char *name, char *outname) { |
486 | 548 | return 0; |
487 | 549 | } |
488 | 550 |
|
489 | | -/* |
| 551 | +/* |
490 | 552 | * Loads a movie, if fcm movie will convert first. And will |
491 | 553 | * ask for rom too, returns 1 on success, 0 otherwise. |
492 | 554 | */ |
@@ -539,11 +601,17 @@ int main(int argc, char *argv[]) { |
539 | 601 |
|
540 | 602 | FCEUD_Message("\nStarting "FCEU_NAME_AND_VERSION"...\n"); |
541 | 603 |
|
| 604 | + /* Init Signals */ |
| 605 | + signal(SIGUSR1, handle_sigusr1); |
| 606 | + |
542 | 607 | #ifdef WIN32 |
543 | 608 | /* Taken from win32 sdl_main.c */ |
544 | 609 | SDL_SetModuleHandle(GetModuleHandle(NULL)); |
545 | 610 | #endif |
546 | 611 |
|
| 612 | + /* Set env var for no mouse */ |
| 613 | + putenv(strdup("SDL_NOMOUSE=1")); |
| 614 | + |
547 | 615 | /* SDL_INIT_VIDEO Needed for (joystick config) event processing? */ |
548 | 616 | if(SDL_Init(SDL_INIT_VIDEO)) { |
549 | 617 | printf("Could not initialize SDL: %s.\n", SDL_GetError()); |
@@ -572,7 +640,60 @@ int main(int argc, char *argv[]) { |
572 | 640 |
|
573 | 641 | /* Load config from file */ |
574 | 642 | g_config->load(); |
| 643 | + |
| 644 | + /* Overwrite load file */ |
| 645 | + g_config->setOption("SDL.loadStateFile", ""); |
| 646 | + |
| 647 | + /* Parse args */ |
575 | 648 | int romIndex = g_config->parse(argc, argv); |
| 649 | + printf("romIndex = %d\n", romIndex); |
| 650 | + if (romIndex < 0) { |
| 651 | + printf("ERROR romIndex = %d, no ROM specified\n", romIndex); |
| 652 | + SDL_Quit(); |
| 653 | + return -1; |
| 654 | + } |
| 655 | + |
| 656 | + /* load state file */ |
| 657 | + g_config->getOption("SDL.loadStateFile", &load_state_file_string); |
| 658 | + if (strcmp(load_state_file_string.c_str(), "")) { |
| 659 | + printf("************ load_state_file: %s\n", load_state_file_string.c_str()); |
| 660 | + } |
| 661 | + |
| 662 | + /* Get rom names, directory and quick save file */ |
| 663 | + prog_name = argv[0]; |
| 664 | + mRomName = argv[romIndex]; |
| 665 | + FILE *f = fopen(mRomName, "rb"); |
| 666 | + if (f) { |
| 667 | + |
| 668 | + /* Save Rom path */ |
| 669 | + mRomPath = (char*)malloc(strlen(mRomName)+1) ; |
| 670 | + strcpy(mRomPath, mRomName) ; |
| 671 | + char *slash = strrchr ((char*)mRomPath, '/'); |
| 672 | + *slash = 0; |
| 673 | + |
| 674 | + /* Rom name without extension */ |
| 675 | + char *point = strrchr ((char*)slash+1, '.'); |
| 676 | + *point = 0; |
| 677 | + |
| 678 | + /* Set quicksave filename */ |
| 679 | + quick_save_file = (char*) malloc(strlen(mRomPath) + strlen(slash+1) + strlen(quick_save_file_extension) + 2 + 1); |
| 680 | + sprintf(quick_save_file, "%s/%s.%s", |
| 681 | + mRomPath, slash+1, quick_save_file_extension); |
| 682 | + printf("************ quick_save_file: %s\n", quick_save_file); |
| 683 | + printf("************ mRomPath: %s\n", mRomPath); |
| 684 | + printf("************ mRomName: %s\n", mRomName); |
| 685 | + |
| 686 | + fclose(f); |
| 687 | + } else { |
| 688 | + printf("Rom file %s not found \n", mRomName); |
| 689 | + SDL_Quit(); |
| 690 | + return -1; |
| 691 | + } |
| 692 | + |
| 693 | + /* Override saving directories */ |
| 694 | + FCEUI_SetDirOverride(FCEUIOD_STATES, mRomPath); |
| 695 | + FCEUI_SetDirOverride(FCEUIOD_NV, mRomPath); |
| 696 | + |
576 | 697 |
|
577 | 698 | // This is here so that a default fceux.cfg will be created on first |
578 | 699 | // run, even without a valid ROM to play. |
@@ -743,6 +864,7 @@ int main(int argc, char *argv[]) { |
743 | 864 | setHotKeys(); |
744 | 865 |
|
745 | 866 | if (romIndex >= 0) { |
| 867 | + printf("Loading game: argv[%d] = %s\n", romIndex, argv[romIndex]); |
746 | 868 | // load the specified game |
747 | 869 | error = LoadGame(argv[romIndex]); |
748 | 870 | if (error != 1) { |
@@ -812,6 +934,33 @@ int main(int argc, char *argv[]) { |
812 | 934 |
|
813 | 935 | // update rom specified input config |
814 | 936 | UpdateInput(g_config); |
| 937 | + if (strcmp(load_state_file_string.c_str(), "") ) { |
| 938 | + |
| 939 | + /* Load file */ |
| 940 | + printf("LOADING FROM FILE %s...\n", load_state_file_string.c_str()); |
| 941 | + FCEUI_LoadState(load_state_file_string.c_str()); |
| 942 | + printf("LOADED FROM SLOT %s\n", load_state_file_string.c_str()); |
| 943 | + load_state_file_string = ""; |
| 944 | + } else if (access( quick_save_file, F_OK ) != -1) { |
| 945 | + |
| 946 | + /* Load quick save file */ |
| 947 | + printf("Found quick save file: %s\n", quick_save_file); |
| 948 | + |
| 949 | + int resume = launch_resume_menu_loop(); |
| 950 | + if(resume == RESUME_YES){ |
| 951 | + printf("Resume game from quick save file: %s\n", quick_save_file); |
| 952 | + FCEUI_LoadState(quick_save_file); |
| 953 | + } else { |
| 954 | + printf("Reset game\n"); |
| 955 | + |
| 956 | + /* Remove quicksave file if present */ |
| 957 | + if (remove(quick_save_file) == 0) { |
| 958 | + printf("Deleted successfully: %s\n", quick_save_file); |
| 959 | + } else { |
| 960 | + printf("Unable to delete the file: %s\n", quick_save_file); |
| 961 | + } |
| 962 | + } |
| 963 | + } |
815 | 964 |
|
816 | 965 | // loop playing the game |
817 | 966 | DoFun(frameskip); |
@@ -911,7 +1060,7 @@ extern int FDSSwitchRequested; |
911 | 1060 |
|
912 | 1061 | void FCEUI_FDSFlip(void) |
913 | 1062 | { |
914 | | - /* Taken from fceugc |
| 1063 | + /* Taken from fceugc |
915 | 1064 | the commands shouldn't be issued in parallel so |
916 | 1065 | * we'll delay them so the virtual FDS has a chance |
917 | 1066 | * to process them |
|
0 commit comments