mirror of
https://github.com/libretro/RetroArch.git
synced 2025-02-21 10:11:18 +00:00
(Image) Put image functions through abstract interface
(Image) Add image_driver to retroarch.cfg to specify image driver to use (Menu) Add Image Driver to Drivers section
This commit is contained in:
parent
107efae2e2
commit
b2b5c6daec
4
Makefile
4
Makefile
@ -36,7 +36,8 @@ OBJ = frontend/frontend.o \
|
||||
gfx/scaler/pixconv.o \
|
||||
gfx/scaler/scaler_int.o \
|
||||
gfx/scaler/scaler_filter.o \
|
||||
gfx/image/image.o \
|
||||
gfx/image/image_rpng.o \
|
||||
gfx/image_context.o \
|
||||
gfx/fonts/fonts.o \
|
||||
gfx/fonts/bitmapfont.o \
|
||||
audio/resampler.o \
|
||||
@ -318,6 +319,7 @@ ifeq ($(HAVE_FREETYPE), 1)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL_IMAGE), 1)
|
||||
OBJ += gfx/image/image_sdl.o
|
||||
LIBS += $(SDL_IMAGE_LIBS)
|
||||
DEFINES += $(SDL_IMAGE_CFLAGS)
|
||||
endif
|
||||
|
@ -38,7 +38,8 @@ OBJ = frontend/platform/platform_emscripten.o \
|
||||
gfx/shader_parse.o \
|
||||
gfx/fonts/fonts.o \
|
||||
gfx/fonts/bitmapfont.o \
|
||||
gfx/image/image.o \
|
||||
gfx/image/image_rpng.o \
|
||||
gfx/image_context.o \
|
||||
audio/resampler.o \
|
||||
audio/sinc.o \
|
||||
audio/cc_resampler.o \
|
||||
|
@ -43,7 +43,8 @@ OBJ = frontend/frontend.o \
|
||||
gfx/shader_parse.o \
|
||||
gfx/fonts/fonts.o \
|
||||
gfx/fonts/bitmapfont.o \
|
||||
gfx/image/image.o \
|
||||
gfx/image/image_rpng.o \
|
||||
gfx/image_context.o \
|
||||
audio/resampler.o \
|
||||
audio/sinc.o \
|
||||
audio/cc_resampler.o \
|
||||
@ -146,6 +147,7 @@ ifeq ($(HAVE_OPENGL), 1)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL_IMAGE), 1)
|
||||
OBJ += gfx/image/image_sdl.o
|
||||
LIBS += -lSDL_image
|
||||
DEFINES += -DHAVE_SDL_IMAGE
|
||||
endif
|
||||
|
13
config.def.h
13
config.def.h
@ -87,6 +87,11 @@ enum
|
||||
INPUT_RWEBINPUT,
|
||||
INPUT_NULL,
|
||||
|
||||
IMAGE_SDL,
|
||||
IMAGE_XDK,
|
||||
IMAGE_PS3,
|
||||
IMAGE_RPNG,
|
||||
|
||||
CAMERA_V4L2,
|
||||
CAMERA_RWEBCAM,
|
||||
CAMERA_ANDROID,
|
||||
@ -200,6 +205,14 @@ enum
|
||||
#define INPUT_DEFAULT_DRIVER INPUT_NULL
|
||||
#endif
|
||||
|
||||
#if defined(__CELLOS_LV2__)
|
||||
#define IMAGE_DEFAULT_DRIVER IMAGE_PS3
|
||||
#elif defined(_XBOX1)
|
||||
#define IMAGE_DEFAULT_DRIVER IMAGE_XDK
|
||||
#else
|
||||
#define IMAGE_DEFAULT_DRIVER IMAGE_RPNG
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_V4L2)
|
||||
#define CAMERA_DEFAULT_DRIVER CAMERA_V4L2
|
||||
#elif defined(EMSCRIPTEN)
|
||||
|
4
driver.c
4
driver.c
@ -509,6 +509,7 @@ void init_drivers_pre(void)
|
||||
#ifdef HAVE_CAMERA
|
||||
find_camera_driver();
|
||||
#endif
|
||||
find_image_driver();
|
||||
#ifdef HAVE_LOCATION
|
||||
find_location_driver();
|
||||
#endif
|
||||
@ -926,6 +927,8 @@ void uninit_drivers(void)
|
||||
|
||||
uninit_video_input();
|
||||
|
||||
driver.image = NULL;
|
||||
|
||||
#ifdef HAVE_CAMERA
|
||||
uninit_camera();
|
||||
|
||||
@ -1484,6 +1487,7 @@ static bool init_video_pixel_converter(unsigned size)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void init_video_input(void)
|
||||
{
|
||||
rarch_init_filter(g_extern.system.pix_fmt);
|
||||
|
5
driver.h
5
driver.h
@ -24,7 +24,7 @@
|
||||
#include <stdint.h>
|
||||
#include "msvc/msvc_compat.h"
|
||||
#include "gfx/scaler/scaler.h"
|
||||
#include "gfx/image/image.h"
|
||||
#include "gfx/image_context.h"
|
||||
#include "gfx/filters/softfilter.h"
|
||||
#include "audio/filters/rarch_dsp.h"
|
||||
#include "input/overlay.h"
|
||||
@ -449,6 +449,7 @@ enum rarch_display_type
|
||||
typedef struct driver
|
||||
{
|
||||
const audio_driver_t *audio;
|
||||
const image_ctx_driver_t *image;
|
||||
const video_driver_t *video;
|
||||
const input_driver_t *input;
|
||||
#ifdef HAVE_OSK
|
||||
@ -543,6 +544,8 @@ void uninit_drivers(void);
|
||||
void global_init_drivers(void);
|
||||
void global_uninit_drivers(void);
|
||||
|
||||
void init_image_input(void);
|
||||
|
||||
void init_video_input(void);
|
||||
void uninit_video_input(void);
|
||||
void init_audio(void);
|
||||
|
@ -356,6 +356,7 @@ static void menu_common_entries_init(void *data, unsigned menu_type)
|
||||
file_list_push(rgui->selection_buf, "Audio Device", RGUI_SETTINGS_DRIVER_AUDIO_DEVICE, 0);
|
||||
file_list_push(rgui->selection_buf, "Audio Resampler", RGUI_SETTINGS_DRIVER_AUDIO_RESAMPLER, 0);
|
||||
file_list_push(rgui->selection_buf, "Input Driver", RGUI_SETTINGS_DRIVER_INPUT, 0);
|
||||
file_list_push(rgui->selection_buf, "Image Driver", RGUI_SETTINGS_DRIVER_IMAGE, 0);
|
||||
#ifdef HAVE_CAMERA
|
||||
file_list_push(rgui->selection_buf, "Camera Driver", RGUI_SETTINGS_DRIVER_CAMERA, 0);
|
||||
#endif
|
||||
@ -3095,6 +3096,12 @@ static int menu_common_setting_set(void *data, unsigned setting, unsigned action
|
||||
else if (action == RGUI_ACTION_RIGHT)
|
||||
find_next_input_driver();
|
||||
break;
|
||||
case RGUI_SETTINGS_DRIVER_IMAGE:
|
||||
if (action == RGUI_ACTION_LEFT)
|
||||
find_prev_image_driver();
|
||||
else if (action == RGUI_ACTION_RIGHT)
|
||||
find_next_image_driver();
|
||||
break;
|
||||
#ifdef HAVE_CAMERA
|
||||
case RGUI_SETTINGS_DRIVER_CAMERA:
|
||||
if (action == RGUI_ACTION_LEFT)
|
||||
@ -3860,6 +3867,9 @@ static void menu_common_setting_set_label(char *type_str, size_t type_str_size,
|
||||
case RGUI_SETTINGS_DRIVER_INPUT:
|
||||
strlcpy(type_str, g_settings.input.driver, type_str_size);
|
||||
break;
|
||||
case RGUI_SETTINGS_DRIVER_IMAGE:
|
||||
strlcpy(type_str, g_settings.image.driver, type_str_size);
|
||||
break;
|
||||
#ifdef HAVE_CAMERA
|
||||
case RGUI_SETTINGS_DRIVER_CAMERA:
|
||||
strlcpy(type_str, g_settings.camera.driver, type_str_size);
|
||||
|
@ -100,6 +100,7 @@ typedef enum
|
||||
RGUI_SETTINGS_DRIVER_AUDIO_DEVICE,
|
||||
RGUI_SETTINGS_DRIVER_AUDIO_RESAMPLER,
|
||||
RGUI_SETTINGS_DRIVER_INPUT,
|
||||
RGUI_SETTINGS_DRIVER_IMAGE,
|
||||
RGUI_SETTINGS_DRIVER_CAMERA,
|
||||
RGUI_SETTINGS_DRIVER_LOCATION,
|
||||
RGUI_SETTINGS_DRIVER_MENU,
|
||||
|
@ -437,7 +437,9 @@ static void rmenu_init_assets(void *data)
|
||||
return;
|
||||
|
||||
menu_texture = (struct texture_image*)calloc(1, sizeof(*menu_texture));
|
||||
texture_image_load(g_extern.menu_texture_path, menu_texture);
|
||||
|
||||
if (driver.image && driver.menu->load)
|
||||
driver.image->load(driver.video_data, g_extern.menu_texture_path, menu_texture);
|
||||
rgui->width = menu_texture->width;
|
||||
rgui->height = menu_texture->height;
|
||||
|
||||
@ -455,7 +457,9 @@ static void *rmenu_init(void)
|
||||
|
||||
static void rmenu_free_assets(void *data)
|
||||
{
|
||||
texture_image_free(menu_texture);
|
||||
if (driver.image && driver.image->free)
|
||||
driver.image->free(driver.video_data, menu_texture);
|
||||
|
||||
menu_texture_inited = false;
|
||||
}
|
||||
|
||||
|
@ -193,6 +193,11 @@ struct settings
|
||||
} menu;
|
||||
#endif
|
||||
|
||||
struct
|
||||
{
|
||||
char driver[32];
|
||||
} image;
|
||||
|
||||
#ifdef HAVE_CAMERA
|
||||
struct
|
||||
{
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include "../../frontend/platform/platform_android.h"
|
||||
#include "../image/image.h"
|
||||
|
||||
#include "../fonts/gl_font.h"
|
||||
#include <stdint.h>
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "../../driver.h"
|
||||
#include "../gfx_common.h"
|
||||
#include "../gl_common.h"
|
||||
#include "../image/image.h"
|
||||
|
||||
#include "../fonts/gl_font.h"
|
||||
#include <stdint.h>
|
||||
|
@ -27,8 +27,6 @@
|
||||
#include <sys/platform.h>
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include "../image/image.h"
|
||||
|
||||
#include "../fonts/gl_font.h"
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include "../image/image.h"
|
||||
#include "../../general.h"
|
||||
#include "../../input/input_common.h"
|
||||
#include "../../input/keyboard_line.h"
|
||||
|
2
gfx/gl.c
2
gfx/gl.c
@ -22,7 +22,7 @@
|
||||
#include "../driver.h"
|
||||
#include "../performance.h"
|
||||
#include "scaler/scaler.h"
|
||||
#include "image/image.h"
|
||||
#include "image_context.h"
|
||||
#include "../file.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "image.h"
|
||||
#include "../image_context.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -77,7 +77,7 @@ static int img_free(void *ptr, void *a)
|
||||
Image decompression - libJPEG
|
||||
********************************************************************************/
|
||||
|
||||
static bool ps3graphics_load_jpeg(const char *path, struct texture_image *out_img)
|
||||
static bool ps3_load_jpeg(const char *path, struct texture_image *out_img)
|
||||
{
|
||||
size_t img_size;
|
||||
#ifndef __PSL1GHT__
|
||||
@ -178,7 +178,6 @@ static bool ps3graphics_load_jpeg(const char *path, struct texture_image *out_im
|
||||
return true;
|
||||
|
||||
error:
|
||||
RARCH_ERR("ps3graphics_load_jpeg(): error.\n");
|
||||
if (out_img->pixels)
|
||||
free(out_img->pixels);
|
||||
out_img->pixels = 0;
|
||||
@ -193,7 +192,7 @@ error:
|
||||
Image decompression - libPNG
|
||||
********************************************************************************/
|
||||
|
||||
static bool ps3graphics_load_png(const char *path, struct texture_image *out_img)
|
||||
static bool ps3_load_png(const char *path, struct texture_image *out_img)
|
||||
{
|
||||
size_t img_size;
|
||||
#ifndef __PSL1GHT__
|
||||
@ -294,8 +293,6 @@ static bool ps3graphics_load_png(const char *path, struct texture_image *out_img
|
||||
return true;
|
||||
|
||||
error:
|
||||
RARCH_ERR("ps3graphics_load_png(): error.\n");
|
||||
|
||||
if (out_img->pixels)
|
||||
free(out_img->pixels);
|
||||
out_img->pixels = 0;
|
||||
@ -307,25 +304,39 @@ error:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool texture_image_load(const char *path, struct texture_image *out_img)
|
||||
static bool ps3_image_load(void *data, const char *path, void *image_data)
|
||||
{
|
||||
(void)data;
|
||||
struct texture_image *out_img = (struct texture_image*)image_data;
|
||||
|
||||
if (!out_img)
|
||||
return false;
|
||||
|
||||
if(strstr(path, ".PNG") != NULL || strstr(path, ".png") != NULL)
|
||||
{
|
||||
if (!ps3graphics_load_png(path, out_img))
|
||||
if (!ps3_load_png(path, out_img))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ps3graphics_load_jpeg(path, out_img))
|
||||
if (!ps3_load_jpeg(path, out_img))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void texture_image_free(struct texture_image *img)
|
||||
static void ps3_image_free(void *data, void *image_data)
|
||||
{
|
||||
struct texture_image *img = (struct texture_image*)image_data;
|
||||
|
||||
if (img->pixels)
|
||||
free(img->pixels);
|
||||
memset(img, 0, sizeof(*img));
|
||||
}
|
||||
|
||||
const image_ctx_driver_t image_ctx_ps3 = {
|
||||
ps3_image_load,
|
||||
ps3_image_free,
|
||||
"ps3",
|
||||
};
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "image.h"
|
||||
#include "../image_context.h"
|
||||
#include "../../file.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -26,84 +26,7 @@
|
||||
#include "../../general.h"
|
||||
#include "../rpng/rpng.h"
|
||||
|
||||
#ifdef HAVE_SDL_IMAGE
|
||||
|
||||
#include "SDL_image.h"
|
||||
bool texture_image_load_argb_shift(const char *path, struct texture_image *out_img,
|
||||
unsigned a_shift, unsigned r_shift, unsigned g_shift, unsigned b_shift)
|
||||
{
|
||||
int y, x;
|
||||
SDL_Surface *img = IMG_Load(path);
|
||||
if (!img)
|
||||
return false;
|
||||
|
||||
out_img->width = img->w;
|
||||
out_img->height = img->h;
|
||||
|
||||
size_t size = out_img->width * out_img->height * sizeof(uint32_t);
|
||||
out_img->pixels = (uint32_t*)malloc(size);
|
||||
if (!out_img->pixels)
|
||||
{
|
||||
SDL_FreeSurface(img);
|
||||
return false;
|
||||
}
|
||||
|
||||
const SDL_PixelFormat *fmt = img->format;
|
||||
|
||||
RARCH_LOG("SDL_image: %dx%d @ %d bpp\n", img->w, img->h, img->format->BitsPerPixel);
|
||||
if (img->format->BitsPerPixel == 32)
|
||||
{
|
||||
for (y = 0; y < img->h; y++)
|
||||
{
|
||||
uint32_t *dst = out_img->pixels + y * img->w;
|
||||
const uint32_t *src = (const uint32_t*)img->pixels + y * img->pitch / sizeof(uint32_t);
|
||||
|
||||
for (x = 0; x < img->w; x++)
|
||||
{
|
||||
uint32_t r = (src[x] & fmt->Rmask) >> fmt->Rshift;
|
||||
uint32_t g = (src[x] & fmt->Gmask) >> fmt->Gshift;
|
||||
uint32_t b = (src[x] & fmt->Bmask) >> fmt->Bshift;
|
||||
uint32_t a = (src[x] & fmt->Amask) >> fmt->Ashift;
|
||||
dst[x] = (a << a_shift) | (r << r_shift) | (g << g_shift) | (b << b_shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (img->format->BitsPerPixel == 24)
|
||||
{
|
||||
for (y = 0; y < img->h; y++)
|
||||
{
|
||||
uint32_t *dst = out_img->pixels + y * img->w;
|
||||
const uint8_t *src = (const uint8_t*)img->pixels + y * img->pitch;
|
||||
|
||||
for (x = 0; x < img->w; x++)
|
||||
{
|
||||
// Correct?
|
||||
uint32_t color = 0;
|
||||
color |= src[3 * x + 0] << 0;
|
||||
color |= src[3 * x + 1] << 8;
|
||||
color |= src[3 * x + 2] << 16;
|
||||
uint32_t r = (color & fmt->Rmask) >> fmt->Rshift;
|
||||
uint32_t g = (color & fmt->Gmask) >> fmt->Gshift;
|
||||
uint32_t b = (color & fmt->Bmask) >> fmt->Bshift;
|
||||
dst[x] = (0xff << a_shift) | (r << r_shift) | (g << g_shift) | (b << b_shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RARCH_ERR("8-bit and 16-bit image support are not implemented.\n");
|
||||
SDL_FreeSurface(img);
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_FreeSurface(img);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static bool texture_image_load_tga_shift(const char *path, struct texture_image *out_img,
|
||||
static bool rpng_image_load_tga_shift(const char *path, struct texture_image *out_img,
|
||||
unsigned a_shift, unsigned r_shift, unsigned g_shift, unsigned b_shift)
|
||||
{
|
||||
unsigned i;
|
||||
@ -185,18 +108,21 @@ static bool texture_image_load_tga_shift(const char *path, struct texture_image
|
||||
return true;
|
||||
}
|
||||
|
||||
bool texture_image_load_argb_shift(const char *path, struct texture_image *out_img,
|
||||
static bool rpng_image_load_argb_shift(const char *path, struct texture_image *out_img,
|
||||
unsigned a_shift, unsigned r_shift, unsigned g_shift, unsigned b_shift)
|
||||
{
|
||||
unsigned i;
|
||||
(void)i;
|
||||
|
||||
if (strstr(path, ".tga"))
|
||||
return texture_image_load_tga_shift(path, out_img, a_shift, r_shift, g_shift, b_shift);
|
||||
return rpng_image_load_tga_shift(path, out_img, a_shift, r_shift, g_shift, b_shift);
|
||||
#ifdef HAVE_ZLIB
|
||||
else if (strstr(path, ".png"))
|
||||
{
|
||||
RARCH_LOG("[RPNG]: Using RPNG loader.\n");
|
||||
bool ret = rpng_load_image_argb(path, &out_img->pixels, &out_img->width, &out_img->height);
|
||||
|
||||
RARCH_LOG("[RPNG]: Using RPNG loader.\n");
|
||||
|
||||
if (!ret)
|
||||
return false;
|
||||
|
||||
@ -205,6 +131,7 @@ bool texture_image_load_argb_shift(const char *path, struct texture_image *out_i
|
||||
{
|
||||
unsigned num_pixels = out_img->width * out_img->height;
|
||||
uint32_t *pixels = out_img->pixels;
|
||||
|
||||
for (i = 0; i < num_pixels; i++)
|
||||
{
|
||||
uint32_t col = pixels[i];
|
||||
@ -223,8 +150,6 @@ bool texture_image_load_argb_shift(const char *path, struct texture_image *out_i
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef GEKKO
|
||||
|
||||
#define GX_BLIT_LINE_32(off) \
|
||||
@ -245,7 +170,7 @@ bool texture_image_load_argb_shift(const char *path, struct texture_image *out_i
|
||||
src += tmp_pitch; \
|
||||
}
|
||||
|
||||
static bool gx_convert_texture32(struct texture_image *image)
|
||||
static bool rpng_gx_convert_texture32(struct texture_image *image)
|
||||
{
|
||||
// memory allocation in libogc is extremely primitive so try to avoid gaps in memory when converting
|
||||
// by copying over to temp buffer first then converting over into main buffer again
|
||||
@ -279,21 +204,32 @@ static bool gx_convert_texture32(struct texture_image *image)
|
||||
|
||||
#endif
|
||||
|
||||
bool texture_image_load(const char *path, struct texture_image *out_img)
|
||||
static void rpng_image_free(void *data, void *image_data)
|
||||
{
|
||||
struct texture_image *img = (struct texture_image*)image_data;
|
||||
|
||||
free(img->pixels);
|
||||
memset(img, 0, sizeof(*img));
|
||||
}
|
||||
|
||||
static bool rpng_image_load(void *data, const char *path, void *image_data)
|
||||
{
|
||||
(void)data;
|
||||
bool ret;
|
||||
struct texture_image *out_img = (struct texture_image*)image_data;
|
||||
|
||||
// This interface "leak" is very ugly. FIXME: Fix this properly ...
|
||||
if (driver.gfx_use_rgba)
|
||||
ret = texture_image_load_argb_shift(path, out_img, 24, 0, 8, 16);
|
||||
ret = rpng_image_load_argb_shift(path, out_img, 24, 0, 8, 16);
|
||||
else
|
||||
ret = texture_image_load_argb_shift(path, out_img, 24, 16, 8, 0);
|
||||
ret = rpng_image_load_argb_shift(path, out_img, 24, 16, 8, 0);
|
||||
|
||||
#ifdef GEKKO
|
||||
if (ret)
|
||||
{
|
||||
if (!gx_convert_texture32(out_img))
|
||||
if (!rpng_gx_convert_texture32(out_img))
|
||||
{
|
||||
texture_image_free(out_img);
|
||||
rpng_image_free(data, out_img);
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
@ -302,9 +238,8 @@ bool texture_image_load(const char *path, struct texture_image *out_img)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void texture_image_free(struct texture_image *img)
|
||||
{
|
||||
free(img->pixels);
|
||||
memset(img, 0, sizeof(*img));
|
||||
}
|
||||
|
||||
const image_ctx_driver_t image_ctx_rpng = {
|
||||
rpng_image_load,
|
||||
rpng_image_free,
|
||||
"rpng",
|
||||
};
|
135
gfx/image/image_sdl.c
Normal file
135
gfx/image/image_sdl.c
Normal file
@ -0,0 +1,135 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../image_context.h"
|
||||
#include "../../file.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include "../../general.h"
|
||||
#include "../rpng/rpng.h"
|
||||
|
||||
#include "SDL_image.h"
|
||||
|
||||
static bool sdl_load_argb_shift(const char *path, struct texture_image *out_img,
|
||||
unsigned a_shift, unsigned r_shift, unsigned g_shift, unsigned b_shift)
|
||||
{
|
||||
int y, x;
|
||||
size_t size;
|
||||
SDL_PixelFormat *fmt;
|
||||
SDL_Surface *img = (SDL_Surface*)IMG_Load(path);
|
||||
if (!img)
|
||||
return false;
|
||||
|
||||
out_img->width = img->w;
|
||||
out_img->height = img->h;
|
||||
|
||||
size = out_img->width * out_img->height * sizeof(uint32_t);
|
||||
out_img->pixels = (uint32_t*)malloc(size);
|
||||
|
||||
if (!out_img->pixels)
|
||||
{
|
||||
SDL_FreeSurface(img);
|
||||
return false;
|
||||
}
|
||||
|
||||
fmt = (SDL_PixelFormat*)img->format;
|
||||
|
||||
RARCH_LOG("SDL_image: %dx%d @ %d bpp\n", img->w, img->h, img->format->BitsPerPixel);
|
||||
|
||||
if (img->format->BitsPerPixel == 32)
|
||||
{
|
||||
for (y = 0; y < img->h; y++)
|
||||
{
|
||||
uint32_t *dst = (uint32_t*)(out_img->pixels + y * img->w);
|
||||
const uint32_t *src = (const uint32_t*)(img->pixels + y * img->pitch / sizeof(uint32_t));
|
||||
|
||||
for (x = 0; x < img->w; x++)
|
||||
{
|
||||
uint32_t r = (src[x] & fmt->Rmask) >> fmt->Rshift;
|
||||
uint32_t g = (src[x] & fmt->Gmask) >> fmt->Gshift;
|
||||
uint32_t b = (src[x] & fmt->Bmask) >> fmt->Bshift;
|
||||
uint32_t a = (src[x] & fmt->Amask) >> fmt->Ashift;
|
||||
dst[x] = (a << a_shift) | (r << r_shift) | (g << g_shift) | (b << b_shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (img->format->BitsPerPixel == 24)
|
||||
{
|
||||
for (y = 0; y < img->h; y++)
|
||||
{
|
||||
uint32_t *dst = (uint32_t*)(out_img->pixels + y * img->w);
|
||||
const uint8_t *src = (const uint8_t*)(img->pixels + y * img->pitch);
|
||||
|
||||
for (x = 0; x < img->w; x++)
|
||||
{
|
||||
// Correct?
|
||||
uint32_t color,r, g, b;
|
||||
color = 0;
|
||||
color |= src[3 * x + 0] << 0;
|
||||
color |= src[3 * x + 1] << 8;
|
||||
color |= src[3 * x + 2] << 16;
|
||||
r = (color & fmt->Rmask) >> fmt->Rshift;
|
||||
g = (color & fmt->Gmask) >> fmt->Gshift;
|
||||
b = (color & fmt->Bmask) >> fmt->Bshift;
|
||||
dst[x] = (0xff << a_shift) | (r << r_shift) | (g << g_shift) | (b << b_shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RARCH_ERR("8-bit and 16-bit image support are not implemented.\n");
|
||||
SDL_FreeSurface(img);
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_FreeSurface(img);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool sdl_image_load(void *data, const char *path, void *image_data)
|
||||
{
|
||||
bool ret;
|
||||
(void)data;
|
||||
struct texture_image *out_img = (struct texture_image*)image_data;
|
||||
|
||||
// This interface "leak" is very ugly. FIXME: Fix this properly ...
|
||||
|
||||
if (driver.gfx_use_rgba)
|
||||
ret = sdl_load_argb_shift(path, out_img, 24, 0, 8, 16);
|
||||
else
|
||||
ret = sdl_load_argb_shift(path, out_img, 24, 16, 8, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sdl_image_free(void *data, void *image_data)
|
||||
{
|
||||
struct texture_image *img = (struct texture_image*)image_data;
|
||||
free(img->pixels);
|
||||
memset(img, 0, sizeof(*img));
|
||||
}
|
||||
|
||||
const image_ctx_driver_t image_ctx_sdl = {
|
||||
sdl_image_load,
|
||||
sdl_image_free,
|
||||
"sdl",
|
||||
};
|
@ -14,12 +14,13 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "image.h"
|
||||
#include "../image_context.h"
|
||||
#include "../../xdk/xdk_d3d.h"
|
||||
|
||||
bool texture_image_load(const char *path, struct texture_image *out_img)
|
||||
static bool xdk_image_load(void *data, const char *path, void *image_data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)driver.video_data;
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
struct texture_image *out_img = (struct texture_image*)image_data;
|
||||
|
||||
D3DXIMAGE_INFO m_imageInfo;
|
||||
|
||||
@ -54,11 +55,22 @@ bool texture_image_load(const char *path, struct texture_image *out_img)
|
||||
return true;
|
||||
}
|
||||
|
||||
void texture_image_free(struct texture_image *img)
|
||||
static void xdk_image_free(void *data, void *image_data)
|
||||
{
|
||||
struct texture_image *img = (struct texture_image*)image_data;
|
||||
|
||||
if (!img)
|
||||
return;
|
||||
|
||||
if (img->vertex_buf)
|
||||
img->vertex_buf->Release();
|
||||
if (img->pixels)
|
||||
img->pixels->Release();
|
||||
memset(img, 0, sizeof(*img));
|
||||
}
|
||||
|
||||
const image_ctx_driver_t image_ctx_xdk = {
|
||||
xdk_image_load,
|
||||
xdk_image_free,
|
||||
"xdk",
|
||||
};
|
||||
|
92
gfx/image_context.c
Normal file
92
gfx/image_context.c
Normal file
@ -0,0 +1,92 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2014 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../general.h"
|
||||
#include "gfx_context.h"
|
||||
#include "../general.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../config.h"
|
||||
#endif
|
||||
|
||||
static const image_ctx_driver_t *image_ctx_drivers[] = {
|
||||
#if defined(__CELLOS_LV2__)
|
||||
&image_ctx_ps3,
|
||||
#endif
|
||||
#if defined(_XBOX1)
|
||||
&image_ctx_xdk1,
|
||||
#endif
|
||||
&image_ctx_rpng,
|
||||
#if defined(HAVE_SDL_IMAGE)
|
||||
&image_ctx_sdl,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
static int find_image_driver_index(const char *driver)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; image_ctx_drivers[i]; i++)
|
||||
if (strcasecmp(driver, image_ctx_drivers[i]->ident) == 0)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void find_image_driver(void)
|
||||
{
|
||||
int i;
|
||||
if (driver.image)
|
||||
return;
|
||||
|
||||
i = find_image_driver_index(g_settings.image.driver);
|
||||
if (i >= 0)
|
||||
driver.image = image_ctx_drivers[i];
|
||||
else
|
||||
{
|
||||
unsigned d;
|
||||
RARCH_ERR("Couldn't find any image driver named \"%s\"\n", g_settings.image.driver);
|
||||
RARCH_LOG_OUTPUT("Available image drivers are:\n");
|
||||
for (d = 0; image_ctx_drivers[d]; d++)
|
||||
RARCH_LOG_OUTPUT("\t%s\n", image_ctx_drivers[d]->ident);
|
||||
|
||||
rarch_fail(1, "find_image_driver()");
|
||||
}
|
||||
}
|
||||
|
||||
void find_prev_image_driver(void)
|
||||
{
|
||||
int i = find_image_driver_index(g_settings.image.driver);
|
||||
if (i > 0)
|
||||
{
|
||||
strlcpy(g_settings.image.driver, image_ctx_drivers[i - 1]->ident, sizeof(g_settings.image.driver));
|
||||
driver.image = (image_ctx_driver_t*)image_ctx_drivers[i - 1];
|
||||
}
|
||||
else
|
||||
RARCH_WARN("Couldn't find any previous image driver (current one: \"%s\").\n", g_settings.image.driver);
|
||||
}
|
||||
|
||||
void find_next_image_driver(void)
|
||||
{
|
||||
int i = find_image_driver_index(g_settings.image.driver);
|
||||
if (i >= 0 && image_ctx_drivers[i + 1])
|
||||
{
|
||||
strlcpy(g_settings.image.driver, image_ctx_drivers[i + 1]->ident, sizeof(g_settings.image.driver));
|
||||
driver.image = (image_ctx_driver_t*)image_ctx_drivers[i + 1];
|
||||
}
|
||||
else
|
||||
RARCH_WARN("Couldn't find any next image driver (current one: \"%s\").\n", g_settings.image.driver);
|
||||
}
|
@ -13,15 +13,15 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __RARCH_IMAGE_H
|
||||
#define __RARCH_IMAGE_H
|
||||
#ifndef __RARCH_IMAGE_CONTEXT_H
|
||||
#define __RARCH_IMAGE_CONTEXT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../../boolean.h"
|
||||
#include "../boolean.h"
|
||||
|
||||
#ifdef _XBOX1
|
||||
#include <xtl.h>
|
||||
#include "../../xdk/xdk_defines.h"
|
||||
#include "../xdk/xdk_defines.h"
|
||||
#endif
|
||||
|
||||
struct texture_image
|
||||
@ -38,8 +38,22 @@ struct texture_image
|
||||
#endif
|
||||
};
|
||||
|
||||
bool texture_image_load(const char *path, struct texture_image* img);
|
||||
void texture_image_free(struct texture_image *img);
|
||||
typedef struct image_ctx_driver
|
||||
{
|
||||
bool (*load)(void*, const char*, void *);
|
||||
void (*free)(void *, void *);
|
||||
// Human readable string.
|
||||
const char *ident;
|
||||
} image_ctx_driver_t;
|
||||
|
||||
extern const image_ctx_driver_t image_ctx_xdk1;
|
||||
extern const image_ctx_driver_t image_ctx_ps3;
|
||||
extern const image_ctx_driver_t image_ctx_sdl;
|
||||
extern const image_ctx_driver_t image_ctx_rpng;
|
||||
|
||||
const void *image_ctx_find_driver(const char *ident);
|
||||
void find_prev_image_driver(void);
|
||||
void find_next_image_driver(void);
|
||||
const void *image_ctx_init_first(void);
|
||||
|
||||
#endif
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include <string.h>
|
||||
#include "../compat/strl.h"
|
||||
#include "../conf/config_file.h"
|
||||
#include "image/image.h"
|
||||
#include "../dynamic.h"
|
||||
#include "../compat/posix_string.h"
|
||||
#include "../file.h"
|
||||
|
@ -63,10 +63,17 @@ bool gl_load_luts(const struct gfx_shader *generic_shader, GLuint *lut_textures)
|
||||
glGenTextures(num_luts, lut_textures);
|
||||
for (i = 0; i < num_luts; i++)
|
||||
{
|
||||
bool ret = false;
|
||||
struct texture_image img = {0};
|
||||
RARCH_LOG("Loading texture image from: \"%s\" ...\n",
|
||||
generic_shader->lut[i].path);
|
||||
if (!texture_image_load(generic_shader->lut[i].path, &img))
|
||||
|
||||
ret = driver.image && driver.image->load;
|
||||
|
||||
if (ret)
|
||||
ret = driver.image->load(driver.video_data, generic_shader->lut[i].path, &img);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
RARCH_ERR("Failed to load texture image from: \"%s\"\n", generic_shader->lut[i].path);
|
||||
return false;
|
||||
@ -76,7 +83,9 @@ bool gl_load_luts(const struct gfx_shader *generic_shader, GLuint *lut_textures)
|
||||
gl_wrap_type_to_enum(generic_shader->lut[i].wrap),
|
||||
generic_shader->lut[i].filter != RARCH_FILTER_NEAREST,
|
||||
generic_shader->lut[i].mipmap);
|
||||
texture_image_free(&img);
|
||||
|
||||
if (driver.image && driver.image->free)
|
||||
driver.image->free(driver.video_data, &img);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gl_common.h"
|
||||
#include "image/image.h"
|
||||
|
||||
#ifdef HAVE_OPENGLES2
|
||||
#define BORDER_FUNC GL_CLAMP_TO_EDGE
|
||||
|
@ -172,13 +172,13 @@ VIDEO IMAGE
|
||||
#include "../gfx/image/image_ps3.c"
|
||||
#elif defined(_XBOX1)
|
||||
#include "../gfx/image/image_xdk1.c"
|
||||
#else
|
||||
#include "../gfx/image/image.c"
|
||||
#elif defined(HAVE_SDL_IMAGE)
|
||||
#include "../gfx/image/image_sdl.c"
|
||||
#endif
|
||||
|
||||
#if defined(WANT_RPNG) || defined(RARCH_MOBILE)
|
||||
#include "../gfx/image_context.c"
|
||||
#include "../gfx/image/image_rpng.c"
|
||||
#include "../gfx/rpng/rpng.c"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
VIDEO DRIVER
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "../general.h"
|
||||
#include "../driver.h"
|
||||
#include "../libretro.h"
|
||||
#include "../gfx/image/image.h"
|
||||
#include "../gfx/image_context.h"
|
||||
#include "../conf/config_file.h"
|
||||
#include "../compat/posix_string.h"
|
||||
#include "input_common.h"
|
||||
@ -162,11 +162,16 @@ void input_overlay_set_scale_factor(input_overlay_t *ol, float scale)
|
||||
static void input_overlay_free_overlay(struct overlay *overlay)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < overlay->size; i++)
|
||||
texture_image_free(&overlay->descs[i].image);
|
||||
|
||||
if (driver.image && driver.image->free)
|
||||
for (i = 0; i < overlay->size; i++)
|
||||
driver.image->free(driver.video_data, &overlay->descs[i].image);
|
||||
|
||||
free(overlay->load_images);
|
||||
free(overlay->descs);
|
||||
texture_image_free(&overlay->image);
|
||||
|
||||
if (driver.image && driver.image->free)
|
||||
driver.image->free(driver.video_data, &overlay->image);
|
||||
}
|
||||
|
||||
static void input_overlay_free_overlays(input_overlay_t *ol)
|
||||
@ -197,8 +202,9 @@ static bool input_overlay_load_desc(input_overlay_t *ol, config_file_t *conf, st
|
||||
fill_pathname_resolve_relative(path, ol->overlay_path, image_path, sizeof(path));
|
||||
|
||||
struct texture_image img = {0};
|
||||
if (texture_image_load(path, &img))
|
||||
desc->image = img;
|
||||
if (driver.image && driver.image->load)
|
||||
if (driver.image->load(driver.video_data, path, &img))
|
||||
desc->image = img;
|
||||
}
|
||||
|
||||
char overlay_desc_normalized_key[64];
|
||||
@ -345,13 +351,22 @@ static bool input_overlay_load_overlay(input_overlay_t *ol, config_file_t *conf,
|
||||
snprintf(overlay_path_key, sizeof(overlay_path_key), "overlay%u_overlay", index);
|
||||
if (config_get_path(conf, overlay_path_key, overlay_path, sizeof(overlay_path)))
|
||||
{
|
||||
struct texture_image img = {0};
|
||||
bool ret = false;
|
||||
|
||||
fill_pathname_resolve_relative(overlay_resolved_path, config_path,
|
||||
overlay_path, sizeof(overlay_resolved_path));
|
||||
|
||||
struct texture_image img = {0};
|
||||
if (texture_image_load(overlay_resolved_path, &img))
|
||||
overlay->image = img;
|
||||
else
|
||||
ret = driver.image && driver.image->load;
|
||||
|
||||
if (ret)
|
||||
{
|
||||
ret = driver.image->load(driver.video_data, overlay_resolved_path, &img);
|
||||
if(ret)
|
||||
overlay->image = img;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
RARCH_ERR("[Overlay]: Failed to load image: %s.\n", overlay_resolved_path);
|
||||
return false;
|
||||
|
@ -77,6 +77,9 @@
|
||||
# Load up a specific config file based on the core being used.
|
||||
# core_specific_config = false
|
||||
|
||||
# Image driver to use. "rpng", "sdl"
|
||||
# image_driver = "rpng"
|
||||
|
||||
#### Video
|
||||
|
||||
# Video driver to use. "gl", "xvideo", "sdl"
|
||||
|
21
settings.c
21
settings.c
@ -202,11 +202,28 @@ const char *config_get_default_location(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *config_get_default_image(void)
|
||||
{
|
||||
switch (IMAGE_DEFAULT_DRIVER)
|
||||
{
|
||||
case IMAGE_SDL:
|
||||
return "sdl";
|
||||
case IMAGE_XDK:
|
||||
return "xdk";
|
||||
case IMAGE_PS3:
|
||||
return "ps3";
|
||||
case IMAGE_RPNG:
|
||||
return "rpng";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void config_set_defaults(void)
|
||||
{
|
||||
unsigned i, j;
|
||||
const char *def_video = config_get_default_video();
|
||||
const char *def_image = config_get_default_image();
|
||||
const char *def_audio = config_get_default_audio();
|
||||
const char *def_input = config_get_default_input();
|
||||
#ifdef HAVE_CAMERA
|
||||
@ -235,6 +252,8 @@ void config_set_defaults(void)
|
||||
strlcpy(g_settings.audio.driver, def_audio, sizeof(g_settings.audio.driver));
|
||||
if (def_input)
|
||||
strlcpy(g_settings.input.driver, def_input, sizeof(g_settings.input.driver));
|
||||
if (def_image)
|
||||
strlcpy(g_settings.image.driver, def_image, sizeof(g_settings.image.driver));
|
||||
|
||||
g_settings.load_dummy_on_core_shutdown = load_dummy_on_core_shutdown;
|
||||
|
||||
@ -947,6 +966,7 @@ bool config_load_file(const char *path, bool set_defaults)
|
||||
CONFIG_GET_BOOL(location.allow, "location_allow");
|
||||
#endif
|
||||
|
||||
CONFIG_GET_STRING(image.driver, "image_driver");
|
||||
CONFIG_GET_STRING(video.driver, "video_driver");
|
||||
CONFIG_GET_STRING(video.gl_context, "video_gl_context");
|
||||
CONFIG_GET_STRING(audio.driver, "audio_driver");
|
||||
@ -1331,6 +1351,7 @@ bool config_save_file(const char *path)
|
||||
config_set_int(conf, "video_fullscreen_x", g_settings.video.fullscreen_x);
|
||||
config_set_int(conf, "video_fullscreen_y", g_settings.video.fullscreen_y);
|
||||
config_set_string(conf,"video_driver", g_settings.video.driver);
|
||||
config_set_string(conf,"image_driver", g_settings.image.driver);
|
||||
config_set_bool(conf, "video_vsync", g_settings.video.vsync);
|
||||
config_set_bool(conf, "video_hard_sync", g_settings.video.hard_sync);
|
||||
config_set_int(conf, "video_hard_sync_frames", g_settings.video.hard_sync_frames);
|
||||
|
@ -23,7 +23,7 @@
|
||||
#endif
|
||||
#include "../gfx/shader_common.h"
|
||||
#include "../gfx/shader_parse.h"
|
||||
#include "../gfx/image/image.h"
|
||||
#include "../gfx/image_context.h"
|
||||
#include "../gfx/fonts/d3d_font.h"
|
||||
|
||||
#include "../gfx/gfx_context.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user