From 05c37bd39fb27102055dac54b213af406adb0dd4 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Wed, 4 Jan 2017 02:07:19 -0500 Subject: [PATCH] initial GDI driver skeleton --- Makefile.common | 5 + config.def.h | 4 + configuration.c | 4 + gfx/common/gdi_common.h | 26 ++ gfx/common/win32_common.cpp | 1 + gfx/drivers/gdi_gfx.c | 304 ++++++++++++++++++++++ gfx/drivers_context/gdi_ctx.cpp | 325 ++++++++++++++++++++++++ gfx/drivers_font/gdi_font.c | 133 ++++++++++ gfx/font_driver.c | 34 +++ gfx/font_driver.h | 4 +- gfx/video_context_driver.c | 3 + gfx/video_context_driver.h | 1 + gfx/video_driver.c | 3 + gfx/video_driver.h | 1 + griffin/griffin.c | 7 + menu/drivers_display/menu_display_gdi.c | 101 ++++++++ menu/menu_display.c | 7 + menu/menu_display.h | 4 +- 18 files changed, 965 insertions(+), 2 deletions(-) create mode 100644 gfx/common/gdi_common.h create mode 100644 gfx/drivers/gdi_gfx.c create mode 100644 gfx/drivers_context/gdi_ctx.cpp create mode 100644 gfx/drivers_font/gdi_font.c create mode 100644 menu/drivers_display/menu_display_gdi.c diff --git a/Makefile.common b/Makefile.common index 15374c1dca..e6b455f8a3 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1164,6 +1164,11 @@ ifneq ($(findstring Win32,$(OS)),) input/drivers_keyboard/keyboard_event_win32.o \ gfx/common/win32_common.o \ frontend/drivers/platform_win32.o + + OBJ += gfx/drivers/gdi_gfx.o \ + gfx/drivers_context/gdi_ctx.o \ + gfx/drivers_font/gdi_font.o \ + menu/drivers_display/menu_display_gdi.o endif ifeq ($(HAVE_AVFOUNDATION), 1) diff --git a/config.def.h b/config.def.h index dc5b14d610..28ed46adef 100644 --- a/config.def.h +++ b/config.def.h @@ -51,6 +51,8 @@ enum video_driver_enum VIDEO_EXYNOS, VIDEO_SUNXI, VIDEO_DISPMANX, + VIDEO_CACA, + VIDEO_GDI, VIDEO_NULL }; @@ -209,6 +211,8 @@ enum record_driver_enum #define VIDEO_DEFAULT_DRIVER VIDEO_SDL #elif defined(HAVE_SDL2) #define VIDEO_DEFAULT_DRIVER VIDEO_SDL2 +#elif defined(_WIN32) && !defined(_XBOX) +#define VIDEO_DEFAULT_DRIVER VIDEO_GDI #elif defined(HAVE_DYLIB) && !defined(ANDROID) #define VIDEO_DEFAULT_DRIVER VIDEO_EXT #else diff --git a/configuration.c b/configuration.c index 00edc333da..76d2271c77 100644 --- a/configuration.c +++ b/configuration.c @@ -310,6 +310,10 @@ const char *config_get_default_video(void) return "dispmanx"; case VIDEO_SUNXI: return "sunxi"; + case VIDEO_CACA: + return "caca"; + case VIDEO_GDI: + return "gdi"; case VIDEO_NULL: break; } diff --git a/gfx/common/gdi_common.h b/gfx/common/gdi_common.h new file mode 100644 index 0000000000..31334cfb74 --- /dev/null +++ b/gfx/common/gdi_common.h @@ -0,0 +1,26 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * copyright (c) 2011-2015 - Daniel De Matteis + * copyright (c) 2016 - Brad Parker + * + * 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 . + */ + +#ifndef __GDI_COMMON_H +#define __GDI_COMMON_H + +typedef struct gdi +{ + bool test; +} gdi_t; + +#endif diff --git a/gfx/common/win32_common.cpp b/gfx/common/win32_common.cpp index 2179dd7d17..7a8da43e08 100644 --- a/gfx/common/win32_common.cpp +++ b/gfx/common/win32_common.cpp @@ -57,6 +57,7 @@ LRESULT win32_menu_loop(HWND owner, WPARAM wparam); extern "C" bool dinput_handle_message(void *dinput, UINT message, WPARAM wParam, LPARAM lParam); +extern void *dinput_gdi; extern void *dinput_wgl; extern void *dinput; diff --git a/gfx/drivers/gdi_gfx.c b/gfx/drivers/gdi_gfx.c new file mode 100644 index 0000000000..2009aa0c0b --- /dev/null +++ b/gfx/drivers/gdi_gfx.c @@ -0,0 +1,304 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2016 - Daniel De Matteis + * Copyright (C) 2016 - Brad Parker + * + * 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 . + */ + +#include + +#include "../../driver.h" +#include "../../configuration.h" +#include "../../verbosity.h" +#include "../../menu/menu_driver.h" +#include "../common/gdi_common.h" + +static unsigned char *gdi_menu_frame = NULL; +static unsigned gdi_menu_width = 0; +static unsigned gdi_menu_height = 0; +static unsigned gdi_menu_pitch = 0; +static unsigned gdi_video_width = 0; +static unsigned gdi_video_height = 0; +static unsigned gdi_video_pitch = 0; +static bool gdi_rgb32 = 0; + +static void gdi_gfx_free(void *data); + +static void gdi_gfx_create() +{ + if(!gdi_video_width || !gdi_video_height) + { + printf("***** GDI: no width or height!\n"); + } + + //video_driver_set_size(&gdi_video_width, &gdi_video_height); +} + +static void *gdi_gfx_init(const video_info_t *video, + const input_driver_t **input, void **input_data) +{ + settings_t *settings = config_get_ptr(); + gdi_t *gdi = (gdi_t*)calloc(1, sizeof(*gdi)); + + *input = NULL; + *input_data = NULL; + + gdi_video_width = video->width; + gdi_video_height = video->height; + gdi_rgb32 = video->rgb32; + + if (video->rgb32) + gdi_video_pitch = video->width * 4; + else + gdi_video_pitch = video->width * 2; + + gdi_gfx_create(); + + if (settings->video.font_enable) + font_driver_init_osd(NULL, false, FONT_DRIVER_RENDER_GDI); + + return gdi; +} + +static bool gdi_gfx_frame(void *data, const void *frame, + unsigned frame_width, unsigned frame_height, uint64_t frame_count, + unsigned pitch, const char *msg) +{ + const void *frame_to_copy = frame; + unsigned width = 0; + unsigned height = 0; + bool draw = true; + + (void)data; + (void)frame; + (void)frame_width; + (void)frame_height; + (void)pitch; + (void)msg; + + if (!frame || !frame_width || !frame_height) + return true; + + if (gdi_video_width != frame_width || gdi_video_height != frame_height || gdi_video_pitch != pitch) + { + if (frame_width > 4 && frame_height > 4) + { + gdi_video_width = frame_width; + gdi_video_height = frame_height; + gdi_video_pitch = pitch; + gdi_gfx_free(NULL); + gdi_gfx_create(); + } + } + + if (gdi_menu_frame) + frame_to_copy = gdi_menu_frame; + + //width = gdi_get_canvas_width(gdi_cv); + //height = gdi_get_canvas_height(gdi_cv); + width = frame_width; + height = frame_height; + + if (frame_to_copy == frame && frame_width == 4 && frame_height == 4 && (frame_width < width && frame_height < height)) + draw = false; + +#ifdef HAVE_MENU + menu_driver_ctl(RARCH_MENU_CTL_FRAME, NULL); +#endif + + if (msg) + font_driver_render_msg(NULL, msg, NULL); + + if (draw) + { + /*gdi_dither_bitmap(gdi_cv, 0, 0, + width, + height, + gdi_dither, frame_to_copy);*/ + } + + return true; +} + +static void gdi_gfx_set_nonblock_state(void *data, bool toggle) +{ + (void)data; + (void)toggle; +} + +static bool gdi_gfx_alive(void *data) +{ + (void)data; + video_driver_set_size(&gdi_video_width, &gdi_video_height); + return true; +} + +static bool gdi_gfx_focus(void *data) +{ + (void)data; + return true; +} + +static bool gdi_gfx_suppress_screensaver(void *data, bool enable) +{ + (void)data; + (void)enable; + return false; +} + +static bool gdi_gfx_has_windowed(void *data) +{ + (void)data; + return true; +} + +static void gdi_gfx_free(void *data) +{ + (void)data; + + if (gdi_menu_frame) + { + free(gdi_menu_frame); + gdi_menu_frame = NULL; + } +} + +static bool gdi_gfx_set_shader(void *data, + enum rarch_shader_type type, const char *path) +{ + (void)data; + (void)type; + (void)path; + + return false; +} + +static void gdi_gfx_set_rotation(void *data, + unsigned rotation) +{ + (void)data; + (void)rotation; +} + +static void gdi_gfx_viewport_info(void *data, + struct video_viewport *vp) +{ + (void)data; + (void)vp; +} + +static bool gdi_gfx_read_viewport(void *data, uint8_t *buffer) +{ + (void)data; + (void)buffer; + + return true; +} + +static void gdi_set_texture_frame(void *data, + const void *frame, bool rgb32, unsigned width, unsigned height, + float alpha) +{ + unsigned pitch = width * 2; + + if (rgb32) + pitch = width * 4; + + if (gdi_menu_frame) + { + free(gdi_menu_frame); + gdi_menu_frame = NULL; + } + + if (!gdi_menu_frame || gdi_menu_width != width || gdi_menu_height != height || gdi_menu_pitch != pitch) + if (pitch && height) + gdi_menu_frame = (unsigned char*)malloc(pitch * height); + + if (gdi_menu_frame && frame && pitch && height) + memcpy(gdi_menu_frame, frame, pitch * height); +} + +static void gdi_set_osd_msg(void *data, const char *msg, + const struct font_params *params, void *font) +{ + font_driver_render_msg(font, msg, params); +} + +static const video_poke_interface_t gdi_poke_interface = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +#ifdef HAVE_FBO + NULL, +#else + NULL, +#endif + NULL, + NULL, + NULL, +#if defined(HAVE_MENU) + gdi_set_texture_frame, + NULL, + gdi_set_osd_msg, + NULL, +#else + NULL, + NULL, + NULL, + NULL, +#endif + + NULL, +#ifdef HAVE_MENU + NULL, +#endif +}; + +static void gdi_gfx_get_poke_interface(void *data, + const video_poke_interface_t **iface) +{ + (void)data; + *iface = &gdi_poke_interface; +} + +static void gdi_gfx_set_viewport(void *data, unsigned viewport_width, + unsigned viewport_height, bool force_full, bool allow_rotate) +{ +} + +video_driver_t video_gdi = { + gdi_gfx_init, + gdi_gfx_frame, + gdi_gfx_set_nonblock_state, + gdi_gfx_alive, + gdi_gfx_focus, + gdi_gfx_suppress_screensaver, + gdi_gfx_has_windowed, + gdi_gfx_set_shader, + gdi_gfx_free, + "gdi", + gdi_gfx_set_viewport, + gdi_gfx_set_rotation, + gdi_gfx_viewport_info, + gdi_gfx_read_viewport, + NULL, /* read_frame_raw */ + +#ifdef HAVE_OVERLAY + NULL, /* overlay_interface */ +#endif + gdi_gfx_get_poke_interface, +}; diff --git a/gfx/drivers_context/gdi_ctx.cpp b/gfx/drivers_context/gdi_ctx.cpp new file mode 100644 index 0000000000..4ea4baadca --- /dev/null +++ b/gfx/drivers_context/gdi_ctx.cpp @@ -0,0 +1,325 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2016 - Daniel De Matteis + * Copyright (C) 2016 - Brad Parker + * + * 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 . + */ + +/* Win32/GDI context. */ + +/* necessary for mingw32 multimon defines: */ +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0500 //_WIN32_WINNT_WIN2K +#endif + +#include +#include + +#include +#include + +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif + +#include "../../configuration.h" +#include "../../dynamic.h" +#include "../../runloop.h" +#include "../../verbosity.h" +#include "../video_context_driver.h" + +#include "../common/win32_common.h" + +static HDC win32_hdc; + +static unsigned win32_major = 0; +static unsigned win32_minor = 0; +static unsigned win32_interval = 0; +static enum gfx_ctx_api win32_api = GFX_CTX_NONE; + +void *dinput_gdi; + +/*static void setup_pixel_format(HDC hdc) +{ + PIXELFORMATDESCRIPTOR pfd = {0}; + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 32; + pfd.cDepthBits = 0; + pfd.cStencilBits = 0; + pfd.iLayerType = PFD_MAIN_PLANE; + + SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd); +}*/ + +static void gfx_ctx_gdi_check_window(void *data, bool *quit, + bool *resize, unsigned *width, unsigned *height, unsigned frame_count) +{ + win32_check_window(quit, resize, width, height); +} + +static bool gfx_ctx_gdi_set_resize(void *data, + unsigned width, unsigned height) +{ + (void)data; + (void)width; + (void)height; + + switch (win32_api) + { + case GFX_CTX_NONE: + default: + break; + } + + return false; +} + +static void gfx_ctx_gdi_update_window_title(void *data) +{ + char buf[128]; + char buf_fps[128]; + settings_t *settings = config_get_ptr(); + const ui_window_t *window = ui_companion_driver_get_window_ptr(); + + buf[0] = buf_fps[0] = '\0'; + + if (window && video_monitor_get_fps(buf, sizeof(buf), + buf_fps, sizeof(buf_fps))) + window->set_title(&main_window, buf); + if (settings->fps_show) + runloop_msg_queue_push(buf_fps, 1, 1, false); +} + +static void gfx_ctx_gdi_get_video_size(void *data, + unsigned *width, unsigned *height) +{ + (void)data; + HWND window = win32_get_window(); + + if (!window) + { + RECT mon_rect; + MONITORINFOEX current_mon; + unsigned mon_id = 0; + HMONITOR hm_to_use = NULL; + + win32_monitor_info(¤t_mon, &hm_to_use, &mon_id); + mon_rect = current_mon.rcMonitor; + *width = mon_rect.right - mon_rect.left; + *height = mon_rect.bottom - mon_rect.top; + } + else + { + *width = g_resize_width; + *height = g_resize_height; + } +} + +static void *gfx_ctx_gdi_init(void *video_driver) +{ + WNDCLASSEX wndclass = {0}; + + (void)video_driver; + + if (g_inited) + return NULL; + + win32_window_reset(); + win32_monitor_init(); + + wndclass.lpfnWndProc = WndProcGL; + if (!win32_window_init(&wndclass, true, NULL)) + return NULL; + + switch (win32_api) + { + case GFX_CTX_NONE: + default: + break; + } + + return (void*)"gdi"; +} + +static void gfx_ctx_gdi_destroy(void *data) +{ + HWND window = win32_get_window(); + + (void)data; + + switch (win32_api) + { + case GFX_CTX_NONE: + default: + break; + } + + if (window && win32_hdc) + { + ReleaseDC(window, win32_hdc); + win32_hdc = NULL; + } + + if (window) + { + win32_monitor_from_window(); + win32_destroy_window(); + } + + if (g_restore_desktop) + { + win32_monitor_get_info(); + g_restore_desktop = false; + } + + g_inited = false; + win32_major = 0; + win32_minor = 0; +} + +static bool gfx_ctx_gdi_set_video_mode(void *data, + unsigned width, unsigned height, + bool fullscreen) +{ + if (!win32_set_video_mode(NULL, width, height, fullscreen)) + { + RARCH_ERR("[GDI]: win32_set_video_mode failed.\n"); + goto error; + } + + switch (win32_api) + { + case GFX_CTX_NONE: + default: + break; + } + + return true; + +error: + gfx_ctx_gdi_destroy(data); + return false; +} + + +static void gfx_ctx_gdi_input_driver(void *data, + const input_driver_t **input, void **input_data) +{ + (void)data; + + dinput_gdi = input_dinput.init(); + + *input = dinput_gdi ? &input_dinput : NULL; + *input_data = dinput_gdi; +} + +static bool gfx_ctx_gdi_has_focus(void *data) +{ + return win32_has_focus(); +} + +static bool gfx_ctx_gdi_suppress_screensaver(void *data, bool enable) +{ + return win32_suppress_screensaver(data, enable); +} + +static bool gfx_ctx_gdi_has_windowed(void *data) +{ + (void)data; + + return true; +} + +static bool gfx_ctx_gdi_get_metrics(void *data, + enum display_metric_types type, float *value) +{ + return win32_get_metrics(data, type, value); +} + +static bool gfx_ctx_gdi_bind_api(void *data, + enum gfx_ctx_api api, unsigned major, unsigned minor) +{ + (void)data; + + win32_major = major; + win32_minor = minor; + win32_api = api; + + return true; +} + +static void gfx_ctx_gdi_show_mouse(void *data, bool state) +{ + (void)data; + win32_show_cursor(state); +} + +static void gfx_ctx_gdi_swap_interval(void *data, unsigned interval) +{ + (void)data; + (void)interval; +} + +static void gfx_ctx_gdi_set_flags(void *data, uint32_t flags) +{ + (void)data; + (void)flags; +} + +static uint32_t gfx_ctx_gdi_get_flags(void *data) +{ + uint32_t flags = 0; + BIT32_SET(flags, GFX_CTX_FLAGS_NONE); + return flags; +} + +static void gfx_ctx_gdi_swap_buffers(void *data) +{ + (void)data; +} + +const gfx_ctx_driver_t gfx_ctx_gdi = { + gfx_ctx_gdi_init, + gfx_ctx_gdi_destroy, + gfx_ctx_gdi_bind_api, + gfx_ctx_gdi_swap_interval, + gfx_ctx_gdi_set_video_mode, + gfx_ctx_gdi_get_video_size, + NULL, /* get_video_output_size */ + NULL, /* get_video_output_prev */ + NULL, /* get_video_output_next */ + gfx_ctx_gdi_get_metrics, + NULL, + gfx_ctx_gdi_update_window_title, + gfx_ctx_gdi_check_window, + gfx_ctx_gdi_set_resize, + gfx_ctx_gdi_has_focus, + gfx_ctx_gdi_suppress_screensaver, + gfx_ctx_gdi_has_windowed, + gfx_ctx_gdi_swap_buffers, + gfx_ctx_gdi_input_driver, + NULL, + NULL, + NULL, + gfx_ctx_gdi_show_mouse, + "gdi", + gfx_ctx_gdi_get_flags, + gfx_ctx_gdi_set_flags, + NULL, + NULL, + NULL +}; + diff --git a/gfx/drivers_font/gdi_font.c b/gfx/drivers_font/gdi_font.c new file mode 100644 index 0000000000..2ca5c627ec --- /dev/null +++ b/gfx/drivers_font/gdi_font.c @@ -0,0 +1,133 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2016 - Daniel De Matteis + * Copyright (C) 2016 - Brad Parker + * + * 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 . + */ + +#include +#include + +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif + +#include "../font_driver.h" +#include "../../configuration.h" +#include "../../verbosity.h" +#include "../common/gdi_common.h" + +typedef struct +{ + const font_renderer_driver_t *gdi_font_driver; + void *gdi_font_data; + gdi_t *gdi; +} gdi_raster_t; + +static void *gdi_init_font(void *data, + const char *font_path, float font_size) +{ + gdi_raster_t *font = (gdi_raster_t*)calloc(1, sizeof(*font)); + + if (!font) + return NULL; + + font->gdi = (gdi_t*)data; + + font_size = 1; + + if (!font_renderer_create_default((const void**)&font->gdi_font_driver, + &font->gdi_font_data, font_path, font_size)) + { + RARCH_WARN("Couldn't initialize font renderer.\n"); + return NULL; + } + + return font; +} + +static void gdi_render_free_font(void *data) +{ + +} + +static int gdi_get_message_width(void *data, const char *msg, + unsigned msg_len, float scale) +{ + return 0; +} + +static const struct font_glyph *gdi_font_get_glyph( + void *data, uint32_t code) +{ + return NULL; +} + +static void gdi_render_msg(void *data, const char *msg, + const void *userdata) +{ + gdi_raster_t *font = (gdi_raster_t*)data; + float x, y; + unsigned width = 0, height = 0; + unsigned newX, newY; + settings_t *settings = config_get_ptr(); + const struct font_params *params = (const struct font_params*)userdata; + + if (!font || string_is_empty(msg)) + return; + + if (params) + { + x = params->x; + y = params->y; + } + else + { + x = settings->video.msg_pos_x; + y = settings->video.msg_pos_y; + } + + if (!font->gdi) + return; + + newX = x * width; + newY = height - (y * height); + + if (strlen(msg) + newX > width) + newX -= strlen(msg) + newX - width; + + //gdi_put_str(*font->gdi->gdi_cv, newX, newY, msg); + + //gdi_refresh_display(*font->gdi->gdi_display); +} + +static void gdi_font_flush_block(void* data) +{ + (void)data; +} + +static void gdi_font_bind_block(void* data, void* userdata) +{ + (void)data; +} + +font_renderer_t gdi_font = { + gdi_init_font, + gdi_render_free_font, + gdi_render_msg, + "gdi font", + gdi_font_get_glyph, /* get_glyph */ + gdi_font_bind_block, /* bind_block */ + gdi_font_flush_block, /* flush */ + gdi_get_message_width /* get_message_width */ +}; diff --git a/gfx/font_driver.c b/gfx/font_driver.c index 9b6900121f..5fd85f93d0 100644 --- a/gfx/font_driver.c +++ b/gfx/font_driver.c @@ -178,6 +178,35 @@ static bool caca_font_init_first( } #endif +#if defined(_WIN32) && !defined(_XBOX) +static const font_renderer_t *gdi_font_backends[] = { + &gdi_font, + NULL, +}; + +static bool gdi_font_init_first( + const void **font_driver, void **font_handle, + void *video_data, const char *font_path, float font_size) +{ + unsigned i; + + for (i = 0; gdi_font_backends[i]; i++) + { + void *data = gdi_font_backends[i]->init( + video_data, font_path, font_size); + + if (!data) + continue; + + *font_driver = gdi_font_backends[i]; + *font_handle = data; + return true; + } + + return false; +} +#endif + #ifdef HAVE_VULKAN static const font_renderer_t *vulkan_font_backends[] = { &vulkan_raster_font, @@ -301,6 +330,11 @@ static bool font_init_first( case FONT_DRIVER_RENDER_CACA: return caca_font_init_first(font_driver, font_handle, video_data, font_path, font_size); +#endif +#if defined(_WIN32) && !defined(_XBOX) + case FONT_DRIVER_RENDER_GDI: + return gdi_font_init_first(font_driver, font_handle, + video_data, font_path, font_size); #endif case FONT_DRIVER_RENDER_DONT_CARE: /* TODO/FIXME - lookup graphics driver's 'API' */ diff --git a/gfx/font_driver.h b/gfx/font_driver.h index 6d3e374780..f2484db51f 100644 --- a/gfx/font_driver.h +++ b/gfx/font_driver.h @@ -32,7 +32,8 @@ enum font_driver_render_api FONT_DRIVER_RENDER_VITA2D, FONT_DRIVER_RENDER_CTR, FONT_DRIVER_RENDER_VULKAN_API, - FONT_DRIVER_RENDER_CACA + FONT_DRIVER_RENDER_CACA, + FONT_DRIVER_RENDER_GDI }; enum text_alignment @@ -164,6 +165,7 @@ extern font_renderer_t vita2d_vita_font; extern font_renderer_t ctr_font; extern font_renderer_t vulkan_raster_font; extern font_renderer_t caca_font; +extern font_renderer_t gdi_font; extern font_renderer_driver_t stb_font_renderer; extern font_renderer_driver_t stb_unicode_font_renderer; diff --git a/gfx/video_context_driver.c b/gfx/video_context_driver.c index f1b114ee61..59e223224b 100644 --- a/gfx/video_context_driver.c +++ b/gfx/video_context_driver.c @@ -88,6 +88,9 @@ static const gfx_ctx_driver_t *gfx_ctx_drivers[] = { #endif #if defined(HAVE_VULKAN) && defined(HAVE_VULKAN_DISPLAY) &gfx_ctx_khr_display, +#endif +#if defined(_WIN32) && !defined(_XBOX) + &gfx_ctx_gdi, #endif &gfx_ctx_null, NULL diff --git a/gfx/video_context_driver.h b/gfx/video_context_driver.h index 3b78e72a0a..63426451e7 100644 --- a/gfx/video_context_driver.h +++ b/gfx/video_context_driver.h @@ -249,6 +249,7 @@ extern const gfx_ctx_driver_t gfx_ctx_cocoagl; extern const gfx_ctx_driver_t gfx_ctx_emscripten; extern const gfx_ctx_driver_t gfx_ctx_opendingux_fbdev; extern const gfx_ctx_driver_t gfx_ctx_khr_display; +extern const gfx_ctx_driver_t gfx_ctx_gdi; extern const gfx_ctx_driver_t gfx_ctx_null; /** diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 30148ebd0c..ef7380267c 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -227,6 +227,9 @@ static const video_driver_t *video_drivers[] = { #ifdef HAVE_XSHM &video_xshm, #endif +#if defined(_WIN32) && !defined(_XBOX) + &video_gdi, +#endif #ifdef HAVE_CACA &video_caca, #endif diff --git a/gfx/video_driver.h b/gfx/video_driver.h index e6f83c1a21..6efb630b8b 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -563,6 +563,7 @@ extern video_driver_t video_sunxi; extern video_driver_t video_drm; extern video_driver_t video_xshm; extern video_driver_t video_caca; +extern video_driver_t video_gdi; extern video_driver_t video_null; extern const void *frame_cache_data; diff --git a/griffin/griffin.c b/griffin/griffin.c index 041d9b92c9..bd09df0a0a 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -402,6 +402,9 @@ FONTS #include "../gfx/drivers_font/caca_font.c" #endif +#if defined(_WIN32) && !defined(_XBOX) +#include "../gfx/drivers_font/gdi_font.c" +#endif #if defined(HAVE_VULKAN) #include "../gfx/drivers_font/vulkan_raster_font.c" @@ -994,6 +997,10 @@ MENU #include "../menu/drivers_display/menu_display_caca.c" #endif +#if defined(_WIN32) && !defined(_XBOX) +#include "../menu/drivers_display/menu_display_gdi.c" +#endif + #endif diff --git a/menu/drivers_display/menu_display_gdi.c b/menu/drivers_display/menu_display_gdi.c new file mode 100644 index 0000000000..18c804c22d --- /dev/null +++ b/menu/drivers_display/menu_display_gdi.c @@ -0,0 +1,101 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2016 - Daniel De Matteis + * Copyright (C) 2016 - Brad Parker + * + * 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 . + */ + +#include + +#include +#include + +#include "../../config.def.h" +#include "../../gfx/font_driver.h" +#include "../../gfx/video_context_driver.h" + +#include "../menu_display.h" + +static void *menu_display_gdi_get_default_mvp(void) +{ + return NULL; +} + +static void menu_display_gdi_blend_begin(void) +{ +} + +static void menu_display_gdi_blend_end(void) +{ +} + +static void menu_display_gdi_draw(void *data) +{ + (void)data; +} + +static void menu_display_gdi_draw_pipeline(void *data) +{ + (void)data; +} + +static void menu_display_gdi_viewport(void *data) +{ + (void)data; +} + +static void menu_display_gdi_restore_clear_color(void) +{ +} + +static void menu_display_gdi_clear_color(menu_display_ctx_clearcolor_t *clearcolor) +{ + (void)clearcolor; +} + +static bool menu_display_gdi_font_init_first( + void **font_handle, void *video_data, + const char *font_path, float font_size) +{ + font_data_t **handle = (font_data_t**)font_handle; + *handle = font_driver_init_first(video_data, + font_path, font_size, true, FONT_DRIVER_RENDER_GDI); + return *handle; +} + +static const float *menu_display_gdi_get_default_vertices(void) +{ + static float dummy[16] = {0.0f}; + return &dummy[0]; +} + +static const float *menu_display_gdi_get_default_tex_coords(void) +{ + static float dummy[16] = {0.0f}; + return &dummy[0]; +} + +menu_display_ctx_driver_t menu_display_ctx_gdi = { + menu_display_gdi_draw, + menu_display_gdi_draw_pipeline, + menu_display_gdi_viewport, + menu_display_gdi_blend_begin, + menu_display_gdi_blend_end, + menu_display_gdi_restore_clear_color, + menu_display_gdi_clear_color, + menu_display_gdi_get_default_mvp, + menu_display_gdi_get_default_vertices, + menu_display_gdi_get_default_tex_coords, + menu_display_gdi_font_init_first, + MENU_VIDEO_DRIVER_GDI, + "menu_display_gdi", +}; diff --git a/menu/menu_display.c b/menu/menu_display.c index d2eaf151e0..6e45e1fbc7 100644 --- a/menu/menu_display.c +++ b/menu/menu_display.c @@ -82,6 +82,9 @@ static menu_display_ctx_driver_t *menu_display_ctx_drivers[] = { #endif #ifdef HAVE_CACA &menu_display_ctx_caca, +#endif +#if defined(_WIN32) && !defined(_XBOX) + &menu_display_ctx_gdi, #endif &menu_display_ctx_null, NULL, @@ -140,6 +143,10 @@ static bool menu_display_check_compatibility( if (string_is_equal(video_driver, "caca")) return true; break; + case MENU_VIDEO_DRIVER_GDI: + if (string_is_equal(video_driver, "gdi")) + return true; + break; } return false; diff --git a/menu/menu_display.h b/menu/menu_display.h index d58c00df12..6e7faa5c42 100644 --- a/menu/menu_display.h +++ b/menu/menu_display.h @@ -95,7 +95,8 @@ enum menu_display_driver_type MENU_VIDEO_DRIVER_DIRECT3D, MENU_VIDEO_DRIVER_VITA2D, MENU_VIDEO_DRIVER_CTR, - MENU_VIDEO_DRIVER_CACA + MENU_VIDEO_DRIVER_CACA, + MENU_VIDEO_DRIVER_GDI }; typedef struct menu_display_ctx_clearcolor @@ -294,6 +295,7 @@ extern menu_display_ctx_driver_t menu_display_ctx_d3d; extern menu_display_ctx_driver_t menu_display_ctx_vita2d; extern menu_display_ctx_driver_t menu_display_ctx_ctr; extern menu_display_ctx_driver_t menu_display_ctx_caca; +extern menu_display_ctx_driver_t menu_display_ctx_gdi; extern menu_display_ctx_driver_t menu_display_ctx_null; RETRO_END_DECLS