mirror of
https://github.com/libretro/RetroArch
synced 2025-01-18 13:23:40 +00:00
Merge branch 'master' of http://github.com/Themaister/RetroArch
Conflicts: qb/config.libs.sh
This commit is contained in:
commit
7986e01cbf
2
Makefile
2
Makefile
@ -257,6 +257,8 @@ clean:
|
||||
rm -f audio/*.o
|
||||
rm -f conf/*.o
|
||||
rm -f gfx/*.o
|
||||
rm -f gfx/fonts/*.o
|
||||
rm -f gfx/context/*.o
|
||||
rm -f gfx/py_state/*.o
|
||||
rm -f record/*.o
|
||||
rm -f input/*.o
|
||||
|
@ -94,7 +94,7 @@ ifeq ($(HAVE_DYLIB), 1)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_NETPLAY), 1)
|
||||
DEFINES += -DHAVE_NETPLAY
|
||||
DEFINES += -DHAVE_NETPLAY -DHAVE_NETWORK_CMD
|
||||
OBJ += netplay.o network_cmd.o
|
||||
LIBS += -lws2_32
|
||||
endif
|
||||
@ -184,6 +184,8 @@ clean:
|
||||
rm -f audio/xaudio-c/*.o
|
||||
rm -f conf/*.o
|
||||
rm -f gfx/*.o
|
||||
rm -f gfx/context/*.o
|
||||
rm -f gfx/fonts/*.o
|
||||
rm -f gfx/py_state/*.o
|
||||
rm -f record/*.o
|
||||
rm -f input/*.o
|
||||
|
@ -345,7 +345,7 @@ static const struct snes_keybind snes_keybinds_1[] = {
|
||||
{ true, RARCH_CHEAT_INDEX_PLUS, SK_y, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_CHEAT_INDEX_MINUS, SK_t, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_CHEAT_TOGGLE, SK_u, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_SCREENSHOT, SK_PRINT, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_SCREENSHOT, SK_F8, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_DSP_CONFIG, SK_c, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_MUTE, SK_F9, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_NETPLAY_FLIP, SK_i, NO_BTN, AXIS_NONE },
|
||||
|
6
configure
vendored
6
configure
vendored
@ -1,14 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo ""
|
||||
|
||||
PACKAGE_NAME=retroarch
|
||||
PACKAGE_VERSION=0.9.6
|
||||
|
||||
. qb/qb.params.sh
|
||||
|
||||
. qb/qb.comp.sh
|
||||
. qb/config.libs.sh
|
||||
|
||||
|
||||
|
||||
. qb/qb.libs.sh
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define FILEBROWSER_H_
|
||||
|
||||
#define MAXJOLIET 255
|
||||
#define MAX_DIR_STACK 25
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
@ -28,7 +29,7 @@
|
||||
#include <sys/types.h>
|
||||
#define FS_MAX_PATH 256
|
||||
#define FS_MAX_FS_PATH_LENGTH 255
|
||||
#define MAX_FILE_LIMIT 30000
|
||||
#define MAX_FILE_LIMIT 8192
|
||||
#elif defined(_XBOX)
|
||||
#define FS_MAX_PATH MAX_PATH
|
||||
#define FS_MAX_FS_PATH_LENGTH 2048
|
||||
@ -54,9 +55,9 @@ typedef struct
|
||||
uint32_t file_count; /* amount of files in current dir*/
|
||||
uint32_t currently_selected; /* currently select browser entry*/
|
||||
uint32_t directory_stack_size;
|
||||
char dir[128][FS_MAX_FS_PATH_LENGTH]; /* info of the current directory*/
|
||||
char dir[MAX_DIR_STACK][FS_MAX_FS_PATH_LENGTH]; /* info of the current directory*/
|
||||
DirectoryEntry cur[MAX_FILE_LIMIT]; /* current file listing*/
|
||||
char extensions[512]; /* allowed extensions*/
|
||||
char extensions[FS_MAX_PATH]; /* allowed extensions*/
|
||||
} filebrowser_t;
|
||||
|
||||
void filebrowser_new(filebrowser_t * filebrowser, const char * start_dir, const char * extensions);
|
||||
|
@ -87,7 +87,7 @@ const char *rarch_manage_libretro_set_first_file(const char *libretro_path, cons
|
||||
//We need to set libretro to the first entry in the cores
|
||||
//directory so that it will be saved to the config file
|
||||
|
||||
char ** dir_list = dir_list_new(libretro_path, exe_ext);
|
||||
char ** dir_list = dir_list_new(libretro_path, exe_ext, false);
|
||||
|
||||
const char * retstr = NULL;
|
||||
const char * first_exe;
|
||||
|
@ -87,9 +87,9 @@ static void find_and_set_first_file(void)
|
||||
// we can find in the RetroArch cores directory
|
||||
|
||||
#if defined(_XBOX)
|
||||
char ** dir_list = dir_list_new("game:\\", ".xex");
|
||||
char ** dir_list = dir_list_new("game:\\", ".xex", false);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
char ** dir_list = dir_list_new(LIBRETRO_DIR_PATH, ".SELF");
|
||||
char ** dir_list = dir_list_new(LIBRETRO_DIR_PATH, ".SELF", false);
|
||||
#endif
|
||||
|
||||
if (!dir_list)
|
||||
|
2
driver.c
2
driver.c
@ -477,7 +477,7 @@ static void init_shader_dir(void)
|
||||
if (!*g_settings.video.shader_dir)
|
||||
return;
|
||||
|
||||
g_extern.shader_dir.elems = dir_list_new(g_settings.video.shader_dir, ".shader");
|
||||
g_extern.shader_dir.elems = dir_list_new(g_settings.video.shader_dir, ".shader", false);
|
||||
g_extern.shader_dir.size = 0;
|
||||
g_extern.shader_dir.ptr = 0;
|
||||
if (g_extern.shader_dir.elems)
|
||||
|
6
driver.h
6
driver.h
@ -166,6 +166,10 @@ typedef struct video_driver
|
||||
#endif
|
||||
|
||||
void (*set_rotation)(void *data, unsigned rotation);
|
||||
void (*viewport_size)(void *data, unsigned *width, unsigned *height);
|
||||
|
||||
// Reads out in BGR byte order (24bpp).
|
||||
bool (*read_viewport)(void *data, uint8_t *buffer);
|
||||
} video_driver_t;
|
||||
|
||||
typedef struct driver
|
||||
@ -252,6 +256,8 @@ extern const input_driver_t input_linuxraw;
|
||||
#define video_xml_shader_func(path) driver.video->xml_shader(driver.video_data, path)
|
||||
#define video_set_rotation_func(rotate) driver.video->set_rotation(driver.video_data, rotate)
|
||||
#define video_set_aspect_ratio_func(aspect_idx) driver.video->set_aspect_ratio(driver.video_data, aspect_idx)
|
||||
#define video_viewport_size_func(width, height) driver.video->viewport_size(driver.video_data, width, height)
|
||||
#define video_read_viewport_func(buffer) driver.video->read_viewport(driver.video_data, buffer)
|
||||
#define video_free_func() driver.video->free(driver.video_data)
|
||||
|
||||
#define input_init_func() driver.input->init()
|
||||
|
@ -317,11 +317,18 @@ static bool environment_cb(unsigned cmd, void *data)
|
||||
}
|
||||
|
||||
case RETRO_ENVIRONMENT_SHUTDOWN:
|
||||
RARCH_LOG("Environ SHUTDOWN.\n");
|
||||
g_extern.system.shutdown = true;
|
||||
break;
|
||||
|
||||
case RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL:
|
||||
g_extern.system.performance_level = *(const unsigned*)data;
|
||||
RARCH_LOG("Environ PERFORMANCE_LEVEL: %u.\n", g_extern.system.performance_level);
|
||||
break;
|
||||
|
||||
case RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY:
|
||||
*(const char **)data = *g_settings.system_directory ? g_settings.system_directory : NULL;
|
||||
RARCH_LOG("Environ SYSTEM_DIRECTORY: \"%s\".\n", g_settings.system_directory);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
2
file.h
2
file.h
@ -43,7 +43,7 @@ bool init_rom_file(enum rarch_game_type type);
|
||||
// Returns a NULL-terminated list of files in a directory with full paths.
|
||||
// If ext is NULL, any file will be picked.
|
||||
// If non-NULL, only files with extension ext are added.
|
||||
char **dir_list_new(const char *dir, const char *ext);
|
||||
char **dir_list_new(const char *dir, const char *ext, bool include_dirs);
|
||||
void dir_list_free(char **dir_list);
|
||||
|
||||
bool path_is_directory(const char *path);
|
||||
|
34
file_path.c
34
file_path.c
@ -43,7 +43,7 @@
|
||||
#endif
|
||||
|
||||
// Yep, this is C alright ;)
|
||||
char **dir_list_new(const char *dir, const char *ext)
|
||||
char **dir_list_new(const char *dir, const char *ext, bool include_dirs)
|
||||
{
|
||||
size_t cur_ptr = 0;
|
||||
size_t cur_size = 32;
|
||||
@ -94,13 +94,29 @@ char **dir_list_new(const char *dir, const char *ext)
|
||||
{
|
||||
// Not a perfect search of course, but hopefully good enough in practice.
|
||||
#ifdef _WIN32
|
||||
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
continue;
|
||||
if (ext && !strstr(ffd.cFileName, ext))
|
||||
continue;
|
||||
if (include_dirs)
|
||||
{
|
||||
if (ext && !strstr(ffd.cFileName, ext) && !path_is_directory(ffd.cFileName))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
continue;
|
||||
if (ext && !strstr(ffd.cFileName, ext))
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
if (ext && !strstr(entry->d_name, ext))
|
||||
continue;
|
||||
if (include_dirs)
|
||||
{
|
||||
if (ext && !strstr(entry->d_name, ext) && !path_is_directory(entry->d_name))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ext && !strstr(entry->d_name, ext))
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
dir_list[cur_ptr] = (char*)malloc(PATH_MAX);
|
||||
@ -175,10 +191,6 @@ bool path_is_directory(const char *path)
|
||||
return false;
|
||||
|
||||
return buf.st_mode & CELL_FS_S_IFDIR;
|
||||
#elif defined(XENON)
|
||||
// Dummy
|
||||
(void)path;
|
||||
return false;
|
||||
#else
|
||||
struct stat buf;
|
||||
if (stat(path, &buf) < 0)
|
||||
|
@ -169,6 +169,7 @@ struct settings
|
||||
char cheat_settings_path[PATH_MAX];
|
||||
|
||||
char screenshot_directory[PATH_MAX];
|
||||
char system_directory[PATH_MAX];
|
||||
|
||||
bool rewind_enable;
|
||||
size_t rewind_buffer_size;
|
||||
|
@ -24,7 +24,7 @@ extern "C" {
|
||||
#define RARCH_API_CALLTYPE
|
||||
#endif
|
||||
|
||||
#define RARCH_GRAPHICS_API_VERSION 2
|
||||
#define RARCH_GRAPHICS_API_VERSION 3
|
||||
|
||||
// Since we don't want to rely on C++ or C99 for a proper boolean type,
|
||||
// make sure return semantics are perfectly clear ... ;)
|
||||
@ -204,7 +204,7 @@ typedef struct rarch_input_driver
|
||||
// The range of this is [0, 1],
|
||||
// where 0 means any displacement will register,
|
||||
// and 1 means the axis has to be pressed all the way to register.
|
||||
void *(*init)(const int joypad_index[5], float axis_threshold);
|
||||
void *(*init)(const int joypad_index[8], float axis_threshold);
|
||||
|
||||
// Polls input. Called once every frame.
|
||||
void (*poll)(void *data);
|
||||
@ -264,6 +264,16 @@ typedef struct rarch_video_driver
|
||||
// Needs to be defined to RARCH_GRAPHICS_API_VERSION.
|
||||
// This is used to detect API/ABI mismatches.
|
||||
int api_version;
|
||||
|
||||
// The final image should be rotated counter-clockwise by rot * 90 degrees.
|
||||
void (*set_rotation)(void *data, unsigned rot);
|
||||
|
||||
// Gets the current width/height of the viewport.
|
||||
void (*viewport_size)(void *data, unsigned *width, unsigned *height);
|
||||
|
||||
// Reads the content of the viewport into memory.
|
||||
// Tightly packed BGR888. Pitch is width * 3.
|
||||
int (*read_viewport)(void *data, unsigned char *buffer);
|
||||
} rarch_video_driver_t;
|
||||
|
||||
// Called by RetroArch on startup to get a driver handle.
|
||||
|
@ -183,9 +183,8 @@ static bool video_ext_frame(void *data, const void *frame, unsigned width, unsig
|
||||
|
||||
static void *setup_input(ext_t *ext, const rarch_input_driver_t *driver)
|
||||
{
|
||||
// TODO: Change external API to allow more players. To be done in next major ABI break.
|
||||
int joypad_index[5];
|
||||
for (unsigned i = 0; i < 5; i++)
|
||||
int joypad_index[8];
|
||||
for (unsigned i = 0; i < 8; i++)
|
||||
joypad_index[i] = g_settings.input.joypad_map[i] < 0 ? -1 : g_settings.input.joypad_map[i];
|
||||
|
||||
void *handle = driver->init(joypad_index, g_settings.input.axis_threshold);
|
||||
@ -213,9 +212,11 @@ static bool setup_video(ext_t *ext, const video_info_t *video, const input_drive
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *cg_shader = NULL;
|
||||
const char *cg_shader = NULL;
|
||||
const char *xml_shader = NULL;
|
||||
|
||||
enum rarch_shader_type type = g_settings.video.shader_type;
|
||||
|
||||
if ((type == RARCH_SHADER_CG || type == RARCH_SHADER_AUTO) && *g_settings.video.cg_shader_path)
|
||||
cg_shader = g_settings.video.cg_shader_path;
|
||||
else if ((type == RARCH_SHADER_BSNES || type == RARCH_SHADER_AUTO) && *g_settings.video.bsnes_shader_path)
|
||||
@ -247,25 +248,25 @@ static bool setup_video(ext_t *ext, const video_info_t *video, const input_drive
|
||||
gfx_window_title(title_buf, sizeof(title_buf));
|
||||
|
||||
rarch_video_info_t info = {0};
|
||||
info.width = video->width;
|
||||
info.height = video->height;
|
||||
info.fullscreen = video->fullscreen;
|
||||
info.vsync = video->vsync;
|
||||
info.force_aspect = video->force_aspect;
|
||||
info.aspect_ratio = g_settings.video.aspect_ratio;
|
||||
info.smooth = video->smooth;
|
||||
info.input_scale = video->input_scale;
|
||||
info.color_format = video->rgb32 ? RARCH_COLOR_FORMAT_ARGB8888 : RARCH_COLOR_FORMAT_XRGB1555;
|
||||
info.xml_shader = xml_shader;
|
||||
info.cg_shader = cg_shader;
|
||||
info.ttf_font = font;
|
||||
info.ttf_font_size = g_settings.video.font_size;
|
||||
info.ttf_font_color = (font_color_r << 16) | (font_color_g << 8) | (font_color_b << 0);
|
||||
info.title_hint = title_buf;
|
||||
info.width = video->width;
|
||||
info.height = video->height;
|
||||
info.fullscreen = video->fullscreen;
|
||||
info.vsync = video->vsync;
|
||||
info.force_aspect = video->force_aspect;
|
||||
info.aspect_ratio = g_settings.video.aspect_ratio;
|
||||
info.smooth = video->smooth;
|
||||
info.input_scale = video->input_scale;
|
||||
info.color_format = video->rgb32 ? RARCH_COLOR_FORMAT_ARGB8888 : RARCH_COLOR_FORMAT_XRGB1555;
|
||||
info.xml_shader = xml_shader;
|
||||
info.cg_shader = cg_shader;
|
||||
info.ttf_font = font;
|
||||
info.ttf_font_size = g_settings.video.font_size;
|
||||
info.ttf_font_color = (font_color_r << 16) | (font_color_g << 8) | (font_color_b << 0);
|
||||
info.title_hint = title_buf;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
info.python_state_new = py_state_new;
|
||||
info.python_state_get = py_state_get;
|
||||
info.python_state_new = py_state_new;
|
||||
info.python_state_get = py_state_get;
|
||||
info.python_state_free = py_state_free;
|
||||
#endif
|
||||
|
||||
@ -335,6 +336,24 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void video_set_rotation(void *data, unsigned rot)
|
||||
{
|
||||
ext_t *ext = (ext_t*)data;
|
||||
ext->driver->set_rotation(ext->handle, rot);
|
||||
}
|
||||
|
||||
static void video_viewport_size(void *data, unsigned *width, unsigned *height)
|
||||
{
|
||||
ext_t *ext = (ext_t*)data;
|
||||
ext->driver->viewport_size(ext->handle, width, height);
|
||||
}
|
||||
|
||||
static bool video_read_viewport(void *data, uint8_t *buffer)
|
||||
{
|
||||
ext_t *ext = (ext_t*)data;
|
||||
return ext->driver->read_viewport(ext->handle, buffer);
|
||||
}
|
||||
|
||||
const video_driver_t video_ext = {
|
||||
video_ext_init,
|
||||
video_ext_frame,
|
||||
@ -343,6 +362,10 @@ const video_driver_t video_ext = {
|
||||
video_ext_focus,
|
||||
NULL,
|
||||
video_ext_free,
|
||||
"ext"
|
||||
"ext",
|
||||
|
||||
video_set_rotation,
|
||||
video_viewport_size,
|
||||
video_read_viewport,
|
||||
};
|
||||
|
||||
|
80
gfx/gl.c
80
gfx/gl.c
@ -46,6 +46,9 @@
|
||||
#include "shader_glsl.h"
|
||||
#endif
|
||||
|
||||
extern const GLfloat vertexes_flipped[];
|
||||
extern const GLfloat white_color[];
|
||||
|
||||
// Used for the last pass when rendering to the back buffer.
|
||||
const GLfloat vertexes_flipped[] = {
|
||||
0, 0,
|
||||
@ -440,20 +443,8 @@ void gl_set_projection(gl_t *gl, struct gl_ortho *ortho, bool allow_rotate)
|
||||
|
||||
void gl_set_viewport(gl_t *gl, unsigned width, unsigned height, bool force_full, bool allow_rotate)
|
||||
{
|
||||
unsigned vp_x_temp, vp_y_temp, vp_width_temp, vp_height_temp;
|
||||
struct gl_ortho ortho = {0};
|
||||
|
||||
vp_x_temp = 0;
|
||||
vp_y_temp = 0;
|
||||
vp_width_temp = width;
|
||||
vp_height_temp = height;
|
||||
|
||||
ortho.left = 0.0f;
|
||||
ortho.right = 1.0f;
|
||||
ortho.bottom = 0.0f;
|
||||
ortho.top = 1.0f;
|
||||
ortho.znear = -1.0f;
|
||||
ortho.zfar = 1.0f;
|
||||
unsigned x = 0, y = 0;
|
||||
struct gl_ortho ortho = {0, 1, 0, 1, -1, 1};
|
||||
|
||||
if (gl->keep_aspect && !force_full)
|
||||
{
|
||||
@ -464,11 +455,10 @@ void gl_set_viewport(gl_t *gl, unsigned width, unsigned height, bool force_full,
|
||||
#ifdef RARCH_CONSOLE
|
||||
if (g_console.aspect_ratio_index == ASPECT_RATIO_CUSTOM)
|
||||
{
|
||||
delta = (desired_aspect / device_aspect - 1.0) / 2.0 + 0.5;
|
||||
vp_x_temp = g_console.viewports.custom_vp.x;
|
||||
vp_y_temp = g_console.viewports.custom_vp.y;
|
||||
vp_width_temp = g_console.viewports.custom_vp.width;
|
||||
vp_height_temp = g_console.viewports.custom_vp.height;
|
||||
x = g_console.viewports.custom_vp.x;
|
||||
y = g_console.viewports.custom_vp.y;
|
||||
width = g_console.viewports.custom_vp.width;
|
||||
height = g_console.viewports.custom_vp.height;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -481,31 +471,29 @@ void gl_set_viewport(gl_t *gl, unsigned width, unsigned height, bool force_full,
|
||||
else if (device_aspect > desired_aspect)
|
||||
{
|
||||
delta = (desired_aspect / device_aspect - 1.0) / 2.0 + 0.5;
|
||||
vp_x_temp = (GLint)(width * (0.5 - delta));
|
||||
vp_width_temp = (GLint)(2.0 * width * delta);
|
||||
x = (unsigned)(width * (0.5 - delta));
|
||||
width = (unsigned)(2.0 * width * delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = (device_aspect / desired_aspect - 1.0) / 2.0 + 0.5;
|
||||
vp_y_temp = (GLint)(height * (0.5 - delta));
|
||||
vp_height_temp = (GLint)(2.0 * height * delta);
|
||||
delta = (device_aspect / desired_aspect - 1.0) / 2.0 + 0.5;
|
||||
y = (unsigned)(height * (0.5 - delta));
|
||||
height = (unsigned)(2.0 * height * delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glViewport(vp_x_temp, vp_y_temp, vp_width_temp, vp_height_temp);
|
||||
glViewport(x, y, width, height);
|
||||
|
||||
gl_set_projection(gl, &ortho, allow_rotate);
|
||||
|
||||
gl->vp_width = width;
|
||||
gl->vp_width = width;
|
||||
gl->vp_height = height;
|
||||
|
||||
// Set last backbuffer viewport.
|
||||
if (!force_full)
|
||||
{
|
||||
gl->vp_out_width = width;
|
||||
gl->vp_out_width = width;
|
||||
gl->vp_out_height = height;
|
||||
}
|
||||
|
||||
@ -1227,6 +1215,36 @@ static bool gl_xml_shader(void *data, const char *path)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_RGL
|
||||
static void gl_viewport_size(void *data, unsigned *width, unsigned *height)
|
||||
{
|
||||
(void)data;
|
||||
|
||||
GLint vp[4];
|
||||
glGetIntegerv(GL_VIEWPORT, vp);
|
||||
|
||||
*width = vp[2];
|
||||
*height = vp[3];
|
||||
}
|
||||
|
||||
static bool gl_read_viewport(void *data, uint8_t *buffer)
|
||||
{
|
||||
(void)data;
|
||||
|
||||
GLint vp[4];
|
||||
glGetIntegerv(GL_VIEWPORT, vp);
|
||||
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, get_alignment(vp[2]));
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, vp[2]);
|
||||
|
||||
glReadPixels(vp[0], vp[1],
|
||||
vp[2], vp[3],
|
||||
GL_BGR, GL_UNSIGNED_BYTE, buffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RARCH_CONSOLE
|
||||
static void gl_start(void)
|
||||
{
|
||||
@ -1323,5 +1341,13 @@ const video_driver_t video_gl = {
|
||||
#endif
|
||||
|
||||
gl_set_rotation,
|
||||
|
||||
#ifndef HAVE_RGL
|
||||
gl_viewport_size,
|
||||
gl_read_viewport,
|
||||
#else
|
||||
NULL,
|
||||
NULL,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -225,7 +225,7 @@ void gl_shader_use(unsigned index);
|
||||
void gl_set_projection(gl_t *gl, struct gl_ortho *ortho, bool allow_rotate);
|
||||
void gl_set_viewport(gl_t *gl, unsigned width, unsigned height, bool force_full, bool allow_rotate);
|
||||
|
||||
void gl_init_fbo(gl_t * gl, unsigned width, unsigned height);
|
||||
void gl_init_fbo(gl_t *gl, unsigned width, unsigned height);
|
||||
void gl_deinit_fbo(gl_t *gl);
|
||||
|
||||
#endif
|
||||
|
11
libretro.h
11
libretro.h
@ -121,7 +121,7 @@ extern "C" {
|
||||
// Requests the frontend to shutdown.
|
||||
// Should only be used if game has a specific
|
||||
// way to shutdown the game from a menu item or similar.
|
||||
|
||||
//
|
||||
#define RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL 8
|
||||
// const unsigned * --
|
||||
// Gives a hint to the frontend how demanding this implementation
|
||||
@ -142,6 +142,15 @@ extern "C" {
|
||||
// as certain games an implementation can play might be
|
||||
// particularily demanding.
|
||||
// If called, it should be called in retro_load_game().
|
||||
//
|
||||
#define RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY 9
|
||||
// const char ** --
|
||||
// Returns the "system" directory of the frontend.
|
||||
// This directory can be used to store system specific ROMs such as BIOSes, configuration data, etc.
|
||||
// The returned value can be NULL.
|
||||
// If so, no such directory is defined,
|
||||
// and it's up to the implementation to find a suitable directory.
|
||||
|
||||
|
||||
struct retro_message
|
||||
{
|
||||
|
@ -1,19 +1,14 @@
|
||||
. qb/qb.libs.sh
|
||||
|
||||
check_switch_c C99 -std=gnu99
|
||||
check_critical C99 "Cannot find C99 compatible compiler."
|
||||
check_switch_c C99 -std=gnu99 "Cannot find C99 compatible compiler."
|
||||
|
||||
check_switch_c NOUNUSED -Wno-unused-result
|
||||
add_define_make NOUNUSED $HAVE_NOUNUSED
|
||||
add_define_make NOUNUSED "$HAVE_NOUNUSED"
|
||||
|
||||
# There are still broken 64-bit Linux distros out there. :)
|
||||
if [ -d /usr/lib64 ]; then
|
||||
add_library_dirs /usr/lib64
|
||||
fi
|
||||
[ -d /usr/lib64 ] && add_library_dirs /usr/lib64
|
||||
|
||||
if [ -d /opt/local/lib ]; then
|
||||
add_library_dirs /opt/local/lib
|
||||
fi
|
||||
[ -d /opt/local/lib ] && add_library_dirs /opt/local/lib
|
||||
|
||||
if [ "$OS" = 'BSD' ]; then DYLIB=-lc; else DYLIB=-ldl; fi
|
||||
|
||||
if [ -d /opt/vc/lib ]; then
|
||||
add_library_dirs /opt/vc/lib
|
||||
@ -26,45 +21,38 @@ else
|
||||
HAVE_RPI=no
|
||||
fi
|
||||
|
||||
if [ "$OS" = BSD ]; then
|
||||
DYLIB=-lc
|
||||
else
|
||||
DYLIB=-ldl
|
||||
fi
|
||||
|
||||
if [ -z "$LIBRETRO" ]; then
|
||||
LIBRETRO="-lretro"
|
||||
else
|
||||
if [ "$LIBRETRO" ]; then
|
||||
echo "Explicit libsnes used, disabling dynamic libsnes loading ..."
|
||||
HAVE_DYNAMIC=no
|
||||
HAVE_DYNAMIC='no'
|
||||
else LIBRETRO="-lretro"
|
||||
fi
|
||||
|
||||
if [ "$HAVE_DYNAMIC" != yes ]; then
|
||||
check_lib_cxx RETRO $LIBRETRO retro_init $DYLIB
|
||||
check_critical RETRO "Cannot find libretro."
|
||||
add_define_make libretro $LIBRETRO
|
||||
fi
|
||||
[ "$HAVE_DYNAMIC" = 'yes' ] || {
|
||||
check_lib_cxx RETRO "$LIBRETRO" retro_init "$DYLIB" "Cannot find libretro."
|
||||
add_define_make libretro "$LIBRETRO"
|
||||
}
|
||||
|
||||
check_lib THREADS -lpthread pthread_create
|
||||
check_lib DYLIB $DYLIB dlopen
|
||||
check_lib DYLIB "$DYLIB" dlopen
|
||||
|
||||
check_lib NETPLAY -lc socket
|
||||
if [ "$HAVE_NETPLAY" = yes ]; then
|
||||
if [ "$HAVE_NETPLAY" = 'yes' ]; then
|
||||
HAVE_GETADDRINFO=auto
|
||||
check_lib GETADDRINFO -lc getaddrinfo
|
||||
if [ "$HAVE_GETADDRINFO" = yes ]; then
|
||||
HAVE_SOCKET_LEGACY=no
|
||||
if [ "$HAVE_GETADDRINFO" = 'yes' ]; then
|
||||
HAVE_SOCKET_LEGACY='no'
|
||||
else
|
||||
HAVE_SOCKET_LEGACY=yes
|
||||
HAVE_SOCKET_LEGACY='yes'
|
||||
fi
|
||||
HAVE_NETWORK_CMD=yes
|
||||
HAVE_NETWORK_CMD='yes'
|
||||
else
|
||||
HAVE_NETWORK_CMD=no
|
||||
HAVE_NETWORK_CMD='no'
|
||||
fi
|
||||
|
||||
check_lib GETOPT_LONG -lc getopt_long
|
||||
|
||||
if [ "$HAVE_DYLIB" = no ] && [ "$HAVE_DYNAMIC" = yes ]; then
|
||||
if [ "$HAVE_DYLIB" = 'no' ] && [ "$HAVE_DYNAMIC" = 'yes' ]; then
|
||||
echo "Dynamic loading of libsnes is enabled, but your platform does not appear to have dlopen(), use --disable-dynamic or --with-libsnes=\"-lsnes\"".
|
||||
exit 1
|
||||
fi
|
||||
@ -93,31 +81,29 @@ check_pkgconf PULSE libpulse
|
||||
|
||||
check_lib COREAUDIO "-framework AudioUnit" AudioUnitInitialize
|
||||
|
||||
check_pkgconf SDL sdl 1.2.10
|
||||
check_critical SDL "Cannot find SDL library."
|
||||
check_pkgconf SDL sdl 1.2.10 "Cannot find SDL library."
|
||||
|
||||
# On some distros, -lCg doesn't link against -lstdc++ it seems ...
|
||||
if [ "$HAVE_OPENGL" != no ]; then
|
||||
if [ "$HAVE_OPENGL" != 'no' ]; then
|
||||
check_lib_cxx CG -lCg cgCreateContext
|
||||
else
|
||||
echo "Ignoring Cg. OpenGL is not enabled."
|
||||
HAVE_CG=no
|
||||
HAVE_CG='no'
|
||||
fi
|
||||
|
||||
check_pkgconf XML libxml-2.0
|
||||
check_pkgconf SDL_IMAGE SDL_image
|
||||
|
||||
if [ "$HAVE_THREADS" != no ]; then
|
||||
if [ "$HAVE_FFMPEG" != no ]; then
|
||||
if [ "$HAVE_THREADS" != 'no' ]; then
|
||||
if [ "$HAVE_FFMPEG" != 'no' ]; then
|
||||
check_pkgconf AVCODEC libavcodec
|
||||
check_pkgconf AVFORMAT libavformat
|
||||
check_pkgconf AVUTIL libavutil
|
||||
check_pkgconf SWSCALE libswscale
|
||||
|
||||
( [ "$HAVE_FFMPEG" = auto ] && ( [ "$HAVE_AVCODEC" = no ] || [ "$HAVE_AVFORMAT" = no ] || [ "$HAVE_AVUTIL" = no ] || [ "$HAVE_SWSCALE" = no ] ) && HAVE_FFMPEG=no ) || HAVE_FFMPEG=yes
|
||||
( [ "$HAVE_FFMPEG" = 'auto' ] && ( [ "$HAVE_AVCODEC" = 'no' ] || [ "$HAVE_AVFORMAT" = 'no' ] || [ "$HAVE_AVUTIL" = 'no' ] || [ "$HAVE_SWSCALE" = 'no' ] ) && HAVE_FFMPEG='no' ) || HAVE_FFMPEG='yes'
|
||||
fi
|
||||
|
||||
if [ "$HAVE_FFMPEG" = yes ]; then
|
||||
if [ "$HAVE_FFMPEG" = 'yes' ]; then
|
||||
check_lib FFMPEG_ALLOC_CONTEXT3 "$AVCODEC_LIBS" avcodec_alloc_context3
|
||||
check_lib FFMPEG_AVCODEC_OPEN2 "$AVCODEC_LIBS" avcodec_open2
|
||||
check_lib FFMPEG_AVCODEC_ENCODE_AUDIO2 "$AVCODEC_LIBS" avcodec_encode_audio2
|
||||
@ -127,34 +113,33 @@ if [ "$HAVE_THREADS" != no ]; then
|
||||
check_lib FFMPEG_AVCODEC_ENCODE_VIDEO2 "$AVCODEC_LIBS" avcodec_encode_video2
|
||||
fi
|
||||
|
||||
if [ "$HAVE_FFMPEG" = no ] && [ "$HAVE_X264RGB" = yes ]; then
|
||||
if [ "$HAVE_FFMPEG" = 'no' ] && [ "$HAVE_X264RGB" = 'yes' ]; then
|
||||
echo "x264 RGB recording is enabled, but FFmpeg is not. --enable-x264rgb will not have any effect."
|
||||
fi
|
||||
else
|
||||
echo "Not building with threading support. Will skip FFmpeg."
|
||||
HAVE_FFMPEG=no
|
||||
HAVE_FFMPEG='no'
|
||||
fi
|
||||
|
||||
check_lib DYNAMIC $DYLIB dlopen
|
||||
check_lib DYNAMIC "$DYLIB" dlopen
|
||||
|
||||
check_pkgconf FREETYPE freetype2
|
||||
check_pkgconf X11 x11
|
||||
check_pkgconf XEXT xext
|
||||
if [ "$HAVE_X11" = yes ] && [ "$HAVE_XEXT" = yes ]; then
|
||||
if [ "$HAVE_X11" = 'yes' ] && [ "$HAVE_XEXT" = 'yes' ]; then
|
||||
check_pkgconf XVIDEO xv
|
||||
else
|
||||
echo "X11 or Xext not present. Skipping XVideo."
|
||||
HAVE_XVIDEO=no
|
||||
HAVE_XVIDEO='no'
|
||||
fi
|
||||
|
||||
check_lib STRL -lc strlcpy
|
||||
|
||||
check_pkgconf PYTHON python3
|
||||
|
||||
add_define_make OS $OS
|
||||
add_define_make OS "$OS"
|
||||
|
||||
# Creates config.mk and config.h.
|
||||
VARS="ALSA OSS OSS_BSD OSS_LIB AL RSOUND ROAR JACK COREAUDIO PULSE SDL OPENGL DYLIB GETOPT_LONG THREADS CG XML SDL_IMAGE DYNAMIC FFMPEG AVCODEC AVFORMAT AVUTIL SWSCALE CONFIGFILE FREETYPE XVIDEO X11 XEXT NETPLAY NETWORK_CMD SOCKET_LEGACY FBO STRL PYTHON FFMPEG_ALLOC_CONTEXT3 FFMPEG_AVCODEC_OPEN2 FFMPEG_AVIO_OPEN FFMPEG_AVFORMAT_WRITE_HEADER FFMPEG_AVFORMAT_NEW_STREAM FFMPEG_AVCODEC_ENCODE_AUDIO2 FFMPEG_AVCODEC_ENCODE_VIDEO2 X264RGB SINC BSV_MOVIE RPI"
|
||||
create_config_make config.mk $VARS
|
||||
create_config_header config.h $VARS
|
||||
|
||||
create_config_header config.h $VARS
|
@ -4,66 +4,46 @@ TEMP_C=.tmp.c
|
||||
TEMP_CXX=.tmp.cxx
|
||||
TEMP_EXE=.tmp
|
||||
|
||||
ECHOBUF="Checking operating system ... "
|
||||
OS="Win32" # whatever ;D
|
||||
unamestr="`uname -a`"
|
||||
if [ ! -z "`echo "$unamestr" | grep -i Linux`" ]; then
|
||||
OS="Linux"
|
||||
elif [ ! -z "`echo "$unamestr" | grep -i Darwin`" ]; then
|
||||
OS="Darwin"
|
||||
elif [ ! -z "`echo "$unamestr" | grep -i BSD`" ]; then
|
||||
OS="BSD"
|
||||
elif [ ! -z "`echo "$unamestr" | grep -i MINGW32`" ]; then
|
||||
OS="MinGW"
|
||||
elif [ ! -z "`echo "$unamestr" | grep -i NT`" ]; then
|
||||
OS="Cygwin"
|
||||
fi
|
||||
|
||||
echo $ECHOBUF $OS
|
||||
ECHOBUF="Checking operating system"
|
||||
#echo -n "Checking operating system"
|
||||
case "$(uname)" in
|
||||
'Linux') OS='Linux';;
|
||||
*'BSD') OS='BSD';;
|
||||
'Darwin') OS='Darwin';;
|
||||
'MINGW32'*) OS='MinGW';;
|
||||
'CYGWIN'*) OS='Cygwin';;
|
||||
*) OS="Win32";;
|
||||
esac
|
||||
echo "$ECHOBUF ... $OS"
|
||||
|
||||
# Checking for working C compiler
|
||||
if [ "$USE_LANG_C" = yes ]; then
|
||||
echo "Checking for working C compiler ..."
|
||||
if [ -z $CC ]; then
|
||||
CC=`which gcc cc 2> /dev/null | grep ^/ | head -n 1`
|
||||
fi
|
||||
if [ -z $CC ]; then
|
||||
echo "Could not find C compiler in path. Exiting ..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ECHOBUF="Checking if $CC is a suitable compiler ..."
|
||||
answer=no
|
||||
echo "#include <stdio.h>" > $TEMP_C
|
||||
echo "int main(void) { puts(\"Hai world!\"); return 0; }" >> $TEMP_C
|
||||
$CC -o $TEMP_EXE $TEMP_C 2>/dev/null >/dev/null && answer=yes
|
||||
echo $ECHOBUF $answer
|
||||
|
||||
rm -rf $TEMP_C $TEMP_EXE
|
||||
|
||||
[ "$answer" = no ] && echo "Can't find suitable C compiler. Exiting ..." && exit 1
|
||||
if [ "$USE_LANG_C" = 'yes' ]; then
|
||||
ECHOBUF="Checking for suitable working C compiler"
|
||||
# echo -n "Checking for suitable working C compiler"
|
||||
cat << EOF > "$TEMP_C"
|
||||
#include <stdio.h>
|
||||
int main(void) { puts("Hai world!"); return 0; }
|
||||
EOF
|
||||
for CC in ${CC:=$(which gcc cc)} ''; do
|
||||
"$CC" -o "$TEMP_EXE" "$TEMP_C" >/dev/null 2>&1 && break
|
||||
done
|
||||
[ "$CC" ] || { echo "$ECHOBUF ... Not found. Exiting."; exit 1;}
|
||||
echo "$ECHOBUF ... $CC"
|
||||
rm "$TEMP_C" "$TEMP_EXE"
|
||||
fi
|
||||
|
||||
# Checking for working C++ compiler
|
||||
if [ "$USE_LANG_CXX" = "yes" ]; then
|
||||
echo "Checking for working C++ compiler ..."
|
||||
if [ -z $CXX ]; then
|
||||
CXX=`which g++ c++ 2> /dev/null | grep ^/ | head -n 1`
|
||||
fi
|
||||
if [ -z $CXX ]; then
|
||||
echo "Could not find C++ compiler in path. Exiting ..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ECHOBUF="Checking if $CXX is a suitable compiler ..."
|
||||
answer=no
|
||||
echo "#include <iostream>" > $TEMP_CXX
|
||||
echo "int main() { std::cout << \"Hai guise\" << std::endl; return 0; }" >> $TEMP_CXX
|
||||
$CXX -o $TEMP_EXE $TEMP_CXX 2>/dev/null >/dev/null && answer=yes
|
||||
echo $ECHOBUF $answer
|
||||
|
||||
rm -rf $TEMP_CXX $TEMP_EXE
|
||||
|
||||
[ "$answer" = no ] && echo "Can't find suitable C++ compiler. Exiting ..." && exit 1
|
||||
# Checking for working C++
|
||||
if [ "$USE_LANG_CXX" = 'yes' ]; then
|
||||
ECHOBUF="Checking for suitable working C++ compiler"
|
||||
# echo -n "Checking for suitable working C++ compiler"
|
||||
cat << EOF > "$TEMP_CXX"
|
||||
#include <iostream>
|
||||
int main() { std::cout << "Hai guise" << std::endl; return 0; }
|
||||
EOF
|
||||
for CXX in ${CXX:=$(which g++ c++)} ''; do
|
||||
"$CXX" -o "$TEMP_EXE" "$TEMP_CXX" >/dev/null 2>&1 && break
|
||||
done
|
||||
[ "$CXX" ] || { echo "$ECHOBUF ... Not found. Exiting."; exit 1;}
|
||||
echo "$ECHOBUF ... $CXX"
|
||||
rm "$TEMP_CXX" "$TEMP_EXE"
|
||||
fi
|
||||
|
||||
|
501
qb/qb.libs.sh
501
qb/qb.libs.sh
@ -1,352 +1,239 @@
|
||||
#<maister> echo -n is broken on recent OSX btw
|
||||
|
||||
PKG_CONF_PATH=""
|
||||
PKG_CONF_USED=""
|
||||
CONFIG_DEFINES=""
|
||||
MAKEFILE_DEFINES=""
|
||||
INCLUDE_DIRS=""
|
||||
LIBRARY_DIRS=""
|
||||
[ -z "$PREFIX" ] && PREFIX="/usr/local"
|
||||
MAKEFILE_DEFINES='.MAKEFILE_DEFINES'
|
||||
CONFIG_DEFINES='.CONFIG_DEFINES'
|
||||
cat /dev/null > "$MAKEFILE_DEFINES" > "$CONFIG_DEFINES"
|
||||
#cat /dev/null > "${MAKEFILE_DEFINES:=.MAKEFILE_DEFINES}" > "${CONFIG_DEFINES=.CONFIG_DEFINES}"
|
||||
|
||||
[ "$PREFIX" ] || PREFIX="/usr/local"
|
||||
|
||||
add_define_header()
|
||||
{
|
||||
CONFIG_DEFINES="$CONFIG_DEFINES:@$1@$2@:"
|
||||
}
|
||||
{ echo "$1=$2" >> "$CONFIG_DEFINES";}
|
||||
|
||||
add_define_make()
|
||||
{
|
||||
MAKEFILE_DEFINES="$MAKEFILE_DEFINES:@$1@$2@:"
|
||||
}
|
||||
{ echo "$1=$2" >> "$MAKEFILE_DEFINES";}
|
||||
|
||||
add_include_dirs()
|
||||
{
|
||||
while [ ! -z "$1" ]
|
||||
do
|
||||
INCLUDE_DIRS="$INCLUDE_DIRS -I$1"
|
||||
shift
|
||||
done
|
||||
}
|
||||
{ while [ "$1" ]; do INCLUDE_DIRS="$INCLUDE_DIRS -I$1"; shift; done;}
|
||||
|
||||
add_library_dirs()
|
||||
{
|
||||
while [ ! -z "$1" ]
|
||||
do
|
||||
LIBRARY_DIRS="$LIBRARY_DIRS -L$1"
|
||||
shift
|
||||
done
|
||||
{ while [ "$1" ]; do LIBRARY_DIRS="$LIBRARY_DIRS -L$1"; shift; done;}
|
||||
|
||||
check_lib() #$1 = HAVE_$1 $2 = lib $3 = function in lib $4 = extralibs
|
||||
{ tmpval="$(eval echo \$HAVE_$1)"
|
||||
[ "$tmpval" = 'no' ] && return 0
|
||||
|
||||
if [ "$3" ]; then
|
||||
ECHOBUF="Checking function $3 in ${2% }"
|
||||
echo "void $3(void); int main(void) { $3(); return 0; }" > $TEMP_C
|
||||
else
|
||||
ECHOBUF="Checking existence of ${2% }"
|
||||
echo "int main(void) { return 0; }" > $TEMP_C
|
||||
fi
|
||||
answer='no'
|
||||
# echo -n "$ECHOBUF"
|
||||
"$CC" -o "$TEMP_EXE" "$TEMP_C" $INCLUDE_DIRS $LIBRARY_DIRS $4 $CFLAGS $LDFLAGS $2 >/dev/null 2>&1 && answer='yes'
|
||||
eval HAVE_$1="$answer"; echo "$ECHOBUF ... $answer"
|
||||
rm "$TEMP_C" "$TEMP_EXE" >/dev/null 2>&1
|
||||
|
||||
[ "$tmpval" = 'yes' ] && [ "$answer" = 'no' ] && {
|
||||
echo "Forced to build with library $2, but cannot locate. Exiting ..."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
check_lib()
|
||||
{
|
||||
tmpval="HAVE_$1"
|
||||
eval tmpval=\$$tmpval
|
||||
[ "$tmpval" = "no" ] && return 0
|
||||
check_lib_cxx() #$1 = HAVE_$1 $2 = lib $3 = function in lib $4 = extralibs $5 = critical error message [checked only if non-empty]
|
||||
{ tmpval="$(eval echo \$HAVE_$1)"
|
||||
[ "$tmpval" = 'no' ] && return 0
|
||||
|
||||
if [ -z "$3" ]; then
|
||||
ECHOBUF="Checking existence of $2 ..."
|
||||
echo "int main(void) { return 0; }" > $TEMP_C
|
||||
else
|
||||
ECHOBUF="Checking function $3 in $2 ..."
|
||||
echo "void $3(void); int main(void) { $3(); return 0; }" > $TEMP_C
|
||||
fi
|
||||
|
||||
eval HAVE_$1=no
|
||||
answer=no
|
||||
|
||||
extralibs="$4"
|
||||
|
||||
$CC -o $TEMP_EXE $TEMP_C $INCLUDE_DIRS $LIBRARY_DIRS $extralibs $CFLAGS $LDFLAGS $2 2>/dev/null >/dev/null && answer=yes && eval HAVE_$1=yes
|
||||
|
||||
echo $ECHOBUF $answer
|
||||
|
||||
rm -f $TEMP_C $TEMP_EXE
|
||||
if [ "$tmpval" = "yes" ] && [ "$answer" = "no" ]; then
|
||||
echo "Forced to build with library $2, but cannot locate. Exiting ..."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_lib_cxx()
|
||||
{
|
||||
tmpval="HAVE_$1"
|
||||
eval tmpval=\$$tmpval
|
||||
[ "$tmpval" = "no" ] && return 0
|
||||
|
||||
if [ -z "$3" ]; then
|
||||
ECHOBUF="Checking existence of $2 ..."
|
||||
echo "int main() { return 0; }" > $TEMP_CXX
|
||||
else
|
||||
ECHOBUF="Checking function $3 in $2 ..."
|
||||
echo "extern \"C\" { void $3(void); } int main() { $3(); }" > $TEMP_CXX
|
||||
fi
|
||||
|
||||
eval HAVE_$1=no
|
||||
answer=no
|
||||
|
||||
extralibs="$4"
|
||||
|
||||
$CXX -o $TEMP_EXE $TEMP_CXX $INCLUDE_DIRS $LIBRARY_DIRS $extralibs $CFLAGS $LDFLAGS $2 2>/dev/null >/dev/null && answer=yes && eval HAVE_$1=yes
|
||||
|
||||
echo $ECHOBUF $answer
|
||||
|
||||
rm -f $TEMP_CXX $TEMP_EXE
|
||||
if [ "$tmpval" = "yes" ] && [ "$answer" = "no" ]; then
|
||||
echo "Forced to build with library $2, but cannot locate. Exiting ..."
|
||||
exit 1
|
||||
fi
|
||||
if [ "$3" ]; then
|
||||
ECHOBUF="Checking function $3 in ${2% }"
|
||||
echo "extern \"C\" { void $3(void); } int main() { $3(); }" > $TEMP_CXX
|
||||
else
|
||||
ECHOBUF="Checking existence of ${2% }"
|
||||
echo "int main() { return 0; }" > $TEMP_CXX
|
||||
fi
|
||||
answer='no'
|
||||
# echo -n "$ECHOBUF"
|
||||
"$CXX" -o "$TEMP_EXE" "$TEMP_CXX" $INCLUDE_DIRS $LIBRARY_DIRS $4 $CFLAGS $LDFLAGS $2 >/dev/null 2>&1 && answer='yes'
|
||||
eval HAVE_$1="$answer"; echo "$ECHOBUF ... $answer"
|
||||
rm "$TEMP_CXX" "$TEMP_EXE" >/dev/null 2>&1
|
||||
[ "$answer" = 'no' ] && {
|
||||
[ "$5" ] && { echo "$5"; exit 1;}
|
||||
[ "$tmpval" = 'yes' ] && {
|
||||
echo "Forced to build with library $2, but cannot locate. Exiting ..."
|
||||
exit 1
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
check_code_c()
|
||||
{
|
||||
tmpval="HAVE_$1"
|
||||
eval tmpval=\$$tmpval
|
||||
[ "$tmpval" = "no" ] && return 0
|
||||
{ tmpval="$(eval echo \$HAVE_$1)"
|
||||
[ "$tmpval" = 'no' ] && return 0
|
||||
|
||||
ECHOBUF="Checking C code snippet \"$3\" ..."
|
||||
eval HAVE_$1=no
|
||||
answer=no
|
||||
$CC -o $TEMP_EXE $TEMP_C $INCLUDE_DIRS $LIBRARY_DIRS $2 $CFLAGS $LDFLAGS 2>/dev/null >/dev/null && answer=yes && eval HAVE_$1=yes
|
||||
|
||||
echo $ECHOBUF $answer
|
||||
rm -f $TEMP_C $TEMP_EXE
|
||||
ECHOBUF="Checking C code snippet \"$3\""
|
||||
# echo -n "Checking C code snippet \"$3\""
|
||||
answer='no'
|
||||
"$CC" -o "$TEMP_EXE" "$TEMP_C" $INCLUDE_DIRS $LIBRARY_DIRS $2 $CFLAGS $LDFLAGS >/dev/null 2>&1 && answer='yes'
|
||||
eval HAVE_$1="$answer"; echo "$ECHOBUF ... $answer"
|
||||
rm "$TEMP_C" "$TEMP_EXE" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
check_code_cxx()
|
||||
{
|
||||
tmpval="HAVE_$1"
|
||||
eval tmpval=\$$tmpval
|
||||
[ "$tmpval" = "no" ] && return 0
|
||||
{ tmpval="$(eval echo \$HAVE_$1)"
|
||||
[ "$tmpval" = 'no' ] && return 0
|
||||
|
||||
ECHOBUF="Checking C++ code snippet \"$3\" ..."
|
||||
eval HAVE_$1=no
|
||||
answer=no
|
||||
$CXX -o $TEMP_EXE $TEMP_CXX $INCLUDE_DIRS $LIBRARY_DIRS $2 $CXXFLAGS $LDFLAGS 2>/dev/null >/dev/null && answer=yes && eval HAVE_$1=yes
|
||||
|
||||
echo $ECHOBUF $answer
|
||||
rm -f $TEMP_CXX $TEMP_EXE
|
||||
ECHOBUF="Checking C++ code snippet \"$3\""
|
||||
# echo -n "Checking C++ code snippet \"$3\""
|
||||
answer='no'
|
||||
"$CXX" -o "$TEMP_EXE" "$TEMP_CXX" $INCLUDE_DIRS $LIBRARY_DIRS $2 $CXXFLAGS $LDFLAGS >/dev/null 2>&1 && answer='yes'
|
||||
eval HAVE_$1="$answer"; echo "$ECHOBUF ... $answer"
|
||||
rm "$TEMP_CXX" "$TEMP_EXE" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
locate_pkg_conf()
|
||||
{
|
||||
ECHOBUF="Checking for pkg-config ... "
|
||||
PKG_CONF_PATH="`which pkg-config | grep ^/ | head -n1`"
|
||||
if [ -z $PKG_CONF_PATH ]; then
|
||||
echo "not found"
|
||||
echo "Cannot locate pkg-config. Exiting ..."
|
||||
exit 1
|
||||
fi
|
||||
echo $ECHOBUF $PKG_CONF_PATH
|
||||
check_pkgconf() #$1 = HAVE_$1 $2 = package $3 = version $4 = critical error message [checked only if non-empty]
|
||||
{ tmpval="$(eval echo \$HAVE_$1)"
|
||||
[ "$tmpval" = 'no' ] && return 0
|
||||
|
||||
[ "$PKG_CONF_PATH" ] || {
|
||||
ECHOBUF="Checking for pkg-config"
|
||||
# echo -n "Checking for pkg-config"
|
||||
for PKG_CONF_PATH in $(which pkg-config) ''; do [ "$PKG_CONF_PATH" ] && break; done
|
||||
[ "$PKG_CONF_PATH" ] || { echo "Not found. Exiting ..."; exit 1;}
|
||||
echo "$ECHOBUF ... $PKG_CONF_PATH"
|
||||
}
|
||||
|
||||
ECHOBUF="Checking presence of package $2"
|
||||
[ "$3" ] && ECHOBUF="$ECHOBUF with minimum version $3"
|
||||
# echo -n "$ECHOBUF ... "
|
||||
answer='no'
|
||||
pkg-config --atleast-version="${3:-0.0}" "$2" && {
|
||||
answer='yes'
|
||||
eval $1_CFLAGS=\"$(pkg-config $2 --cflags)\"
|
||||
eval $1_LIBS=\"$(pkg-config $2 --libs)\"
|
||||
}
|
||||
|
||||
eval HAVE_$1="$answer"; echo "$ECHOBUF ... $answer"
|
||||
PKG_CONF_USED="$PKG_CONF_USED $1"
|
||||
[ "$answer" = 'no' ] && {
|
||||
[ "$4" ] && { echo "$4"; exit 1;}
|
||||
[ "$tmpval" = 'yes' ] && {
|
||||
echo "Forced to build with package $2, but cannot locate. Exiting ..."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
check_pkgconf()
|
||||
{
|
||||
[ -z "$PKG_CONF_PATH" ] && locate_pkg_conf
|
||||
|
||||
tmpval="HAVE_$1"
|
||||
eval tmpval=\$$tmpval
|
||||
[ "$tmpval" = "no" ] && return 0
|
||||
|
||||
ECHOBUF="Checking presence of package $2"
|
||||
eval HAVE_$1=no
|
||||
eval $1_CFLAGS=""
|
||||
eval $1_LIBS=""
|
||||
answer=no
|
||||
minver=0.0
|
||||
[ ! -z $3 ] && minver=$3 && ECHOBUF="$ECHOBUF with minimum version $minver"
|
||||
ECHOBUF="$ECHOBUF ... "
|
||||
pkg-config --atleast-version=$minver "$2" && eval HAVE_$1=yes && eval $1_CFLAGS='"`pkg-config $2 --cflags`"' && eval $1_LIBS='"`pkg-config $2 --libs`"' && answer=yes
|
||||
echo $ECHOBUF $answer
|
||||
|
||||
PKG_CONF_USED="$PKG_CONF_USED $1"
|
||||
|
||||
if [ "$tmpval" = "yes" ] && [ "$answer" = "no" ]; then
|
||||
echo "Forced to build with package $2, but cannot locate. Exiting ..."
|
||||
exit 1
|
||||
fi
|
||||
check_header() #$1 = HAVE_$1 $2 = header file
|
||||
{ tmpval="$(eval echo \$HAVE_$1)"
|
||||
[ "$tmpval" = 'no' ] && return 0
|
||||
ECHOBUF="Checking presence of header file $2"
|
||||
# echo -n "Checking presence of header file $2"
|
||||
cat << EOF > "$TEMP_C"
|
||||
#include<$2>
|
||||
int main(void) { return 0; }
|
||||
EOF
|
||||
answer='no'
|
||||
"$CC" -o "$TEMP_EXE" "$TEMP_C" $INCLUDE_DIRS >/dev/null 2>&1 && answer='yes'
|
||||
eval HAVE_$1="$answer"; echo "$ECHOBUF ... $answer"
|
||||
rm "$TEMP_C" "$TEMP_EXE" >/dev/null 2>&1
|
||||
[ "$tmpval" = 'yes' ] && [ "$answer" = 'no' ] && {
|
||||
echo "Build assumed that $2 exists, but cannot locate. Exiting ..."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
check_header()
|
||||
{
|
||||
tmpval="HAVE_$1"
|
||||
eval tmpval=\$$tmpval
|
||||
[ "$tmpval" = "no" ] && return 0
|
||||
|
||||
ECHOBUF="Checking presence of header file $2 ..."
|
||||
echo "#include<$2>" > $TEMP_C
|
||||
echo "int main(void) { return 0; }" >> $TEMP_C
|
||||
eval HAVE_$1=no
|
||||
answer=no
|
||||
|
||||
$CC -o $TEMP_EXE $TEMP_C $INCLUDE_DIRS 2>/dev/null >/dev/null && answer=yes && eval HAVE_$1=yes
|
||||
|
||||
echo $ECHOBUF $answer
|
||||
|
||||
rm -rf $TEMP_C $TEMP_EXE
|
||||
if [ "$tmpval" = "yes" ] && [ "$answer" = "no" ]; then
|
||||
echo "Build assumed that $2 exists, but cannot locate. Exiting ..."
|
||||
exit 1
|
||||
fi
|
||||
check_switch_c() #$1 = HAVE_$1 $2 = switch $3 = critical error message [checked only if non-empty]
|
||||
{ ECHOBUF="Checking for availability of switch $2 in $CC"
|
||||
# echo -n "Checking for availability of switch $2 in $CC "
|
||||
echo "int main(void) { return 0; }" > $TEMP_C
|
||||
answer='no'
|
||||
"$CC" -o "$TEMP_EXE" "$TEMP_C" $2 >/dev/null 2>&1 && answer='yes'
|
||||
eval HAVE_$1="$answer"; echo "$ECHOBUF ... $answer"
|
||||
rm "$TEMP_C" "$TEMP_EXE" >/dev/null 2>&1
|
||||
[ "$answer" = 'no' ] && {
|
||||
[ "$3" ] && { echo "$3"; exit 1;}
|
||||
}
|
||||
}
|
||||
|
||||
check_switch_c()
|
||||
{
|
||||
ECHOBUF="Checking for availability of switch $2 in $CC ..."
|
||||
if [ -z "$CC" ]; then
|
||||
echo "No C compiler, cannot check ..."
|
||||
exit 1
|
||||
fi
|
||||
echo "int main(void) { return 0; }" > $TEMP_C
|
||||
eval HAVE_$1=no
|
||||
answer=no
|
||||
$CC -o $TEMP_EXE $TEMP_C $2 2>/dev/null >/dev/null && answer=yes && eval HAVE_$1=yes
|
||||
|
||||
echo $ECHOBUF $answer
|
||||
|
||||
rm -rf $TEMP_C $TEMP_EXE
|
||||
}
|
||||
|
||||
check_switch_cxx()
|
||||
{
|
||||
ECHOBUF="Checking for availability of switch $2 in $CXX ... "
|
||||
if [ -z "$CXX" ]; then
|
||||
echo "No C++ compiler, cannot check ..."
|
||||
exit 1
|
||||
fi
|
||||
echo "int main() { return 0; }" > $TEMP_CXX
|
||||
eval HAVE_$1=no
|
||||
answer=no
|
||||
$CXX -o $TEMP_EXE $TEMP_CXX $2 2>/dev/null >/dev/null && answer=yes && eval HAVE_$1=yes
|
||||
|
||||
echo $ECHOBUF $answer
|
||||
|
||||
rm -rf $TEMP_CXX $TEMP_EXE
|
||||
}
|
||||
|
||||
check_critical()
|
||||
{
|
||||
val=HAVE_$1
|
||||
eval val=\$$val
|
||||
if [ "$val" != "yes" ]; then
|
||||
echo "$2"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
output_define_header()
|
||||
{
|
||||
arg1="`echo $2 | sed 's|^@\([^@]*\)@\([^@]*\)@$|\1|'`"
|
||||
arg2="`echo $2 | sed 's|^@\([^@]*\)@\([^@]*\)@$|\2|'`"
|
||||
|
||||
echo "#define $arg1 $arg2" >> "$outfile"
|
||||
check_switch_cxx() #$1 = HAVE_$1 $2 = switch $3 = critical error message [checked only if non-empty]
|
||||
{ ECHOBUF="Checking for availability of switch $2 in $CXX"
|
||||
# echo -n "Checking for availability of switch $2 in $CXX"
|
||||
echo "int main() { return 0; }" > $TEMP_CXX
|
||||
answer='no'
|
||||
"$CXX" -o "$TEMP_EXE" "$TEMP_CXX" "$2" >/dev/null 2>&1 && answer='yes'
|
||||
eval HAVE_$1="$answer"; echo "$ECHOBUF ... $answer"
|
||||
rm "$TEMP_CXX" "$TEMP_EXE" >/dev/null 2>&1
|
||||
[ "$answer" = 'no' ] && {
|
||||
[ "$3" ] && { echo "$3"; exit 1;}
|
||||
}
|
||||
}
|
||||
|
||||
create_config_header()
|
||||
{
|
||||
outfile="$1"
|
||||
shift
|
||||
{ outfile="$1"; shift
|
||||
|
||||
echo "Creating config header: $outfile"
|
||||
echo "Creating config header: $outfile"
|
||||
name=$(echo "QB_${outfile}__" | tr '.[a-z]' '_[A-Z]')
|
||||
{ echo "#ifndef $name"
|
||||
echo "#define $name"
|
||||
echo ""
|
||||
echo "#define PACKAGE_NAME \"$PACKAGE_NAME\""
|
||||
echo "#define PACKAGE_VERSION \"$PACKAGE_VERSION\""
|
||||
|
||||
name="`echo QB_${outfile}__ | sed 's|[\./]|_|g' | tr '[a-z]' '[A-Z]'`"
|
||||
echo "#ifndef $name" > "$outfile"
|
||||
echo "#define $name" >> "$outfile"
|
||||
echo "" >> "$outfile"
|
||||
echo "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >> "$outfile"
|
||||
echo "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >> "$outfile"
|
||||
while [ "$1" ]; do
|
||||
case $(eval echo \$HAVE_$1) in
|
||||
'yes') echo "#define HAVE_$1 1";;
|
||||
'no') echo "/* #undef HAVE_$1 */";;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
while [ ! -z "$1" ]
|
||||
do
|
||||
tmpval="HAVE_$1"
|
||||
eval tmpval=\$$tmpval
|
||||
if [ "$tmpval" = "yes" ]; then
|
||||
echo "#define HAVE_$1 1" >> "$outfile"
|
||||
elif [ "$tmpval" = "no" ]; then
|
||||
echo "/* #undef HAVE_$1 */" >> "$outfile"
|
||||
fi
|
||||
while IFS='=' read VAR VAL; do echo "#define $VAR $VAL"; done < "$CONFIG_DEFINES"
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
echo "" >> "$outfile"
|
||||
|
||||
tmpdefs="$CONFIG_DEFINES"
|
||||
while [ ! -z "$tmpdefs" ]
|
||||
do
|
||||
subdefs="`echo $tmpdefs | sed 's|^:\(@[^@]*@[^@]*@\):.*$|\1|'`"
|
||||
tmpdefs="`echo $tmpdefs | sed 's|^\W*$||'`"
|
||||
tmpdefs="`echo $tmpdefs | sed 's|^:\(@[^@]*@[^@]*@\):||'`"
|
||||
output_define_header "$outfile" "$subdefs"
|
||||
done
|
||||
|
||||
echo "#endif" >> "$outfile"
|
||||
}
|
||||
|
||||
output_define_make()
|
||||
{
|
||||
arg1="`echo $2 | sed 's|^@\([^@]*\)@\([^@]*\)@$|\1|'`"
|
||||
arg2="`echo $2 | sed 's|^@\([^@]*\)@\([^@]*\)@$|\2|'`"
|
||||
|
||||
echo "$arg1 = $arg2" >> "$outfile"
|
||||
echo "#endif"
|
||||
} > "$outfile"
|
||||
}
|
||||
|
||||
create_config_make()
|
||||
{
|
||||
outfile="$1"
|
||||
shift
|
||||
{ outfile="$1"; shift
|
||||
|
||||
echo "Creating make config: $outfile"
|
||||
echo "Creating make config: $outfile"
|
||||
|
||||
rm -rf "$outfile"
|
||||
touch "$outfile"
|
||||
if [ "$USE_LANG_C" = "yes" ]; then
|
||||
echo "CC = $CC" >> "$outfile"
|
||||
echo "CFLAGS = $CFLAGS" >> "$outfile"
|
||||
fi
|
||||
if [ "$USE_LANG_CXX" = "yes" ]; then
|
||||
echo "CXX = $CXX" >> "$outfile"
|
||||
echo "CXXFLAGS = $CXXFLAGS" >> "$outfile"
|
||||
fi
|
||||
echo "LDFLAGS = $LDFLAGS" >> "$outfile"
|
||||
echo "INCLUDE_DIRS = $INCLUDE_DIRS" >> "$outfile"
|
||||
echo "LIBRARY_DIRS = $LIBRARY_DIRS" >> "$outfile"
|
||||
echo "PACKAGE_NAME = $PACKAGE_NAME" >> "$outfile"
|
||||
echo "PACKAGE_VERSION = $PACKAGE_VERSION" >> "$outfile"
|
||||
echo "PREFIX = $PREFIX" >> "$outfile"
|
||||
{ if [ "$USE_LANG_C" = 'yes' ]; then
|
||||
echo "CC = $CC"
|
||||
echo "CFLAGS = $CFLAGS"
|
||||
fi
|
||||
if [ "$USE_LANG_CXX" = 'yes' ]; then
|
||||
echo "CXX = $CXX"
|
||||
echo "CXXFLAGS = $CXXFLAGS"
|
||||
fi
|
||||
echo "LDFLAGS = $LDFLAGS"
|
||||
echo "INCLUDE_DIRS = $INCLUDE_DIRS"
|
||||
echo "LIBRARY_DIRS = $LIBRARY_DIRS"
|
||||
echo "PACKAGE_NAME = $PACKAGE_NAME"
|
||||
echo "PACKAGE_VERSION = $PACKAGE_VERSION"
|
||||
echo "PREFIX = $PREFIX"
|
||||
|
||||
while [ ! -z "$1" ]
|
||||
do
|
||||
tmpval="HAVE_$1"
|
||||
eval tmpval=\$$tmpval
|
||||
if [ "$tmpval" = yes ]; then
|
||||
echo "HAVE_$1 = 1" >> "$outfile"
|
||||
elif [ "$tmpval" = no ]; then
|
||||
echo "HAVE_$1 = 0" >> "$outfile"
|
||||
fi
|
||||
|
||||
if [ ! -z "`echo $PKG_CONF_USED | grep $1`" ]; then
|
||||
tmpval="$1_CFLAGS"
|
||||
eval tmpval=\$$tmpval
|
||||
echo "$1_CFLAGS = $tmpval" >> "$outfile"
|
||||
|
||||
tmpval="$1_LIBS"
|
||||
eval tmpval=\$$tmpval
|
||||
echo "$1_LIBS = $tmpval" >> "$outfile"
|
||||
fi
|
||||
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
echo "" >> "$outfile"
|
||||
|
||||
tmpdefs="$MAKEFILE_DEFINES"
|
||||
while [ ! -z "$tmpdefs" ]
|
||||
do
|
||||
subdefs="`echo $tmpdefs | sed 's|^:\(@[^@]*@[^@]*@\):.*$|\1|'`"
|
||||
tmpdefs="`echo $tmpdefs | sed 's|^\W*$||'`"
|
||||
tmpdefs="`echo $tmpdefs | sed 's|^:\(@[^@]*@[^@]*@\):||'`"
|
||||
output_define_make "$outfile" "$subdefs"
|
||||
done
|
||||
while [ "$1" ]; do
|
||||
case $(eval echo \$HAVE_$1) in
|
||||
'yes') echo "HAVE_$1 = 1";;
|
||||
'no') echo "HAVE_$1 = 0";;
|
||||
esac
|
||||
|
||||
case "$PKG_CONF_USED" in
|
||||
*$1*)
|
||||
echo "$1_CFLAGS = $(eval echo \$$1_CFLAGS)"
|
||||
echo "$1_LIBS = $(eval echo \$$1_LIBS)"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
while IFS='=' read VAR VAL; do echo "$VAR = $VAL"; done < "$MAKEFILE_DEFINES"
|
||||
|
||||
} > "$outfile"
|
||||
}
|
||||
|
||||
. qb/config.libs.sh
|
||||
|
||||
rm "$MAKEFILE_DEFINES" "$CONFIG_DEFINES"
|
||||
|
@ -23,49 +23,48 @@ EOF
|
||||
while IFS='=#' read VAR VAL COMMENT; do
|
||||
VAR=$(echo "${VAR##HAVE_}" | tr '[A-Z]' '[a-z]')
|
||||
case "$VAL" in
|
||||
'yes'*) echo "--disable-$VAR: $COMMENT";;
|
||||
'no'*) echo "--enable-$VAR: $COMMENT";;
|
||||
'auto'*) echo "--enable-$VAR: $COMMENT"; echo "--disable-$VAR";;
|
||||
*) echo "--with-$VAR: $COMMENT";;
|
||||
'yes'*)
|
||||
echo "--disable-$VAR: $COMMENT";;
|
||||
'no'*)
|
||||
echo "--enable-$VAR: $COMMENT";;
|
||||
'auto'*)
|
||||
echo "--enable-$VAR: $COMMENT"
|
||||
echo "--disable-$VAR";;
|
||||
*)
|
||||
echo "--with-$VAR: $COMMENT";;
|
||||
esac
|
||||
done < 'qb/config.params.sh'
|
||||
}
|
||||
|
||||
opt_exists() # $opt is returned if exists in OPTS
|
||||
{
|
||||
opt=$(echo "$1" | tr '[a-z]' '[A-Z]')
|
||||
{ opt=$(echo "$1" | tr '[a-z]' '[A-Z]')
|
||||
for OPT in $OPTS; do [ "$opt" = "$OPT" ] && return; done
|
||||
print_help; exit 1
|
||||
}
|
||||
|
||||
parse_input() # Parse stuff :V
|
||||
{
|
||||
#OPTS contains all available options in config.params.sh
|
||||
while IFS='=' read VAR dummy; do OPTS="$OPTS ${VAR##HAVE_}"; done < 'qb/config.params.sh'
|
||||
{ OPTS=; while IFS='=' read VAR dummy; do OPTS="$OPTS ${VAR##HAVE_}"; done < 'qb/config.params.sh'
|
||||
#OPTS contains all available options in config.params.sh - used to speedup
|
||||
#things in opt_exists()
|
||||
|
||||
while [ "$1" ]; do
|
||||
case "$1" in
|
||||
--prefix=*) PREFIX=${1##--prefix=};;
|
||||
|
||||
--enable-*)
|
||||
opt_exists "${1##--enable-}" "$OPTS"
|
||||
opt_exists "${1##--enable-}"
|
||||
eval "HAVE_$opt=yes"
|
||||
;;
|
||||
|
||||
--disable-*)
|
||||
opt_exists "${1##--disable-}" "$OPTS"
|
||||
opt_exists "${1##--disable-}"
|
||||
eval "HAVE_$opt=no"
|
||||
;;
|
||||
|
||||
--with-*)
|
||||
arg=${1##--with-}
|
||||
val=${arg##*=}
|
||||
opt_exists "${arg%%=*}" "$OPTS"
|
||||
opt_exists "${arg%%=*}"
|
||||
eval "$opt=$val"
|
||||
;;
|
||||
|
||||
-h|--help) print_help; exit 0;;
|
||||
|
||||
*) print_help; exit 1;;
|
||||
esac
|
||||
shift
|
||||
@ -74,6 +73,4 @@ parse_input() # Parse stuff :V
|
||||
|
||||
. qb/config.params.sh
|
||||
|
||||
parse_input "$@"
|
||||
|
||||
|
||||
parse_input "$@"
|
||||
|
61
retroarch.c
61
retroarch.c
@ -95,22 +95,61 @@ static void set_fast_forward_button(bool new_button_state, bool new_hold_button_
|
||||
}
|
||||
|
||||
#ifdef HAVE_SCREENSHOTS
|
||||
static bool take_screenshot_viewport(void)
|
||||
{
|
||||
unsigned width = 0, height = 0;
|
||||
video_viewport_size_func(&width, &height);
|
||||
|
||||
if (!width || !height)
|
||||
return false;
|
||||
|
||||
uint8_t *buffer = (uint8_t*)malloc(width * height * 3);
|
||||
if (!buffer)
|
||||
return false;
|
||||
|
||||
if (!video_read_viewport_func(buffer))
|
||||
{
|
||||
free(buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Data read from viewport is in bottom-up order, suitable for BMP.
|
||||
if (!screenshot_dump(g_settings.screenshot_directory,
|
||||
buffer,
|
||||
width, height, width * 3, true))
|
||||
{
|
||||
free(buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool take_screenshot_raw(void)
|
||||
{
|
||||
const uint16_t *data = (const uint16_t*)g_extern.frame_cache.data;
|
||||
unsigned width = g_extern.frame_cache.width;
|
||||
unsigned height = g_extern.frame_cache.height;
|
||||
int pitch = g_extern.frame_cache.pitch;
|
||||
|
||||
// Negative pitch is needed as screenshot takes bottom-up,
|
||||
// but we use top-down.
|
||||
return screenshot_dump(g_settings.screenshot_directory,
|
||||
data + (height - 1) * (pitch >> 1),
|
||||
width, height, -pitch, false);
|
||||
}
|
||||
|
||||
static void take_screenshot(void)
|
||||
{
|
||||
if (!(*g_settings.screenshot_directory))
|
||||
return;
|
||||
|
||||
bool ret = false;
|
||||
if (g_extern.frame_cache.data)
|
||||
{
|
||||
const uint16_t *data = (const uint16_t*)g_extern.frame_cache.data;
|
||||
unsigned width = g_extern.frame_cache.width;
|
||||
unsigned height = g_extern.frame_cache.height;
|
||||
size_t pitch = g_extern.frame_cache.pitch;
|
||||
ret = screenshot_dump(g_settings.screenshot_directory,
|
||||
data,
|
||||
width, height, pitch);
|
||||
}
|
||||
|
||||
if (driver.video->read_viewport && driver.video->viewport_size)
|
||||
ret = take_screenshot_viewport();
|
||||
else if (g_extern.frame_cache.data)
|
||||
ret = take_screenshot_raw();
|
||||
|
||||
const char *msg = NULL;
|
||||
if (ret)
|
||||
@ -1500,7 +1539,7 @@ static void set_savestate_auto_index(void)
|
||||
|
||||
unsigned max_index = 0;
|
||||
|
||||
char **dir_list = dir_list_new(dir, NULL);
|
||||
char **dir_list = dir_list_new(dir, NULL, false);
|
||||
if (!dir_list)
|
||||
return;
|
||||
|
||||
|
@ -26,6 +26,10 @@
|
||||
# I.e.: "key1=value1;key2=value2;..."
|
||||
# environment_variables =
|
||||
|
||||
# Sets the "system" directory.
|
||||
# Implementations can query for this directory to load BIOSes, system-specific configs, etc.
|
||||
# system_directory =
|
||||
|
||||
#### Video
|
||||
|
||||
# Video driver to use. "gl", "xvideo", "sdl" or "ext" (external API driver)
|
||||
|
70
screenshot.c
70
screenshot.c
@ -52,49 +52,70 @@ static void write_header(FILE *file, unsigned width, unsigned height)
|
||||
fwrite(header, 1, sizeof(header), file);
|
||||
}
|
||||
|
||||
static void dump_content(FILE *file, const uint16_t *frame, unsigned width, unsigned height, unsigned pitch)
|
||||
static void dump_line_bgr(uint8_t *line, const uint8_t *src, unsigned width)
|
||||
{
|
||||
pitch >>= 1;
|
||||
memcpy(line, src, width * 3);
|
||||
}
|
||||
|
||||
static void dump_line_16(uint8_t *line, const uint16_t *src, unsigned width)
|
||||
{
|
||||
for (unsigned i = 0; i < width; i++)
|
||||
{
|
||||
uint16_t pixel = *src++;
|
||||
uint8_t b = (pixel >> 0) & 0x1f;
|
||||
uint8_t g = (pixel >> 5) & 0x1f;
|
||||
uint8_t r = (pixel >> 10) & 0x1f;
|
||||
*line++ = (b << 3) | (b >> 2);
|
||||
*line++ = (g << 3) | (g >> 2);
|
||||
*line++ = (r << 3) | (r >> 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_content(FILE *file, const void *frame,
|
||||
int width, int height, int pitch, bool bgr24)
|
||||
{
|
||||
const uint8_t *frame_bgr = (const uint8_t*)frame;
|
||||
const uint16_t *frame16 = (const uint16_t*)frame;
|
||||
|
||||
if (!bgr24)
|
||||
pitch /= 2;
|
||||
|
||||
unsigned line_size = (width * 3 + 3) & ~3;
|
||||
uint8_t *line = (uint8_t*)calloc(1, line_size);
|
||||
if (!line)
|
||||
return;
|
||||
|
||||
// BMP likes reverse ordering for some reason :v
|
||||
for (int j = height - 1; j >= 0; j--)
|
||||
if (bgr24) // BGR24 byte order. Can directly copy.
|
||||
{
|
||||
uint8_t *dst = line;
|
||||
const uint16_t *src = frame + j * pitch;
|
||||
for (unsigned i = 0; i < width; i++)
|
||||
for (int j = 0; j < height; j++, frame_bgr += pitch)
|
||||
{
|
||||
uint16_t pixel = *src++;
|
||||
uint8_t b = (pixel >> 0) & 0x1f;
|
||||
uint8_t g = (pixel >> 5) & 0x1f;
|
||||
uint8_t r = (pixel >> 10) & 0x1f;
|
||||
*dst++ = (b << 3) | (b >> 2);
|
||||
*dst++ = (g << 3) | (g >> 2);
|
||||
*dst++ = (r << 3) | (r >> 2);
|
||||
dump_line_bgr(line, frame_bgr, width);
|
||||
fwrite(line, 1, line_size, file);
|
||||
}
|
||||
}
|
||||
else // ARGB1555
|
||||
{
|
||||
for (int j = 0; j < height; j++, frame16 += pitch)
|
||||
{
|
||||
dump_line_16(line, frame16, width);
|
||||
fwrite(line, 1, line_size, file);
|
||||
}
|
||||
|
||||
fwrite(line, 1, line_size, file);
|
||||
}
|
||||
|
||||
free(line);
|
||||
}
|
||||
|
||||
bool screenshot_dump(const char *folder, const uint16_t *frame,
|
||||
unsigned width, unsigned height, unsigned pitch)
|
||||
bool screenshot_dump(const char *folder, const void *frame,
|
||||
unsigned width, unsigned height, int pitch, bool bgr24)
|
||||
{
|
||||
time_t cur_time;
|
||||
time(&cur_time);
|
||||
|
||||
char timefmt[128];
|
||||
strftime(timefmt, sizeof(timefmt), "SSNES-%m%d-%H%M%S.bmp", localtime(&cur_time));
|
||||
strftime(timefmt, sizeof(timefmt), "RetroArch-%m%d-%H%M%S.bmp", localtime(&cur_time));
|
||||
|
||||
char filename[256];
|
||||
strlcpy(filename, folder, sizeof(filename));
|
||||
strlcat(filename, "/", sizeof(filename));
|
||||
strlcat(filename, timefmt, sizeof(filename));
|
||||
char filename[PATH_MAX];
|
||||
snprintf(filename, sizeof(filename), "%s/%s", folder, timefmt);
|
||||
|
||||
FILE *file = fopen(filename, "wb");
|
||||
if (!file)
|
||||
@ -104,9 +125,10 @@ bool screenshot_dump(const char *folder, const uint16_t *frame,
|
||||
}
|
||||
|
||||
write_header(file, width, height);
|
||||
dump_content(file, frame, width, height, pitch);
|
||||
dump_content(file, frame, width, height, pitch, bgr24);
|
||||
|
||||
fclose(file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include <stdint.h>
|
||||
#include "boolean.h"
|
||||
|
||||
bool screenshot_dump(const char *folder, const uint16_t *frame,
|
||||
unsigned width, unsigned height, unsigned pitch);
|
||||
bool screenshot_dump(const char *folder, const void *frame,
|
||||
unsigned width, unsigned height, int pitch, bool bgr24);
|
||||
|
||||
#endif
|
||||
|
@ -490,6 +490,7 @@ bool config_load_file(const char *path)
|
||||
else
|
||||
RARCH_WARN("savefile_directory is not a directory, ignoring ....\n");
|
||||
}
|
||||
|
||||
if (!g_extern.has_set_state_path && config_get_array(conf, "savestate_directory", tmp_str, sizeof(tmp_str)))
|
||||
{
|
||||
if (path_is_directory(tmp_str))
|
||||
@ -501,6 +502,8 @@ bool config_load_file(const char *path)
|
||||
RARCH_WARN("savestate_directory is not a directory, ignoring ...\n");
|
||||
}
|
||||
|
||||
CONFIG_GET_STRING(system_directory, "system_directory");
|
||||
|
||||
config_read_keybinds_conf(conf);
|
||||
|
||||
config_file_free(conf);
|
||||
|
Loading…
x
Reference in New Issue
Block a user