Beispiel #1
0
int fs_emu_font_render_with_outline(fs_emu_font *font, const char *text,
        float x, float y, float r, float g, float b, float a,
        float o_r, float o_g, float o_b, float o_a, float o_w) {
    fs_emu_font_render(font, text, x - o_w, y - o_w, o_r, o_g, o_b, o_a);
    fs_emu_font_render(font, text, x + o_w, y + o_w, o_r, o_g, o_b, o_a);
    fs_emu_font_render(font, text, x + o_w, y - o_w, o_r, o_g, o_b, o_a);
    fs_emu_font_render(font, text, x - o_w, y + o_w, o_r, o_g, o_b, o_a);
    return fs_emu_font_render(font, text, x, y, r, g, b, a);
}
Beispiel #2
0
int fs_emu_font_render(fs_emu_font *font, const char *text, float x, float y,
        float r, float g, float b, float alpha) {
    if (font->image == NULL) {
        return 0;
    }
    if (text == NULL || *text == '\0') {
        return 0 ;
    }
    if (!g_initialized) {
        initialize();
    }
    /*
    if (g_fs_ml_opengl_context_stamp != g_video_version) {
        GList* list = g_cache;
        while (list) {
            cache_item *item = (cache_item *) list->data;
            g_free(item->text);
            g_free(item);
            list = list->next;
        }
        g_list_free(g_cache);
        g_cache = NULL;
        initialize_cache();
    }
    */
    // find cached text entry, if any
    //sanity_check();
    GList* list = g_cache;
    while (list) {
        cache_item *item = (cache_item *) list->data;
        if (item->font == font && strcmp(item->text, text) == 0) {
            break;
        }
        list = list->next;
    }
    if (list) {
        cache_item *item = (cache_item *) list->data;
        g_cache = g_list_delete_link(g_cache, list);
        sanity_check();
        fs_gl_blending(1);
        fs_gl_texturing(1);
        //fs_emu_ortho();
        //fs_emu_set_texture(NULL);
        fs_gl_bind_texture(g_text_texture);
        //glColor4f(1.0, 1.0, 1.0, alpha);
        //printf("rendering %f %f %f %f...\n", item->x1, item->x2, item->y1, item->y2);
        fs_gl_color4f(r * alpha, g * alpha, b * alpha, alpha);
        //glColor4f(r * alpha, g * alpha, b * alpha, alpha);
        GLfloat tex[] = {
            item->x1, item->y2,
            item->x2, item->y2,
            item->x2, item->y1,
            item->x1, item->y1
        };
        GLfloat vert[] = {
            x, y,
            x + item->width, y,
            x + item->width, y + item->height,
            x, y + item->height
        };

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        glVertexPointer(2, GL_FLOAT, 0, vert);
        glTexCoordPointer(2, GL_FLOAT, 0, tex);
        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);

        g_cache = g_list_prepend(g_cache, item);
        sanity_check();
        return item->width;
    }

    // calculate size of text

    //printf(":: %s\n", text);

    int chars = 0;
    int required_width = 0;
    int required_height = font->h;
    unsigned char *cp = (unsigned char *) text;
    for(; *cp; cp++) {
        unsigned char c = *cp;
        //printf("  %p\n", font);
        //printf("    %d\n", c);
        //printf("    %d\n", font->w[c]);
        if (required_width + font->w[c] > TEXTURE_WIDTH) {
            break;
        }
        required_width += font->w[c];
        chars++;
    }
    //fs_log("width: %d, height: %d\n", required_width, required_height);

    //float tw = font->texture->width;
    //float th = font->texture->height;




    // FIXME: clear g_buffer




    //int length = strlen(text);
    //for (int i = 0; i < length; i++) {
    cp = (unsigned char *) text;
    //glBegin(GL_QUADS);
    //glColor4f(1.0, 1.0, 1.0, 1.0);
    //int x2 = 0;

    int dx = 0;
    int dy = 0;

    for(int i = 0; i < chars; i++) {
        unsigned char c = *cp++;
        //unsigned char = (unsigned char) text[i];
        int sx = font->x[c];
        int sy = font->y[c];
        int sw = font->w[c];
        int sh = font->h;

        //printf("%d %d %d %d\n", sx, sy, sw, sh);

        // draw character

        int *sl = ((int *) font->image->data) + font->image->width * sy + sx;
        int ss = font->image->width; // source stride
        //int *sl = sp;
        int *dl = ((int *) g_buffer) + TEXTURE_WIDTH * dy + dx;
        int ds = TEXTURE_WIDTH; // destination stride
        //int *dl = dp;

        for (int y = 0; y < sh; y++) {
            //printf("%d\n", y);
            int *sp = sl;
            int *dp = dl;
            for (int x = 0; x < sw; x++) {
                //printf("%d %d\n", x, y);
                //*dp++ = 0xff0000ff;
                *dp++ = *sp++;
                //int a = *sp++;
            }
            sl += ss;
            dl += ds;
        }

        dx += sw;

        /*
        //fs_log("%d %d %d %d\n", font->x[c], font->y[c], w, h);
        float s1 = font->x[c] / tw;
        float s2 = (font->x[c] + w) / tw;
        //double t1 = 1.0 - (font->y[c]) / th;
        //double t2 = 1.0 - (font->y[c] + h) / th;
        float t1 = (font->y[c]) / th;
        float t2 = (font->y[c] + h) / th;
        //fs_log("%d %d %d %d\n", x, y, w, h);
        glTexCoord2f(s1, t2);
        //glVertex2f(x, y);
        glVertex2f(x2, 0);
        glTexCoord2f(s2, t2);
        //glVertex2f(x + w, y);
        glVertex2f(x2 + w, 0);
        glTexCoord2f(s2, t1);
        //glVertex2f(x + w, y + h);
        glVertex2f(x2 + w, h);
        glTexCoord2f(s1, t1);
        //glVertex2f(x, y + h);
        glVertex2f(x2, h);
        x2 += w;
        */
    }
    //printf("...\n");
    /*
    glEnd();

    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopAttrib();
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    glPopMatrix();

    glDeleteFramebuffersEXT(1, &frame_buffer);
    //glDeleteRenderbuffersEXT(1, &depth_buffer);

    fs_emu_set_texture(NULL);

    if (mipmapping) {
        fs_gl_bind_texture(render_texture);
        glGenerateMipmapEXT(GL_TEXTURE_2D);
        fs_gl_bind_texture(0);
    }
    */

    GList *last = g_list_last(g_cache);
    cache_item *last_item = (cache_item *) last->data;
    int position = last_item->position;


    fs_gl_bind_texture(g_text_texture);
#ifndef HAVE_GLES
    fs_gl_unpack_row_length(TEXTURE_WIDTH);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, position * 32, required_width,
            required_height, fs_emu_get_video_format(),
            GL_UNSIGNED_BYTE, g_buffer);
#else
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, required_width, required_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, g_buffer);

    for (int y = 0; y < required_height; y++) {
        char *row = g_buffer + ((y + position * 32)*TEXTURE_WIDTH) * 4;
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, position * 32, required_width, 1, GL_RGBA, GL_UNSIGNED_BYTE, row);
    }
#endif

    cache_item *item = g_malloc(sizeof(cache_item));
    item->font = font;
    item->text = g_strdup(text);
    item->width = required_width;
    item->height = required_height;
    item->position = position;

    item->x1 = 0;
    item->x2 = required_width / (1.0 * TEXTURE_WIDTH);
    item->y1 = (item->position * 32) / (1.0 * TEXTURE_HEIGHT);
    item->y2 = (item->position * 32 + required_height) /
            (1.0 * TEXTURE_HEIGHT);
    //item->texture = render_texture;
    g_cache = g_list_prepend(g_cache, item);
    sanity_check();

    if (last_item->text) {
        g_free(last_item->text);
    }
    /*
    if (last_item->texture) {
        glDeleteTextures(1, &last_item->texture);
    }
    */
    g_free(last_item);

    g_cache = g_list_delete_link(g_cache, last);
    sanity_check();

    // now the text is in the cache, so call function again
    return fs_emu_font_render(font, text, x, y, r, g, b, alpha);
}
Beispiel #3
0
int fs_emu_font_render(fs_emu_font *font, const char *text, float x, float y,
        float r, float g, float b, float alpha) {
    if (font == NULL || font->image == NULL) {
        return 0;
    }
    if (text == NULL || *text == '\0') {
        return 0 ;
    }
    if (!g_initialized) {
        initialize();
    }

    // find cached text entry, if any
    GList* list = g_cache;
    while (list) {
        cache_item *item = (cache_item *) list->data;
        if (item->font == font && strcmp(item->text, text) == 0) {
            break;
        }
        list = list->next;
    }
    if (list) {
        cache_item *item = (cache_item *) list->data;
        g_cache = g_list_delete_link(g_cache, list);
        sanity_check();
        fs_gl_blending(1);
        fs_gl_texturing(1);
        //fs_emu_ortho();
        //fs_emu_set_texture(NULL);
        fs_gl_bind_texture(g_text_texture);
        //glColor4f(1.0, 1.0, 1.0, alpha);
        //printf("rendering %f %f %f %f...\n", item->x1, item->x2, item->y1, item->y2);
        fs_gl_color4f(r, g, b, alpha);
        //glColor4f(r * alpha, g * alpha, b * alpha, alpha);

#ifdef USE_GLES
        GLfloat tex[] = {
            item->x1, item->y2,
            item->x2, item->y2,
            item->x2, item->y1,
            item->x1, item->y1
        };
        GLfloat vert[] = {
            x, y,
            x + item->width, y,
            x + item->width, y + item->height,
            x, y + item->height
        };

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        glVertexPointer(2, GL_FLOAT, 0, vert);
        glTexCoordPointer(2, GL_FLOAT, 0, tex);
        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
#else
        glBegin(GL_QUADS);
        glTexCoord2f(item->x1, item->y2);
        glVertex2f(x, y);
        glTexCoord2f(item->x2, item->y2);
        glVertex2f(x + item->width, y);
        glTexCoord2f(item->x2, item->y1);
        glVertex2f(x + item->width, y + item->height);
        glTexCoord2f(item->x1, item->y1);
        glVertex2f(x, y + item->height);
        glEnd();
#endif

        g_cache = g_list_prepend(g_cache, item);
        sanity_check();
        return item->width;
    }

    // calculate size of text

    //printf(":: %s\n", text);

    int num_chars = 0;
    int required_width = 0;
    int required_height = font->h;

    //char *base_text = fs_utf8_strup(text, -1);
    const char *base_text = text;

    unsigned const char *c = (unsigned const char*) base_text;
    int continuations = 0;
    int cp = 0;
    while(*c) {
        //if ((*c & 0b10000000) == 0b00000000) {
        if ((*c & 0x80) == 0x0) {
            continuations = 0;
            //cp = *c & 0b01111111;
            cp = *c & 0x7f;
        }
        //else if ((*c & 0b11000000) == 0b10000000) {
        else if ((*c & 0xc0) == 0x80) {
            continuations--;
            cp = cp << 6;
            //cp = cp | (*c & 0b00111111);
            cp = cp | (*c & 0x3f);
        }
        //else if ((*c & 0b11111110) == 0b11111100) { // 1111110x
        else if ((*c & 0xfe) == 0xfc) { // 1111110x
            continuations = 5;
            //cp = *c & 0b00000001;
            cp = *c & 0x1;
        }
        //else if ((*c & 0b11111100) == 0b11111000) { // 111110xx
        else if ((*c & 0xfc) == 0xf8) { // 111110xx
            continuations = 4;
            //cp = *c & 0b00000011;
            cp = *c & 0x3;
        }
        //else if ((*c & 0b11111000) == 0b11110000) { // 11110xxx
        else if ((*c & 0xf8) == 0xf0) { // 11110xxx
            continuations = 3;
            //cp = *c & 0b00000111;
            cp = *c & 0x7;
        }
        //else if ((*c & 0b11110000) == 0b11100000) { // 1110xxxx
        else if ((*c & 0xf0) == 0xe0) { // 1110xxxx
            continuations = 2;
            //cp = *c & 0b00001111;
            cp = *c & 0xf;
        }
        //else if ((*c & 0b11100000) == 0b11000000) { // 110xxxxx
        else if ((*c & 0xe0) == 0xc0) { // 110xxxxx
            continuations = 1;
            //cp = *c & 0b00011111;
            cp = *c & 0x1f;
        }

        ++c;
        if (continuations) {
            continue;
        }

        cp = fix_char(font, cp);
        //printf("%d\n", cp);
        if (required_width + font->w[cp] > g_texture_width) {
            break;
        }
        required_width += font->w[cp];
        num_chars++;
    }

    int dx = 0;
    int dy = 0;
    c = (unsigned const char*) base_text;
    //printf("base_text: %s\n", c);
    continuations = 0;
    cp = 0;
    int k = 0;
    while(*c) {
        //printf("%d\n", *c);
        //if ((*c & 0b10000000) == 0b00000000) {
        if ((*c & 0x80) == 0x0) {
            continuations = 0;
            //cp = *c & 0b01111111;
            cp = *c & 0x7f;
        }
        //else if ((*c & 0b11000000) == 0b10000000) {
        else if ((*c & 0xc0) == 0x80) {
            continuations--;
            cp = cp << 6;
            //cp = cp | (*c & 0b00111111);
            cp = cp | (*c & 0x3f);
        }
        //else if ((*c & 0b11111110) == 0b11111100) { // 1111110x
        else if ((*c & 0xfe) == 0xfc) { // 1111110x
            continuations = 5;
            //cp = *c & 0b00000001;
            cp = *c & 0x1;
        }
        //else if ((*c & 0b11111100) == 0b11111000) { // 111110xx
        else if ((*c & 0xfc) == 0xf8) { // 111110xx
            continuations = 4;
            //cp = *c & 0b00000011;
            cp = *c & 0x3;
        }
        //else if ((*c & 0b11111000) == 0b11110000) { // 11110xxx
        else if ((*c & 0xf8) == 0xf0) { // 11110xxx
            continuations = 3;
            //cp = *c & 0b00000111;
            cp = *c & 0x7;
        }
        //else if ((*c & 0b11110000) == 0b11100000) { // 1110xxxx
        else if ((*c & 0xf0) == 0xe0) { // 1110xxxx
            continuations = 2;
            //cp = *c & 0b00001111;
            cp = *c & 0xf;
        }
        //else if ((*c & 0b11100000) == 0b11000000) { // 110xxxxx
        else if ((*c & 0xe0) == 0xc0) { // 110xxxxx
            continuations = 1;
            //cp = *c & 0b00011111;
            cp = *c & 0x1f;
        }

        ++c;
        if (continuations) {
            continue;
        }

        if (++k > num_chars) {
            // there may be more chars left in the original string,
            // but there is no room for the next char in the texture
            break;
        }

        cp = fix_char(font, cp);

        int sx = font->x[cp];
        int sy = font->y[cp];
        int sw = font->w[cp];
        int sh = font->h;

        //if (c > 256) {
        //    printf("%d %d %d %d %d\n", c, sx, sy, sw, sh);
        //}

        // draw character
        //printf("-----------> %d\n", cp);

        int *sl = ((int *) font->image->data) + font->image->width * sy + sx;
        int ss = font->image->width; // source stride
        //int *sl = sp;
        int *dl = ((int *) g_buffer) + g_texture_width * dy + dx;
        int ds = g_texture_width; // destination stride
        //int *dl = dp;

        for (int y = 0; y < sh; y++) {
            //printf("%d\n", y);
            int *sp = sl;
            int *dp = dl;
            for (int x = 0; x < sw; x++) {
                //printf("%d %d\n", x, y);
                //*dp++ = 0xff0000ff;
                //*dp++ = *sp++;
                int a = *sp;
                sp++;
                *dp = a;
                dp++;
                //int a = *sp++;
            }
            sl += ss;
            dl += ds;
        }

        dx += sw;
    }
    //free(utext);
    //free(base_text);

    GList *last = g_list_last(g_cache);
    cache_item *last_item = (cache_item *) last->data;
    int position = last_item->position;

    fs_gl_bind_texture(g_text_texture);
    int gl_buffer_format = GL_RGBA;
    if (fs_emu_get_video_format() == FS_EMU_VIDEO_FORMAT_BGRA) {
        gl_buffer_format = GL_BGRA;
    }
#ifdef USE_GLES
    /* GLES does not support unpack padding of buffer. we have to update line-wise (or create a new one) */
    uint8_t *buf = g_buffer;
    for(int y=0;y<required_height;y++) {
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, position * 32 + y, required_width,
                1, gl_buffer_format, GL_UNSIGNED_BYTE, buf);
        buf += g_texture_width * 4;
    }
#else
    fs_gl_unpack_row_length(g_texture_width);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, position * 32, required_width,
            required_height, gl_buffer_format, GL_UNSIGNED_BYTE, g_buffer);
#endif

    cache_item *item = malloc(sizeof(cache_item));
    item->font = font;
    item->text = g_strdup(text);
    item->width = required_width;
    item->height = required_height;
    item->position = position;

    item->x1 = 0;
    item->x2 = required_width / (1.0 * g_texture_width);
    item->y1 = (item->position * 32) / (1.0 * g_texture_height);
    item->y2 = (item->position * 32 + required_height) /
            (1.0 * g_texture_height);
    //item->texture = render_texture;
    g_cache = g_list_prepend(g_cache, item);
    sanity_check();

    if (last_item->text) {
        free(last_item->text);
    }
    /*
    if (last_item->texture) {
        glDeleteTextures(1, &last_item->texture);
    }
    */
    free(last_item);

    g_cache = g_list_delete_link(g_cache, last);
    sanity_check();

    // now the text is in the cache, so call function again
    return fs_emu_font_render(font, text, x, y, r, g, b, alpha);
}
Beispiel #4
0
void fs_emu_video_render_function() {
    static int initialized_menu = 0;
    if (!initialized_menu) {
        // render menu once (without really showing it, so all menu
        // resources are initialized and loaded, -prevents flickering
        // when really opening the menu later
        fs_emu_render_menu(g_menu_transition);
        initialized_menu = 1;
    }

    if (g_fs_emu_video_debug) {
        int quarter_height = fs_ml_video_height() / 4;
        fs_gl_viewport(0, quarter_height, fs_ml_video_width(),
                fs_ml_video_height() - quarter_height);
    }
    else {
        fs_gl_viewport(0, 0, fs_ml_video_width(), fs_ml_video_height());
    }

    // FIXME: can perhaps remove this soon..
    fs_emu_video_render_mutex_lock();

    int in_menu = fs_emu_menu_is_active();
    if (in_menu && g_menu_transition_target < 1.0) {
        g_menu_transition_target = 1.0;
    }
    if (!in_menu && g_menu_transition_target > 0.0) {
        g_menu_transition_target = 0.0;
    }

    // FIXME: ideally, we would use time-based animation - for now, we use a
    // simple frame-based animation
    if (g_menu_transition < g_menu_transition_target) {
        if (g_menu_transition_target == 1.0) {
            g_menu_transition += 0.10;
        }
    }
    if (g_menu_transition > g_menu_transition_target) {
        if (g_menu_transition_target == 0.0) {
            g_menu_transition -= 0.10;
        }
    }
    if (g_menu_transition > 1.0) {
        g_menu_transition = 1.0;
    }
    else if (g_menu_transition < 0.0) {
        g_menu_transition = 0.0;
    }

    int matrix_pushed = 0;

    double t0_x = 0.0;
    double t0_y = 0.0;
    double t0_z = -2.42;
    double r0_a = 0.0;

    double t1_x = -0.31;
    //double t1_y = -0.04;
    double t1_y = 0.0;
    double t1_z = -3.7;
    double r1_a = 30.0;

    int perspective = 0;
    if (g_menu_transition == 0.0) {
        perspective = 0;
        fs_gl_ortho();
        //glTranslated(1920.0 / 2.0, 1080.0 / 2.0, 0.0);
        //glScaled(1920.0 / 2.0, 1080.0 / 2.0, 1.0);
    }
    else {
        perspective = 1;

        glClearColor(0.1, 0.1, 0.1, 1.0);
        glClear(GL_DEPTH_BUFFER_BIT);
        CHECK_GL_ERROR();
        fs_gl_ortho_hd();

        // transition y-coordinate between floor and wall
        int splt = 361;
        fs_gl_blending(FALSE);
        fs_gl_texturing(FALSE);
        GLfloat color[] = {
            39.0 / 255.0, 44.0 / 255.0, 51.0 / 255.0, 1.0,
            39.0 / 255.0, 44.0 / 255.0, 51.0 / 255.0, 1.0,
            0.0, 0.0, 0.0, 1.0,
            0.0, 0.0, 0.0, 1.0,

            0.0, 0.0, 0.0, 1.0,
            0.0, 0.0, 0.0, 1.0,
            0.0, 0.0, 0.0, 1.0,
            0.0, 0.0, 0.0, 1.0,

            0.0, 0.0, 0.0, 1.0,
            0.0, 0.0, 0.0, 1.0,
            20.0 / 255.0, 22.0 / 255.0, 26.0 / 255.0, 1.0,
            20.0 / 255.0, 22.0 / 255.0, 26.0 / 255.0, 1.0
        };
        GLfloat vert[] = {
               0, splt, -0.9,
            1920, splt, -0.9,
            1920, 1020, -0.9,
               0, 1020, -0.9,

               0, 1020, -0.9,
            1920, 1020, -0.9,
            1920, 1080, -0.9,
               0, 1080, -0.9,

               0,    0, -0.9,
            1920,    0, -0.9,
            1920, splt, -0.9,
               0, splt, -0.9
        };

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);

        glColorPointer(4, GL_FLOAT, 0, color);
        glVertexPointer(3, GL_FLOAT, 0, vert);
        glDrawArrays(GL_TRIANGLE_FAN, 0, 12);

        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_COLOR_ARRAY);
        CHECK_GL_ERROR();

        fs_gl_perspective();
        double t_x = t0_x + (t1_x - t0_x) * g_menu_transition;
        double t_y = t0_y + (t1_y - t0_y) * g_menu_transition;
        double t_z = t0_z + (t1_z - t0_z) * g_menu_transition;
        double r_a = r0_a + (r1_a - r0_a) * g_menu_transition;

        glPushMatrix();
        matrix_pushed = 1;

        glScaled(16.0 / 9.0, 1.0, 1.0);
        glTranslated(t_x, t_y, t_z);
        glRotated(r_a, 0.0, 1.0, 0.0);
        CHECK_GL_ERROR();
    }

    if (perspective) {
        render_glow(g_menu_transition);
    }
    if (perspective) {
        glPushMatrix();
        glTranslatef(0.0, -2.0, 0.0);
        //glTranslatef(0.0, -1.0, 0.0);
        //glScalef(1.0, -1.0, 1.0);
        glScalef(1.0, -0.5, 1.0);
        glTranslatef(0.0, -1.0, 0.0);
        CHECK_GL_ERROR();
        render_frame(0.33, perspective);
        CHECK_GL_ERROR();
        render_gloss(g_menu_transition * 0.66);
        CHECK_GL_ERROR();
        glPopMatrix();
        CHECK_GL_ERROR();
    }
    render_frame(1.0, perspective);
    if (perspective) {
        render_gloss(g_menu_transition);
    }
    /*
    if (fs_emu_is_paused()) {
        render_pause_fade();
    }
    */

    if (matrix_pushed) {
        glPopMatrix();
        CHECK_GL_ERROR();
        matrix_pushed = 0;
    }

    fs_emu_acquire_gui_lock();
    fs_emu_render_chat();

    //if (fs_emu_menu_is_active()) {
    if (g_menu_transition > 0.0) {
        fs_emu_render_menu(g_menu_transition);
    }

	fs_emu_render_dialog();
    fs_emu_release_gui_lock();

    if (g_fs_emu_hud_mode && fs_emu_netplay_enabled()) {
        fs_gl_ortho_hd();
        fs_gl_texturing(0);
        fs_gl_blending(1);
	fs_gl_color4f(0.0, 0.0, 0.0, 0.5);
        GLfloat vert[] = {
            0, 1030,
            1920, 1030,
            1920, 1080,
            0, 1080
        };
        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(2, GL_FLOAT, 0, vert);
        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
        glDisableClientState(GL_VERTEX_ARRAY);
        CHECK_GL_ERROR();
#if 0
        glBegin(GL_QUADS);
        glVertex2f(0, 1030);
        glVertex2f(1920, 1030);
        fs_gl_color4f(0.0, 0.0, 0.0, 0.0);
        glVertex2f(1920, 1030 - 50);
        glVertex2f(0, 1030 - 50);
        glEnd();
#endif
        fs_emu_font *menu_font = fs_emu_font_get_menu();
        char *str;

        for (int i = 0; i < MAX_PLAYERS; i++) {
            fs_emu_player *player = g_fs_emu_players + i;
            int x = i * 1920 / 6 + 20;
            int y = 1038;

            int rendered_tag = 0;
            if (player->tag && player->tag[0]) {
                str = g_strdup_printf("%s", player->tag);
                fs_emu_font_render(menu_font, str, x, y,
                        1.0, 1.0, 1.0, 1.0);
                g_free(str);
                rendered_tag = 1;
            }
            if (rendered_tag || player->ping) {
                str = g_strdup_printf("%03d", player->ping);
                fs_emu_font_render(menu_font, str, x + 100, y,
                        1.0, 1.0, 1.0, 1.0);
                g_free(str);
            }
            if (rendered_tag || player->lag) {
                str = g_strdup_printf("%03d", player->lag);
                fs_emu_font_render(menu_font, str, x + 200, y,
                        1.0, 1.0, 1.0, 1.0);
                g_free(str);
            }
        }
    }

    if (g_fs_emu_video_debug) {
        int quarter_height = fs_ml_video_height() / 4;
        fs_gl_viewport(0, 0, fs_ml_video_width(), quarter_height);
        CHECK_GL_ERROR();

        fs_emu_set_texture(NULL);
        CHECK_GL_ERROR();
        static GLuint debug_texture = 0;
        static uint32_t *debug_texture_data = NULL;
        if (debug_texture == 0) {
            debug_texture_data = g_malloc0(256 * 256 * 4);
            glGenTextures(1, &debug_texture);
            CHECK_GL_ERROR();
            fs_gl_bind_texture(debug_texture);
#ifndef HAVE_GLES
            fs_gl_unpack_row_length(0);
#endif
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0,
                    GL_RGBA, GL_UNSIGNED_BYTE, NULL);
            CHECK_GL_ERROR();
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
                    GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
                    GL_CLAMP_TO_EDGE);
            CHECK_GL_ERROR();
        }
        else {
            fs_gl_bind_texture(debug_texture);
            CHECK_GL_ERROR();
        }

        memset(debug_texture_data, 0x00, 256 * 256 * 4);
        CHECK_GL_ERROR();
        fs_emu_video_render_debug_info(debug_texture_data);
        CHECK_GL_ERROR();
        fs_emu_audio_render_debug_info(debug_texture_data);
        CHECK_GL_ERROR();

#ifndef HAVE_GLES
        fs_gl_unpack_row_length(0);
#endif
        CHECK_GL_ERROR();
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 256,
                GL_RGBA, GL_UNSIGNED_BYTE, debug_texture_data);
        CHECK_GL_ERROR();
        fs_gl_ortho_hd();
        fs_gl_texturing(1);
        fs_gl_blending(0);
        fs_gl_color4f(1.0, 1.0, 1.0, 1.0);
        GLfloat tex[] = {
            0.0, 0.0,
            1.0, 0.0,
            1.0, 1.0,
            0.0, 1.0
        };
        GLfloat vert[] = {
            0, 0,
            1920, 0,
            1920, 1080,
            0, 1080
        };

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        glTexCoordPointer(2, GL_FLOAT, 0, tex);
        glVertexPointer(2, GL_FLOAT, 0, vert);
        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        CHECK_GL_ERROR();

        glPushMatrix();
        glScalef(1.0, 4.0, 1.0);

        fs_emu_font *menu_font = fs_emu_font_get_menu();
        char *str;

        /*
        str = g_strdup_printf("%d", fs_emu_get_audio_frequency());
        fs_emu_font_render(menu_font, str, 1920 / 2 + 20, 3,
                1.0, 1.0, 1.0, 1.0);
        g_free(str);
        */

        str = g_strdup_printf("%0.1f",
                fs_emu_audio_get_measured_avg_buffer_fill(0) / 1000.0);
        fs_emu_font_render(menu_font, str, 1920 / 2 + 220, 3,
                1.0, 1.0, 1.0, 1.0);
        g_free(str);
        str = g_strdup_printf("%d", g_fs_emu_audio_buffer_underruns);
        fs_emu_font_render(menu_font, str, 1920 / 2 + 420, 3,
                1.0, 1.0, 1.0, 1.0);
        g_free(str);

        fs_emu_font_render(menu_font, "EMU", 20, 3, 1.0, 1.0, 1.0, 1.0);
        str = g_strdup_printf("%0.1f", fs_emu_get_average_emu_fps());
        fs_emu_font_render(menu_font, str, 220, 3, 1.0, 1.0, 1.0, 1.0);
        g_free(str);
        str = g_strdup_printf("%d", g_fs_emu_lost_frames);
        fs_emu_font_render(menu_font, str, 420, 3, 1.0, 1.0, 1.0, 1.0);
        g_free(str);
        str = g_strdup_printf("%d", g_fs_emu_repeated_frames);
        fs_emu_font_render(menu_font, str, 620, 3, 1.0, 1.0, 1.0, 1.0);
        g_free(str);

        fs_emu_font_render(menu_font, "SYS", 20, 140, 1.0, 1.0, 1.0, 1.0);
        str = g_strdup_printf("%0.1f", fs_emu_get_average_sys_fps());
        fs_emu_font_render(menu_font, str, 220, 140, 1.0, 1.0, 1.0, 1.0);
        g_free(str);
        str = g_strdup_printf("%d", g_fs_emu_lost_vblanks);
        fs_emu_font_render(menu_font, str, 420, 140, 1.0, 1.0, 1.0, 1.0);
        g_free(str);

        glPopMatrix();
        CHECK_GL_ERROR();
    }

    if (fs_emu_is_quitting()) {
        handle_quit_sequence();
    }

    fs_emu_video_render_mutex_unlock();
}
Beispiel #5
0
void fs_emu_render_dialog() {
    fs_emu_dialog *dialog = fs_emu_get_current_dialog();
    if (!dialog) {
        return;
    }

    fs_gl_ortho_hd();
    fs_gl_blending(1);
    fs_gl_texturing(0);
    fs_gl_color4f(0.0, 0.0, 0.0, 0.5);
    GLfloat vert[] = {
        0, 0,
        1920, 0,
        1920, 1080,
        0, 1080
    };

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, vert);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    fs_gl_blending(0);

    int width = 1920 / 2;
    int height = 480; //1080 / 2;
    float x1 = (1920 - width) / 2;
    float x2 = x1 + width;
    float y1 = (1080 - height) / 2;
    float y2 = y1 + height;

    GLfloat color2[] = {
        0.0, 0.4, 0.75, 1.0,
        0.0, 0.4, 0.75, 1.0,
        0.0, 0.2, 0.375, 1.0,
        0.0, 0.2, 0.375, 1.0
    };
    GLfloat vert2[] = {
        x1, y1,
        x2, y1,
        x2, y2,
        x1, y2
    };

    glEnableClientState(GL_COLOR_ARRAY);

    glColorPointer(4, GL_FLOAT, 0, color2);
    glVertexPointer(2, GL_FLOAT, 0, vert2);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);

    fs_emu_font *font = fs_emu_font_get_menu();
    int tx = x1 + 50;
    int ty = y2 - 80;
    if (dialog->title) {
        fs_emu_font_render(font, dialog->title,
                tx, ty, 1.0, 1.0, 1.0, 1.0);
        ty -= 50;
    }

    for (int i = 0; i < DIALOG_MAX_LINES; i++) {
        if (dialog->lines[i]) {
            fs_emu_font_render(font, dialog->lines[i],
                    tx, ty, 1.0, 1.0, 1.0, 1.0);
        }
        ty -= 50;
    }

    tx = x2;
    ty = y1 - 50;
    int tw;
    if (dialog->affirmative) {
        fs_emu_font_measure(font, dialog->affirmative, &tw, NULL);
        tx -= tw;
        fs_emu_font_render(font, dialog->affirmative,
                tx, ty, 1.0, 1.0, 1.0, 1.0);
        tx -= 20;
        fs_emu_font_measure(font, "<OK>", &tw, NULL);
        tx -= tw;
        fs_emu_font_render(font, "<OK>", tx, ty, 1.0, 1.0, 1.0, 1.0);
        //tx -= 40;
    }
    tx = x1;
    if (dialog->negative) {
        //fs_emu_font_measure(font, dialog->negative, &tw, NULL);
        //tx -= tw;
        tx += fs_emu_font_render(font, "<BK>", tx, ty, 1.0, 1.0, 1.0, 1.0);
        tx += 20;
        fs_emu_font_render(font, dialog->negative,
                tx, ty, 1.0, 1.0, 1.0, 1.0);
        //fs_emu_font_measure(font, "<BK>", &tw, NULL);
        //tx -= tw;
        //tx -= 40;
    }
}