mirror of
https://github.com/libretro/RetroArch.git
synced 2025-02-16 15:39:54 +00:00
Merge pull request #7403 from bparker06/gdi_imp
win32: Improvements to GDI drivers
This commit is contained in:
commit
1fae526337
@ -27,6 +27,7 @@ typedef struct gdi
|
||||
#endif
|
||||
HDC winDC;
|
||||
HDC memDC;
|
||||
HDC texDC;
|
||||
HBITMAP bmp;
|
||||
HBITMAP bmp_old;
|
||||
unsigned video_width;
|
||||
@ -35,4 +36,17 @@ typedef struct gdi
|
||||
unsigned screen_height;
|
||||
} gdi_t;
|
||||
|
||||
typedef struct gdi_texture
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int active_width;
|
||||
int active_height;
|
||||
|
||||
enum texture_filter_type type;
|
||||
void* data;
|
||||
HBITMAP bmp;
|
||||
HBITMAP bmp_old;
|
||||
} gdi_texture_t;
|
||||
|
||||
#endif
|
||||
|
@ -837,18 +837,18 @@ LRESULT CALLBACK WndProcGDI(HWND hwnd, UINT message,
|
||||
/* draw menu contents behind a gradient background */
|
||||
if (gdi && gdi->memDC)
|
||||
{
|
||||
RECT rect;
|
||||
/*RECT rect;
|
||||
HBRUSH brush = CreateSolidBrush(RGB(1,81,127));
|
||||
|
||||
GetClientRect(hwnd, &rect);
|
||||
GetClientRect(hwnd, &rect);*/
|
||||
|
||||
StretchBlt(gdi->winDC,
|
||||
0, 0,
|
||||
gdi->screen_width, gdi->screen_height,
|
||||
gdi->memDC, 0, 0, gdi->video_width, gdi->video_height, SRCCOPY);
|
||||
|
||||
FillRect(gdi->memDC, &rect, brush);
|
||||
DeleteObject(brush);
|
||||
/*FillRect(gdi->memDC, &rect, brush);
|
||||
DeleteObject(brush);*/
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <formats/image.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
@ -192,6 +193,9 @@ static bool gdi_gfx_frame(void *data, const void *frame,
|
||||
HWND hwnd = win32_get_window();
|
||||
BITMAPINFO *info;
|
||||
|
||||
/* FIXME */
|
||||
video_info->xmb_shadows_enable = false;
|
||||
|
||||
if (!frame || !frame_width || !frame_height)
|
||||
return true;
|
||||
|
||||
@ -414,9 +418,16 @@ static void gdi_gfx_free(void *data)
|
||||
if (!gdi)
|
||||
return;
|
||||
|
||||
if (gdi->bmp)
|
||||
DeleteObject(gdi->bmp);
|
||||
|
||||
if (gdi->texDC)
|
||||
{
|
||||
DeleteDC(gdi->texDC);
|
||||
gdi->texDC = 0;
|
||||
}
|
||||
if (gdi->memDC)
|
||||
{
|
||||
DeleteObject(gdi->bmp);
|
||||
DeleteDC(gdi->memDC);
|
||||
gdi->memDC = 0;
|
||||
}
|
||||
@ -532,12 +543,61 @@ static void gdi_set_video_mode(void *data, unsigned width, unsigned height,
|
||||
video_context_driver_set_video_mode(&mode);
|
||||
}
|
||||
|
||||
static uintptr_t gdi_load_texture(void *video_data, void *data,
|
||||
bool threaded, enum texture_filter_type filter_type)
|
||||
{
|
||||
struct texture_image *image = (struct texture_image*)data;
|
||||
int size = image->width * image->height * sizeof(uint32_t);
|
||||
gdi_texture_t *texture = NULL;
|
||||
void *tmpdata = NULL;
|
||||
|
||||
if (!image || image->width > 2048 || image->height > 2048)
|
||||
return 0;
|
||||
|
||||
texture = calloc(1, sizeof(*texture));
|
||||
texture->width = image->width;
|
||||
texture->height = image->height;
|
||||
texture->active_width = image->width;
|
||||
texture->active_height = image->height;
|
||||
texture->data = calloc(1, texture->width * texture->height * sizeof(uint32_t));
|
||||
texture->type = filter_type;
|
||||
|
||||
if (!texture->data)
|
||||
{
|
||||
free(texture);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(texture->data, image->pixels, texture->width * texture->height * sizeof(uint32_t));
|
||||
|
||||
return (uintptr_t)texture;
|
||||
}
|
||||
|
||||
static void gdi_unload_texture(void *data, uintptr_t handle)
|
||||
{
|
||||
struct gdi_texture *texture = (struct gdi_texture*)handle;
|
||||
|
||||
if (!texture)
|
||||
return;
|
||||
|
||||
if (texture->data)
|
||||
free(texture->data);
|
||||
|
||||
if (texture->bmp)
|
||||
{
|
||||
DeleteObject(texture->bmp);
|
||||
texture->bmp = NULL;
|
||||
}
|
||||
|
||||
free(texture);
|
||||
}
|
||||
|
||||
static const video_poke_interface_t gdi_poke_interface = {
|
||||
NULL, /* get_flags */
|
||||
NULL, /* set_coords */
|
||||
NULL, /* set_mvp */
|
||||
NULL,
|
||||
NULL,
|
||||
gdi_load_texture,
|
||||
gdi_unload_texture,
|
||||
gdi_set_video_mode,
|
||||
win32_get_refresh_rate,
|
||||
NULL,
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string/stdstring.h>
|
||||
#include <encodings/utf.h>
|
||||
#include <lists/string_list.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
@ -85,65 +86,116 @@ static void gdi_render_msg(
|
||||
void *data, const char *msg,
|
||||
const struct font_params *params)
|
||||
{
|
||||
float x, y, scale;
|
||||
unsigned newX, newY, len;
|
||||
float x, y, scale, drop_mod, alpha, drop_alpha;
|
||||
int i, drop_x, drop_y, msg_strlen;
|
||||
unsigned newX, newY, newDropX, newDropY;
|
||||
unsigned align;
|
||||
unsigned red;
|
||||
unsigned green;
|
||||
unsigned blue;
|
||||
unsigned red, green, blue;
|
||||
unsigned drop_red, drop_green, drop_blue;
|
||||
gdi_raster_t *font = (gdi_raster_t*)data;
|
||||
unsigned width = video_info->width;
|
||||
unsigned height = video_info->height;
|
||||
SIZE textSize = {0};
|
||||
struct string_list *msg_list = NULL;
|
||||
|
||||
if (!font || string_is_empty(msg) || !font->gdi)
|
||||
return;
|
||||
|
||||
if (params)
|
||||
{
|
||||
x = params->x;
|
||||
y = params->y;
|
||||
scale = params->scale;
|
||||
align = params->text_align;
|
||||
x = params->x;
|
||||
y = params->y;
|
||||
drop_x = params->drop_x;
|
||||
drop_y = params->drop_y;
|
||||
drop_mod = params->drop_mod;
|
||||
drop_alpha = params->drop_alpha;
|
||||
scale = params->scale;
|
||||
align = params->text_align;
|
||||
|
||||
red = FONT_COLOR_GET_RED(params->color);
|
||||
green = FONT_COLOR_GET_GREEN(params->color);
|
||||
blue = FONT_COLOR_GET_BLUE(params->color);
|
||||
red = FONT_COLOR_GET_RED(params->color);
|
||||
green = FONT_COLOR_GET_GREEN(params->color);
|
||||
blue = FONT_COLOR_GET_BLUE(params->color);
|
||||
alpha = FONT_COLOR_GET_ALPHA(params->color);
|
||||
}
|
||||
else
|
||||
{
|
||||
x = video_info->font_msg_pos_x;
|
||||
y = video_info->font_msg_pos_y;
|
||||
scale = 1.0f;
|
||||
align = TEXT_ALIGN_LEFT;
|
||||
red = video_info->font_msg_color_r * 255.0f;
|
||||
green = video_info->font_msg_color_g * 255.0f;
|
||||
blue = video_info->font_msg_color_b * 255.0f;
|
||||
x = video_info->font_msg_pos_x;
|
||||
y = video_info->font_msg_pos_y;
|
||||
drop_x = -2;
|
||||
drop_y = -2;
|
||||
drop_mod = 0.3f;
|
||||
drop_alpha = 1.0f;
|
||||
scale = 1.0f;
|
||||
align = TEXT_ALIGN_LEFT;
|
||||
red = video_info->font_msg_color_r * 255.0f;
|
||||
green = video_info->font_msg_color_g * 255.0f;
|
||||
blue = video_info->font_msg_color_b * 255.0f;
|
||||
alpha = 255;
|
||||
}
|
||||
|
||||
len = utf8len(msg);
|
||||
msg_strlen = strlen(msg);
|
||||
|
||||
GetTextExtentPoint32(font->gdi->memDC, msg, msg_strlen, &textSize);
|
||||
|
||||
switch (align)
|
||||
{
|
||||
case TEXT_ALIGN_LEFT:
|
||||
newX = x * width * scale;
|
||||
newDropX = drop_x * width * scale;
|
||||
break;
|
||||
case TEXT_ALIGN_RIGHT:
|
||||
newX = (x * width * scale) - len;
|
||||
newX = (x * width * scale) - textSize.cx;
|
||||
newDropX = (drop_x * width * scale) - textSize.cx;
|
||||
break;
|
||||
case TEXT_ALIGN_CENTER:
|
||||
newX = (x * width * scale) - (len / 2);
|
||||
newX = (x * width * scale) - (textSize.cx / 2);
|
||||
newDropX = (drop_x * width * scale) - (textSize.cx / 2);
|
||||
break;
|
||||
default:
|
||||
newX = 0;
|
||||
newDropX = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
newY = height - (y * height * scale);
|
||||
newY = height - (y * height * scale) - textSize.cy;
|
||||
newDropY = height - (drop_y * height * scale) - textSize.cy;
|
||||
|
||||
font->gdi->bmp_old = (HBITMAP)SelectObject(font->gdi->memDC, font->gdi->bmp);
|
||||
|
||||
SetBkMode(font->gdi->memDC, TRANSPARENT);
|
||||
|
||||
msg_list = string_split(msg, "\n");
|
||||
|
||||
if (drop_x || drop_y)
|
||||
{
|
||||
float dark_alpha = drop_alpha;
|
||||
drop_red = red * drop_mod * dark_alpha;
|
||||
drop_green = green * drop_mod * dark_alpha;
|
||||
drop_blue = blue * drop_mod * dark_alpha;
|
||||
|
||||
SetTextColor(font->gdi->memDC, RGB(drop_red, drop_green, drop_blue));
|
||||
|
||||
if (msg_list)
|
||||
{
|
||||
for (i = 0; i < msg_list->size; i++)
|
||||
{
|
||||
TextOut(font->gdi->memDC, newDropX, newDropY + (textSize.cy * i), msg_list->elems[i].data, utf8len(msg_list->elems[i].data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetTextColor(font->gdi->memDC, RGB(red, green, blue));
|
||||
TextOut(font->gdi->memDC, newX, newY, msg, len);
|
||||
|
||||
if (msg_list)
|
||||
{
|
||||
for (i = 0; i < msg_list->size; i++)
|
||||
{
|
||||
TextOut(font->gdi->memDC, newX, newY + (textSize.cy * i), msg_list->elems[i].data, utf8len(msg_list->elems[i].data));
|
||||
}
|
||||
|
||||
string_list_free(msg_list);
|
||||
}
|
||||
|
||||
SelectObject(font->gdi->memDC, font->gdi->bmp_old);
|
||||
}
|
||||
|
||||
|
@ -16,17 +16,20 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <clamping.h>
|
||||
#include <queues/message_queue.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#include "../../config.def.h"
|
||||
#include "../../gfx/font_driver.h"
|
||||
#include "../../gfx/video_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#include "../menu_driver.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#include "../../gfx/common/win32_common.h"
|
||||
#include "../../gfx/common/gdi_common.h"
|
||||
#endif
|
||||
|
||||
static void *menu_display_gdi_get_default_mvp(video_frame_info_t *video_info)
|
||||
@ -45,6 +48,63 @@ static void menu_display_gdi_blend_end(video_frame_info_t *video_info)
|
||||
static void menu_display_gdi_draw(menu_display_ctx_draw_t *draw,
|
||||
video_frame_info_t *video_info)
|
||||
{
|
||||
struct gdi_texture *texture = NULL;
|
||||
gdi_t *gdi = (gdi_t*)video_driver_get_ptr(false);
|
||||
BITMAPINFO info = {0};
|
||||
|
||||
if (!gdi || !draw || draw->x < 0 || draw->y < 0 || draw->width <= 1 || draw->height <= 1)
|
||||
return;
|
||||
|
||||
texture = (struct gdi_texture*)draw->texture;
|
||||
|
||||
if (!texture || texture->width <= 1 || texture->height <= 1)
|
||||
return;
|
||||
|
||||
info.bmiHeader.biBitCount = 32;
|
||||
info.bmiHeader.biWidth = texture->width;
|
||||
info.bmiHeader.biHeight = -texture->height;
|
||||
info.bmiHeader.biPlanes = 1;
|
||||
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
info.bmiHeader.biSizeImage = 0;
|
||||
info.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
if (gdi->memDC)
|
||||
{
|
||||
BLENDFUNCTION blend = {0};
|
||||
|
||||
if (!gdi->texDC)
|
||||
gdi->texDC = CreateCompatibleDC(gdi->winDC);
|
||||
|
||||
if (texture->bmp)
|
||||
{
|
||||
texture->bmp_old = SelectObject(gdi->texDC, texture->bmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* scale texture data into a bitmap we can easily blit later */
|
||||
texture->bmp = CreateCompatibleBitmap(gdi->winDC, draw->width, draw->height);
|
||||
texture->bmp_old = SelectObject(gdi->texDC, texture->bmp);
|
||||
|
||||
StretchDIBits(gdi->texDC, 0, 0, draw->width, draw->height, 0, 0, texture->width, texture->height, texture->data, &info, DIB_RGB_COLORS, SRCCOPY);
|
||||
}
|
||||
|
||||
gdi->bmp_old = SelectObject(gdi->memDC, gdi->bmp);
|
||||
|
||||
blend.BlendOp = AC_SRC_OVER;
|
||||
blend.BlendFlags = 0;
|
||||
blend.SourceConstantAlpha = 255;/*clamp_8bit(draw->coords->color[3] * 255.0f);*/
|
||||
blend.AlphaFormat = AC_SRC_ALPHA;
|
||||
|
||||
AlphaBlend(gdi->memDC, draw->x, video_info->height - draw->height - draw->y, draw->width, draw->height, gdi->texDC, 0, 0, draw->width, draw->height, blend);
|
||||
|
||||
/*TransparentBlt(gdi->memDC, draw->x, video_info->height - draw->height - draw->y, draw->width, draw->height, gdi->texDC, 0, 0, draw->width, draw->height, 0);*/
|
||||
|
||||
/* To draw without blending: */
|
||||
/*StretchBlt(gdi->memDC, draw->x, video_info->height - draw->height - draw->y, draw->width, draw->height, gdi->texDC, 0, 0, draw->width, draw->height, SRCCOPY);*/
|
||||
|
||||
SelectObject(gdi->memDC, gdi->bmp_old);
|
||||
SelectObject(gdi->texDC, texture->bmp_old);
|
||||
}
|
||||
}
|
||||
|
||||
static void menu_display_gdi_draw_pipeline(menu_display_ctx_draw_t *draw,
|
||||
@ -80,7 +140,7 @@ static bool menu_display_gdi_font_init_first(
|
||||
font_path, font_size, true,
|
||||
is_threaded,
|
||||
FONT_DRIVER_RENDER_GDI)))
|
||||
return false;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user