diff --git a/game/engine2.c b/game/engine2.c index b5f2dae..8b8ab18 100644 --- a/game/engine2.c +++ b/game/engine2.c @@ -513,7 +513,7 @@ void enemy_draw(const void *src,void *trg,int shade,int scale,int maxspace,int c int rwofs = pcx*(pcy-1); int accu = 0; int *w = ytable; - int sp = maxspace*2; + int sp = maxspace; while (sp > 0 && rwofs >= 0) { *w++ = rwofs; @@ -700,7 +700,7 @@ void enemy_draw_transp(const void *src,void *trg,const void *shade,int scale,int int rwofs = pcx*(pcy-1); int accu = 0; int *w = ytable; - int sp = maxspace*2; + int sp = maxspace; while (sp > 0 && rwofs >= 0) { *w++ = rwofs; @@ -889,7 +889,7 @@ void enemy_draw_mirror_transp(const void *src,void *trg,const void *shade,int sc int rwofs = pcx*(pcy-1); int accu = 0; int *w = ytable; - int sp = maxspace*2; + int sp = maxspace; while (sp > 0 && rwofs >= 0) { *w++ = rwofs; @@ -1079,7 +1079,7 @@ void enemy_draw_mirror(const void *src,void *trg,int shade,int scale,int maxspac int rwofs = pcx*(pcy-1); int accu = 0; int *w = ytable; - int sp = maxspace*2; + int sp = maxspace; while (sp > 0 && rwofs >= 0) { *w++ = rwofs; diff --git a/game/kniha.c b/game/kniha.c index f94f1a2..e25a69e 100644 --- a/game/kniha.c +++ b/game/kniha.c @@ -1,4 +1,5 @@ #include +#include /* Popis jazyka pro psani textu do knihy @@ -98,20 +99,6 @@ static int picture_len=0; static char winconv=0; static int relpos=0; -//static char xlat_table[128]="�__��_____�_____�__��__________________________________�___�__��__��_�__��____���__�___�___�__��__��_�__��____���__�"; -static char xlat_table[128] = { - 0x9b, 0x5f, 0x5f, 0x86, 0x92, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0xad, 0x5f, - 0x5f, 0x5f, 0x5f, 0x5f, 0xa8, 0x5f, 0x5f, 0x9f, 0x91, 0x5f, 0x5f, 0x5f, - 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, - 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, - 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x8f, 0x5f, 0x5f, 0x5f, 0x8a, - 0x5f, 0x5f, 0x80, 0x90, 0x5f, 0x5f, 0x89, 0x8b, 0x5f, 0x85, 0x5f, 0x5f, - 0xa5, 0x95, 0x5f, 0x5f, 0x5f, 0x5f, 0x9e, 0xa6, 0x97, 0x5f, 0x5f, 0x9d, - 0x5f, 0x5f, 0x5f, 0xa0, 0x5f, 0x5f, 0x5f, 0x8d, 0x5f, 0x5f, 0x87, 0x82, - 0x5f, 0x5f, 0x88, 0xa1, 0x5f, 0x83, 0x5f, 0x5f, 0xa4, 0xa2, 0x5f, 0x5f, - 0x5f, 0x5f, 0xa9, 0x96, 0xa3, 0x5f, 0x5f, 0x98, 0x0a -}; - static int insert_num(char *text,int pos,int num) { char c=0x80; @@ -449,11 +436,7 @@ static char skip_section(TMPFILE_RD *txt) void prekodovat(char *c) { - while (*c) - { - if (*c>137) *c=xlat_table[*c-138]; - c++; - } + windows2kamenik(c, strlen(c), c); } static void read_text(TMPFILE_RD *txt) @@ -493,7 +476,7 @@ static void read_text(TMPFILE_RD *txt) } else wsp=0; if (i=='&') i=temp_storage_getc(txt); - if (winconv && i>137) i=xlat_table[i-138]; + if (winconv) i=windows2kamenik_chr(i); ss[0]=i; xs+=text_width(ss); read_buff[buff_end++]=i; @@ -528,7 +511,6 @@ static void seek_section(TMPFILE_RD *txt,int sect_number) } if (i==sect_number) { - c=temp_storage_getc(txt); while(c!=']') { if (c=='W' || c=='w') winconv=1; diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt index 903e7af..3d4be0e 100644 --- a/libs/CMakeLists.txt +++ b/libs/CMakeLists.txt @@ -14,7 +14,8 @@ SET(files basicobj.c strlite.c wav_mem.c strlists.c - music.cpp + cztable.c + music.cpp swaper.c ) add_library(skeldal_libs ${files}) diff --git a/cztable.cpp b/libs/cztable.c similarity index 51% rename from cztable.cpp rename to libs/cztable.c index 61c2e95..9ac5f95 100644 --- a/cztable.cpp +++ b/libs/cztable.c @@ -1,51 +1,51 @@ #include -struct czxlat +typedef struct czxlat { unsigned char kamenik; unsigned char windows; - }; + } CZXLAT; -static czxlat czxlattab[]= +static CZXLAT czxlattab[]= { - {0xA0,''}, - {0x87,''}, - {0x83,''}, - {0x82,''}, - {0x88,''}, - {0xA1,''}, - {0x8D,''}, - {0x8C,''}, - {0xA4,''}, - {0xA2,''}, - {0xAA,''}, - {0xA9,''}, - {0xA8,''}, - {0x9f,''}, - {0xA3,''}, - {0x96,''}, - {0x98,''}, - {0x91,''}, + {0xA0,0xE1}, + {0x87,0xE8}, + {0x83,0xEF}, + {0x82,0xE9}, + {0x88,0xEC}, + {0xA1,0xED}, + {0x8D,0xE5}, + {0x8C,0xBE}, + {0xA4,0xF2}, + {0xA2,0xF3}, + {0xAA,0xE0}, + {0xA9,0xF8}, + {0xA8,0x9A}, + {0x9f,0x9D}, + {0xA3,0xFA}, + {0x96,0xF9}, + {0x98,0xFD}, + {0x91,0x9E}, - {0x8F,''}, - {0x80,''}, - {0x85,''}, - {0x90,''}, - {0x89,''}, - {0x8B,''}, - {0x8A,''}, - {0x9C,''}, - {0xA5,''}, - {0x95,''}, - {0xAB,''}, - {0x9E,''}, - {0x9B,''}, - {0x86,''}, - {0x97,''}, - {0xA6,''}, - {0x9D,''}, - {0x92,''}, + {0x8F,0xC1}, + {0x80,0xC8}, + {0x85,0xCF}, + {0x90,0xC9}, + {0x89,0xCC}, + {0x8B,0xCD}, + {0x8A,0xC5}, + {0x9C,0xBC}, + {0xA5,0xD2}, + {0x95,0xD3}, + {0xAB,0xC0}, + {0x9E,0xD8}, + {0x9B,0x8A}, + {0x86,0x8D}, + {0x97,0xDA}, + {0xA6,0xD9}, + {0x9D,0xDD}, + {0x92,0x8E}, }; static char xlatkm2win[256]; @@ -54,7 +54,7 @@ static char prepare=1; static void PrepareTabs() { - int i; + unsigned int i; for (i=0;i<256;i++) {xlatkm2win[i]=i;xlatwin2km[i]=i;} for (i=0;i 1680) type = CrtFilterType::rgb_matrix_3; + else if (height >= 1200) type = CrtFilterType::scanlines_2; + else type = CrtFilterType::scanlines; + } + + if (type == CrtFilterType::scanlines || type == CrtFilterType::scanlines_2) { + width = 32; + } // Vytvoř novou texturu ve správné velikosti *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, width, height); SDL_SetTextureBlendMode(*texture, SDL_BLENDMODE_MUL); @@ -65,19 +75,67 @@ void SDLContext::generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** textur int pitch; SDL_LockTexture(*texture, nullptr, &pixels, &pitch); - bool wider_lines = height > 1350; - Uint32* pixelArray = (Uint32*)pixels; - Uint32 darkPixel = wider_lines?0x808080FF:0xA0A0A0FF; - Uint32 transparentPixel = wider_lines ?0xFFFFFFE0:0xFFFFFFC0; - int step = wider_lines ?3:2; - for (int y = 0; y < height; y++) { - Uint32 color = (y % step == 0) ? darkPixel : transparentPixel; - for (int x = 0; x < width; x++) { - pixelArray[y * (pitch / 4) + x] = color; + if (type == CrtFilterType::scanlines) { + + + + Uint32 darkPixel = 0xA0A0A0FF; + Uint32 transparentPixel = 0xFFFFFFC0; + + for (int y = 0; y < height; y++) { + Uint32 color = ((y & 1)== 0) ? darkPixel : transparentPixel; + for (int x = 0; x < width; x++) { + pixelArray[y * (pitch / 4) + x] = color; + } } } + else if (type == CrtFilterType::scanlines_2) { + + + Uint32 darkPixel = 0x808080FF; + Uint32 transparentPixel = 0xFFFFFFE0; + + for (int y = 0; y < height; y++) { + Uint32 color = (y % 3== 2) ? darkPixel : transparentPixel; + for (int x = 0; x < width; x++) { + pixelArray[y * (pitch / 4) + x] = color; + } + } + } else { + + static Uint32 red_pixel = 0xFF8080A0; + static Uint32 green_pixel = 0x80FF80A0; + static Uint32 blue_pixel = 0x8080FFA0; + static Uint32 dark_pixel = 0x000000C0; + for (int y = 2; y < height; y++) { + if (type == CrtFilterType::rgb_matrix_2) { + for (int x = 2; x < width; x+=3) { + Uint32 *pos = pixelArray+y*(pitch/4)+x-2; + if ((y % 3) == 2) { + pos[0] = pos[1] = pos[2] = dark_pixel; + } else { + pos[0] = red_pixel; + pos[1] = green_pixel; + pos[2] = blue_pixel; + } + } + } else { + for (int x = 2; x < width; x+=3) { + Uint32 *pos = pixelArray+y*(pitch/4)+x-2; + if ((y & 3) == 3) { + pos[0] = pos[1] = pos[2] = dark_pixel; + } else { + pos[0] = red_pixel; + pos[1] = green_pixel; + pos[2] = blue_pixel; + } + } + } + } + + } // Odemkni texturu SDL_UnlockTexture(*texture); @@ -97,7 +155,7 @@ void SDLContext::init_video(const VideoConfig &config, const char *title) { int height = config.window_height; aspect_x = config.aspect_x; aspect_y = config.aspect_y; - crt_filter_enabled = config.crt_filter; + _crt_filter = config.crt_filter ; _fullscreen_mode = config.fullscreen; @@ -370,10 +428,10 @@ void SDLContext::update_screen() { SDL_SetTextureAlphaMod(_visible_texture, 255); SDL_RenderCopy(_renderer.get(), _visible_texture, NULL, &winrc); } - if (winrc.h > 900 && crt_filter_enabled) { + if (winrc.h >= 720 && _crt_filter != CrtFilterType::none) { if (!_crt_effect) { SDL_Texture *txt; - generateCRTTexture(_renderer.get(), &txt, 128, std::min(1440, winrc.h)); + generateCRTTexture(_renderer.get(), &txt, winrc.w, winrc.h, _crt_filter); _crt_effect.reset(txt); } } diff --git a/platform/sdl/sdl_context.h b/platform/sdl/sdl_context.h index 70fd5d2..16980a2 100644 --- a/platform/sdl/sdl_context.h +++ b/platform/sdl/sdl_context.h @@ -15,10 +15,20 @@ public: SDLContext(); + enum class CrtFilterType { + none, + autoselect, + scanlines, + scanlines_2, + rgb_matrix_2, + rgb_matrix_3 + + }; + struct VideoConfig { int window_width; int window_height; - bool crt_filter; + CrtFilterType crt_filter; int composer; const char *scale_quality; bool fullscreen; @@ -121,7 +131,7 @@ protected: mutable std::mutex _mx; int aspect_x = 4; int aspect_y = 3; - bool crt_filter_enabled = false; + CrtFilterType _crt_filter= CrtFilterType::autoselect; std::function _quit_callback; std::unique_ptr _window; @@ -173,7 +183,7 @@ protected: static SDL_Point to_source_point(const SDL_Rect &win_rec, const SDL_Point &win_pt) ; static SDL_Rect transition_rect(const SDL_Rect &beg, const SDL_Rect &end, float phase); static int transition_int(int beg, int end, float phase); - void generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** texture, int width, int height); + void generateCRTTexture(SDL_Renderer* renderer, SDL_Texture** texture, int width, int height, CrtFilterType type); void signal_push(); diff --git a/skeldal.ini b/skeldal.ini index aa9b3ce..c72b42d 100644 --- a/skeldal.ini +++ b/skeldal.ini @@ -1,7 +1,7 @@ ##### path # # root = path to root of the game. All other paths are relative to this path -# maps = relative path to maps +# maps = relative path to maps # video = relative path to video # data = relative path to skeldal.ddl # savegame = path to savegame, if not defined, retrieved from platform settings @@ -19,7 +19,15 @@ # fullscreen = run game in fullscreen mode # window_width = set window with (in windowed mode) # window_height = set window height (in windowed mode) -# crt_filter = enable filter simmulates lowres CRT monitor for higher resolution +# crt_filter = enable filter simmulates lowres CRT monitor for higher resolution (>720p) +# none = disabled +# auto = auto select depend on resolution (default) +# scanline = 1 pixel wide scanline (best for HD resolution, 960p-1080p) +# scanline_2 = 2 pixels wide scanline (best for QHD resolution, 1440p) +# rgbmatrix_2 = emulates CRT shadow mask (best for QHD resolution, 1440p) +# rgbmatrix_3 = emulates CRT shadow mask (best for 4K resolution, 1920p+) +# (hardware composer and linear filtering is recommended) +# # composer = auto - choose best supported driver # hardware,hw - use hardware for composition # software,sw - use software for composition @@ -33,7 +41,7 @@ #fullscreen=on #window_width=640 #window_height=480 -#crt_filter=on +#crt_filter=auto #scale_quality=auto #composer=auto #aspect_ratio=4:3 @@ -41,9 +49,18 @@ ### audio settings # -# device = name of sound device, optionally with arguments (see SDL_OpenAudioDevice) +# device = name of sound device, optionally with arguments (see SDL_OpenAudioDevice) # (default - use the most suitable device) [audio] #device= - +### localization settings +# +# keyboard_layout = cz_querty, cz_quertz, us +# string_table = path to a stringtable file. (default=none) +# (note, internal fonts supports only characters from KEYBCS2/CP895 code page) +# (https://en.wikipedia.org/wiki/Kamenick%C3%BD_encoding) +# +[localization] +#keyboard_layout=cz_querty +#string_table=