static void gfx_ctx_emscripten_swap_interval(void *data, int interval) { (void)data; if (interval == 0) emscripten_set_main_loop_timing(EM_TIMING_SETIMMEDIATE, 0); else emscripten_set_main_loop_timing(EM_TIMING_RAF, interval); }
SDLApplication::SDLApplication () { if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_TIMER | SDL_INIT_JOYSTICK) != 0) { printf ("Could not initialize SDL: %s.\n", SDL_GetError ()); } currentApplication = this; framePeriod = 1000.0 / 60.0; #ifdef EMSCRIPTEN emscripten_cancel_main_loop (); emscripten_set_main_loop (UpdateFrame, 0, 0); emscripten_set_main_loop_timing (EM_TIMING_RAF, 1); #endif currentUpdate = 0; lastUpdate = 0; nextUpdate = 0; ApplicationEvent applicationEvent; GamepadEvent gamepadEvent; KeyEvent keyEvent; MouseEvent mouseEvent; RenderEvent renderEvent; SensorEvent sensorEvent; TextEvent textEvent; TouchEvent touchEvent; WindowEvent windowEvent; #if defined(IOS) || defined(ANDROID) for (int i = 0; i < SDL_NumJoysticks (); i++) { if (strstr (SDL_JoystickNameForIndex (i), "Accelerometer")) { accelerometer = SDL_JoystickOpen (i); accelerometerID = SDL_JoystickInstanceID (accelerometer); } } #endif #ifdef HX_MACOS CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL (CFBundleGetMainBundle ()); char path[PATH_MAX]; if (CFURLGetFileSystemRepresentation (resourcesURL, TRUE, (UInt8 *)path, PATH_MAX)) { chdir (path); } CFRelease (resourcesURL); #endif }
SDLApplication::SDLApplication () { if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_TIMER | SDL_INIT_JOYSTICK) != 0) { printf ("Could not initialize SDL: %s.\n", SDL_GetError ()); } SDL_LogSetPriority (SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN); currentApplication = this; framePeriod = 1000.0 / 60.0; #ifdef EMSCRIPTEN emscripten_cancel_main_loop (); emscripten_set_main_loop (UpdateFrame, 0, 0); emscripten_set_main_loop_timing (EM_TIMING_RAF, 1); #endif currentUpdate = 0; lastUpdate = 0; nextUpdate = 0; ApplicationEvent applicationEvent; DropEvent dropEvent; GamepadEvent gamepadEvent; JoystickEvent joystickEvent; KeyEvent keyEvent; MouseEvent mouseEvent; RenderEvent renderEvent; SensorEvent sensorEvent; TextEvent textEvent; TouchEvent touchEvent; WindowEvent windowEvent; SDL_EventState (SDL_DROPFILE, SDL_ENABLE); SDLJoystick::Init (); #ifdef HX_MACOS CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL (CFBundleGetMainBundle ()); char path[PATH_MAX]; if (CFURLGetFileSystemRepresentation (resourcesURL, TRUE, (UInt8 *)path, PATH_MAX)) { chdir (path); } CFRelease (resourcesURL); #endif }
SDLApplication::SDLApplication () { if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_TIMER | SDL_INIT_JOYSTICK) != 0) { printf ("Could not initialize SDL: %s.\n", SDL_GetError ()); } currentApplication = this; framePeriod = 1000.0 / 60.0; #ifdef EMSCRIPTEN emscripten_cancel_main_loop (); emscripten_set_main_loop (UpdateFrame, 0, 0); emscripten_set_main_loop_timing (EM_TIMING_RAF, 1); #endif currentUpdate = 0; lastUpdate = 0; nextUpdate = 0; GamepadEvent gamepadEvent; KeyEvent keyEvent; MouseEvent mouseEvent; RenderEvent renderEvent; TextEvent textEvent; TouchEvent touchEvent; UpdateEvent updateEvent; WindowEvent windowEvent; #ifdef HX_MACOS CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL (CFBundleGetMainBundle ()); char path[PATH_MAX]; if (CFURLGetFileSystemRepresentation (resourcesURL, TRUE, (UInt8 *)path, PATH_MAX)) { chdir (path); } CFRelease (resourcesURL); #endif }
static inline void emu_sleep ( int td ) { if (td <= 0) return; #ifdef __EMSCRIPTEN__ #define __SLEEP_METHOD_DESC "emscripten_set_main_loop_timing" // If too short period of sleep (not enough for 1ms), give some time for browser to run // to avoid the "stop the script" warning or so ... // For Js, it's not really a sleep what name would mean for function (emu_sleep) but // rather then a setTimeout value for the handler emscripten_set_main_loop_timing(EM_TIMING_SETTIMEOUT, td > 999 ? td / 1000 : 1); #elif defined(XEMU_SLEEP_IS_SDL_DELAY) #define __SLEEP_METHOD_DESC "SDL_Delay" SDL_Delay(td / 1000); #elif defined(XEMU_SLEEP_IS_USLEEP) #define __SLEEP_METHOD_DESC "usleep" usleep(td); #else #define __SLEEP_METHOD_DESC "nanosleep" struct timespec req, rem; td *= 1000; req.tv_sec = td / 1000000000UL; req.tv_nsec = td % 1000000000UL; for (;;) { if (nanosleep(&req, &rem)) { if (errno == EINTR) { req.tv_sec = rem.tv_sec; req.tv_nsec = rem.tv_nsec; } else { ERROR_WINDOW("Nanosleep() returned with unhandlable error"); return; } } else return; } #endif }
int main(int argc,char **argv) { #if defined(__GNUC__) && defined(__WIN32__) //HACK: workaround for precompiled SDL libraries that block output to console FILE * ctt = fopen("CON", "w" ); freopen( "CON", "w", stdout ); freopen( "CON", "w", stderr ); #endif // init basic flags before parsing args uzebox.sdl_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC; if(argc == 1) { showHelp(argv[0]); return 1; } int opt; char* heximage = NULL; while((opt = getopt_long(argc, argv,shortopts,longopts,NULL)) != -1) { switch(opt) { default: /* fallthrough */ case 'h': showHelp(argv[0]); return 1; case 'n': uzebox.enableSound = false; break; case 'f': uzebox.fullscreen = true; break; case 'w': uzebox.sdl_flags = (uzebox.sdl_flags & ~(SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC)) | SDL_RENDERER_SOFTWARE; break; case 'v': uzebox.sdl_flags &= ~SDL_RENDERER_PRESENTVSYNC; break; case 'm': uzebox.pad_mode = avr8::SNES_MOUSE; break; case '2': uzebox.pad_mode = avr8::SNES_PAD2; break; #ifndef __EMSCRIPTEN__ case 'r': uzebox.recordMovie=true; break; #endif // __EMSCRIPTEN__ case 's': uzebox.SDpath = optarg; break; case 'e': uzebox.eepromFile=optarg; break; case 'b': uzebox.pc = 0x7800;//0xF000; //set start for boot image break; case 'c': uzebox.captureMode=CAPTURE_WRITE; break; case 'l': uzebox.captureMode=CAPTURE_READ; break; case 'z': uzebox.hsyncHelp=true; break; #ifndef NOGDB case 'd': uzebox.enableGdb = true; break; case 't': long port = strtol(optarg,NULL,10); if ((port == LONG_MAX) || (port == LONG_MIN) || (port < 0) || port > 65535) uzebox.gdbPort = 0; else uzebox.gdbPort = port; break; #endif // NOGDB } } // get leftovers for (int i = optind; i < argc; ++i) { if(heximage){ printerr("Error: HEX file already specified (too many arguments?).\n\n"); showHelp(argv[0]); return 1; } else{ heximage = argv[i]; } } #ifndef NOGDB if (uzebox.gdbPort == 0) { printerr("Error: invalid port address.\n\n"); showHelp(argv[0]); return 1; } #endif // NOGDB // start EEPROM emulation if appropriate if(uzebox.eepromFile){ uzebox.LoadEEPROMFile(uzebox.eepromFile); } // attempt to load the hex image if(!heximage){ printerr("Error: No HEX program or boot file specified.\n\n"); showHelp(argv[0]); return 1; } // write hex image if(heximage){ unsigned char* buffer = (unsigned char*)(uzebox.progmem); if(ends_with(heximage,"uze", 3)){ if(isUzeromFile(heximage)){ printf("-- Loading UzeROM Image --\n"); if(!loadUzeImage(heximage,&uzeRomHeader,buffer)){ printerr("Error: cannot load UzeRom file '%s'.\n\n",heximage); showHelp(argv[0]); return 1; } // enable mouse support if required if(uzeRomHeader.mouse){ uzebox.pad_mode = avr8::SNES_MOUSE; printf("Mouse support enabled\n"); } }else{ printerr("Error: Cannot load UZE ROM file '%s'. Bad format header?\n\n",heximage); showHelp(argv[0]); return 1; } }else{ printf("Loading Hex Image...\n"); if(!loadHex(heximage,buffer)){ printerr("Error: cannot load HEX image '%s'.\n\n",heximage); showHelp(argv[0]); return 1; } } uzebox.decodeFlash(); //get rom name without extension char *pfile = heximage + strlen(heximage); for (;; pfile--) { if ((*pfile == '\\') || (*pfile == '/') || pfile==heximage) { if(pfile!=heximage)pfile++; //skip the slash character for(int i=0;i<256;i++){ if(*pfile=='.') break; uzebox.romName[i]=*pfile; pfile++; } break; } } //build the capture file name int len=strlen(uzebox.romName); char capfname[len+5]; strcpy(capfname,uzebox.romName); capfname[len+0]='.'; capfname[len+1]='c'; capfname[len+2]='a'; capfname[len+3]='p'; capfname[len+4]=0; /* char capfname[256]; char *pfile = heximage + strlen(heximage); for (;; pfile--) { if ((*pfile == '\\') || (*pfile == '/') || pfile==heximage) { if(pfile!=heximage)pfile++; //skip the slash character for(int i=0;i<256;i++){ if(*pfile=='.'){ capfname[i+0]='.'; capfname[i+1]='c'; capfname[i+2]='a'; capfname[i+3]='p'; capfname[i+4]=0; break; } capfname[i]=*pfile; pfile++; } break; } } */ if(uzebox.captureMode==CAPTURE_READ) { uzebox.captureFile=fopen(capfname,"rb"); if(uzebox.captureFile==0){ uzebox.captureMode=CAPTURE_NONE; printerr("Warning: Cannot open capture file %s. Capture replay ignored.\n\n",capfname); }else{ fseek(uzebox.captureFile, 0L, SEEK_END); long fz = ftell(uzebox.captureFile); rewind(uzebox.captureFile); uzebox.captureData=new u8[fz]; uzebox.captureSize=fz; uzebox.capturePtr=0; fread(uzebox.captureData,1,fz,uzebox.captureFile); fclose(uzebox.captureFile); uzebox.captureFile = 0; } } else if(uzebox.captureMode==CAPTURE_WRITE) { uzebox.captureFile=fopen(capfname,"wb"); if(uzebox.captureFile==0){ uzebox.captureMode=CAPTURE_NONE; printerr("Error: Cannot open capture file %s.\n\n",capfname); return 1; } } //if user did not specify a path for the sd card, use the rom's path if(uzebox.SDpath == NULL){ //extract path char *pfile; pfile = heximage + strlen(heximage); for (;; pfile--) { if ((*pfile == '\\') || (*pfile == '/')) { *pfile=0; pfile = heximage; break; } if (pfile == heximage) { pfile[0] = '.'; pfile[1] = '/'; pfile[2] = 0; break; } } uzebox.SDpath=pfile; printf("\nUsing HEX path for SD emulation: %s\n",pfile); } } if (uzebox.SDpath != NULL) { if (!uzebox.init_sd()) { printerr("Error: cannot load directory for SD emulation '%s'.\n\n", uzebox.SDpath); showHelp(argv[0]); return 1; } } sprintf(uzebox.caption,"Uzebox Emulator " VERSION " (ESC=quit, F1=help)"); // init the GUI if (!uzebox.init_gui()){ printerr("Error: Failed to init GUI.\n\n"); showHelp(argv[0]); return 1; } #ifndef NOGDB if (uzebox.enableGdb == true) { #if defined(USE_GDBSERVER_DEBUG) uzebox.gdb = new GdbServer(&uzebox, uzebox.gdbPort, true, true); #else uzebox.gdb = new GdbServer(&uzebox, uzebox.gdbPort, false, true); #endif } else uzebox.state = CPU_RUNNING; #endif // NOGDB uzebox.randomSeed=time(NULL); srand(uzebox.randomSeed); //used for the watchdog timer entropy const int cycles=100000000; int left, now; #ifdef __EMSCRIPTEN__ emscripten_set_main_loop(one_iter, 60, 1); emscripten_set_main_loop_timing(EM_TIMING_RAF, 1); #else // __EMSCRIPTEN__ while (true) { if (uzebox.fullscreen){ puts(uzebox.caption); }else{ if (uzebox.window) SDL_SetWindowTitle(uzebox.window,uzebox.caption); } left = cycles; now = SDL_GetTicks(); while (left > 0) left -= uzebox.exec(); now = SDL_GetTicks() - now; sprintf(uzebox.caption,"Uzebox Emulator " VERSION " (ESC=quit, F1=help) %02d.%03d Mhz",cycles/now/1000,(cycles/now)%1000); } #endif // __EMSCRIPTEN__ return 0; }