180 lines
6.4 KiB
C
180 lines
6.4 KiB
C
#include <SDL2/SDL.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include "video.h"
|
|
#include "wx-utils.h"
|
|
#include "wx-sdl2-video.h"
|
|
#include "wx-sdl2-video-renderer.h"
|
|
|
|
static SDL_Texture* texture = NULL;
|
|
static SDL_Renderer* renderer = NULL;
|
|
|
|
extern int video_scale_mode;
|
|
extern int video_vsync;
|
|
extern int video_focus_dim;
|
|
extern int take_screenshot;
|
|
extern void screenshot_taken(unsigned char* rgb, int width, int height);
|
|
|
|
int sdl_video_renderer_init(SDL_Window* window, sdl_render_driver requested_render_driver, SDL_Rect screen)
|
|
{
|
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_scale_mode ? "1" : "0");
|
|
const char* driver = requested_render_driver.sdl_id;
|
|
if (!driver) driver = "0";
|
|
SDL_SetHint(SDL_HINT_RENDER_DRIVER, driver);
|
|
|
|
int flags = SDL_RENDERER_ACCELERATED;
|
|
if (video_vsync) {
|
|
flags |= SDL_RENDERER_PRESENTVSYNC;
|
|
}
|
|
renderer = SDL_CreateRenderer(window, -1, flags);
|
|
|
|
if (!renderer)
|
|
{
|
|
char message[200];
|
|
sprintf(message,
|
|
"SDL window could not be created! Error: %s\n",
|
|
SDL_GetError());
|
|
wx_messagebox(0, message, "SDL Error", WX_MB_OK);
|
|
return SDL_FALSE;
|
|
}
|
|
|
|
SDL_RendererInfo rendererInfo;
|
|
SDL_GetRendererInfo(renderer, &rendererInfo);
|
|
sdl_render_driver* d = sdl_get_render_driver_by_name_ptr(rendererInfo.name);
|
|
if (!d)
|
|
strcpy(current_render_driver_name, "Unknown");
|
|
else
|
|
strcpy(current_render_driver_name, d->name);
|
|
|
|
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
|
|
SDL_TEXTUREACCESS_STREAMING,
|
|
screen.w, screen.h);
|
|
|
|
return SDL_TRUE;
|
|
|
|
}
|
|
|
|
void sdl_video_renderer_close()
|
|
{
|
|
if (texture)
|
|
{
|
|
SDL_DestroyTexture(texture);
|
|
texture = NULL;
|
|
}
|
|
if (renderer)
|
|
{
|
|
SDL_DestroyRenderer(renderer);
|
|
renderer = NULL;
|
|
}
|
|
}
|
|
|
|
void sdl_video_renderer_update(SDL_Window* window, SDL_Rect updated_rect, BITMAP* screen)
|
|
{
|
|
SDL_UpdateTexture(texture, &updated_rect, &((uint32_t*) screen->dat)[updated_rect.y * screen->w + updated_rect.x], screen->w * 4);
|
|
}
|
|
|
|
void sdl_video_renderer_present(SDL_Window* window, SDL_Rect texture_rect, SDL_Rect window_rect, SDL_Rect screen)
|
|
{
|
|
SDL_RenderClear(renderer);
|
|
SDL_RenderCopy(renderer, texture, &texture_rect, &window_rect);
|
|
int sshot = take_screenshot;
|
|
if (!sshot)
|
|
{
|
|
if (video_focus_dim && !(SDL_GetWindowFlags(window)&SDL_WINDOW_INPUT_FOCUS)) {
|
|
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0x80);
|
|
SDL_RenderFillRect(renderer, NULL);
|
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff);
|
|
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
|
|
}
|
|
if (flash.enabled)
|
|
{
|
|
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
|
SDL_SetRenderDrawColor(renderer, flash.color[0], flash.color[1], flash.color[2], flash.color[3]);
|
|
SDL_RenderFillRect(renderer, NULL);
|
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff);
|
|
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
|
|
}
|
|
}
|
|
SDL_RenderPresent(renderer);
|
|
|
|
if (sshot)
|
|
{
|
|
take_screenshot = 0;
|
|
|
|
int width = window_rect.w;
|
|
int height = window_rect.h;
|
|
|
|
SDL_GetWindowSize(window, &width, &height);
|
|
|
|
/* seems to work without rendering to texture first */
|
|
// SDL_Texture* tex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_TARGET, width, height);
|
|
//
|
|
// SDL_SetRenderTarget(renderer, tex);
|
|
// SDL_RenderClear(renderer);
|
|
// SDL_RenderCopy(renderer, texture, &texture_rect, &window_rect);
|
|
// SDL_RenderPresent(renderer);
|
|
|
|
unsigned char* rgba = (unsigned char*)malloc(width*height*4);
|
|
int res = SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_ABGR8888, rgba, width*4);
|
|
|
|
// SDL_SetRenderTarget(renderer, NULL);
|
|
// SDL_DestroyTexture(tex);
|
|
|
|
if (!res)
|
|
{
|
|
int x, y;
|
|
unsigned char* rgb = (unsigned char*)malloc(width*height*3);
|
|
|
|
for (x = 0; x < width; ++x)
|
|
{
|
|
for (y = 0; y < height; ++y)
|
|
{
|
|
rgb[(y*width+x)*3+0] = rgba[(y*width+x)*4+0];
|
|
rgb[(y*width+x)*3+1] = rgba[(y*width+x)*4+1];
|
|
rgb[(y*width+x)*3+2] = rgba[(y*width+x)*4+2];
|
|
}
|
|
}
|
|
|
|
screenshot_taken(rgb, width, height);
|
|
|
|
free(rgb);
|
|
}
|
|
else
|
|
screenshot_taken(0, 0, 0);
|
|
|
|
free(rgba);
|
|
}
|
|
|
|
}
|
|
|
|
sdl_renderer_t* sdl2_renderer_create()
|
|
{
|
|
sdl_renderer_t* renderer = malloc(sizeof(sdl_renderer_t));
|
|
renderer->init = sdl_video_renderer_init;
|
|
renderer->close = sdl_video_renderer_close;
|
|
renderer->update = sdl_video_renderer_update;
|
|
renderer->present = sdl_video_renderer_present;
|
|
renderer->always_update = 0;
|
|
return renderer;
|
|
}
|
|
|
|
void sdl2_renderer_close(sdl_renderer_t* renderer)
|
|
{
|
|
free(renderer);
|
|
}
|
|
|
|
int sdl2_renderer_available(struct sdl_render_driver* driver)
|
|
{
|
|
int i;
|
|
SDL_RendererInfo renderInfo;
|
|
for (i = 0; i < SDL_GetNumRenderDrivers(); ++i)
|
|
{
|
|
SDL_GetRenderDriverInfo(i, &renderInfo);
|
|
if (!strcmp(driver->sdl_id, renderInfo.name))
|
|
return 1;
|
|
}
|
|
return 0;
|
|
|
|
}
|