Exemple #1
0
int fs_emu_is_quitting()
{
    // FIXME: move to header file for possible inlining...
    return fs_ml_is_quitting();
}
Exemple #2
0
void fs_ml_render_iteration() {
    static int first = 1;
    if (first) {
        first = 0;
        initialize_opengl_sync();
    }

    if (g_fs_ml_vblank_sync) {
        render_iteration_vsync();
    }
    else if (g_fs_ml_benchmarking) {
        update_frame();
        render_frame();
        swap_opengl_buffers();
    }
    else {
        // when vsync is off, we wait until a new frame is ready and
        // then we display it immediately

        if (fs_ml_is_quitting()) {
            // but when the emulation is quitting, we can't expect any new
            // frames so there's no point waiting for them. Instead, we just
            // sleep a bit to throttle the frame rate for the quit animation
            fs_ml_usleep(10000);
        } else {
            // wait max 33 ms to allow the user interface to work even if
            // the emu hangs
            // int64_t dest_time = fs_get_real_time() + 33 * 1000;
            int64_t end_time = fs_condition_get_wait_end_time(33 * 1000);
            int64_t check_time = 0;

            fs_mutex_lock(g_frame_available_mutex);
            // fs_log("cond wait until %lld\n", end_time);
            while (g_rendered_frame == g_available_frame) {
                fs_condition_wait_until(
                    g_frame_available_cond, g_frame_available_mutex, end_time);
                check_time = fs_condition_get_wait_end_time(0);
                if (check_time >= end_time) {
                    // fs_log("timed out at %lld\n", check_time);
                    break;
                } else {
                    // fs_log("wake-up at %lld (end_time = %lld)\n", check_time, end_time);
                }
            }
            fs_mutex_unlock(g_frame_available_mutex);
        }

        update_frame();
        render_frame();
        swap_opengl_buffers();
        //gl_finish();
    }

    if (g_fs_ml_video_screenshot_path) {
        fs_mutex_lock(g_fs_ml_video_screenshot_mutex);
        if (g_fs_ml_video_screenshot_path) {
            save_screenshot_of_opengl_framebuffer(
                    g_fs_ml_video_screenshot_path);
            g_free(g_fs_ml_video_screenshot_path);
            g_fs_ml_video_screenshot_path = NULL;
        }
        fs_mutex_unlock(g_fs_ml_video_screenshot_mutex);
    }

    if (g_fs_ml_video_post_render_function) {
        g_fs_ml_video_post_render_function();
    }
}
Exemple #3
0
static void *manymouse_thread(void* data)
{
    fs_log("[MANYMOUSE] Thread running\n");

    int k = g_fs_ml_input_device_count;
    g_first_manymouse_index = k;
    int mouse_count = ManyMouse_Init();
    if (mouse_count < 0) {
        fs_log("[MANYMOUSE] Initialization failed (%d)\n", mouse_count);
    }
    else if (mouse_count == 0) {
        fs_log("MANYMOUSE: no mice found\n");
        // no mice found, so we just quit using the library
    }

    for (int i = 0; i < mouse_count; i++) {
        const char *device = ManyMouse_DeviceName(i);
        const char *driver = ManyMouse_DriverName();

        char *name;
        if (device[0] == 0 || g_ascii_strcasecmp(device, "mouse") == 0) {
            name = g_strdup("Mouse: Unnamed Mouse");
        } else {
            name = g_strdup_printf("Mouse: %s", device);
        }
        // fs_ml_input_unique_device_name either returns name, or frees it
        // and return another name, so name must be malloced and owned by
        // caller
        name = fs_ml_input_unique_device_name(name);
        fs_log("MANYMOUSE: Adding %s (%s)\n", name, driver);

        g_fs_ml_input_devices[k].type = FS_ML_MOUSE;
        g_fs_ml_input_devices[k].index = k;
        g_fs_ml_input_devices[k].name = name;
        g_fs_ml_input_devices[k].alias = g_strdup_printf("MOUSE #%d", i + 2);
        k += 1;
    }

    // when done like this, I believe no memory barrier is needed when the
    // other thread polls g_manymouse_last_index
    g_manymouse_last_index = k;

    if (mouse_count < 0) {
        // ManyMouse library was not initialized
        return NULL;
    }

    ManyMouseEvent event;
    fs_ml_event *new_event;
    while (!fs_ml_is_quitting()) {
        // printf("..\n");
        while (ManyMouse_PollEvent(&event)) {
            // printf(" -- event type %d -- \n", event.type);
            if (event.type == MANYMOUSE_EVENT_RELMOTION) {
                // printf("MANYMOUSE_EVENT_RELMOTION\n");
                new_event = fs_ml_alloc_event();
                new_event->type = FS_ML_MOUSEMOTION;
                new_event->motion.device = g_first_manymouse_index + \
                        event.device;
                if (event.item == 0) {
                    new_event->motion.xrel = event.value;
                    new_event->motion.yrel = 0;
                }
                else if (event.item == 1) {
                    new_event->motion.xrel = 0;
                    new_event->motion.yrel = event.value;
                }
                new_event->motion.x = FS_ML_NO_ABSOLUTE_MOUSE_POS;
                new_event->motion.y = FS_ML_NO_ABSOLUTE_MOUSE_POS;

                fs_ml_post_event(new_event);
                // ManyMouseEventType type;
                // unsigned int device;
                // unsigned int item;
                // int value;
                // int minval;
                // int maxval;
            }
            else if (event.type == MANYMOUSE_EVENT_BUTTON) {
                db_log(input, "MANYMOUSE: EVENT_BUTTON "
                       "device %d item %d value %d\n",
                       event.device, event.item, event.value);
                new_event = fs_ml_alloc_event();
                new_event->type = event.value ? FS_ML_MOUSEBUTTONDOWN :
                        FS_ML_MOUSEBUTTONUP;
                new_event->button.state = event.value != 0;
                new_event->button.device = g_first_manymouse_index + \
                        event.device;
                if (event.item == 0) {
                    new_event->button.button = FS_ML_BUTTON_LEFT;
                }
                else if (event.item == 1) {
                    new_event->button.button = FS_ML_BUTTON_RIGHT;
                }
                else if (event.item == 2) {
                    new_event->button.button = FS_ML_BUTTON_MIDDLE;
                }
                else {
                    new_event->button.button = 0;
                }
                fs_ml_post_event(new_event);
            }
            else if (event.type == MANYMOUSE_EVENT_ABSMOTION) {
                // printf("MANYMOUSE_EVENT_ABSMOTION\n");
            }
            else if (event.type == MANYMOUSE_EVENT_SCROLL) {
                db_log(input, "MANYMOUSE: EVENT_SCROLL "
                       "device %d item %d value %d\n",
                       event.device, event.item, event.value);
                new_event = fs_ml_alloc_event();
                new_event->type = FS_ML_MOUSEBUTTONDOWN;
                new_event->button.state = 1;
                new_event->button.device = g_first_manymouse_index + \
                        event.device;
                new_event->button.button = 0;
                if (event.item == 0) {
                    if (event.value == 1) {
                        new_event->button.button = FS_ML_BUTTON_WHEELUP;
                    }
                    else {
                        new_event->button.button = FS_ML_BUTTON_WHEELDOWN;
                    }
                }
                fs_ml_post_event(new_event);
            }
        }
        fs_ml_usleep(1000);
    }

    ManyMouse_Quit();
    return NULL;
}