Esempio n. 1
0
void wait_for_input(void)
{
   printf("\n\nPress Start.\n\n");
   fflush(stdout);

   while(aptMainLoop())
   {
      u32 kDown;

      hidScanInput();

      kDown = hidKeysDown();

      if (kDown & KEY_START)
         break;

      if (kDown & KEY_SELECT)
         exit(0);
#if 0
      select_pressed = true;
#endif

      retro_sleep(1);
   }
}
Esempio n. 2
0
void MCPHookClose()
{
   if (mcp_hook_fd < 0)
      return;

   //close down wupserver, return control to mcp
   IOSUHAX_Close();
   //wait for mcp to return
   retro_sleep(1000);
   IOS_Close(mcp_hook_fd);
   mcp_hook_fd = -1;
}
Esempio n. 3
0
static void emscripten_mainloop(void)
{
   unsigned sleep_ms = 0;
   int ret = runloop_iterate(&sleep_ms);
   if (ret == 1 && sleep_ms > 0)
      retro_sleep(sleep_ms);
   runloop_ctl(RUNLOOP_CTL_DATA_ITERATE, NULL);
   if (ret != -1)
      return;

   main_exit(NULL);
   exit(0);
}
Esempio n. 4
0
static void emscripten_mainloop(void)
{
   unsigned sleep_ms = 0;
   int ret = runloop_iterate(&sleep_ms);
   if (ret == 1 && sleep_ms > 0)
      retro_sleep(sleep_ms);
   task_queue_ctl(TASK_QUEUE_CTL_CHECK, NULL);
   if (ret != -1)
      return;

   main_exit(NULL);
   exit(0);
}
Esempio n. 5
0
static void threaded_worker(void *userdata)
{
   (void)userdata;

   for (;;)
   {
      retro_task_t *task  = NULL;

      if (!worker_continue)
         break; /* should we keep running until all tasks finished? */

      slock_lock(running_lock);

      /* Get first task to run */
      task = tasks_running.front;
      if (task == NULL)
      {
         scond_wait(worker_cond, running_lock);
         slock_unlock(running_lock);
         continue;
      }

      slock_unlock(running_lock);

      task->handler(task);

      slock_lock(running_lock);
      task_queue_remove(&tasks_running, task);
      slock_unlock(running_lock);

      /* Update queue */
      if (!task->finished)
      {
         /* Re-add task to running queue */
         retro_task_threaded_push_running(task);
      }
      else
      {
         /* Add task to finished queue */
         slock_lock(finished_lock);
         task_queue_put(&tasks_finished, task);
         slock_unlock(finished_lock);
      }

#if 0
      retro_sleep(10);
#endif
   }

   slock_unlock(running_lock);
}
Esempio n. 6
0
/**
 * main_entry:
 *
 * Main function of RetroArch.
 *
 * If HAVE_MAIN is not defined, will contain main loop and will not
 * be exited from until we exit the program. Otherwise, will
 * just do initialization.
 *
 * Returns: varies per platform.
 **/
int rarch_main(int argc, char *argv[], void *data)
{
   void *args                      = (void*)data;
#ifndef HAVE_MAIN
   int ret                         = 0;
#endif

   rarch_ctl(RARCH_CTL_PREINIT, NULL);
   frontend_driver_init_first(args);
   rarch_ctl(RARCH_CTL_INIT, NULL);
   
   if (frontend_driver_is_inited())
   {
      content_ctx_info_t info;

      info.argc            = argc;
      info.argv            = argv;
      info.args            = args;
      info.environ_get     = frontend_driver_environment_get_ptr();

      if (!task_push_content_load_default(
               NULL,
               NULL,
               &info,
               CORE_TYPE_PLAIN,
               CONTENT_MODE_LOAD_FROM_CLI,
               NULL,
               NULL))
         return 0;
   }

   ui_companion_driver_init_first();

#ifndef HAVE_MAIN
   do
   {
      unsigned sleep_ms = 0;
      ret = runloop_iterate(&sleep_ms);

      if (ret == 1 && sleep_ms > 0)
         retro_sleep(sleep_ms);
      task_queue_ctl(TASK_QUEUE_CTL_CHECK, NULL);
   }while(ret != -1);

   main_exit(args);
#endif

   return 0;
}
Esempio n. 7
0
/**
 * task_http_iterate_transfer:
 *
 * Resumes HTTP transfer update.
 *
 * Returns: 0 when finished, -1 when we should continue
 * with the transfer on the next frame.
 **/
static int task_http_iterate_transfer(retro_task_t *task)
{
   http_handle_t *http  = (http_handle_t*)task->state;
   size_t pos  = 0, tot = 0;

   /* FIXME: This wouldn't be needed if we could wait for a timeout */
   if (task_queue_is_threaded())
      retro_sleep(1);

   if (!net_http_update(http->handle, &pos, &tot))
   {
      task_set_progress(task, (tot == 0) ? -1 : (signed)(pos * 100 / tot));
      return -1;
   }

   return 0;
}
Esempio n. 8
0
bool retro_load_game(const struct retro_game_info* game)
{
   init_descriptors();
   check_variables();

   uint8_t bios_data[256];
   char bios_path[PATH_MAX_LENGTH];
   char* system_dir;
   if(environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_dir) && system_dir)
      strncpy(bios_path, system_dir, sizeof(bios_path));
   else if (game->path)
      strncpy(bios_path, game->path, sizeof(bios_path));
   else
      strncpy(bios_path, ".", sizeof(bios_path));
#if defined(_WIN32)
   char slash = '\\';
#else
   char slash = '/';
#endif
   char* tmp = strrchr(bios_path, slash);
   if(!tmp)
      tmp = strrchr(bios_path, '\0');
   *tmp++ = slash;
   strcpy(tmp, "gbbios.gb");

   retro_sleep(10);
   fflush(stdout);
   gbemu_printf("romd info\n");
   gbemu_printf("path : %s\n", game->path);
   gbemu_printf("size : %u\n", game->size);
   fflush(stdout);

   gbemu_printf("loading bios from : %s\n", bios_path);
   FILE* fp = fopen(bios_path, "rb");
   if(fp)
   {
      fread(bios_data, 1, sizeof(bios_data), fp);
      fclose(fp);
   }
   else
      gbemu_printf("bios not found !\n");

   gbemu_load_game(game->data, game->size, fp? bios_data: NULL);

   return true;
}
Esempio n. 9
0
void gbemu_wait_for_input(void)
{
   if(!poll_cb || !input_cb)
      return;

   printf("press START\n");
   fflush(stdout);

   do
   {
      retro_sleep(50);
      poll_cb();
      if(input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT))
         exit(0);
   }
   while(!input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START));
}
Esempio n. 10
0
int MCPHookOpen()
{
   //take over mcp thread
   mcp_hook_fd = IOS_Open("/dev/mcp", 0);

   if (mcp_hook_fd < 0)
      return -1;

   IOS_IoctlAsync(mcp_hook_fd, 0x62, (void *)0, 0, (void *)0, 0, someFunc, (void *)0);
   //let wupserver start up
   retro_sleep(1000);

   if (IOSUHAX_Open("/dev/mcp") < 0)
   {
      IOS_Close(mcp_hook_fd);
      mcp_hook_fd = -1;
      return -1;
   }

   return 0;
}
Esempio n. 11
0
/**
 * runloop_iterate:
 *
 * Run Libretro core in RetroArch for one frame.
 *
 * Returns: 0 on success, 1 if we have to wait until button input in order
 * to wake up the loop, -1 if we forcibly quit out of the RetroArch iteration loop.
 **/
int runloop_iterate(unsigned *sleep_ms)
{
   unsigned i;
   event_cmd_state_t    cmd;
   event_cmd_state_t   *cmd_ptr                 = &cmd;
   retro_time_t current, target, to_sleep_ms;
   static retro_usec_t frame_time_last          = 0;
   static retro_time_t frame_limit_minimum_time = 0.0;
   static retro_time_t frame_limit_last_time    = 0.0;
   static retro_input_t last_input              = 0;
   settings_t *settings                         = config_get_ptr();
   global_t   *global                           = global_get_ptr();
   rarch_system_info_t *system                  = NULL;

   cmd.state[1]                                 = last_input;
   cmd.state[0]                                 = input_keys_pressed();
   last_input                                   = cmd.state[0];

   runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system);

   if (runloop_ctl(RUNLOOP_CTL_IS_FRAME_TIME_LAST, NULL))
   {
      frame_time_last = 0;
      runloop_ctl(RUNLOOP_CTL_UNSET_FRAME_TIME_LAST, NULL);
   }

   if (runloop_ctl(RUNLOOP_CTL_SHOULD_SET_FRAME_LIMIT, NULL))
   {
      struct retro_system_av_info *av_info = video_viewport_get_system_av_info();
      float fastforward_ratio              = (settings->fastforward_ratio == 0.0f) 
         ? 1.0f : settings->fastforward_ratio;

      frame_limit_last_time    = retro_get_time_usec();
      frame_limit_minimum_time = (retro_time_t)roundf(1000000.0f 
            / (av_info->timing.fps * fastforward_ratio));

      runloop_ctl(RUNLOOP_CTL_UNSET_FRAME_LIMIT, NULL);
   }

   if (input_driver_ctl(RARCH_INPUT_CTL_IS_FLUSHING_INPUT, NULL))
   {
      input_driver_ctl(RARCH_INPUT_CTL_UNSET_FLUSHING_INPUT, NULL);
      if (cmd.state[0])
      {
         cmd.state[0] = 0;

         /* If core was paused before entering menu, evoke
          * pause toggle to wake it up. */
         if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL))
            BIT64_SET(cmd.state[0], RARCH_PAUSE_TOGGLE);
         input_driver_ctl(RARCH_INPUT_CTL_SET_FLUSHING_INPUT, NULL);
      }
   }

   if (system->frame_time.callback)
   {
      /* Updates frame timing if frame timing callback is in use by the core.
       * Limits frame time if fast forward ratio throttle is enabled. */

      bool is_slowmotion;
      retro_time_t current     = retro_get_time_usec();
      retro_time_t delta       = current - frame_time_last;
      bool is_locked_fps       = (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL) ||
            input_driver_ctl(RARCH_INPUT_CTL_IS_NONBLOCK_STATE, NULL)) |
         !!recording_driver_get_data_ptr();

      runloop_ctl(RUNLOOP_CTL_IS_SLOWMOTION, &is_slowmotion);

      if (!frame_time_last || is_locked_fps)
         delta = system->frame_time.reference;

      if (!is_locked_fps && is_slowmotion)
         delta /= settings->slowmotion_ratio;

      frame_time_last = current;

      if (is_locked_fps)
         frame_time_last = 0;

      system->frame_time.callback(delta);
   }

   cmd.state[2]      = cmd.state[0] & ~cmd.state[1];  /* trigger  */

   if (runloop_cmd_triggered(cmd_ptr, RARCH_OVERLAY_NEXT))
      event_command(EVENT_CMD_OVERLAY_NEXT);

   if (runloop_cmd_triggered(cmd_ptr, RARCH_FULLSCREEN_TOGGLE_KEY))
   {
      bool fullscreen_toggled = !runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL);
#ifdef HAVE_MENU
      fullscreen_toggled = fullscreen_toggled || menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL);
#endif

      if (fullscreen_toggled)
         event_command(EVENT_CMD_FULLSCREEN_TOGGLE);
   }

   if (runloop_cmd_triggered(cmd_ptr, RARCH_GRAB_MOUSE_TOGGLE))
      event_command(EVENT_CMD_GRAB_MOUSE_TOGGLE);

#ifdef HAVE_MENU
   if (runloop_cmd_menu_press(cmd_ptr) || (global->inited.core.type == CORE_TYPE_DUMMY))
   {
      if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
      {
         if (global->inited.main && (global->inited.core.type != CORE_TYPE_DUMMY))
            rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL);
      }
      else
         rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL);
   }
#endif

#ifdef HAVE_OVERLAY
   runloop_iterate_linefeed_overlay(settings);
#endif

   if (runloop_iterate_time_to_exit(runloop_cmd_press(cmd_ptr, RARCH_QUIT_KEY)) != 1)
   {
      frame_limit_last_time = 0.0;
      return -1;
   }


#ifdef HAVE_MENU
   if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
   {
      bool focused = runloop_ctl(RUNLOOP_CTL_CHECK_FOCUS, NULL) && !ui_companion_is_on_foreground();
      bool is_idle = runloop_ctl(RUNLOOP_CTL_IS_IDLE, NULL);

      if (menu_driver_iterate((enum menu_action)menu_input_frame_retropad(cmd.state[0], cmd.state[2])) == -1)
         rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL);

      if (focused || !is_idle)
         menu_driver_ctl(RARCH_MENU_CTL_RENDER, NULL);

      if (!focused || is_idle)
      {
         *sleep_ms = 10;
         return 1;
      }

      goto end;
   }
#endif

   if (!runloop_ctl(RUNLOOP_CTL_CHECK_STATE, &cmd))
   {
      /* RetroArch has been paused. */
      retro_ctx.poll_cb();
      *sleep_ms = 10;
      return 1;
   }

#if defined(HAVE_THREADS)
   lock_autosave();
#endif

#ifdef HAVE_NETPLAY
   netplay_driver_ctl(RARCH_NETPLAY_CTL_PRE_FRAME, NULL);
#endif

   if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL))
      bsv_movie_ctl(BSV_MOVIE_CTL_SET_FRAME_START, NULL);

   if (system->camera_callback.caps)
      driver_camera_poll();

   /* Update binds for analog dpad modes. */
   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_push_analog_dpad(settings->input.binds[i],
            settings->input.analog_dpad_mode[i]);
      input_push_analog_dpad(settings->input.autoconf_binds[i],
            settings->input.analog_dpad_mode[i]);
   }

   if ((settings->video.frame_delay > 0) && 
         !input_driver_ctl(RARCH_INPUT_CTL_IS_NONBLOCK_STATE, NULL))
      retro_sleep(settings->video.frame_delay);

   /* Run libretro for one frame. */
   core.retro_run();

#ifdef HAVE_CHEEVOS
   /* Test the achievements. */
   cheevos_test();
#endif

   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_pop_analog_dpad(settings->input.binds[i]);
      input_pop_analog_dpad(settings->input.autoconf_binds[i]);
   }

   if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL))
      bsv_movie_ctl(BSV_MOVIE_CTL_SET_FRAME_END, NULL);

#ifdef HAVE_NETPLAY
   netplay_driver_ctl(RARCH_NETPLAY_CTL_POST_FRAME, NULL);
#endif

#if defined(HAVE_THREADS)
   unlock_autosave();
#endif

#ifdef HAVE_MENU
end:
#endif
   if (!settings->fastforward_ratio)
      return 0;

   current                        = retro_get_time_usec();
   target                         = frame_limit_last_time + frame_limit_minimum_time;
   to_sleep_ms                    = (target - current) / 1000;

   if (to_sleep_ms > 0)
   {
      *sleep_ms = (unsigned)to_sleep_ms;
      /* Combat jitter a bit. */
      frame_limit_last_time += frame_limit_minimum_time;
      return 1;
   }

   frame_limit_last_time  = retro_get_time_usec();

   return 0;
}
Esempio n. 12
0
/**
 * runloop_iterate:
 *
 * Run Libretro core in RetroArch for one frame.
 *
 * Returns: 0 on success, 1 if we have to wait until 
 * button input in order to wake up the loop, 
 * -1 if we forcibly quit out of the RetroArch iteration loop.
 **/
int runloop_iterate(unsigned *sleep_ms)
{
   unsigned i;
   event_cmd_state_t    cmd;
   retro_time_t current, target, to_sleep_ms;
   static retro_input_t last_input              = {0};
   event_cmd_state_t   *cmd_ptr                 = &cmd;
   static retro_time_t frame_limit_minimum_time = 0.0;
   static retro_time_t frame_limit_last_time    = 0.0;
   settings_t *settings                         = config_get_ptr();

   cmd.state[1]                                 = last_input;
   cmd.state[0]                                 = input_keys_pressed();
   last_input                                   = cmd.state[0];

   runloop_ctl(RUNLOOP_CTL_UNSET_FRAME_TIME_LAST, NULL);

   if (runloop_ctl(RUNLOOP_CTL_SHOULD_SET_FRAME_LIMIT, NULL))
   {
      struct retro_system_av_info *av_info = 
         video_viewport_get_system_av_info();
      float fastforward_ratio              = 
         (settings->fastforward_ratio == 0.0f) 
         ? 1.0f : settings->fastforward_ratio;

      frame_limit_last_time    = cpu_features_get_time_usec();
      frame_limit_minimum_time = (retro_time_t)roundf(1000000.0f 
            / (av_info->timing.fps * fastforward_ratio));

      runloop_ctl(RUNLOOP_CTL_UNSET_FRAME_LIMIT, NULL);
   }

   if (input_driver_is_flushing_input())
   {
      input_driver_unset_flushing_input();
      if (cmd.state[0].state)
      {
         cmd.state[0].state = 0;

         /* If core was paused before entering menu, evoke
          * pause toggle to wake it up. */
         if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL))
            BIT64_SET(cmd.state[0].state, RARCH_PAUSE_TOGGLE);
         input_driver_set_flushing_input();
      }
   }
   
   if (runloop_frame_time.callback)
   {
      /* Updates frame timing if frame timing callback is in use by the core.
       * Limits frame time if fast forward ratio throttle is enabled. */

      retro_time_t current     = cpu_features_get_time_usec();
      retro_time_t delta       = current - runloop_frame_time_last;
      bool is_locked_fps       = (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL) ||
                                  input_driver_is_nonblock_state()) |
                                  !!recording_driver_get_data_ptr();


      if (!runloop_frame_time_last || is_locked_fps)
         delta = runloop_frame_time.reference;

      if (!is_locked_fps && runloop_ctl(RUNLOOP_CTL_IS_SLOWMOTION, NULL))
         delta /= settings->slowmotion_ratio;

      runloop_frame_time_last = current;

      if (is_locked_fps)
         runloop_frame_time_last = 0;

      runloop_frame_time.callback(delta);
   }

   cmd.state[2].state      = cmd.state[0].state & ~cmd.state[1].state;  /* trigger  */

   if (runloop_cmd_triggered(cmd_ptr, RARCH_OVERLAY_NEXT))
      command_event(CMD_EVENT_OVERLAY_NEXT, NULL);

   if (runloop_cmd_triggered(cmd_ptr, RARCH_FULLSCREEN_TOGGLE_KEY))
   {
      bool fullscreen_toggled = !runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL);
#ifdef HAVE_MENU
      fullscreen_toggled = fullscreen_toggled || 
         menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL);
#endif

      if (fullscreen_toggled)
         command_event(CMD_EVENT_FULLSCREEN_TOGGLE, NULL);
   }

   if (runloop_cmd_triggered(cmd_ptr, RARCH_GRAB_MOUSE_TOGGLE))
      command_event(CMD_EVENT_GRAB_MOUSE_TOGGLE, NULL);

#ifdef HAVE_MENU
   if (runloop_cmd_menu_press(cmd_ptr) || 
         rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL))
   {
      if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
      {
         if (rarch_ctl(RARCH_CTL_IS_INITED, NULL) && 
               !rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL))
            rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL);
      }
      else
         rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL);
   }
#endif

#ifdef HAVE_OVERLAY
   runloop_iterate_linefeed_overlay(settings);
#endif

   if (runloop_iterate_time_to_exit(
            runloop_cmd_press(cmd_ptr, RARCH_QUIT_KEY)) != 1)
   {
      frame_limit_last_time = 0.0;
      return -1;
   }


#ifdef HAVE_MENU
   if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL))
   {
      int ret = runloop_iterate_menu((enum menu_action)
      menu_input_frame_retropad(cmd.state[0], cmd.state[2]),
      sleep_ms);

      if (ret == -1)
         goto end;
      return ret;
   }
#endif

   if (!runloop_check_state(&cmd, &runloop_shader_dir))
   {
      /* RetroArch has been paused. */
      core_poll();
      *sleep_ms = 10;
      return 1;
   }

#if defined(HAVE_THREADS)
   autosave_lock();
#endif

#ifdef HAVE_NETPLAY
   netplay_driver_ctl(RARCH_NETPLAY_CTL_PRE_FRAME, NULL);
#endif

   if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL))
      bsv_movie_ctl(BSV_MOVIE_CTL_SET_FRAME_START, NULL);

   camera_driver_ctl(RARCH_CAMERA_CTL_POLL, NULL);

   /* Update binds for analog dpad modes. */
   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_push_analog_dpad(settings->input.binds[i],
            settings->input.analog_dpad_mode[i]);
      input_push_analog_dpad(settings->input.autoconf_binds[i],
            settings->input.analog_dpad_mode[i]);
   }

   if ((settings->video.frame_delay > 0) && 
         !input_driver_is_nonblock_state())
      retro_sleep(settings->video.frame_delay);

   core_run();

#ifdef HAVE_CHEEVOS
   cheevos_test();
#endif

   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_pop_analog_dpad(settings->input.binds[i]);
      input_pop_analog_dpad(settings->input.autoconf_binds[i]);
   }

   if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL))
      bsv_movie_ctl(BSV_MOVIE_CTL_SET_FRAME_END, NULL);

#ifdef HAVE_NETPLAY
   netplay_driver_ctl(RARCH_NETPLAY_CTL_POST_FRAME, NULL);
#endif

#if defined(HAVE_THREADS)
   autosave_unlock();
#endif

   if (!settings->fastforward_ratio)
      return 0;
#ifdef HAVE_MENU
end:
#endif

   current                        = cpu_features_get_time_usec();
   target                         = frame_limit_last_time + 
      frame_limit_minimum_time;
   to_sleep_ms                    = (target - current) / 1000;

   if (to_sleep_ms > 0)
   {
      *sleep_ms = (unsigned)to_sleep_ms;
      /* Combat jitter a bit. */
      frame_limit_last_time += frame_limit_minimum_time;
      return 1;
   }

   frame_limit_last_time  = cpu_features_get_time_usec();

   return 0;
}
Esempio n. 13
0
int main(int argc, char **argv)
{
#else
int __entry_menu(int argc, char **argv)
{
   InitFunctionPointers();
#endif
#if 1
   setup_os_exceptions();
#else
   InstallExceptionHandler();
#endif
   socket_lib_init();
#if defined(PC_DEVELOPMENT_IP_ADDRESS) && defined(PC_DEVELOPMENT_TCP_PORT)
   log_init(PC_DEVELOPMENT_IP_ADDRESS, PC_DEVELOPMENT_TCP_PORT);
#endif
   devoptab_list[STD_OUT] = &dotab_stdout;
   devoptab_list[STD_ERR] = &dotab_stdout;
   memoryInitialize();
   mount_sd_fat("sd");
   VPADInit();

   verbosity_enable();
   DEBUG_VAR(argc);
   DEBUG_STR(argv[0]);
   DEBUG_STR(argv[1]);
#if 0
   int argc_ = 2;
//   char* argv_[] = {WIIU_SD_PATH "retroarch/retroarch.elf", WIIU_SD_PATH "rom.nes", NULL};
   char* argv_[] = {WIIU_SD_PATH "retroarch/retroarch.elf", WIIU_SD_PATH "rom.sfc", NULL};

   rarch_main(argc_, argv_, NULL);
#else
   rarch_main(argc, argv, NULL);
#endif
//   int frames = 0;
   do
   {
      unsigned sleep_ms = 0;
      int ret = runloop_iterate(&sleep_ms);

      if (ret == 1 && sleep_ms > 0)
       retro_sleep(sleep_ms);
      task_queue_ctl(TASK_QUEUE_CTL_WAIT, NULL);
      if (ret == -1)
       break;

   }while(1);
//   }while(frames++ < 300);

   main_exit(NULL);
   unmount_sd_fat("sd");
   memoryRelease();
   fflush(stdout);
   fflush(stderr);
#if defined(PC_DEVELOPMENT_IP_ADDRESS) && defined(PC_DEVELOPMENT_TCP_PORT)
   log_deinit();
#endif

   return 0;
}
Esempio n. 14
0
/**
 * rarch_main_iterate:
 *
 * Run Libretro core in RetroArch for one frame.
 *
 * Returns: 0 on success, 1 if we have to wait until button input in order
 * to wake up the loop, -1 if we forcibly quit out of the RetroArch iteration loop.
 **/
int rarch_main_iterate(unsigned *sleep_ms)
{
   int ret;
   unsigned i;
   retro_input_t trigger_input;
   event_cmd_state_t    cmd;
   retro_time_t current, target, to_sleep_ms;
   static retro_input_t last_input = 0;
   driver_t *driver                = driver_get_ptr();
   settings_t *settings            = config_get_ptr();
   global_t   *global              = global_get_ptr();
   retro_input_t input             = input_keys_pressed(driver, settings, global);
   rarch_system_info_t *system     = rarch_system_info_get_ptr();
   retro_input_t old_input         = last_input;
   last_input                      = input;

   if (driver->flushing_input)
   {
      driver->flushing_input = false;
      if (input)
      {
         input = 0;

         /* If core was paused before entering menu, evoke
          * pause toggle to wake it up. */
         if (main_is_paused)
            BIT64_SET(input, RARCH_PAUSE_TOGGLE);
         driver->flushing_input = true;
      }
   }

   trigger_input = input & ~old_input;

   rarch_main_cmd_get_state(driver, settings, &cmd, input, old_input, trigger_input);

   if (system->frame_time.callback)
   {
      /* Updates frame timing if frame timing callback is in use by the core.
       * Limits frame time if fast forward ratio throttle is enabled. */

      retro_time_t current     = retro_get_time_usec();
      retro_time_t delta       = current - system->frame_time_last;
      bool is_locked_fps       = (main_is_paused || driver->nonblock_state) |
         !!driver->recording_data;

      if (!system->frame_time_last || is_locked_fps)
         delta = system->frame_time.reference;

      if (!is_locked_fps && main_is_slowmotion)
         delta /= settings->slowmotion_ratio;

      system->frame_time_last = current;

      if (is_locked_fps)
         system->frame_time_last = 0;

      system->frame_time.callback(delta);
   }

   if (cmd.overlay_next_pressed)
      event_command(EVENT_CMD_OVERLAY_NEXT);

   if (!main_is_paused || menu_driver_alive())
   {
      if (cmd.fullscreen_toggle)
         event_command(EVENT_CMD_FULLSCREEN_TOGGLE);
   }

   if (cmd.grab_mouse_pressed)
      event_command(EVENT_CMD_GRAB_MOUSE_TOGGLE);

#ifdef HAVE_MENU
   if (cmd.menu_pressed || (global->inited.core.type == CORE_TYPE_DUMMY))
   {
      if (menu_driver_alive())
      {
         if (global->inited.main && (global->inited.core.type != CORE_TYPE_DUMMY))
            rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED, NULL);
      }
      else
         rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING, NULL);
   }
#endif

#ifdef HAVE_OVERLAY
   rarch_main_iterate_linefeed_overlay(driver, settings);
#endif

   ret = rarch_main_iterate_time_to_exit(&cmd);

   if (ret != 1)
      return -1;


#ifdef HAVE_MENU
   if (menu_driver_alive())
   {
      if (menu_driver_iterate((enum menu_action)menu_input_frame(input, trigger_input)) == -1)
         rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED, NULL);

      if (!input && settings->menu.pause_libretro)
        return 1;
      goto end;
   }
#endif

   if (!rarch_main_ctl(RARCH_MAIN_CTL_CHECK_STATE, &cmd))
   {
      /* RetroArch has been paused. */
      driver->retro_ctx.poll_cb();
      *sleep_ms = 10;
      return 1;
   }

#if defined(HAVE_THREADS)
   lock_autosave();
#endif

#ifdef HAVE_NETPLAY
   if (driver->netplay_data)
      netplay_pre_frame((netplay_t*)driver->netplay_data);
#endif

   if (global->bsv.movie)
      bsv_movie_set_frame_start(global->bsv.movie);

   if (system->camera_callback.caps)
      driver_camera_poll();

   /* Update binds for analog dpad modes. */
   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_push_analog_dpad(settings->input.binds[i],
            settings->input.analog_dpad_mode[i]);
      input_push_analog_dpad(settings->input.autoconf_binds[i],
            settings->input.analog_dpad_mode[i]);
   }

   if ((settings->video.frame_delay > 0) && !driver->nonblock_state)
      retro_sleep(settings->video.frame_delay);

   /* Run libretro for one frame. */
   core.retro_run();

#ifdef HAVE_CHEEVOS
   /* Test the achievements. */
   cheevos_test();
#endif

   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_pop_analog_dpad(settings->input.binds[i]);
      input_pop_analog_dpad(settings->input.autoconf_binds[i]);
   }

   if (global->bsv.movie)
      bsv_movie_set_frame_end(global->bsv.movie);

#ifdef HAVE_NETPLAY
   if (driver->netplay_data)
      netplay_post_frame((netplay_t*)driver->netplay_data);
#endif

#if defined(HAVE_THREADS)
   unlock_autosave();
#endif

#ifdef HAVE_MENU
end:
#endif
   if (!settings->fastforward_ratio)
      return 0;

   current                        = retro_get_time_usec();
   target                         = frame_limit_last_time + frame_limit_minimum_time;
   to_sleep_ms                    = (target - current) / 1000;

   if (to_sleep_ms > 0)
   {
      *sleep_ms = (unsigned)to_sleep_ms;
      /* Combat jitter a bit. */
      frame_limit_last_time += frame_limit_minimum_time;
      return 1;
   }

   frame_limit_last_time  = retro_get_time_usec();

   return 0;
}
Esempio n. 15
0
static void dsound_thread(void *data)
{
   DWORD write_ptr;
   dsound_t *ds = (dsound_t*)data;

   SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);

   get_positions(ds, NULL, &write_ptr);
   write_ptr = (write_ptr + ds->buffer_size / 2) % ds->buffer_size;

   while (ds->thread_alive)
   {
      struct audio_lock region;
      DWORD read_ptr, avail, fifo_avail;
      get_positions(ds, &read_ptr, NULL);
      
      avail = write_avail(read_ptr, write_ptr, ds->buffer_size);

      EnterCriticalSection(&ds->crit);
      fifo_avail = fifo_read_avail(ds->buffer);
      LeaveCriticalSection(&ds->crit);

      if (avail < CHUNK_SIZE || ((fifo_avail < CHUNK_SIZE) && (avail < ds->buffer_size / 2)))
      {
         /* No space to write, or we don't have data in our fifo, 
          * but we can wait some time before it underruns ... */


         /* We could opt for using the notification interface,
          * but it is not guaranteed to work, so use high 
          * priority sleeping patterns.
          */
         retro_sleep(1);
         continue;
      }

      if (!grab_region(ds, write_ptr, &region))
      {
         ds->thread_alive = false;
         SetEvent(ds->event);
         break;
      }

      if (fifo_avail < CHUNK_SIZE)
      {
         /* Got space to write, but nothing in FIFO (underrun), 
          * fill block with silence. */

         memset(region.chunk1, 0, region.size1);
         memset(region.chunk2, 0, region.size2);

         release_region(ds, &region);
         write_ptr = (write_ptr + region.size1 + region.size2) % ds->buffer_size;
      }
      else 
      {
         /* All is good. Pull from it and notify FIFO. */

         EnterCriticalSection(&ds->crit);
         if (region.chunk1)
            fifo_read(ds->buffer, region.chunk1, region.size1);
         if (region.chunk2)
            fifo_read(ds->buffer, region.chunk2, region.size2);
         LeaveCriticalSection(&ds->crit);

         release_region(ds, &region);
         write_ptr = (write_ptr + region.size1 + region.size2) % ds->buffer_size;

         SetEvent(ds->event);
      }
   }

   ExitThread(0);
}
Esempio n. 16
0
/**
 * main_entry:
 *
 * Main function of RetroArch.
 *
 * If HAVE_MAIN is not defined, will contain main loop and will not
 * be exited from until we exit the program. Otherwise, will
 * just do initialization.
 *
 * Returns: varies per platform.
 **/
int rarch_main(int argc, char *argv[], void *data)
{
   void *args                      = (void*)data;
   int ret                         = 0;
   settings_t *settings            = NULL;

   rarch_ctl(RARCH_CTL_PREINIT, NULL);

   frontend_driver_init_first(args);
   rarch_ctl(RARCH_CTL_INIT, NULL);

#ifdef HAVE_THREADS
   async_jobs = async_job_new();
#endif
   
   if (frontend_driver_is_inited())
   {
      ret = main_load_content(argc, argv, args,
            frontend_driver_environment_get_ptr());

      if (!ret)
         return ret;
   }

   event_cmd_ctl(EVENT_CMD_HISTORY_INIT, NULL);

   settings = config_get_ptr();

   if (settings->history_list_enable)
   {
      char *fullpath              = NULL;
      rarch_system_info_t *system = NULL;
      
      runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET,  &system);
      runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath);

      if (content_ctl(CONTENT_CTL_IS_INITED, NULL) || system->no_content)
         history_playlist_push(
               g_defaults.history,
               fullpath,
               settings->libretro,
               system ? &system->info : NULL);
   }

   ui_companion_driver_init_first();

#ifndef HAVE_MAIN
   do
   {
      unsigned sleep_ms = 0;
      ret = runloop_iterate(&sleep_ms);

      if (ret == 1 && sleep_ms > 0)
         retro_sleep(sleep_ms);
      runloop_ctl(RUNLOOP_CTL_DATA_ITERATE, NULL);
   }while(ret != -1);

   main_exit(args);
#endif

#ifdef HAVE_THREADS
   async_job_free(async_jobs);
   async_jobs = NULL;
#endif

   return 0;
}
Esempio n. 17
0
/**
 * runloop_iterate:
 *
 * Run Libretro core in RetroArch for one frame.
 *
 * Returns: 0 on success, 1 if we have to wait until
 * button input in order to wake up the loop,
 * -1 if we forcibly quit out of the RetroArch iteration loop.
 **/
int runloop_iterate(unsigned *sleep_ms)
{
   unsigned i;
   retro_time_t current, target, to_sleep_ms;
   static uint64_t last_input                   = 0;
   enum runloop_state runloop_status            = RUNLOOP_STATE_NONE;
   static retro_time_t frame_limit_minimum_time = 0.0;
   static retro_time_t frame_limit_last_time    = 0.0;
   settings_t *settings                         = config_get_ptr();
   uint64_t current_input                       = menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL) ? input_menu_keys_pressed() : input_keys_pressed();
   uint64_t old_input                           = last_input;

   last_input                                   = current_input;

   if (runloop_frame_time_last_enable)
   {
      runloop_frame_time_last        = 0;
      runloop_frame_time_last_enable = false;
   }

   if (runloop_set_frame_limit)
   {
      struct retro_system_av_info *av_info =
         video_viewport_get_system_av_info();
      float fastforward_ratio              =
         (settings->fastforward_ratio == 0.0f)
         ? 1.0f : settings->fastforward_ratio;

      frame_limit_last_time    = cpu_features_get_time_usec();
      frame_limit_minimum_time = (retro_time_t)roundf(1000000.0f
            / (av_info->timing.fps * fastforward_ratio));

      runloop_set_frame_limit = false;
   }

   if (runloop_frame_time.callback)
   {
      /* Updates frame timing if frame timing callback is in use by the core.
       * Limits frame time if fast forward ratio throttle is enabled. */

      retro_time_t current     = cpu_features_get_time_usec();
      retro_time_t delta       = current - runloop_frame_time_last;
      bool is_locked_fps       = (runloop_paused ||
                                  input_driver_is_nonblock_state()) |
                                  !!recording_driver_get_data_ptr();


      if (!runloop_frame_time_last || is_locked_fps)
         delta = runloop_frame_time.reference;

      if (!is_locked_fps && runloop_slowmotion)
         delta /= settings->slowmotion_ratio;

      runloop_frame_time_last = current;

      if (is_locked_fps)
         runloop_frame_time_last = 0;

      runloop_frame_time.callback(delta);
   }

   runloop_status = runloop_check_state(settings, current_input,
         old_input, sleep_ms);

   switch (runloop_status)
   {
      case RUNLOOP_STATE_QUIT:
         frame_limit_last_time = 0.0;
         command_event(CMD_EVENT_QUIT, NULL);
         return -1;
      case RUNLOOP_STATE_SLEEP:
      case RUNLOOP_STATE_END:
      case RUNLOOP_STATE_MENU_ITERATE:
         core_poll();
#ifdef HAVE_NETWORKING
         /* FIXME: This is an ugly way to tell Netplay this... */
         netplay_driver_ctl(RARCH_NETPLAY_CTL_PAUSE, NULL);
#endif
         if (runloop_status == RUNLOOP_STATE_SLEEP)
            *sleep_ms = 10;
         if (runloop_status == RUNLOOP_STATE_END)
            goto end;
         if (runloop_status == RUNLOOP_STATE_MENU_ITERATE)
            return 0;
         return 1;
      case RUNLOOP_STATE_ITERATE:
      case RUNLOOP_STATE_NONE:
      default:
         break;
   }

   autosave_lock();

   if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL))
      bsv_movie_ctl(BSV_MOVIE_CTL_SET_FRAME_START, NULL);

   camera_driver_ctl(RARCH_CAMERA_CTL_POLL, NULL);

   /* Update binds for analog dpad modes. */
   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_push_analog_dpad(settings->input.binds[i],
            settings->input.analog_dpad_mode[i]);
      input_push_analog_dpad(settings->input.autoconf_binds[i],
            settings->input.analog_dpad_mode[i]);
   }

   if ((settings->video.frame_delay > 0) &&
         !input_driver_is_nonblock_state())
      retro_sleep(settings->video.frame_delay);

   core_run();

#ifdef HAVE_CHEEVOS
   cheevos_test();
#endif

   for (i = 0; i < settings->input.max_users; i++)
   {
      if (!settings->input.analog_dpad_mode[i])
         continue;

      input_pop_analog_dpad(settings->input.binds[i]);
      input_pop_analog_dpad(settings->input.autoconf_binds[i]);
   }

   if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL))
      bsv_movie_ctl(BSV_MOVIE_CTL_SET_FRAME_END, NULL);

   autosave_unlock();

   if (!settings->fastforward_ratio)
      return 0;

end:

   current                        = cpu_features_get_time_usec();
   target                         = frame_limit_last_time +
      frame_limit_minimum_time;
   to_sleep_ms                    = (target - current) / 1000;

   if (to_sleep_ms > 0)
   {
      *sleep_ms = (unsigned)to_sleep_ms;
      /* Combat jitter a bit. */
      frame_limit_last_time += frame_limit_minimum_time;
      return 1;
   }

   frame_limit_last_time  = cpu_features_get_time_usec();

   return 0;
}
Esempio n. 18
0
int main(int argc, char **argv)
{
#if 1
   setup_os_exceptions();
#else
   InstallExceptionHandler();
#endif
   ProcUIInit(&SaveCallback);

   socket_lib_init();
#if defined(PC_DEVELOPMENT_IP_ADDRESS) && defined(PC_DEVELOPMENT_TCP_PORT)
   log_init(PC_DEVELOPMENT_IP_ADDRESS, PC_DEVELOPMENT_TCP_PORT);
   devoptab_list[STD_OUT] = &dotab_stdout;
   devoptab_list[STD_ERR] = &dotab_stdout;
#endif
#ifndef IS_SALAMANDER
   VPADInit();
   WPADEnableURCC(true);
   WPADEnableWiiRemote(true);
   KPADInit();
#endif
   verbosity_enable();

   printf("starting\n");
   fflush(stdout);
   DEBUG_VAR(ARGV_PTR);
   if(ARGV_PTR && ((u32)ARGV_PTR < 0x01000000))
   {
      struct
      {
         u32 magic;
         u32 argc;
         char * argv[3];
      }*param = ARGV_PTR;
      if(param->magic == ARGV_MAGIC)
      {
         argc = param->argc;
         argv = param->argv;
      }
      ARGV_PTR = NULL;
   }

   DEBUG_VAR(argc);
   DEBUG_STR(argv[0]);
   DEBUG_STR(argv[1]);
   fflush(stdout);
#ifdef IS_SALAMANDER
   int salamander_main(int, char **);
   salamander_main(argc, argv);
#else
#if 1
#if 0
   int argc_ = 2;
//   char* argv_[] = {WIIU_SD_PATH "retroarch/retroarch.elf", WIIU_SD_PATH "rom.nes", NULL};
   char *argv_[] = {WIIU_SD_PATH "retroarch/retroarch.elf", WIIU_SD_PATH "rom.sfc", NULL};

   rarch_main(argc_, argv_, NULL);
#else
   rarch_main(argc, argv, NULL);
#endif
   do
   {
      unsigned sleep_ms = 0;
      int ret = runloop_iterate(&sleep_ms);

      if (ret == 1 && sleep_ms > 0)
         retro_sleep(sleep_ms);

      task_queue_ctl(TASK_QUEUE_CTL_WAIT, NULL);

      if (ret == -1)
         break;

   }
   while (1);

   main_exit(NULL);
#endif
#endif
   fflush(stdout);
   fflush(stderr);
   ProcUIShutdown();

#if defined(PC_DEVELOPMENT_IP_ADDRESS) && defined(PC_DEVELOPMENT_TCP_PORT)
   log_deinit();
#endif

   /* returning non 0 here can prevent loading a different rpx/elf in the HBL environment */
   return 0;
}
Esempio n. 19
0
void gbemu_cpu_run(int cycles)
{
   gbemu_cpu_t CPU = GB.CPU;

   CPU.cycles = 0;
   GB.APU.cycles = 0;
   GB.APU.write_pos = gbemu_sound_buffer;
   int cycles_last = 0;
   static int h_cycles = 0;
next_instruction:

   gbemu_ppu_draw(CPU.cycles);
   gbemu_apu_run(CPU.cycles);

   CPU.timer.ticks += CPU.cycles - cycles_last;

   while (CPU.timer.ticks_last < CPU.timer.ticks)
   {
      CPU.timer.ticks_last++;
      if (!(CPU.timer.ticks_last & 0x3F))
         GB.DIV++;

      if (GB.TAC.active)
      {
         /* 0: 0xFF
          * 1: 0x03
          * 2: 0x0F
          * 3: 0x3F */
         static const uint8_t timer_masks[4] = {0xFF, 0x03, 0x0F, 0x3F};
         if (!(CPU.timer.ticks_last & timer_masks[GB.TAC.clock_select]))
         {
            GB.TIMA++;
            if (!GB.TIMA)
            {
               GB.TIMA = GB.TMA;
               GB.IF.timer = 1;
            }
         }
      }
   }

   if (CPU.cycles > cycles)
      goto cpu_exit;

   h_cycles += CPU.cycles - cycles_last;
   cycles_last = CPU.cycles;
   if (h_cycles > GB_LINE_TICK_COUNT)
   {
      h_cycles -= GB_LINE_TICK_COUNT;
      GB.LY++;
      if (GB.LY >= GB_V_COUNT)
      {
         GB.LY = 0;
         goto cpu_exit;
      }
   }



   if (GB.LCDC.LCD_enable)
   {
      if (GB.LY == GB.LYC)
      {
         if(!GB.LCD_STAT.LCY_eq_LY_flag)
         {
            GB.LCD_STAT.LCY_eq_LY_flag = 1;
            if(GB.LCD_STAT.LCY_eq_LY_IE)
               GB.IF.LCD_stat = 1;
         }
      }
      else
         GB.LCD_STAT.LCY_eq_LY_flag = 0;


      if (GB.LY < 144)
      {
         if (h_cycles > (80 + 20))
         {
            if(GB.LCD_STAT.mode_flag != GB_LCD_STAT_MODE0_HBLANK)
            {
               GB.LCD_STAT.mode_flag = GB_LCD_STAT_MODE0_HBLANK;
               if(GB.LCD_STAT.HBlank_IE)
                  GB.IF.LCD_stat = 1;
            }
         }
         else if (h_cycles > 20)
         {
            if(GB.LCD_STAT.mode_flag != GB_LCD_STAT_MODE3_OAM_VRAM_busy)
               GB.LCD_STAT.mode_flag = GB_LCD_STAT_MODE3_OAM_VRAM_busy;
         }
         else
         {
            if (GB.LCD_STAT.mode_flag != GB_LCD_STAT_MODE2_OAM_busy)
            {
               GB.LCD_STAT.mode_flag = GB_LCD_STAT_MODE2_OAM_busy;
               if(GB.LCD_STAT.OAM_IE)
                  GB.IF.LCD_stat = 1;
            }
         }

      }
      else if (GB.LCD_STAT.mode_flag != GB_LCD_STAT_MODE1_VBLANK)
      {
         GB.LCD_STAT.mode_flag = GB_LCD_STAT_MODE1_VBLANK;
         GB.IF.Vblank = 1;
         if(GB.LCD_STAT.VBlank_IE)
            GB.IF.LCD_stat = 1;
      }



   }

//   if((GB.LCD_STAT.VBlank_IE && (GB.LCD_STAT.mode_flag == GB_LCD_STAT_MODE1_VBLANK)) ||
//      (GB.LCD_STAT.HBlank_IE && (GB.LCD_STAT.mode_flag == GB_LCD_STAT_MODE0_HBLANK)) ||
//      (GB.LCD_STAT.OAM_IE && (GB.LCD_STAT.mode_flag == GB_LCD_STAT_MODE2_OAM_busy)) ||
//      (GB.LCD_STAT.LCY_eq_LY_IE && GB.LCD_STAT.LCY_eq_LY_flag))
//      GB.IF.LCD_stat = 1;
   if(CPU.HALT)
   {
      if (GB.IF.Vblank
          || GB.IF.LCD_stat
          || GB.IF.timer
          || GB.IF.serial
          || GB.IF.joypad )
         CPU_disable_halt();
      else
      {
         CPU_cycles_inc();
         goto next_instruction;
      }
   }

   if (CPU.IME)
   {
      if ((GB.IF.Vblank && GB.IE.Vblank) && GB.LCDC.LCD_enable)
      {
         CPU.IME = 0;
         GB.IF.Vblank = 0;
         CPU_INT(0x40);
      }
      else if (GB.IF.LCD_stat && GB.IE.LCD_stat)
      {
         CPU.IME = 0;
         GB.IF.LCD_stat = 0;
         CPU_INT(0x48);
      }
      else if (GB.IF.timer && GB.IE.timer)
      {
         CPU.IME = 0;
         GB.IF.timer = 0;
         CPU_INT(0x50);
      }
      else if (GB.IF.serial && GB.IE.serial)
      {
         CPU.IME = 0;
         GB.IF.serial = 0;
         CPU_INT(0x58);
      }
      else if (GB.IF.joypad && GB.IE.joypad)
      {
         CPU.IME = 0;
         GB.IF.joypad = 0;
         CPU_INT(0x60);
      }
   }

//#define DISASM
   #define SKIP_COUNT 0x12000
   //#define SKIP_COUNT 0xEEE9
//   #define SKIP_COUNT 0x00049B4C
//#define SKIP_COUNT 0xFFFFFFFF
//#define SKIP_COUNT 0x00000000


   static int total_exec = 0;
#ifdef DISASM
   static bool force_disasm = false;
#endif
next_instruction_nocheck:
#ifdef DISASM
//      if(CPU.PC == 0xC2B5)
//   if (CPU.PC >= 0x4000)
//      force_disasm = true;

   if (total_exec > SKIP_COUNT)
   {
      force_disasm = true;
      printf("0x%08X: ", total_exec);
   }

   if (force_disasm)
   {
      gbemu_disasm_current(&CPU, true);
      fflush(stdout);
   }
#endif

   total_exec++;
//   if(GB.MEMORY[0xFF44] == 0x94)
//      fflush(stdout);
//   if ((CPU.AF == 0x810b))
//       fflush(stdout);
//   if ((CPU.PC == 0xDEF8))
//       fflush(stdout);
//   if ((CPU.PC == 0xC4C2) && (CPU.A == 0xF1))
//       fflush(stdout);


#ifdef USE_BIOS
   if(CPU.PC == 0x100)
      memcpy(GB.MEMORY, GB.BIOS, 0x100);
#endif

   switch (GB_READ_PC())
   {
   // NOP
   //   case 0x7F:
   //   case 0x40:
   //   case 0x49:
   //   case 0x52:
   //   case 0x5B:
   //   case 0x64:
   //   case 0x6D:
   case 0x00:
      CPU_NOP();
   case 0x08:
      CPU_LD_addr16_SP();
   case 0x10:
      CPU_STOP();
   case 0x18:
      CPU_JR(CPU_COND_ALWAYS);
   case 0x20:
      CPU_JR(CPU_COND_NZ);
   case 0x28:
      CPU_JR(CPU_COND_Z);
   case 0x30:
      CPU_JR(CPU_COND_NC);
   case 0x38:
      CPU_JR(CPU_COND_C);

   case 0x01:
      CPU_LD_rr_imm16(REG_BC);
   case 0x11:
      CPU_LD_rr_imm16(REG_DE);
   case 0x21:
      CPU_LD_rr_imm16(REG_HL);
   case 0x31:
      CPU_LD_rr_imm16(REG_SP);

   case 0x09:
      CPU_ADD_rr_rr(REG_HL, REG_BC);
   case 0x19:
      CPU_ADD_rr_rr(REG_HL, REG_DE);
   case 0x29:
      CPU_ADD_rr_rr(REG_HL, REG_HL);
   case 0x39:
      CPU_ADD_rr_rr(REG_HL, REG_SP);

   case 0x02:
      CPU_LD_raddr_r(REG_BC, REG_A);
   case 0x0A:
      CPU_LD_r_raddr(REG_A, REG_BC);
   case 0x12:
      CPU_LD_raddr_r(REG_DE, REG_A);
   case 0x1A:
      CPU_LD_r_raddr(REG_A, REG_DE);
   case 0x22:
      CPU_LD_raddr_r(REG_HL++, REG_A);
   case 0x2A:
      CPU_LD_r_raddr(REG_A, REG_HL++);
   case 0x32:
      CPU_LD_raddr_r(REG_HL--, REG_A);
   case 0x3A:
      CPU_LD_r_raddr(REG_A, REG_HL--);

   case 0x03:
      CPU_INC_rr(REG_BC);
   case 0x0B:
      CPU_DEC_rr(REG_BC);
   case 0x13:
      CPU_INC_rr(REG_DE);
   case 0x1B:
      CPU_DEC_rr(REG_DE);
   case 0x23:
      CPU_INC_rr(REG_HL);
   case 0x2B:
      CPU_DEC_rr(REG_HL);
   case 0x33:
      CPU_INC_rr(REG_SP);
   case 0x3B:
      CPU_DEC_rr(REG_SP);

   case 0x04:
      CPU_INC_r(REG_B);
   case 0x0C:
      CPU_INC_r(REG_C);
   case 0x14:
      CPU_INC_r(REG_D);
   case 0x1C:
      CPU_INC_r(REG_E);
   case 0x24:
      CPU_INC_r(REG_H);
   case 0x2C:
      CPU_INC_r(REG_L);
   case 0x34:
      CPU_INC_raddr(REG_HL);
   case 0x3C:
      CPU_INC_r(REG_A);

   case 0x05:
      CPU_DEC_r(REG_B);
   case 0x0D:
      CPU_DEC_r(REG_C);
   case 0x15:
      CPU_DEC_r(REG_D);
   case 0x1D:
      CPU_DEC_r(REG_E);
   case 0x25:
      CPU_DEC_r(REG_H);
   case 0x2D:
      CPU_DEC_r(REG_L);
   case 0x35:
      CPU_DEC_raddr(REG_HL);
   case 0x3D:
      CPU_DEC_r(REG_A);

   case 0x06:
      CPU_LD_r_imm8(REG_B);
   case 0x0E:
      CPU_LD_r_imm8(REG_C);
   case 0x16:
      CPU_LD_r_imm8(REG_D);
   case 0x1E:
      CPU_LD_r_imm8(REG_E);
   case 0x26:
      CPU_LD_r_imm8(REG_H);
   case 0x2E:
      CPU_LD_r_imm8(REG_L);
   case 0x36:
      CPU_LD_raddr_imm8(REG_HL);
   case 0x3E:
      CPU_LD_r_imm8(REG_A);

   case 0x07:
      CPU_RLCA();
   case 0x0F:
      CPU_RRCA();
   case 0x17:
      CPU_RLA();
   case 0x1F:
      CPU_RRA();
   case 0x27:
      CPU_DAA();
   case 0x2F:
      CPU_CPL();
   case 0x37:
      CPU_SCF();
   case 0x3F:
      CPU_CCF();
      
   // LD r1, r2
   case 0x40:
      CPU_LD_r0_r1(CPU.B, CPU.B);
   case 0x41:
      CPU_LD_r0_r1(CPU.B, CPU.C);
   case 0x42:
      CPU_LD_r0_r1(CPU.B, CPU.D);
   case 0x43:
      CPU_LD_r0_r1(CPU.B, CPU.E);
   case 0x44:
      CPU_LD_r0_r1(CPU.B, CPU.H);
   case 0x45:
      CPU_LD_r0_r1(CPU.B, CPU.L);
   case 0x46:
      CPU_LD_r_raddr(CPU.B, CPU.HL);
   case 0x47:
      CPU_LD_r0_r1(CPU.B, CPU.A);

   case 0x48:
      CPU_LD_r0_r1(CPU.C, CPU.B);
   case 0x49:
      CPU_LD_r0_r1(CPU.C, CPU.C);
   case 0x4A:
      CPU_LD_r0_r1(CPU.C, CPU.D);
   case 0x4B:
      CPU_LD_r0_r1(CPU.C, CPU.E);
   case 0x4C:
      CPU_LD_r0_r1(CPU.C, CPU.H);
   case 0x4D:
      CPU_LD_r0_r1(CPU.C, CPU.L);
   case 0x4E:
      CPU_LD_r_raddr(CPU.C, CPU.HL);
   case 0x4F:
      CPU_LD_r0_r1(CPU.C, CPU.A);

   case 0x50:
      CPU_LD_r0_r1(CPU.D, CPU.B);
   case 0x51:
      CPU_LD_r0_r1(CPU.D, CPU.C);
   case 0x52:
      CPU_LD_r0_r1(CPU.D, CPU.D);
   case 0x53:
      CPU_LD_r0_r1(CPU.D, CPU.E);
   case 0x54:
      CPU_LD_r0_r1(CPU.D, CPU.H);
   case 0x55:
      CPU_LD_r0_r1(CPU.D, CPU.L);
   case 0x56:
      CPU_LD_r_raddr(CPU.D, CPU.HL);
   case 0x57:
      CPU_LD_r0_r1(CPU.D, CPU.A);

   case 0x58:
      CPU_LD_r0_r1(CPU.E, CPU.B);
   case 0x59:
      CPU_LD_r0_r1(CPU.E, CPU.C);
   case 0x5A:
      CPU_LD_r0_r1(CPU.E, CPU.D);
   case 0x5B:
      CPU_LD_r0_r1(CPU.E, CPU.E);
   case 0x5C:
      CPU_LD_r0_r1(CPU.E, CPU.H);
   case 0x5D:
      CPU_LD_r0_r1(CPU.E, CPU.L);
   case 0x5E:
      CPU_LD_r_raddr(CPU.E, CPU.HL);
   case 0x5F:
      CPU_LD_r0_r1(CPU.E, CPU.A);

   case 0x60:
      CPU_LD_r0_r1(CPU.H, CPU.B);
   case 0x61:
      CPU_LD_r0_r1(CPU.H, CPU.C);
   case 0x62:
      CPU_LD_r0_r1(CPU.H, CPU.D);
   case 0x63:
      CPU_LD_r0_r1(CPU.H, CPU.E);
   case 0x64:
      CPU_LD_r0_r1(CPU.H, CPU.H);
   case 0x65:
      CPU_LD_r0_r1(CPU.H, CPU.L);
   case 0x66:
      CPU_LD_r_raddr(CPU.H, CPU.HL);
   case 0x67:
      CPU_LD_r0_r1(CPU.H, CPU.A);

   case 0x68:
      CPU_LD_r0_r1(CPU.L, CPU.B);
   case 0x69:
      CPU_LD_r0_r1(CPU.L, CPU.C);
   case 0x6A:
      CPU_LD_r0_r1(CPU.L, CPU.D);
   case 0x6B:
      CPU_LD_r0_r1(CPU.L, CPU.E);
   case 0x6C:
      CPU_LD_r0_r1(CPU.L, CPU.H);
   case 0x6D:
      CPU_LD_r0_r1(CPU.L, CPU.L);
   case 0x6E:
      CPU_LD_r_raddr(CPU.L, CPU.HL);
   case 0x6F:
      CPU_LD_r0_r1(CPU.L, CPU.A);

   case 0x70:
      CPU_LD_raddr_r(CPU.HL, CPU.B);
   case 0x71:
      CPU_LD_raddr_r(CPU.HL, CPU.C);
   case 0x72:
      CPU_LD_raddr_r(CPU.HL, CPU.D);
   case 0x73:
      CPU_LD_raddr_r(CPU.HL, CPU.E);
   case 0x74:
      CPU_LD_raddr_r(CPU.HL, CPU.H);
   case 0x75:
      CPU_LD_raddr_r(CPU.HL, CPU.L);
   case 0x76:
      CPU_HALT();
   case 0x77:
      CPU_LD_raddr_r(CPU.HL, CPU.A);

   case 0x78:
      CPU_LD_r0_r1(CPU.A, CPU.B);
   case 0x79:
      CPU_LD_r0_r1(CPU.A, CPU.C);
   case 0x7A:
      CPU_LD_r0_r1(CPU.A, CPU.D);
   case 0x7B:
      CPU_LD_r0_r1(CPU.A, CPU.E);
   case 0x7C:
      CPU_LD_r0_r1(CPU.A, CPU.H);
   case 0x7D:
      CPU_LD_r0_r1(CPU.A, CPU.L);
   case 0x7E:
      CPU_LD_r_raddr(CPU.A, CPU.HL);
   case 0x7F:
      CPU_LD_r0_r1(CPU.A, CPU.A);

   /* ALU */
   case 0x80:
      CPU_ADD_r_r(REG_A, REG_B);
   case 0x81:
      CPU_ADD_r_r(REG_A, REG_C);
   case 0x82:
      CPU_ADD_r_r(REG_A, REG_D);
   case 0x83:
      CPU_ADD_r_r(REG_A, REG_E);
   case 0x84:
      CPU_ADD_r_r(REG_A, REG_H);
   case 0x85:
      CPU_ADD_r_r(REG_A, REG_L);
   case 0x86:
      CPU_ADD_r_raddr(REG_A, REG_HL);
   case 0x87:
      CPU_ADD_r_r(REG_A, REG_A);

   case 0x88:
      CPU_ADC_r_r(REG_A, REG_B);
   case 0x89:
      CPU_ADC_r_r(REG_A, REG_C);
   case 0x8A:
      CPU_ADC_r_r(REG_A, REG_D);
   case 0x8B:
      CPU_ADC_r_r(REG_A, REG_E);
   case 0x8C:
      CPU_ADC_r_r(REG_A, REG_H);
   case 0x8D:
      CPU_ADC_r_r(REG_A, REG_L);
   case 0x8E:
      CPU_ADC_r_raddr(REG_A, REG_HL);
   case 0x8F:
      CPU_ADC_r_r(REG_A, REG_A);

   case 0x90:
      CPU_SUB_r_r(REG_A, REG_B);
   case 0x91:
      CPU_SUB_r_r(REG_A, REG_C);
   case 0x92:
      CPU_SUB_r_r(REG_A, REG_D);
   case 0x93:
      CPU_SUB_r_r(REG_A, REG_E);
   case 0x94:
      CPU_SUB_r_r(REG_A, REG_H);
   case 0x95:
      CPU_SUB_r_r(REG_A, REG_L);
   case 0x96:
      CPU_SUB_r_raddr(REG_A, REG_HL);
   case 0x97:
      CPU_SUB_r_r(REG_A, REG_A);

   case 0x98:
      CPU_SBC_r_r(REG_A, REG_B);
   case 0x99:
      CPU_SBC_r_r(REG_A, REG_C);
   case 0x9A:
      CPU_SBC_r_r(REG_A, REG_D);
   case 0x9B:
      CPU_SBC_r_r(REG_A, REG_E);
   case 0x9C:
      CPU_SBC_r_r(REG_A, REG_H);
   case 0x9D:
      CPU_SBC_r_r(REG_A, REG_L);
   case 0x9E:
      CPU_SBC_r_raddr(REG_A, REG_HL);
   case 0x9F:
      CPU_SBC_r_r(REG_A, REG_A);

   case 0xA0:
      CPU_AND_A_r(REG_B);
   case 0xA1:
      CPU_AND_A_r(REG_C);
   case 0xA2:
      CPU_AND_A_r(REG_D);
   case 0xA3:
      CPU_AND_A_r(REG_E);
   case 0xA4:
      CPU_AND_A_r(REG_H);
   case 0xA5:
      CPU_AND_A_r(REG_L);
   case 0xA6:
      CPU_AND_A_raddr(REG_HL);
   case 0xA7:
      CPU_AND_A_r(REG_A);

   case 0xA8:
      CPU_XOR_A_r(REG_B);
   case 0xA9:
      CPU_XOR_A_r(REG_C);
   case 0xAA:
      CPU_XOR_A_r(REG_D);
   case 0xAB:
      CPU_XOR_A_r(REG_E);
   case 0xAC:
      CPU_XOR_A_r(REG_H);
   case 0xAD:
      CPU_XOR_A_r(REG_L);
   case 0xAE:
      CPU_XOR_A_raddr(REG_HL);
   case 0xAF:
      CPU_XOR_A_r(REG_A);

   case 0xB0:
      CPU_OR_A_r(REG_B);
   case 0xB1:
      CPU_OR_A_r(REG_C);
   case 0xB2:
      CPU_OR_A_r(REG_D);
   case 0xB3:
      CPU_OR_A_r(REG_E);
   case 0xB4:
      CPU_OR_A_r(REG_H);
   case 0xB5:
      CPU_OR_A_r(REG_L);
   case 0xB6:
      CPU_OR_A_raddr(REG_HL);
   case 0xB7:
      CPU_OR_A_r(REG_A);

   case 0xB8:
      CPU_CP_A_r(REG_B);
   case 0xB9:
      CPU_CP_A_r(REG_C);
   case 0xBA:
      CPU_CP_A_r(REG_D);
   case 0xBB:
      CPU_CP_A_r(REG_E);
   case 0xBC:
      CPU_CP_A_r(REG_H);
   case 0xBD:
      CPU_CP_A_r(REG_L);
   case 0xBE:
      CPU_CP_A_raddr(REG_HL);
   case 0xBF:
      CPU_CP_A_r(REG_A);

   /*******/
   case 0xC0:
      CPU_RET_cc(CPU_COND_NZ);
   case 0xC8:
      CPU_RET_cc(CPU_COND_Z);
   case 0xD0:
      CPU_RET_cc(CPU_COND_NC);
   case 0xD8:
      CPU_RET_cc(CPU_COND_C);

   case 0xE0:
      CPU_LD_addr8_r(REG_A);
   case 0xF0:
      CPU_LD_r_addr8(REG_A);
   case 0xE8:      
      CPU_ADD_SP_off8();
   case 0xF8:
      CPU_LD_HL_SP_off8();

   // POP (rr)
   case 0xC1:
      CPU_POP_BC();
   case 0xD1:
      CPU_POP_DE();
   case 0xE1:
      CPU_POP_HL();
   case 0xF1:
      CPU_POP_AF();

   case 0xC9:
      CPU_RET();
   case 0xD9:
      CPU_RETI();
   case 0xE9:
      CPU_JP_HL();


   case 0xC2:
      CPU_JP(CPU_COND_NZ);
   case 0xD2:
      CPU_JP(CPU_COND_NC);
   case 0xCA:
      CPU_JP(CPU_COND_Z);
   case 0xDA:
      CPU_JP(CPU_COND_C);

   case 0xC3:
      CPU_JP(CPU_COND_ALWAYS);

   case 0xF3:
      CPU_DI();
   case 0xFB:
      CPU_EI();

   case 0xC4:
      CPU_CALL(CPU_COND_NZ);
   case 0xCC:
      CPU_CALL(CPU_COND_Z);
   case 0xD4:
      CPU_CALL(CPU_COND_NC);
   case 0xDC:
      CPU_CALL(CPU_COND_C);

   case 0xCD:
      CPU_CALL(CPU_COND_ALWAYS);



   // PUSH (rr)
   case 0xC5:
      CPU_PUSH_BC();
   case 0xD5:
      CPU_PUSH_DE();
   case 0xE5:
      CPU_PUSH_HL();
   case 0xF5:
      CPU_PUSH_AF();


   case 0xC6:
      CPU_ADD_r_imm8(REG_A);
   case 0xCE: // 0x0210 0xC674 0xDEF8
//      if(REG_PC == 0xDEF9)
//         fflush(stdout);
      CPU_ADC_r_imm8(REG_A);
   case 0xD6:
      CPU_SUB_r_imm8(REG_A);
   case 0xDE:
      CPU_SBC_r_imm8(REG_A);
   case 0xE6:
      CPU_AND_A_imm8();
   case 0xEE:
      CPU_XOR_A_imm8();
   case 0xF6:
      CPU_OR_A_imm8();
   case 0xFE:
      CPU_CP_A_imm8();

   case 0xFA:
   {
      uint16_t addr = GB_READ_U8(CPU.PC++);
      addr |= GB_READ_U8(CPU.PC++) << 8;
      CPU.A = GB_READ_U8(addr);
      CPU.cycles += 4;
      CPU_exec_next();
   }

   case 0xEA:
      CPU_LD_addr16_A();
   // LD A,(C)
   case 0xF2:
      CPU.A = GB_READ_U8(CPU.C | 0xFF00);
      CPU.cycles += 2;
      CPU_exec_next();
   // LD (C), A
   case 0xE2:
      GB_WRITE_U8((CPU.C | 0xFF00), CPU.A);
      CPU.cycles += 2;
      CPU_exec_next();

   // LD SP, HL
   case 0xF9:
      CPU.SP = CPU.HL;
      CPU.cycles += 2;
      CPU_exec_next();

   case 0xC7:
      CPU_RST(0x00);
   case 0xD7:
      CPU_RST(0x10);
   case 0xE7:
      CPU_RST(0x20);
   case 0xF7:
      CPU_RST(0x30);

   case 0xCF:
      CPU_RST(0x08);
   case 0xDF:
      CPU_RST(0x18);
   case 0xEF:
      CPU_RST(0x28);
   case 0xFF:
      CPU_RST(0x38);

   case 0xCB:
   {
      switch (GB_READ_PC())
      {
      case 0x00:
         CPU_RLC(REG_B);
      case 0x01:
         CPU_RLC(REG_C);
      case 0x02:
         CPU_RLC(REG_D);
      case 0x03:
         CPU_RLC(REG_E);
      case 0x04:
         CPU_RLC(REG_H);
      case 0x05:
         CPU_RLC(REG_L);
      case 0x06:
         CPU_RLC_HL();
      case 0x07:
         CPU_RLC(REG_A);

      case 0x08:
         CPU_RRC(REG_B);
      case 0x09:
         CPU_RRC(REG_C);
      case 0x0A:
         CPU_RRC(REG_D);
      case 0x0B:
         CPU_RRC(REG_E);
      case 0x0C:
         CPU_RRC(REG_H);
      case 0x0D:
         CPU_RRC(REG_L);
      case 0x0E:
         CPU_RRC_HL();
      case 0x0F:
         CPU_RRC(REG_A);

      case 0x10:
         CPU_RL(REG_B);
      case 0x11:
         CPU_RL(REG_C);
      case 0x12:
         CPU_RL(REG_D);
      case 0x13:
         CPU_RL(REG_E);
      case 0x14:
         CPU_RL(REG_H);
      case 0x15:
         CPU_RL(REG_L);
      case 0x16:
         CPU_RL_HL();
      case 0x17:
         CPU_RL(REG_A);

      case 0x18:
         CPU_RR(REG_B);
      case 0x19:
         CPU_RR(REG_C);
      case 0x1A:
         CPU_RR(REG_D);
      case 0x1B:
         CPU_RR(REG_E);
      case 0x1C:
         CPU_RR(REG_H);
      case 0x1D:
         CPU_RR(REG_L);
      case 0x1E:
         CPU_RR_HL();
      case 0x1F:
         CPU_RR(REG_A);

      case 0x20:
         CPU_SLA(REG_B);
      case 0x21:
         CPU_SLA(REG_C);
      case 0x22:
         CPU_SLA(REG_D);
      case 0x23:
         CPU_SLA(REG_E);
      case 0x24:
         CPU_SLA(REG_H);
      case 0x25:
         CPU_SLA(REG_L);
      case 0x26:
         CPU_SLA_HL();
      case 0x27:
         CPU_SLA(REG_A);

      case 0x28:
         CPU_SRA(REG_B);
      case 0x29:
         CPU_SRA(REG_C);
      case 0x2A:
         CPU_SRA(REG_D);
      case 0x2B:
         CPU_SRA(REG_E);
      case 0x2C:
         CPU_SRA(REG_H);
      case 0x2D:
         CPU_SRA(REG_L);
      case 0x2E:
         CPU_SRA_HL();
      case 0x2F:
         CPU_SRA(REG_A);

      case 0x30:
         CPU_SWAP(REG_B);
      case 0x31:
         CPU_SWAP(REG_C);
      case 0x32:
         CPU_SWAP(REG_D);
      case 0x33:
         CPU_SWAP(REG_E);
      case 0x34:
         CPU_SWAP(REG_H);
      case 0x35:
         CPU_SWAP(REG_L);
      case 0x36:
         CPU_SWAP_HL();
      case 0x37:
         CPU_SWAP(REG_A);

      case 0x38:
         CPU_SRL(REG_B);
      case 0x39:
         CPU_SRL(REG_C);
      case 0x3A:
         CPU_SRL(REG_D);
      case 0x3B:
         CPU_SRL(REG_E);
      case 0x3C:
         CPU_SRL(REG_H);
      case 0x3D:
         CPU_SRL(REG_L);
      case 0x3E:
         CPU_SRL_HL();
      case 0x3F:
         CPU_SRL(REG_A);

      case 0x40:
         CPU_BIT(0, REG_B);
      case 0x41:
         CPU_BIT(0, REG_C);
      case 0x42:
         CPU_BIT(0, REG_D);
      case 0x43:
         CPU_BIT(0, REG_E);
      case 0x44:
         CPU_BIT(0, REG_H);
      case 0x45:
         CPU_BIT(0, REG_L);
      case 0x46:
         CPU_BIT_HL(0);
      case 0x47:
         CPU_BIT(0, REG_A);

      case 0x48:
         CPU_BIT(1, REG_B);
      case 0x49:
         CPU_BIT(1, REG_C);
      case 0x4A:
         CPU_BIT(1, REG_D);
      case 0x4B:
         CPU_BIT(1, REG_E);
      case 0x4C:
         CPU_BIT(1, REG_H);
      case 0x4D:
         CPU_BIT(1, REG_L);
      case 0x4E:
         CPU_BIT_HL(1);
      case 0x4F:
         CPU_BIT(1, REG_A);

      case 0x50:
         CPU_BIT(2, REG_B);
      case 0x51:
         CPU_BIT(2, REG_C);
      case 0x52:
         CPU_BIT(2, REG_D);
      case 0x53:
         CPU_BIT(2, REG_E);
      case 0x54:
         CPU_BIT(2, REG_H);
      case 0x55:
         CPU_BIT(2, REG_L);
      case 0x56:
         CPU_BIT_HL(2);
      case 0x57:
         CPU_BIT(2, REG_A);

      case 0x58:
         CPU_BIT(3, REG_B);
      case 0x59:
         CPU_BIT(3, REG_C);
      case 0x5A:
         CPU_BIT(3, REG_D);
      case 0x5B:
         CPU_BIT(3, REG_E);
      case 0x5C:
         CPU_BIT(3, REG_H);
      case 0x5D:
         CPU_BIT(3, REG_L);
      case 0x5E:
         CPU_BIT_HL(3);
      case 0x5F:
         CPU_BIT(3, REG_A);

      case 0x60:
         CPU_BIT(4, REG_B);
      case 0x61:
         CPU_BIT(4, REG_C);
      case 0x62:
         CPU_BIT(4, REG_D);
      case 0x63:
         CPU_BIT(4, REG_E);
      case 0x64:
         CPU_BIT(4, REG_H);
      case 0x65:
         CPU_BIT(4, REG_L);
      case 0x66:
         CPU_BIT_HL(4);
      case 0x67:
         CPU_BIT(4, REG_A);

      case 0x68:
         CPU_BIT(5, REG_B);
      case 0x69:
         CPU_BIT(5, REG_C);
      case 0x6A:
         CPU_BIT(5, REG_D);
      case 0x6B:
         CPU_BIT(5, REG_E);
      case 0x6C:
         CPU_BIT(5, REG_H);
      case 0x6D:
         CPU_BIT(5, REG_L);
      case 0x6E:
         CPU_BIT_HL(5);
      case 0x6F:
         CPU_BIT(5, REG_A);

      case 0x70:
         CPU_BIT(6, REG_B);
      case 0x71:
         CPU_BIT(6, REG_C);
      case 0x72:
         CPU_BIT(6, REG_D);
      case 0x73:
         CPU_BIT(6, REG_E);
      case 0x74:
         CPU_BIT(6, REG_H);
      case 0x75:
         CPU_BIT(6, REG_L);
      case 0x76:
         CPU_BIT_HL(6);
      case 0x77:
         CPU_BIT(6, REG_A);

      case 0x78:
         CPU_BIT(7, REG_B);
      case 0x79:
         CPU_BIT(7, REG_C);
      case 0x7A:
         CPU_BIT(7, REG_D);
      case 0x7B:
         CPU_BIT(7, REG_E);
      case 0x7C:
         CPU_BIT(7, REG_H);
      case 0x7D:
         CPU_BIT(7, REG_L);
      case 0x7E:
         CPU_BIT_HL(7);
      case 0x7F:
         CPU_BIT(7, REG_A);

      case 0x80:
         CPU_RES(0, REG_B);
      case 0x81:
         CPU_RES(0, REG_C);
      case 0x82:
         CPU_RES(0, REG_D);
      case 0x83:
         CPU_RES(0, REG_E);
      case 0x84:
         CPU_RES(0, REG_H);
      case 0x85:
         CPU_RES(0, REG_L);
      case 0x86:
         CPU_RES_HL(0);
      case 0x87:
         CPU_RES(0, REG_A);

      case 0x88:
         CPU_RES(1, REG_B);
      case 0x89:
         CPU_RES(1, REG_C);
      case 0x8A:
         CPU_RES(1, REG_D);
      case 0x8B:
         CPU_RES(1, REG_E);
      case 0x8C:
         CPU_RES(1, REG_H);
      case 0x8D:
         CPU_RES(1, REG_L);
      case 0x8E:
         CPU_RES_HL(1);
      case 0x8F:
         CPU_RES(1, REG_A);

      case 0x90:
         CPU_RES(2, REG_B);
      case 0x91:
         CPU_RES(2, REG_C);
      case 0x92:
         CPU_RES(2, REG_D);
      case 0x93:
         CPU_RES(2, REG_E);
      case 0x94:
         CPU_RES(2, REG_H);
      case 0x95:
         CPU_RES(2, REG_L);
      case 0x96:
         CPU_RES_HL(2);
      case 0x97:
         CPU_RES(2, REG_A);

      case 0x98:
         CPU_RES(3, REG_B);
      case 0x99:
         CPU_RES(3, REG_C);
      case 0x9A:
         CPU_RES(3, REG_D);
      case 0x9B:
         CPU_RES(3, REG_E);
      case 0x9C:
         CPU_RES(3, REG_H);
      case 0x9D:
         CPU_RES(3, REG_L);
      case 0x9E:
         CPU_RES_HL(3);
      case 0x9F:
         CPU_RES(3, REG_A);

      case 0xA0:
         CPU_RES(4, REG_B);
      case 0xA1:
         CPU_RES(4, REG_C);
      case 0xA2:
         CPU_RES(4, REG_D);
      case 0xA3:
         CPU_RES(4, REG_E);
      case 0xA4:
         CPU_RES(4, REG_H);
      case 0xA5:
         CPU_RES(4, REG_L);
      case 0xA6:
         CPU_RES_HL(4);
      case 0xA7:
         CPU_RES(4, REG_A);

      case 0xA8:
         CPU_RES(5, REG_B);
      case 0xA9:
         CPU_RES(5, REG_C);
      case 0xAA:
         CPU_RES(5, REG_D);
      case 0xAB:
         CPU_RES(5, REG_E);
      case 0xAC:
         CPU_RES(5, REG_H);
      case 0xAD:
         CPU_RES(5, REG_L);
      case 0xAE:
         CPU_RES_HL(5);
      case 0xAF:
         CPU_RES(5, REG_A);

      case 0xB0:
         CPU_RES(6, REG_B);
      case 0xB1:
         CPU_RES(6, REG_C);
      case 0xB2:
         CPU_RES(6, REG_D);
      case 0xB3:
         CPU_RES(6, REG_E);
      case 0xB4:
         CPU_RES(6, REG_H);
      case 0xB5:
         CPU_RES(6, REG_L);
      case 0xB6:
         CPU_RES_HL(6);
      case 0xB7:
         CPU_RES(6, REG_A);

      case 0xB8:
         CPU_RES(7, REG_B);
      case 0xB9:
         CPU_RES(7, REG_C);
      case 0xBA:
         CPU_RES(7, REG_D);
      case 0xBB:
         CPU_RES(7, REG_E);
      case 0xBC:
         CPU_RES(7, REG_H);
      case 0xBD:
         CPU_RES(7, REG_L);
      case 0xBE:
         CPU_RES_HL(7);
      case 0xBF:
         CPU_RES(7, REG_A);

      case 0xC0:
         CPU_SET(0, REG_B);
      case 0xC1:
         CPU_SET(0, REG_C);
      case 0xC2:
         CPU_SET(0, REG_D);
      case 0xC3:
         CPU_SET(0, REG_E);
      case 0xC4:
         CPU_SET(0, REG_H);
      case 0xC5:
         CPU_SET(0, REG_L);
      case 0xC6:
         CPU_SET_HL(0);
      case 0xC7:
         CPU_SET(0, REG_A);

      case 0xC8:
         CPU_SET(1, REG_B);
      case 0xC9:
         CPU_SET(1, REG_C);
      case 0xCA:
         CPU_SET(1, REG_D);
      case 0xCB:
         CPU_SET(1, REG_E);
      case 0xCC:
         CPU_SET(1, REG_H);
      case 0xCD:
         CPU_SET(1, REG_L);
      case 0xCE:
         CPU_SET_HL(1);
      case 0xCF:
         CPU_SET(1, REG_A);

      case 0xD0:
         CPU_SET(2, REG_B);
      case 0xD1:
         CPU_SET(2, REG_C);
      case 0xD2:
         CPU_SET(2, REG_D);
      case 0xD3:
         CPU_SET(2, REG_E);
      case 0xD4:
         CPU_SET(2, REG_H);
      case 0xD5:
         CPU_SET(2, REG_L);
      case 0xD6:
         CPU_SET_HL(2);
      case 0xD7:
         CPU_SET(2, REG_A);

      case 0xD8:
         CPU_SET(3, REG_B);
      case 0xD9:
         CPU_SET(3, REG_C);
      case 0xDA:
         CPU_SET(3, REG_D);
      case 0xDB:
         CPU_SET(3, REG_E);
      case 0xDC:
         CPU_SET(3, REG_H);
      case 0xDD:
         CPU_SET(3, REG_L);
      case 0xDE:
         CPU_SET_HL(3);
      case 0xDF:
         CPU_SET(3, REG_A);

      case 0xE0:
         CPU_SET(4, REG_B);
      case 0xE1:
         CPU_SET(4, REG_C);
      case 0xE2:
         CPU_SET(4, REG_D);
      case 0xE3:
         CPU_SET(4, REG_E);
      case 0xE4:
         CPU_SET(4, REG_H);
      case 0xE5:
         CPU_SET(4, REG_L);
      case 0xE6:
         CPU_SET_HL(4);
      case 0xE7:
         CPU_SET(4, REG_A);

      case 0xE8:
         CPU_SET(5, REG_B);
      case 0xE9:
         CPU_SET(5, REG_C);
      case 0xEA:
         CPU_SET(5, REG_D);
      case 0xEB:
         CPU_SET(5, REG_E);
      case 0xEC:
         CPU_SET(5, REG_H);
      case 0xED:
         CPU_SET(5, REG_L);
      case 0xEE:
         CPU_SET_HL(5);
      case 0xEF:
         CPU_SET(5, REG_A);

      case 0xF0:
         CPU_SET(6, REG_B);
      case 0xF1:
         CPU_SET(6, REG_C);
      case 0xF2:
         CPU_SET(6, REG_D);
      case 0xF3:
         CPU_SET(6, REG_E);
      case 0xF4:
         CPU_SET(6, REG_H);
      case 0xF5:
         CPU_SET(6, REG_L);
      case 0xF6:
         CPU_SET_HL(6);
      case 0xF7:
         CPU_SET(6, REG_A);

      case 0xF8:
         CPU_SET(7, REG_B);
      case 0xF9:
         CPU_SET(7, REG_C);
      case 0xFA:
         CPU_SET(7, REG_D);
      case 0xFB:
         CPU_SET(7, REG_E);
      case 0xFC:
         CPU_SET(7, REG_H);
      case 0xFD:
         CPU_SET(7, REG_L);
      case 0xFE:
         CPU_SET_HL(7);
      case 0xFF:
         CPU_SET(7, REG_A);

      default:
         gbemu_printf("(0xCB)");
         goto unknown_opcode;

      }
   }

   case 0xD3:
   case 0xE3:
   case 0xE4:
   case 0xF4:
   case 0xDB:
   case 0xEB:
   case 0xEC:
   case 0xFC:
   case 0xDD:
   case 0xED:
   case 0xFD:
invalid_opcode:
      {
         extern retro_environment_t environ_cb;
         retro_sleep(10);
         printf("invalid opcode : 0x%02X\n",GB_READ_U8(CPU.PC - 1));
         fflush(stdout);
//         DEBUG_BREAK();

         if (environ_cb)
            environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, NULL);
#ifdef PERF_TEST
         extern struct retro_perf_callback perf_cb;
         perf_cb.perf_log();
#endif
         //      return;
         exit(0);
      }
      break;


   default:
unknown_opcode:
      {
         extern retro_environment_t environ_cb;
         retro_sleep(10);
         printf("unknown opcode : 0x%02X\n", GB_READ_U8(CPU.PC - 1));
         fflush(stdout);
//         DEBUG_BREAK();

         if (environ_cb)
            environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, NULL);
#ifdef PERF_TEST
         extern struct retro_perf_callback perf_cb;
         perf_cb.perf_log();
#endif
         //      return;
         exit(0);
      }
      break;
   }
   
cpu_exit:
   GB.CPU = CPU;
   return;
}
Esempio n. 20
0
static void get_binds(config_file_t *conf, config_file_t *auto_conf,
      int player, int joypad)
{
   int i, timeout_cnt;
   const input_device_driver_t *driver = input_joypad_init_driver(g_driver, NULL);
   const char *joypad_name;

   int16_t initial_axes[MAX_AXES] = {0};
   struct poll_data old_poll = {{0}};
   struct poll_data new_poll = {{0}};

   int last_axis   = -1;
   bool block_axis = false;

   int timeout_ticks = g_timeout * 100;

   if (!driver)
   {
      fprintf(stderr, "Cannot find any valid input driver.\n");
      exit(1);
   }

   if (!driver->query_pad(joypad))
   {
      fprintf(stderr, "Couldn't open joystick #%d.\n", joypad);
      exit(1);
   }

   fprintf(stderr, "Found joypad driver: %s\n", driver->ident);
   joypad_name = input_joypad_name(driver, joypad);
   fprintf(stderr, "Using joypad: %s\n", joypad_name ? joypad_name : "Unknown");

   if (joypad_name && auto_conf)
   {
      config_set_string(auto_conf, "input_device", joypad_name);
      config_set_string(auto_conf, "input_driver", driver->ident);
   }

   poll_joypad(driver, joypad, &old_poll);
   fprintf(stderr, "\nJoypads tend to have stale state after opened.\nPress some buttons and move some axes around to make sure joypad state is completely neutral before proceeding.\nWhen done, press Enter ... ");
   getchar();
   poll_joypad(driver, joypad, &old_poll);

   for (i = 0; i < MAX_AXES; i++)
   {
      int16_t initial = input_joypad_axis_raw(driver, joypad, i);
      if (abs(initial) < 20000)
         initial = 0;

      /* Certain joypads (such as XBox360 controller on Linux)
       * has a default negative axis for shoulder triggers,
       * which makes configuration very awkward.
       *
       * If default negative, we can't trigger on the negative axis,
       * and similar with defaulted positive axes.
       */

      if (initial)
         fprintf(stderr, "Axis %d is defaulted to %s axis value of %d.\n", i, initial > 0 ? "positive" : "negative", initial);

      initial_axes[i] = initial;
   }

   for (i = 0; i < MAX_BUTTONS; i++)
   {
      if (old_poll.buttons[i])
         fprintf(stderr, "Button %d was initially pressed. This indicates broken initial state.\n", i);
   }

   fprintf(stderr, "Configuring binds for player #%d on joypad #%d.\n\n",
         player + 1, joypad);

   for (i = 0, timeout_cnt = 0; input_config_bind_map[i].valid; i++, timeout_cnt = 0)
   {
      unsigned meta_level;
      unsigned player_index;
      int j;
      if (i == RARCH_TURBO_ENABLE)
         continue;

      meta_level = input_config_bind_map[i].meta;
      if (meta_level > g_meta_level)
         continue;

      fprintf(stderr, "%s\n", input_config_bind_map[i].desc);

      player_index = input_config_bind_map[i].meta ? 0 : player;

      for (;;)
      {
         old_poll = new_poll;

         /* To avoid pegging CPU.
          * Ideally use an event-based joypad scheme,
          * but it adds far more complexity, so, meh.
          */
         retro_sleep(10);

         if (timeout_ticks)
         {
            timeout_cnt++;
            if (timeout_cnt >= timeout_ticks)
            {
               fprintf(stderr, "\tTimed out ...\n");
               break;
            }
         }

         poll_joypad(driver, joypad, &new_poll);
         for (j = 0; j < MAX_BUTTONS; j++)
         {
            if (new_poll.buttons[j] && !old_poll.buttons[j])
            {
               char key[64] = {0};

               fprintf(stderr, "\tJoybutton pressed: %d\n", j);

               snprintf(key, sizeof(key), "%s_%s_btn",
                     input_config_get_prefix(player_index,
                        input_config_bind_map[i].meta),
                     input_config_bind_map[i].base);
               config_set_int(conf, key, j);

               if (auto_conf)
               {
                  snprintf(key, sizeof(key), "input_%s_btn",
                        input_config_bind_map[i].base);
                  config_set_int(auto_conf, key, j);
               }

               goto out;
            }
         }

         for (j = 0; j < MAX_AXES; j++)
         {
            int16_t value;
            bool same_axis;
            bool require_negative;
            bool require_positive;

            if (new_poll.axes[j] == old_poll.axes[j])
               continue;

            value            = new_poll.axes[j];
            same_axis        = last_axis == j;
            require_negative = initial_axes[j] > 0;
            require_positive = initial_axes[j] < 0;

            /* Block the axis config until we're sure
             * axes have returned to their neutral state. */
            if (same_axis)
            {
               if (abs(value) < 10000 ||
                     (require_positive && value < 0) ||
                     (require_negative && value > 0))
                  block_axis = false;
            }

            /* If axes are in their neutral state,
             * we can't allow it. */
            if (require_negative && value >= 0)
               continue;
            if (require_positive && value <= 0)
               continue;

            if (block_axis)
               continue;

            if (abs(value) > 20000)
            {
               char buf[8]  = {0};
               char key[64] = {0};

               last_axis = j;
               fprintf(stderr, "\tJoyaxis moved: Axis %d, Value %d\n",
                     j, value);

               snprintf(buf, sizeof(buf),
                     value > 0 ? "+%d" : "-%d", j);

               snprintf(key, sizeof(key), "%s_%s_axis",
                     input_config_get_prefix(player_index,
                        input_config_bind_map[i].meta),
                     input_config_bind_map[i].base);

               config_set_string(conf, key, buf);

               if (auto_conf)
               {
                  snprintf(key, sizeof(key), "input_%s_axis",
                        input_config_bind_map[i].base);
                  config_set_string(auto_conf, key, buf);
               }

               block_axis = true;
               goto out;
            }
         }

         for (j = 0; j < MAX_HATS; j++)
         {
            const char *quark  = NULL;
            uint16_t value     = new_poll.hats[j];
            uint16_t old_value = old_poll.hats[j];

            if ((value & HAT_UP_MASK) && !(old_value & HAT_UP_MASK))
               quark = "up";
            else if ((value & HAT_LEFT_MASK) && !(old_value & HAT_LEFT_MASK))
               quark = "left";
            else if ((value & HAT_RIGHT_MASK) && !(old_value & HAT_RIGHT_MASK))
               quark = "right";
            else if ((value & HAT_DOWN_MASK) && !(old_value & HAT_DOWN_MASK))
               quark = "down";

            if (quark)
            {
               char buf[16] = {0};
               char key[64] = {0};

               fprintf(stderr, "\tJoyhat moved: Hat %d, direction %s\n", j, quark);
               snprintf(buf, sizeof(buf), "h%d%s", j, quark);

               snprintf(key, sizeof(key), "%s_%s_btn",
                     input_config_get_prefix(player_index,
                        input_config_bind_map[i].meta),
                     input_config_bind_map[i].base);

               config_set_string(conf, key, buf);

               if (auto_conf)
               {
                  snprintf(key, sizeof(key), "input_%s_btn",
                        input_config_bind_map[i].base);
                  config_set_string(auto_conf, key, buf);
               }

               goto out;
            }
         }
      }
out:
      old_poll = new_poll;
   }
}
Esempio n. 21
0
static int network_interface_up(struct sockaddr_in *target, int index,
      const char *ip_address, unsigned udp_port, int *s)
{
   (void)index;

#if defined(VITA)
   if (sceNetShowNetstat() == PSP2_NET_ERROR_ENOTINIT)
   {
      SceNetInitParam initparam;
      net_memory = malloc(NET_INIT_SIZE);

      initparam.memory = net_memory;
      initparam.size = NET_INIT_SIZE;
      initparam.flags = 0;

      sceNetInit(&initparam);
   }
   *s                 = sceNetSocket("RA_netlogger", PSP2_NET_AF_INET, PSP2_NET_SOCK_DGRAM, 0);
   target->sin_family = PSP2_NET_AF_INET;
   target->sin_port   = sceNetHtons(udp_port);

   sceNetInetPton(PSP2_NET_AF_INET, ip_address, &target->sin_addr);
#else

#if defined(__CELLOS_LV2__) && !defined(__PSL1GHT__)
   int ret = 0;

   int state, timeout_count = 10;
   ret = cellNetCtlInit();
   if (ret < 0)
      return -1;

   for (;;)
   {
      ret = cellNetCtlGetState(&state);
      if (ret < 0)
         return -1;

      if (state == CELL_NET_CTL_STATE_IPObtained)
         break;

      retro_sleep(500);
      timeout_count--;
      if (index && timeout_count < 0)
         return 0;
   }
#elif defined(GEKKO)
   char t[16];
   if (if_config(t, NULL, NULL, TRUE) < 0)
      ret = -1;
#endif
   if (ret < 0)
      return -1;

   *s                 = socket(AF_INET, SOCK_DGRAM, 0);

   target->sin_family = AF_INET;
   target->sin_port   = htons(udp_port);
#ifdef GEKKO
   target->sin_len    = 8;
#endif

   inet_pton(AF_INET, ip_address, &target->sin_addr);
#endif
   return 0;
}
Esempio n. 22
0
/**
 * network_init:
 *
 * Platform specific socket library initialization.
 *
 * Returns: true (1) if successful, otherwise false (0).
 **/
bool network_init(void)
{
#ifdef _WIN32
   WSADATA wsaData;
#endif
   static bool inited = false;
   if (inited)
      return true;

#if defined(_WIN32)
   if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
   {
      network_deinit();
      return false;
   }
#elif defined(__CELLOS_LV2__) && !defined(__PSL1GHT__)
   int timeout_count = 10;

   cellSysmoduleLoadModule(CELL_SYSMODULE_NET);
   sys_net_initialize_network();

   if (cellNetCtlInit() < 0)
      return false;

   for (;;)
   {
      int state;
      if (cellNetCtlGetState(&state) < 0)
         return false;

      if (state == CELL_NET_CTL_STATE_IPObtained)
         break;

      retro_sleep(500);
      timeout_count--;
      if (timeout_count < 0)
         return 0;
   }
#elif defined(VITA)
   SceNetInitParam initparam;

   if (sceNetShowNetstat() == SCE_NET_ERROR_ENOTINIT)
   {
      _net_compat_net_memory = malloc(COMPAT_NET_INIT_SIZE);

      initparam.memory       = _net_compat_net_memory;
      initparam.size         = COMPAT_NET_INIT_SIZE;
      initparam.flags        = 0;

      sceNetInit(&initparam);

      sceNetCtlInit();
   }

   retro_epoll_fd = sceNetEpollCreate("epoll", 0);
#elif defined(GEKKO)
   char t[16];
   if (if_config(t, NULL, NULL, TRUE, 10) < 0)
      return false;
#elif defined(WIIU)
   socket_lib_init();
#elif defined(_3DS)
    _net_compat_net_memory = (u32*)memalign(SOC_ALIGN, SOC_BUFFERSIZE);
	if (_net_compat_net_memory == NULL)
		return false;
	Result ret = socInit(_net_compat_net_memory, SOC_BUFFERSIZE);//WIFI init
	if (ret != 0)
		return false;
#else
   signal(SIGPIPE, SIG_IGN); /* Do not like SIGPIPE killing our app. */
#endif

   inited = true;
   return true;
}
Esempio n. 23
0
 virtual void delayMillis(uint msecs)
 {
    if(!retroCheckThread(msecs))
       retro_sleep(msecs);
 }