Beispiel #1
0
static void set_window_icon() {
    fs_log("setting _NET_WM_ICON from icon images\n");

    int max_size = (16 * 16 + 32 * 32 + 48 * 48 + 64 * 64 + 128 * 128) * \
            sizeof(unsigned long);
    // add space for width, height cardinals
    max_size += 2 * 5 * sizeof(unsigned long);

    unsigned long *icon_data = (unsigned long *) g_malloc(max_size);
    unsigned long *op = icon_data;
    int card_count  = 0;

    int sizes[] = {128, 64, 48, 32, 16, 0};
    for(int *size = sizes; *size; size++) {
        char *rel = g_strdup_printf("icons/hicolor/%dx%d/apps/fs-uae.png",
                *size, *size);
        char *path = fs_get_data_file(rel);
        g_free(rel);
        if (!path) {
            fs_log("did not find icon for %dx%d\n", *size, *size);
            continue;
        }

        fs_image *image = fs_image_new_from_file(path);
        if (!image) {
            fs_log("could not load icon from %s\n", path);
            continue;
        }
        g_free(path);

        //printf("%d\n", image->width);
        int pixel_count = image->width * image->height;
        unsigned char *p = image->data;
        *op++ = image->width;
        *op++ = image->height;
        for (int i = 0; i < pixel_count; i++) {
            //*op = 0xffff0000;
            *op = (((unsigned long) p[3]) << 24) |
                    (p[0] << 16) |
                    (p[1] << 8) |
                    p[2];
            p += 4;
            op++;
        }
        card_count += 2 + pixel_count;

        fs_unref(image);

        // FIXME

    }

    Atom _NET_WM_ICON = XInternAtom(g_display, "_NET_WM_ICON", False);
    XChangeProperty(g_display, g_window, _NET_WM_ICON, XA_CARDINAL, 32,
            PropModeReplace, (unsigned char *) icon_data, card_count);
    g_free(icon_data);
}
Beispiel #2
0
static fs_image *load_font_from_file(const char *path)
{
    if (path == NULL) {
        fs_emu_warning(_("Could not find font: %s"), path);
        return NULL;
    }
    fs_emu_log("loading image \"%s\"\n", path);
    fs_image *image = fs_image_new_from_file(path);
    if (image == NULL) {
        fs_emu_warning(_("Error loading font: %s"), path);
        return NULL;
    }
    convert_to_premultiplied_alpha(image);
    return image;
}
Beispiel #3
0
fs_image *load_font_from_file(const char *name) {
    char *full_name = g_strconcat(name, ".png", NULL);
    //char *path = g_build_filename(fs_emu_get_share_dir(), full_name, NULL);
    char *path = fs_get_program_data_file(full_name);
    if (path == NULL) {
        fs_emu_warning("Could not find font %s", full_name);
        return NULL;
    }
    fs_emu_log("loading image \"%s\"\n", path);
    fs_image *image = fs_image_new_from_file(path);
    g_free(path);
    if (image == NULL) {
        fs_emu_warning("Error loading font from %s", full_name);
        g_free(full_name);
        return NULL;
    }
    g_free(full_name);

    // convert to premultiplied alpha
    if (image->format == FS_IMAGE_FORMAT_RGBA) {
        int num_pixels = image->width * image->height;
        unsigned char *pixels = image->data;
        for (int i = 0; i < num_pixels; i++) {
            unsigned char alpha = pixels[3];
            // should really divide by 255, but 256 is faster...
            //pixels[0] = ((int) pixels[0]) * alpha / 256;
            //pixels[1] = ((int) pixels[1]) * alpha / 256;
            //pixels[2] = ((int) pixels[2]) * alpha / 256;
            pixels[0] = ((int) pixels[0]) * alpha / 255;
            pixels[1] = ((int) pixels[1]) * alpha / 255;
            pixels[2] = ((int) pixels[2]) * alpha / 255;
            //pixels[0] = (unsigned char) ((pixels[0] * alpha + 0.5) / 255.0);
            //pixels[1] = (unsigned char) ((pixels[1] * alpha + 0.5) / 255.0);
            //pixels[2] = (unsigned char) ((pixels[2] * alpha + 0.5) / 255.0);
            pixels += 4;
        }
    }
    return image;
}
Beispiel #4
0
fs_emu_texture *fs_emu_texture_new_from_file(const char *name) {
    char *full_name;
    char *path;
    if (fs_path_exists(name)) {
        full_name = fs_strdup(name);
        path = fs_strdup(name);
    }
    else {
        full_name = fs_strconcat(name, ".png", NULL);
        path = fs_get_program_data_file(full_name);
        if (path == NULL) {
            fs_emu_warning("Could not find texture %s\n", full_name);
            return NULL;
        }
    }
    fs_image *image = fs_image_new_from_file(path);
    fs_emu_log("loading texture \"%s\"\n", path);
    free(path);
    if (image == NULL) {
        fs_emu_warning("Could not load texture from %s\n", full_name);
        free(full_name);
        return NULL;
    }
    free(full_name);

    if (fs_emu_get_video_format() == FS_EMU_VIDEO_FORMAT_BGRA) {
        // convert to premultiplied alpha
        if (image->format == FS_IMAGE_FORMAT_RGBA) {
            int num_pixels = image->width * image->height;
            unsigned char *pixels = image->data;
            for (int i = 0; i < num_pixels; i++) {
                unsigned char alpha = pixels[3];
                unsigned char temp = pixels[2];
                pixels[2] = ((int) pixels[0]) * alpha / 255;
                pixels[1] = ((int) pixels[1]) * alpha / 255;
                pixels[0] = ((int) temp) * alpha / 255;
                pixels += 4;
            }
        }
        else {
            // FIXME: should swap R and B here...
        }
    }
    else {
        // convert to premultiplied alpha
        if (image->format == FS_IMAGE_FORMAT_RGBA) {
            int num_pixels = image->width * image->height;
            unsigned char *pixels = image->data;
            for (int i = 0; i < num_pixels; i++) {
                unsigned char alpha = pixels[3];
                // should really divide by 255, but 256 is faster...
                //pixels[0] = ((int) pixels[0]) * alpha / 256;
                //pixels[1] = ((int) pixels[1]) * alpha / 256;
                //pixels[2] = ((int) pixels[2]) * alpha / 256;
                pixels[0] = ((int) pixels[0]) * alpha / 255;
                pixels[1] = ((int) pixels[1]) * alpha / 255;
                pixels[2] = ((int) pixels[2]) * alpha / 255;
                //pixels[0] = (unsigned char) ((pixels[0] * alpha + 0.5) / 255.0);
                //pixels[1] = (unsigned char) ((pixels[1] * alpha + 0.5) / 255.0);
                //pixels[2] = (unsigned char) ((pixels[2] * alpha + 0.5) / 255.0);
                pixels += 4;
            }
        }
    }

    fs_emu_texture *texture = fs_new(fs_emu_texture, 1);
    texture->width = image->width;
    texture->height = image->height;
    texture->image = image;
    load_texture(texture);
    fs_emu_set_texture(texture);

    fs_gl_add_context_notification(context_notification_handler, texture);

    return texture;
}
Beispiel #5
0
static void load_atlas_texture(fs_image *atlas_image,
        int texture_id, const char *name) {
    char *path = fs_emu_theme_get_resource(name);
    if (!path) {
        fs_emu_warning("Could not find resource %s\n", name);
        return;
    }

    fs_image *image = fs_image_new_from_file(path);
    if (!image) {
        fs_emu_warning("error loading texture \"%s\"\n", name);
        return;
    }
    fs_emu_log("loaded sub-texture from \"%s\"\n", path);

    // find needed number of cells
    int cw = (image->width + 7) / 8;
    int ch = (image->height + 7) / 8;
    // adding 1 to get some spacing between cells
    if (cw < 128) {
        cw++;
    }
    if (ch < 128) {
        ch++;
    }

    // try to find space for it in the texture atlas using a simple
    // brute-force search
    int cx = 0;
    int cy = 0;
    int ok = 0;
    for (cy = 0; cy <= 128 - ch; cy++) {
        for (cx = 0; cx <= 128 - cw; cx++) {
            if (check_placement(cx, cy, cw, ch)) {
                ok = 1;
                break;
            }
        }
        if (ok) {
            break;
        }
    }
    if (!ok) {
        fs_emu_warning("could not find space for \"%s\"\n", name);
        //printf("%d %d %d %d\n", cx * 8, cy * 8, cw * 8, ch * 8);
        return;
    }
    // mark cells as used
    for (int y = cy; y < cy + ch; y++) {
        for (int x = cx; x < cx + cw; x++) {
            g_cells[y][x] = 1;
        }
    }
    //printf("%d %d %d %d\n", cx * 8, cy * 8, cw * 8, ch * 8);

    // copy sub-texture into texture, also converting to pre-multiplied
    // alpha, and BGRA if needed. Also copy border pixels to pixels outside
    // border to fix unwanted bilinear filtering effects
    int dx = cx * 8;
    int dy = cy * 8;
    int ds = atlas_image->width * 4; // stride
    unsigned char *dst = atlas_image->data + \
            (dy * atlas_image->width + dx) * 4;
    unsigned char *sp = image->data;

    for (int y = 0; y < image->height; y++) {
#if 1
        if (y == 0 && dy > 0) {
            // repeat first line
            unsigned char *dp = dst - ds;
            for (int x = 0; x < image->width; x++) {
                copy_pixel(&dp, &sp);
            }
            sp -= image->width * 4;
        }
#endif
        unsigned char *dp = dst;
        for (int x = 0; x < image->width; x++) {
            copy_pixel(&dp, &sp);
        }
        dst += 1024 * 4; // stride
#if 1
        if (y == image->height - 1 && dy + y - 1 < atlas_image->height - 1) {
            // repeat last line
            sp -= image->width * 4;
            unsigned char *dp = dst;
            for (int x = 0; x < image->width; x++) {
                copy_pixel(&dp, &sp);
            }
        }
#endif
    }

    // repeat left and right borders
    uint32_t *idata = (uint32_t *) atlas_image->data;
    int iwidth = atlas_image->width;
    int y1 = dy;
    int y2 = dy + image->height - 1;
    if (y1 > 0) {
        y1 -= 1;
    }
    if (y2 < atlas_image->height - 1) {
        y2 += 1;
    }
    if (dx > 0) {
        for (int y = y1; y <= y2; y++) {
            idata[y * iwidth + dx - 1] = idata[y * iwidth + dx];
        }
    }
    if (dx + image->width - 1 < atlas_image->width - 1) {
        for (int y = y1; y <= y2; y++) {
            idata[y * iwidth + dx + image->width - 1 + 1] = \
                    idata[y * iwidth + dx + image->width - 1];
        }
    }

    // register texture coordinates
    g_entries[texture_id].x = cx * 8;
    g_entries[texture_id].y = cy * 8;
    g_entries[texture_id].w = image->width;
    g_entries[texture_id].h = image->height;

    // and finally free the sub-texture image
    fs_unref(image);
}