mirror of
https://github.com/perfect-dark-pc-port/perfect_dark.git
synced 2026-10-24 00:02:43 +02:00
this means that now scaling at most 4:3 resolutions will be a bit mangled, since the real base resolution is 320x220
236 lines
4.7 KiB
C
236 lines
4.7 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
#include <PR/ultratypes.h>
|
|
#include <PR/gbi.h>
|
|
#include "platform.h"
|
|
#include "config.h"
|
|
#include "video.h"
|
|
|
|
#include "../fast3d/gfx_api.h"
|
|
#include "../fast3d/gfx_sdl.h"
|
|
#include "../fast3d/gfx_opengl.h"
|
|
|
|
static struct GfxWindowManagerAPI *wmAPI;
|
|
static struct GfxRenderingAPI *renderingAPI;
|
|
|
|
static bool initDone = false;
|
|
|
|
static s32 vidWidth = 640;
|
|
static s32 vidHeight = 480;
|
|
static s32 vidFramebuffers = true;
|
|
static s32 vidFullscreen = false;
|
|
static s32 vidVsync = 1;
|
|
static s32 vidMSAA = 1;
|
|
static s32 vidFramerateLimit = 0;
|
|
|
|
static s32 texFilter = FILTER_LINEAR;
|
|
static s32 texFilter2D = true;
|
|
|
|
static u32 dlcount = 0;
|
|
static u32 frames = 0;
|
|
static u32 framesPerSec = 0;
|
|
static f64 startTime, endTime, fpsTime;
|
|
|
|
s32 videoInit(void)
|
|
{
|
|
wmAPI = &gfx_sdl;
|
|
renderingAPI = &gfx_opengl_api;
|
|
|
|
gfx_current_native_viewport.width = 320;
|
|
gfx_current_native_viewport.height = 220;
|
|
gfx_current_native_aspect = 320.f / 220.f;
|
|
gfx_framebuffers_enabled = (bool)vidFramebuffers;
|
|
gfx_msaa_level = vidMSAA;
|
|
|
|
gfx_init(wmAPI, renderingAPI, "PD", vidFullscreen, vidWidth, vidHeight, 100, 100);
|
|
|
|
wmAPI->set_swap_interval(vidVsync);
|
|
wmAPI->set_target_fps(vidFramerateLimit); // disabled because vsync is on
|
|
renderingAPI->set_texture_filter((enum FilteringMode)texFilter);
|
|
|
|
initDone = true;
|
|
return 0;
|
|
}
|
|
|
|
void videoStartFrame(void)
|
|
{
|
|
if (initDone) {
|
|
startTime = wmAPI->get_time();
|
|
gfx_start_frame();
|
|
}
|
|
}
|
|
|
|
void videoSubmitCommands(Gfx *cmds)
|
|
{
|
|
if (initDone) {
|
|
gfx_run(cmds);
|
|
++dlcount;
|
|
}
|
|
}
|
|
|
|
void videoEndFrame(void)
|
|
{
|
|
if (!initDone) {
|
|
return;
|
|
}
|
|
|
|
gfx_end_frame();
|
|
|
|
endTime = wmAPI->get_time();
|
|
|
|
++frames;
|
|
++framesPerSec;
|
|
|
|
if (endTime >= fpsTime) {
|
|
char tmp[128];
|
|
snprintf(tmp, sizeof(tmp), "fps %3u frt %lf frm %u", framesPerSec, endTime - startTime, frames);
|
|
wmAPI->set_window_title(tmp);
|
|
framesPerSec = 0;
|
|
fpsTime = endTime + 1.0;
|
|
}
|
|
}
|
|
|
|
void videoClearScreen(void)
|
|
{
|
|
videoStartFrame();
|
|
// TODO: clear
|
|
videoEndFrame();
|
|
}
|
|
|
|
void *videoGetWindowHandle(void)
|
|
{
|
|
if (initDone) {
|
|
return wmAPI->get_window_handle();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void videoUpdateNativeResolution(s32 w, s32 h)
|
|
{
|
|
gfx_current_native_viewport.width = w;
|
|
gfx_current_native_viewport.height = h;
|
|
gfx_current_native_aspect = (float)w / (float)h;
|
|
}
|
|
|
|
s32 videoGetNativeWidth(void)
|
|
{
|
|
return gfx_current_native_viewport.width;
|
|
}
|
|
|
|
s32 videoGetNativeHeight(void)
|
|
{
|
|
return gfx_current_native_viewport.height;
|
|
}
|
|
|
|
s32 videoGetWidth(void)
|
|
{
|
|
return gfx_current_dimensions.width;
|
|
}
|
|
|
|
s32 videoGetHeight(void)
|
|
{
|
|
return gfx_current_dimensions.height;
|
|
}
|
|
|
|
s32 videoGetFullscreen(void)
|
|
{
|
|
return vidFullscreen;
|
|
}
|
|
|
|
f32 videoGetAspect(void)
|
|
{
|
|
return gfx_current_dimensions.aspect_ratio;
|
|
}
|
|
|
|
u32 videoGetTextureFilter2D(void)
|
|
{
|
|
return texFilter2D;
|
|
}
|
|
|
|
u32 videoGetTextureFilter(void)
|
|
{
|
|
return texFilter;
|
|
}
|
|
|
|
void videoSetWindowOffset(s32 x, s32 y)
|
|
{
|
|
gfx_current_game_window_viewport.x = x;
|
|
gfx_current_game_window_viewport.y = y;
|
|
}
|
|
|
|
void videoSetFullscreen(s32 fs)
|
|
{
|
|
if (fs != vidFullscreen) {
|
|
vidFullscreen = !!fs;
|
|
wmAPI->set_fullscreen(vidFullscreen);
|
|
}
|
|
}
|
|
|
|
void videoSetTextureFilter(u32 filter)
|
|
{
|
|
if (filter > FILTER_THREE_POINT) filter = FILTER_THREE_POINT;
|
|
texFilter = filter;
|
|
renderingAPI->set_texture_filter((enum FilteringMode)filter);
|
|
}
|
|
|
|
void videoSetTextureFilter2D(u32 filter)
|
|
{
|
|
texFilter2D = !!filter;
|
|
}
|
|
|
|
s32 videoCreateFramebuffer(u32 w, u32 h, s32 upscale, s32 autoresize)
|
|
{
|
|
return gfx_create_framebuffer(w, h, upscale, autoresize);
|
|
}
|
|
|
|
void videoSetFramebuffer(s32 target)
|
|
{
|
|
return gfx_set_framebuffer(target, 1.f);
|
|
}
|
|
|
|
void videoResetFramebuffer(void)
|
|
{
|
|
return gfx_reset_framebuffer();
|
|
}
|
|
|
|
s32 videoFramebuffersSupported(void)
|
|
{
|
|
return gfx_framebuffers_enabled;
|
|
}
|
|
|
|
void videoResizeFramebuffer(s32 target, u32 w, u32 h, s32 upscale, s32 autoresize)
|
|
{
|
|
gfx_resize_framebuffer(target, w, h, upscale, autoresize);
|
|
}
|
|
|
|
void videoCopyFramebuffer(s32 dst, s32 src, s32 left, s32 top)
|
|
{
|
|
// assume immediate copies always read the front buffer
|
|
gfx_copy_framebuffer(dst, src, left, top, false);
|
|
}
|
|
|
|
void videoResetTextureCache(void)
|
|
{
|
|
gfx_texture_cache_clear();
|
|
}
|
|
|
|
void videoFreeCachedTexture(const void *texptr)
|
|
{
|
|
gfx_texture_cache_delete(texptr);
|
|
}
|
|
|
|
PD_CONSTRUCTOR static void videoConfigInit(void)
|
|
{
|
|
configRegisterInt("Video.DefaultFullscreen", &vidFullscreen, 0, 1);
|
|
configRegisterInt("Video.DefaultWidth", &vidWidth, 0, 32767);
|
|
configRegisterInt("Video.DefaultHeight", &vidHeight, 0, 32767);
|
|
configRegisterInt("Video.VSync", &vidVsync, -1, 10);
|
|
configRegisterInt("Video.FramebufferEffects", &vidFramebuffers, 0, 1);
|
|
configRegisterInt("Video.FramerateLimit", &vidFramerateLimit, 0, 10000);
|
|
configRegisterInt("Video.MSAA", &vidMSAA, 1, 16);
|
|
configRegisterInt("Video.TextureFilter", &texFilter, 0, 2);
|
|
configRegisterInt("Video.TextureFilter2D", &texFilter2D, 0, 1);
|
|
}
|