mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-08-13 09:48:25 -04:00
rewrite config, options, work with path
This commit is contained in:
parent
4a0c7d4fd0
commit
77f1700902
30 changed files with 466 additions and 532 deletions
|
@ -14,6 +14,7 @@ target_sources(skeldal_platform PRIVATE
|
|||
config.cpp
|
||||
error.cpp
|
||||
timer.cpp
|
||||
getopt.c
|
||||
)
|
||||
|
||||
# Podmínky pro platformu Windows
|
||||
|
|
|
@ -5,10 +5,16 @@
|
|||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
typedef struct ini_config_section_tag {
|
||||
using Section = std::map<std::string, std::string, std::less<>>;
|
||||
Section data;
|
||||
} INI_CONFIG_SECTION;
|
||||
|
||||
typedef struct ini_config_tag {
|
||||
|
||||
using Section = std::map<std::string, std::string, std::less<>>;
|
||||
using Config = std::map<std::string, Section , std::less<>>;
|
||||
|
||||
using Config = std::map<std::string, INI_CONFIG_SECTION , std::less<>>;
|
||||
Config data;
|
||||
|
||||
} INI_CONFIG;
|
||||
|
@ -44,7 +50,7 @@ void parseIniStream(std::istream& input, Callback &&callback) {
|
|||
if (eqPos != std::string_view::npos) {
|
||||
std::string_view key_view = trim(line_view.substr(0, eqPos));
|
||||
std::string_view value_view = trim(line_view.substr(eqPos + 1));
|
||||
callback(currentSection, std::string(key_view), std::string(value_view));
|
||||
callback(currentSection, key_view, value_view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,9 +65,9 @@ INI_CONFIG* ini_open(const char *filename) {
|
|||
parseIniStream(input, [&](std::string_view section, std::string_view key, std::string_view value) {
|
||||
INI_CONFIG::Config::iterator iter = c->data.find(section);
|
||||
if (iter == c->data.end()) {
|
||||
iter = c->data.emplace(std::string(section), INI_CONFIG::Section()).first;
|
||||
iter = c->data.emplace(std::string(section), INI_CONFIG_SECTION()).first;
|
||||
}
|
||||
iter->second.emplace(std::string(key), std::string(value));
|
||||
iter->second.data.emplace(std::string(key), std::string(value));
|
||||
});
|
||||
return c;
|
||||
}
|
||||
|
@ -73,15 +79,14 @@ void ini_close(INI_CONFIG *config) {
|
|||
const INI_CONFIG_SECTION* ini_section_open(const INI_CONFIG *cfg, const char *section) {
|
||||
auto iter = cfg->data.find(std::string_view(section));
|
||||
if (iter == cfg->data.end()) return NULL;
|
||||
else return reinterpret_cast<const INI_CONFIG_SECTION *>(&iter->second);
|
||||
else return &iter->second;
|
||||
}
|
||||
|
||||
const char* ini_find_key(const INI_CONFIG_SECTION *section,
|
||||
const char *key) {
|
||||
if (section == NULL) return NULL;
|
||||
const INI_CONFIG::Section *s = reinterpret_cast<const INI_CONFIG::Section *>(section);
|
||||
auto iter = s->find(std::string_view(key));
|
||||
if (iter == s->end()) return NULL;
|
||||
auto iter = section->data.find(std::string_view(key));
|
||||
if (iter == section->data.end()) return NULL;
|
||||
return iter->second.c_str();
|
||||
}
|
||||
|
||||
|
@ -171,8 +176,7 @@ int ini_get_boolean(const INI_CONFIG_SECTION *section, const char *key,
|
|||
}
|
||||
|
||||
void ini_replace_key( INI_CONFIG_SECTION *section, const char *key, const char *value) {
|
||||
auto s = reinterpret_cast<INI_CONFIG::Section *>(section);
|
||||
(*s)[std::string(key)] = std::string(value);
|
||||
section->data[std::string(key)] = std::string(value);
|
||||
}
|
||||
|
||||
INI_CONFIG_SECTION* ini_create_section(INI_CONFIG *cfg, const char *section_name) {
|
||||
|
@ -189,7 +193,7 @@ void ini_store_to_file(const INI_CONFIG *config, const char *filename) {
|
|||
std::ofstream out(filename,std::ios::out|std::ios::trunc);
|
||||
for (const auto &[sname, s]: config->data) {
|
||||
out << '[' << sname << ']' << std::endl;
|
||||
for (const auto &[k,v]: s) {
|
||||
for (const auto &[k,v]: s.data) {
|
||||
out << k << '=' << v << std::endl;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include "legacy_coroutines.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdarg>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
extern "C" {
|
||||
#include "error.h"
|
||||
}
|
||||
#include "platform.h"
|
||||
|
||||
|
||||
|
@ -15,8 +15,9 @@ void display_error(const char *text) {
|
|||
|
||||
|
||||
static std::uint32_t gtick = get_game_tick_count();
|
||||
void send_log_impl(int task, const char *format, ...) {
|
||||
void send_log_impl(const char *format, ...) {
|
||||
va_list args;
|
||||
int task = q_current_task();
|
||||
char buff2[1000];
|
||||
va_start(args, format);
|
||||
auto reltik = get_game_tick_count() - gtick;
|
||||
|
|
|
@ -1,4 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
void display_error(const char *text);
|
||||
void send_log_impl(int task, const char *format, ...);
|
||||
void send_log_impl(const char *format, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <cstdarg>
|
||||
#include <filesystem>
|
||||
#include "../libs/logfile.h"
|
||||
|
||||
|
||||
std::filesystem::path break_and_compose_path(const std::string_view &pathname, char sep) {
|
||||
|
@ -67,6 +68,8 @@ FILE *fopen_icase(const char *pathname, const char *mode) {
|
|||
|
||||
static thread_local std::string build_pathname_buffer;
|
||||
|
||||
|
||||
|
||||
const char * build_pathname(size_t nparts, const char *part1, ...) {
|
||||
va_list lst;
|
||||
va_start(lst, part1);
|
||||
|
@ -76,6 +79,7 @@ const char * build_pathname(size_t nparts, const char *part1, ...) {
|
|||
p = p / va_arg(lst, const char *);
|
||||
}
|
||||
build_pathname_buffer = p;
|
||||
SEND_LOG("(BUILD_PATHNAME) %s", build_pathname_buffer.c_str());
|
||||
return build_pathname_buffer.c_str();
|
||||
}
|
||||
|
||||
|
@ -84,3 +88,10 @@ char create_directories(const char *path) {
|
|||
std::error_code ec;
|
||||
return std::filesystem::create_directories(p, ec)?1:0;
|
||||
}
|
||||
|
||||
|
||||
char change_current_directory(const char *path) {
|
||||
std::error_code ec;
|
||||
std::filesystem::current_path(std::filesystem::path(path), ec);
|
||||
return ec == std::error_code{}?1:0;
|
||||
}
|
||||
|
|
117
platform/getopt.c
Normal file
117
platform/getopt.c
Normal file
|
@ -0,0 +1,117 @@
|
|||
// Put this in a separate .h file (called "getopt.h").
|
||||
// The prototype for the header file is:
|
||||
/*
|
||||
#ifndef GETOPT_H
|
||||
#define GETOPT_H
|
||||
|
||||
int getopt(int nargc, char * const nargv[], const char *ostr) ;
|
||||
|
||||
#endif
|
||||
*/
|
||||
|
||||
#include "getopt.h" // make sure you construct the header file as dictated above
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int opterr = 1, /* if error message should be printed */
|
||||
optind = 1, /* index into parent argv vector */
|
||||
optopt, /* character checked for validity */
|
||||
optreset; /* reset getopt */
|
||||
char *optarg; /* argument associated with option */
|
||||
|
||||
#define BADCH (int)'?'
|
||||
#define BADARG (int)':'
|
||||
#define EMSG ""
|
||||
|
||||
/*
|
||||
* getopt --
|
||||
* Parse argc/argv argument vector.
|
||||
*/
|
||||
int getopt(int nargc, char * const nargv[], const char *ostr)
|
||||
{
|
||||
static char *place = EMSG; /* option letter processing */
|
||||
const char *oli; /* option letter list index */
|
||||
|
||||
if (optreset || !*place) { /* update scanning pointer */
|
||||
optreset = 0;
|
||||
if (optind >= nargc || *(place = nargv[optind]) != '-') {
|
||||
place = EMSG;
|
||||
return (-1);
|
||||
}
|
||||
if (place[1] && *++place == '-') { /* found "--" */
|
||||
++optind;
|
||||
place = EMSG;
|
||||
return (-1);
|
||||
}
|
||||
} /* option letter okay? */
|
||||
if ((optopt = (int)*place++) == (int)':' ||
|
||||
!(oli = strchr(ostr, optopt))) {
|
||||
/*
|
||||
* if the user didn't specify '-' as an option,
|
||||
* assume it means -1.
|
||||
*/
|
||||
if (optopt == (int)'-')
|
||||
return (-1);
|
||||
if (!*place)
|
||||
++optind;
|
||||
if (opterr && *ostr != ':')
|
||||
(void)printf("illegal option -- %c\n", optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
if (*++oli != ':') { /* don't need argument */
|
||||
optarg = NULL;
|
||||
if (!*place)
|
||||
++optind;
|
||||
}
|
||||
else { /* need an argument */
|
||||
if (*place) /* no white space */
|
||||
optarg = place;
|
||||
else if (nargc <= ++optind) { /* no arg */
|
||||
place = EMSG;
|
||||
if (*ostr == ':')
|
||||
return (BADARG);
|
||||
if (opterr)
|
||||
(void)printf("option requires an argument -- %c\n", optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
else /* white space */
|
||||
optarg = nargv[optind];
|
||||
place = EMSG;
|
||||
++optind;
|
||||
}
|
||||
return (optopt); /* dump back option letter */
|
||||
}
|
13
platform/getopt.h
Normal file
13
platform/getopt.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef GETOPT_H
|
||||
|
||||
#define GETOPT_H
|
||||
|
||||
extern int opterr; /* if error message should be printed */
|
||||
extern int optind; /* index into parent argv vector */
|
||||
extern int optopt; /* character checked for validity */
|
||||
extern int optreset; /* reset getopt */
|
||||
extern char *optarg; /* argument associated with option */
|
||||
|
||||
int getopt(int nargc, char * const nargv[], const char *ostr);
|
||||
|
||||
#endif
|
|
@ -17,9 +17,10 @@ static std::string get_default_savegame_dir() {
|
|||
|
||||
|
||||
|
||||
const char *get_default_savegame_directory() {
|
||||
const char *get_default_savegame_directory(void) {
|
||||
|
||||
static std::string dir = get_default_savegame_dir();
|
||||
return dir.c_str();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -41,6 +41,13 @@ const char * build_pathname(size_t nparts, const char *part1, ...);
|
|||
* @retval 0 failure
|
||||
*/
|
||||
char create_directories(const char *path);
|
||||
///change current directory
|
||||
/**
|
||||
* @param path path
|
||||
* @retval 1 success
|
||||
* @retval 0 failure
|
||||
*/
|
||||
char change_current_directory(const char *path);
|
||||
|
||||
|
||||
|
||||
|
@ -71,7 +78,7 @@ void sleep_ms(uint32_t);
|
|||
}
|
||||
#endif
|
||||
|
||||
//------------- BGRAPH DX wrapper -------------------
|
||||
|
||||
#include "sdl/BGraph2.h"
|
||||
|
||||
#define WM_RELOADMAP (WM_APP+215)
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
#ifdef __cplusplus__
|
||||
#ifndef _SKELDAL_PLATFORM_SAVE_FOLDER
|
||||
#define _SKELDAL_PLATFORM_SAVE_FOLDER
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SAVEGAME_FOLDERNAME "Skeldal";
|
||||
|
||||
const char *get_default_savegame_directory();
|
||||
const char *get_default_savegame_directory(void);
|
||||
|
||||
#ifdef __cplusplus__
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "BGraph2.h"
|
||||
#include "../platform.h"
|
||||
|
||||
#include "sdl_context.h"
|
||||
#include "global_context.h"
|
||||
|
@ -9,34 +10,50 @@ static std::unique_ptr<uint16_t[]> buffer2nd;
|
|||
static uint16_t *render_target;
|
||||
static uint16_t screen_pitch = 640;
|
||||
|
||||
char DXInit64(char inwindow,int zoom,int monitor, int refresh) {
|
||||
char game_display_init(const INI_CONFIG_SECTION *display_section, const char *title) {
|
||||
|
||||
SDLContext::DisplayMode mode;
|
||||
if (inwindow) {
|
||||
if (zoom) {
|
||||
mode = SDLContext::double_window;
|
||||
} else {
|
||||
mode = SDLContext::native_window;
|
||||
}
|
||||
} else {
|
||||
mode = SDLContext::fullscreen;
|
||||
SDLContext::Config cfg = {};
|
||||
const char *aspect_str;
|
||||
|
||||
aspect_str = ini_get_string(display_section, "aspect_ratio", "4:3");
|
||||
if (sscanf(aspect_str, "%d:%d",&cfg.aspect_x, &cfg.aspect_y) != 2) {
|
||||
cfg.aspect_x = cfg.aspect_y = 0;
|
||||
}
|
||||
cfg.fullscreen = ini_get_boolean(display_section, "fullscreen", 1) == 1;
|
||||
const char *comp = ini_get_string(display_section, "composer", "auto");
|
||||
if (stricmp(comp, "hardware") == 0 || stricmp(comp, "hw") == 0) {
|
||||
cfg.composer = SDL_RENDERER_ACCELERATED;
|
||||
} else if (stricmp(comp, "software") == 0 || stricmp(comp, "sw") == 0) {
|
||||
cfg.composer = SDL_RENDERER_SOFTWARE;
|
||||
} else {
|
||||
cfg.composer = 0;
|
||||
}
|
||||
cfg.scale_quality = ini_get_string(display_section, "scale_quality", "auto");
|
||||
cfg.window_height = ini_get_int(display_section, "window_height", 480);
|
||||
cfg.window_width = ini_get_int(display_section, "window_width", 640);
|
||||
cfg.crt_filter = ini_get_boolean(display_section, "crt_filter", 1) == 1;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
screen_pitch = 640;
|
||||
get_sdl_global_context().init_screen(mode, "Skeldal"); //todo allow change
|
||||
get_sdl_global_context().init_video(cfg, title);
|
||||
screen_buffer = std::make_unique<uint16_t[]>(screen_pitch*480);
|
||||
buffer2nd = std::make_unique<uint16_t[]>(screen_pitch*480);
|
||||
std::fill(screen_buffer.get(), screen_buffer.get()+screen_pitch*480,0);
|
||||
render_target = screen_buffer.get();
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
void DXCloseMode() {
|
||||
get_sdl_global_context().close_screen();
|
||||
void game_display_close(void) {
|
||||
get_sdl_global_context().close_video();
|
||||
}
|
||||
|
||||
|
||||
uint16_t *GetScreenAdr() {
|
||||
return render_target;
|
||||
}
|
||||
|
@ -84,11 +101,26 @@ void StripBlt(void *data, unsigned int startline, uint32_t width) {
|
|||
|
||||
}
|
||||
|
||||
void DXCopyRects64(unsigned short x,unsigned short y,unsigned short xs,unsigned short ys) {
|
||||
static void DXCopyRects64(unsigned short x,unsigned short y,unsigned short xs,unsigned short ys) {
|
||||
get_sdl_global_context().present_rect(screen_buffer.get(), screen_pitch, x,y,xs,ys);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void game_display_update_rect(unsigned short x,unsigned short y,unsigned short xs,unsigned short ys)
|
||||
{
|
||||
|
||||
if (x>DxGetResX() || y>DxGetResY()) return;
|
||||
if (xs==0) xs=DxGetResX();
|
||||
if (ys==0) ys=DxGetResY();
|
||||
if (x+xs>DxGetResX()) xs=DxGetResX()-x;
|
||||
if (y+ys>DxGetResY()) ys=DxGetResY()-y;
|
||||
DXCopyRects64(x,y,xs,ys);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void *DxPrepareWalk(int ypos) {
|
||||
auto &sdl = get_sdl_global_context();
|
||||
sdl.swap_render_buffers();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <stdint.h>
|
||||
#include "../config.h"
|
||||
|
||||
#ifndef __BGRAPH_DX_WRAPPER_
|
||||
#define __BGRAPH_DX_WRAPPER_
|
||||
|
@ -17,16 +18,11 @@ void RedirectScreen(uint16_t *newaddr);
|
|||
void RestoreScreen(void);
|
||||
void RedirectScreenBufferSecond(void);
|
||||
|
||||
char game_display_init(const INI_CONFIG_SECTION *display_section, const char *title);
|
||||
void game_display_close(void);
|
||||
void game_display_update_rect(unsigned short x,unsigned short y,unsigned short xs,unsigned short ys);
|
||||
|
||||
//inicializuje a otevira rezim 640x480x16b v DX - otevre okno, pripravi vse pro beh hry
|
||||
//Vraci 1 pri uspechu
|
||||
char DXInit64(char inwindow,int zoom,int monitor, int refresh);
|
||||
|
||||
//uzavre rezim grafiky
|
||||
void DXCloseMode(void);
|
||||
|
||||
//void DXCopyRects32(unsigned short x,unsigned short y,unsigned short xs,unsigned short ys);
|
||||
void DXCopyRects64(unsigned short x,unsigned short y,unsigned short xs,unsigned short ys);
|
||||
|
||||
void *DxPrepareWalk(int ypos);
|
||||
void DxZoomWalk(void *handle, int ypos, int *points,float phase, void *lodka);
|
||||
|
|
|
@ -60,11 +60,10 @@ void SDLContext::generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** textur
|
|||
int pitch;
|
||||
SDL_LockTexture(*texture, nullptr, &pixels, &pitch);
|
||||
|
||||
bool wider_lines = height > 1024;
|
||||
bool wider_lines = height > 1350;
|
||||
|
||||
// Vyplň texturu patternem (liché řádky tmavší)
|
||||
Uint32* pixelArray = (Uint32*)pixels;
|
||||
Uint32 darkPixel = wider_lines?0x808080FF:0xC0C0C0FF; // Černá s částečnou průhledností
|
||||
Uint32 darkPixel = wider_lines?0x808080FF:0xA0A0A0FF;
|
||||
Uint32 transparentPixel = wider_lines ?0xFFFFFFE0:0xFFFFFFC0;
|
||||
int step = wider_lines ?3:2;
|
||||
|
||||
|
@ -81,7 +80,7 @@ void SDLContext::generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** textur
|
|||
|
||||
|
||||
|
||||
void SDLContext::init_screen(DisplayMode mode, const char *title) {
|
||||
void SDLContext::init_video(const Config &config, const char *title) {
|
||||
char buff[256];
|
||||
static Uint32 update_request_event = SDL_RegisterEvents(1);
|
||||
_update_request_event = update_request_event;
|
||||
|
@ -89,14 +88,14 @@ void SDLContext::init_screen(DisplayMode mode, const char *title) {
|
|||
assert(!_render_thread.joinable());
|
||||
|
||||
|
||||
int width = 640;
|
||||
int height = 480;
|
||||
if (mode == double_window) {
|
||||
width*=2;
|
||||
height*=2;
|
||||
}
|
||||
int width = config.window_width;
|
||||
int height = config.window_height;
|
||||
aspect_x = config.aspect_x;
|
||||
aspect_y = config.aspect_y;
|
||||
crt_filter_enabled = config.crt_filter;
|
||||
|
||||
_fullscreen_mode = mode == fullscreen;
|
||||
|
||||
_fullscreen_mode = config.fullscreen;
|
||||
|
||||
std::atomic<bool> done = false;
|
||||
std::exception_ptr e;
|
||||
|
@ -105,20 +104,31 @@ void SDLContext::init_screen(DisplayMode mode, const char *title) {
|
|||
try {
|
||||
SDL_Window *window = SDL_CreateWindow(title,
|
||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
width, height, SDL_WINDOW_RESIZABLE|(mode==fullscreen?SDL_WINDOW_FULLSCREEN_DESKTOP:0));
|
||||
width, height, SDL_WINDOW_RESIZABLE|(_fullscreen_mode?SDL_WINDOW_FULLSCREEN_DESKTOP:0));
|
||||
|
||||
if (!window) {
|
||||
snprintf(buff, sizeof(buff), "SDL Error create window: %s\n", SDL_GetError());
|
||||
throw std::runtime_error(buff);
|
||||
}
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2");
|
||||
|
||||
_window.reset(window);
|
||||
SDL_Renderer *renderer = SDL_CreateRenderer(_window.get(), -1, 0);
|
||||
SDL_Renderer *renderer = SDL_CreateRenderer(_window.get(), -1, config.composer);
|
||||
if (!renderer) {
|
||||
snprintf(buff,sizeof(buff), "Chyba při vytváření rendereru: %s\n", SDL_GetError());
|
||||
snprintf(buff,sizeof(buff), "Failed to create composer: %s\n", SDL_GetError());
|
||||
throw std::runtime_error(buff);
|
||||
}
|
||||
|
||||
SDL_RendererInfo rinfo;
|
||||
SDL_GetRendererInfo(renderer, &rinfo);
|
||||
|
||||
if (stricmp(config.scale_quality, "auto") == 0) {
|
||||
if (rinfo.flags & SDL_RENDERER_ACCELERATED) {
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
|
||||
}
|
||||
} else {
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, config.scale_quality);
|
||||
}
|
||||
|
||||
_renderer.reset(renderer);
|
||||
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, 640, 480);
|
||||
if (!texture) {
|
||||
|
@ -159,7 +169,7 @@ void SDLContext::init_screen(DisplayMode mode, const char *title) {
|
|||
|
||||
}
|
||||
|
||||
void SDLContext::close_screen() {
|
||||
void SDLContext::close_video() {
|
||||
_render_thread.request_stop();
|
||||
_render_thread.join();
|
||||
}
|
||||
|
@ -358,7 +368,7 @@ void SDLContext::update_screen() {
|
|||
SDL_SetTextureAlphaMod(_visible_texture, 255);
|
||||
SDL_RenderCopy(_renderer.get(), _visible_texture, NULL, &winrc);
|
||||
}
|
||||
if (winrc.h > 900) {
|
||||
if (winrc.h > 900 && crt_filter_enabled) {
|
||||
if (!_crt_effect) {
|
||||
SDL_Texture *txt;
|
||||
generateCRTTexture(_renderer.get(), &txt, 128, std::min<int>(1440, winrc.h));
|
||||
|
@ -431,21 +441,28 @@ SDL_Rect SDLContext::get_window_aspect_rect() const {
|
|||
int ww;
|
||||
int wh;
|
||||
SDL_GetWindowSizeInPixels(_window.get(), &ww, &wh);
|
||||
int apw = wh * 4 / 3;
|
||||
int aph = ww * 3 / 4;
|
||||
int fw;
|
||||
int fh;
|
||||
if (apw > ww) {
|
||||
fw = ww;
|
||||
fh = aph;
|
||||
if (aspect_x && aspect_y) {
|
||||
int apw = wh * aspect_x / aspect_y;
|
||||
int aph = ww * aspect_y / aspect_x;
|
||||
int fw;
|
||||
int fh;
|
||||
if (apw > ww) {
|
||||
fw = ww;
|
||||
fh = aph;
|
||||
} else {
|
||||
fw = apw;
|
||||
fh = wh;
|
||||
}
|
||||
w.h = fh;
|
||||
w.w = fw;
|
||||
w.x = (ww - fw)/2;
|
||||
w.y = (wh - fh)/2;
|
||||
} else {
|
||||
fw = apw;
|
||||
fh = wh;
|
||||
w.x = 0;
|
||||
w.y = 0;
|
||||
w.w = ww;
|
||||
w.h = wh;
|
||||
}
|
||||
w.h = fh;
|
||||
w.w = fw;
|
||||
w.x = (ww - fw)/2;
|
||||
w.y = (wh - fh)/2;
|
||||
return w;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,16 +14,21 @@ public:
|
|||
|
||||
SDLContext();
|
||||
|
||||
enum DisplayMode {
|
||||
native_window,
|
||||
double_window,
|
||||
fullscreen
|
||||
struct Config {
|
||||
int window_width;
|
||||
int window_height;
|
||||
bool crt_filter;
|
||||
int composer;
|
||||
const char *scale_quality;
|
||||
bool fullscreen;
|
||||
int aspect_x;
|
||||
int aspect_y;
|
||||
};
|
||||
|
||||
|
||||
void init_screen(DisplayMode mode, const char *title);
|
||||
void init_video(const Config &config, const char *title);
|
||||
|
||||
void close_screen();
|
||||
void close_video();
|
||||
|
||||
|
||||
void present_rect(uint16_t *pixels, unsigned int pitch, unsigned int x, unsigned int y, unsigned int xs,unsigned ys);
|
||||
|
@ -89,6 +94,9 @@ protected:
|
|||
|
||||
MS_EVENT ms_event;
|
||||
mutable std::mutex _mx;
|
||||
int aspect_x = 4;
|
||||
int aspect_y = 3;
|
||||
bool crt_filter_enabled = false;
|
||||
|
||||
std::unique_ptr<SDL_Window, SDL_Deleter> _window;
|
||||
std::unique_ptr<SDL_Renderer, SDL_Deleter> _renderer;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue