mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-14 02:11:58 -04:00
trying to debug, additional rewrites
This commit is contained in:
parent
378b5586ab
commit
42f780a729
87 changed files with 1771 additions and 529 deletions
|
@ -1,6 +1,7 @@
|
|||
SET(files error.cpp legacy_coroutines.cpp)
|
||||
SET(files error.cpp legacy_coroutines.cpp platform.cpp int2ascii.c istr.c)
|
||||
|
||||
add_library(skeldal_platform_libs ${files})
|
||||
set_property(TARGET skeldal_platform_libs PROPERTY CXX_STANDARD 20)
|
||||
|
||||
add_subdirectory(sdl)
|
||||
add_subdirectory(sdl)
|
||||
add_subdirectory(linux)
|
30
platform/int2ascii.c
Normal file
30
platform/int2ascii.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
#include "platform.h"
|
||||
|
||||
|
||||
|
||||
static char *render_int(char *where, int i, int radix) {
|
||||
if (i == 0) return where;
|
||||
char *r = render_int(where, i/radix, radix);
|
||||
int p = i % radix;
|
||||
if (p<=0) {
|
||||
*r = p + '0';
|
||||
} else {
|
||||
*r = p + 'A' - 10;
|
||||
}
|
||||
return r+1;
|
||||
}
|
||||
|
||||
const char * int2ascii(int i, char *c, int radix) {
|
||||
if (i == 0) {
|
||||
c[0] = '0';
|
||||
c[1] = 0;
|
||||
return c;
|
||||
}
|
||||
if (i<0) {
|
||||
c[0] = '-';
|
||||
*render_int(c+1,-i,radix) = 0;
|
||||
} else {
|
||||
*render_int(c,i,radix) = 0;
|
||||
}
|
||||
return c;
|
||||
}
|
23
platform/istr.c
Normal file
23
platform/istr.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include "platform.h"
|
||||
|
||||
#include <ctype.h>
|
||||
int stricmp(const char *a, const char *b) {
|
||||
while (*a && *b) {
|
||||
char ca = toupper(*a);
|
||||
char cb = toupper(*b);
|
||||
if (ca<cb) return -1;
|
||||
if (ca>cb) return 1;
|
||||
++a;
|
||||
++b;
|
||||
}
|
||||
if (*a) return 1;
|
||||
if (*b) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void strupr(char *c) {
|
||||
while (*c) {
|
||||
*c = toupper(*c);
|
||||
++c;
|
||||
}
|
||||
}
|
2
platform/linux/CMakeLists.txt
Normal file
2
platform/linux/CMakeLists.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
|
||||
add_library(skeldal_linux map_file.cpp timer.cpp)
|
59
platform/linux/map_file.cpp
Normal file
59
platform/linux/map_file.cpp
Normal file
|
@ -0,0 +1,59 @@
|
|||
|
||||
extern "C" {
|
||||
#include "map_file.h"
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Funkce pro mapování souboru do paměti
|
||||
void* map_file_to_memory(const char *name, size_t *sz) {
|
||||
if (!name || !sz) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Otevření souboru pro čtení
|
||||
int fd = open(name, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror("Chyba při otevírání souboru");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Získání velikosti souboru
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) == -1) {
|
||||
perror("Chyba při získávání velikosti souboru");
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
*sz = st.st_size;
|
||||
|
||||
// Namapování souboru do paměti
|
||||
void *mapped = mmap(NULL, *sz, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (mapped == MAP_FAILED) {
|
||||
perror("Chyba při mapování souboru");
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Zavření souborového popisovače (není již potřeba po mmap)
|
||||
close(fd);
|
||||
|
||||
return mapped;
|
||||
}
|
||||
|
||||
// Funkce pro zrušení mapování
|
||||
void unmap_file(void *ptr, size_t sz) {
|
||||
if (!ptr || sz == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Zrušení mapování
|
||||
if (munmap(ptr, sz) == -1) {
|
||||
perror("Chyba při rušení mapování");
|
||||
}
|
||||
}
|
4
platform/linux/map_file.h
Normal file
4
platform/linux/map_file.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
void *map_file_to_memory(const char *name, size_t *sz);
|
||||
void unmap_file(void *ptr, size_t sz);
|
18
platform/linux/timer.cpp
Normal file
18
platform/linux/timer.cpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include "timer.h"
|
||||
#include <chrono>
|
||||
#include "../platform.h"
|
||||
|
||||
#include <thread>
|
||||
int get_timer_value() {
|
||||
auto n = std::chrono::steady_clock::now();
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(n.time_since_epoch()).count()/TIMERSPEED;
|
||||
}
|
||||
|
||||
uint32_t get_game_tick_count() {
|
||||
auto n = std::chrono::steady_clock::now();
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(n.time_since_epoch()).count();
|
||||
}
|
||||
|
||||
void sleep_ms(uint32_t x) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(x));
|
||||
}
|
28
platform/linux/timer.h
Normal file
28
platform/linux/timer.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* timer.h
|
||||
*
|
||||
* Created on: 26. 1. 2025
|
||||
* Author: ondra
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_LINUX_TIMER_H_
|
||||
#define PLATFORM_LINUX_TIMER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int get_timer_value();
|
||||
uint32_t get_game_tick_count();
|
||||
void sleep_ms(uint32_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* PLATFORM_LINUX_TIMER_H_ */
|
7
platform/platform.cpp
Normal file
7
platform/platform.cpp
Normal file
|
@ -0,0 +1,7 @@
|
|||
|
||||
extern "C" {
|
||||
void install_wizard() {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#define BGSWITCHBIT 0x0020
|
||||
|
||||
#define SKELDALINI "WSKELDAL.INI"
|
||||
#define SKELDALINI "wskeldal.ini"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
@ -17,31 +17,17 @@ extern "C"
|
|||
#define _KEYBRD_READY 0
|
||||
#define _KEYBRD_READ 1
|
||||
|
||||
#define TIMERSPEED 20;
|
||||
#define TIMERSPEED 20
|
||||
|
||||
uint32_t _bios_keybrd(int mode);
|
||||
|
||||
|
||||
//LRESULT GameMainWindowWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
void CheckMessageQueue();
|
||||
|
||||
//void DSReportWindowCreation(HWND hWindow);
|
||||
char *AutodetectWinAmp();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define RGB888(r,g,b) ((unsigned short)((((r)<<8)&0xF800) | (((g)<<3) & 0x7C0) | ((b)>>3)))
|
||||
#define RGB555(r,g,b) ((unsigned short)(((r)<<11) | ((g)<<6) | (b)))
|
||||
|
||||
#pragma warning (disable : 4244 4761 4133)
|
||||
|
||||
|
||||
void *LoadDefaultFont();
|
||||
void *LoadResourceFont(const char *name);
|
||||
void *map_file_to_memory(const char *name, size_t *sz);
|
||||
void unmap_file(void *ptr, size_t sz);
|
||||
|
||||
|
@ -56,13 +42,17 @@ int stricmp(const char *a, const char *b);
|
|||
#define MIN(a, b) ((a)<(b)?(a):(b))
|
||||
#define MAX(a, b) ((a)>(b)?(a):(b))
|
||||
void strupr(char *c);
|
||||
const char * itoa(int i, char *c, int radix);
|
||||
const char * int2ascii(int i, char *c, int radix);
|
||||
|
||||
uint32_t get_game_tick_count();
|
||||
void sleep_ms(uint32_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------- BGRAPH DX wrapper -------------------
|
||||
#include "BGraph2Dx.h"
|
||||
#include "sdl/BGraph2.h"
|
||||
|
||||
#define WM_RELOADMAP (WM_APP+215)
|
||||
#define E_RELOADMAP 40
|
112
platform/sdl/BGraph2.cpp
Normal file
112
platform/sdl/BGraph2.cpp
Normal file
|
@ -0,0 +1,112 @@
|
|||
#include "BGraph2.h"
|
||||
|
||||
#include "sdl_context.h"
|
||||
#include "global_context.h"
|
||||
|
||||
|
||||
static std::unique_ptr<uint16_t[]> screen_buffer;
|
||||
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) {
|
||||
|
||||
SDLContext::DisplayMode mode;
|
||||
if (inwindow) {
|
||||
if (zoom) {
|
||||
mode = SDLContext::double_window;
|
||||
} else {
|
||||
mode = SDLContext::native_window;
|
||||
}
|
||||
} else {
|
||||
mode = SDLContext::fullscreen;
|
||||
}
|
||||
|
||||
screen_pitch = 640;
|
||||
get_sdl_global_context().init_screen(mode, "Skeldal"); //todo allow change
|
||||
screen_buffer = std::make_unique<uint16_t[]>(screen_pitch*480);
|
||||
buffer2nd = std::make_unique<uint16_t[]>(screen_pitch*480);
|
||||
render_target = screen_buffer.get();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DXCloseMode() {
|
||||
get_sdl_global_context().close_screen();
|
||||
}
|
||||
|
||||
|
||||
uint16_t *GetScreenAdr() {
|
||||
return render_target;
|
||||
}
|
||||
uint16_t *GetBuffer2nd() {
|
||||
return buffer2nd.get();
|
||||
|
||||
}
|
||||
int32_t GetScreenPitch() {
|
||||
return screen_pitch;
|
||||
}
|
||||
int32_t GetBuffer2ndPitch() {
|
||||
return screen_pitch;
|
||||
}
|
||||
int32_t GetScreenSizeBytes() {
|
||||
return screen_pitch * 480 * 2;
|
||||
}
|
||||
|
||||
void RedirectScreen(uint16_t *newaddr) {
|
||||
render_target = newaddr;
|
||||
}
|
||||
void RestoreScreen() {
|
||||
render_target = screen_buffer.get();
|
||||
}
|
||||
void RedirectScreenBufferSecond() {
|
||||
render_target = buffer2nd.get();
|
||||
}
|
||||
int DxGetResX() {
|
||||
return 640;
|
||||
}
|
||||
int DxGetResY() {
|
||||
return 480;
|
||||
}
|
||||
void setvesa_displaystart(int x,int y){
|
||||
|
||||
}
|
||||
void StripBlt(void *data, unsigned int startline, uint32_t width) {
|
||||
|
||||
unsigned short *start=startline*GetScreenPitch()+GetScreenAdr();
|
||||
while (width--)
|
||||
{
|
||||
memcpy(start,data,640*2);
|
||||
data=(void *)(reinterpret_cast<char *>(data)+get_sdl_global_context().get_surface_pitch());
|
||||
start=start+GetScreenPitch();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 *DxPrepareWalk(int ypos) {
|
||||
return 0;
|
||||
}
|
||||
void DxZoomWalk(void *handle, int ypos, int *points,float phase, void *lodka) {
|
||||
|
||||
}
|
||||
void DxDoneWalk(void *handle) {
|
||||
|
||||
}
|
||||
|
||||
void *DxPrepareTurn(int ypos) {
|
||||
return 0;
|
||||
}
|
||||
void DxTurn(void *handle, char right, int ypos,int border, float phase, void *lodka) {
|
||||
|
||||
}
|
||||
void DxDoneTurn(void *handle) {
|
||||
|
||||
}
|
||||
void DxTurnLeftRight(char right, float phase, int border, int ypos, int *last) {
|
||||
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#ifndef __BGRAPH_DX_WRAPPER_
|
||||
#define __BGRAPH_DX_WRAPPER_
|
||||
|
||||
|
@ -5,21 +7,26 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int32_t scr_linelen;
|
||||
extern int32_t scr_linelen2;
|
||||
extern int32_t dx_linelen;
|
||||
uint16_t *GetScreenAdr();
|
||||
uint16_t *GetBuffer2nd();
|
||||
int32_t GetScreenPitch();
|
||||
int32_t GetBuffer2ndPitch();
|
||||
int32_t GetScreenSizeBytes();
|
||||
|
||||
void RedirectScreen(uint16_t *newaddr);
|
||||
void RestoreScreen();
|
||||
void RedirectScreenBufferSecond();
|
||||
|
||||
|
||||
//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);
|
||||
char DXInit64(char inwindow,int zoom,int monitor, int refresh);
|
||||
|
||||
//uzavre rezim grafiky
|
||||
void DXCloseMode();
|
||||
|
||||
//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 DXCopyRects64zoom2(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);
|
||||
|
@ -35,8 +42,6 @@ void DxDialogs(char enable);
|
|||
|
||||
void setvesa_displaystart(int x,int y);
|
||||
|
||||
extern int32_t scr_linelen;
|
||||
extern int32_t scr_linelen2;
|
||||
|
||||
void DxSetInitResolution(int x, int y);
|
||||
int DxGetResX();
|
||||
|
@ -55,4 +60,4 @@ void StripBlt(void *data, unsigned int startline, uint32_t width);
|
|||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -1 +1,3 @@
|
|||
add_subdirectory(tests)
|
||||
|
||||
add_library(skeldal_sdl sdl_context.cpp BGraph2.cpp input.cpp sound.cpp)
|
11
platform/sdl/global_context.h
Normal file
11
platform/sdl/global_context.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "sdl_context.h"
|
||||
|
||||
inline SDLContext &get_sdl_global_context () {
|
||||
static SDLContext sdl_global_context;
|
||||
return sdl_global_context;
|
||||
}
|
||||
|
||||
|
||||
|
28
platform/sdl/input.cpp
Normal file
28
platform/sdl/input.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include "global_context.h"
|
||||
#include "input.h"
|
||||
|
||||
char get_control_key_state() {
|
||||
return 0; //todo
|
||||
}
|
||||
char get_shift_key_state() {
|
||||
return 0; //todo
|
||||
}
|
||||
uint32_t _bios_keybrd(int mode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetWheelMapping(char up, char down) { //todo
|
||||
|
||||
}
|
||||
|
||||
static MS_EVENT ms_event = {};
|
||||
|
||||
|
||||
|
||||
void get_ms_event(MS_EVENT *event) {
|
||||
*event = ms_event;
|
||||
}
|
||||
|
||||
void ShareCPU() {
|
||||
|
||||
}
|
31
platform/sdl/input.h
Normal file
31
platform/sdl/input.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* input.h
|
||||
*
|
||||
* Created on: 26. 1. 2025
|
||||
* Author: ondra
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_SDL_INPUT_H_
|
||||
#define PLATFORM_SDL_INPUT_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <devices.h>
|
||||
|
||||
|
||||
char get_control_key_state();
|
||||
char get_shift_key_state();
|
||||
uint32_t _bios_keybrd(int mode);
|
||||
void SetWheelMapping(char up, char down);
|
||||
void get_ms_event(MS_EVENT *event);
|
||||
void ShareCPU();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* PLATFORM_SDL_INPUT_H_ */
|
186
platform/sdl/sdl_context.cpp
Normal file
186
platform/sdl/sdl_context.cpp
Normal file
|
@ -0,0 +1,186 @@
|
|||
#include "sdl_context.h"
|
||||
#include "../platform.h"
|
||||
|
||||
#include <stdexcept>
|
||||
void SDLContext::SDL_Deleter::operator ()(SDL_Window* window) {
|
||||
SDL_DestroyWindow(window);
|
||||
}
|
||||
|
||||
void SDLContext::SDL_Deleter::operator ()(SDL_Renderer* renderer) {
|
||||
SDL_DestroyRenderer(renderer);
|
||||
}
|
||||
|
||||
void SDLContext::SDL_Deleter::operator ()(SDL_Surface* surface) {
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
|
||||
void SDLContext::SDL_Deleter::operator ()(SDL_Texture* texture) {
|
||||
SDL_DestroyTexture(texture);
|
||||
}
|
||||
|
||||
struct SDL_INIT_Context {
|
||||
|
||||
SDL_INIT_Context() {
|
||||
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO) < 0) {
|
||||
SDL_Log("Unable to initialize SDL: %s", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
inited = true;
|
||||
}
|
||||
~SDL_INIT_Context() {
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
|
||||
bool inited = false;
|
||||
};
|
||||
|
||||
static SDL_INIT_Context init_context = {};
|
||||
|
||||
SDLContext::SDLContext() {
|
||||
if (!init_context.inited) throw std::runtime_error("SDL not inited");
|
||||
|
||||
}
|
||||
|
||||
void SDLContext::init_screen(DisplayMode mode, const char *title) {
|
||||
char buff[256];
|
||||
|
||||
int width = 640;
|
||||
int height = 480;
|
||||
if (mode == double_window) {
|
||||
width*=2;
|
||||
height*=2;
|
||||
}
|
||||
SDL_Window *window = SDL_CreateWindow(title,
|
||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
width, height, SDL_WINDOW_RESIZABLE|(mode==fullscreen?SDL_WINDOW_FULLSCREEN_DESKTOP:0));
|
||||
|
||||
if (!window) {
|
||||
snprintf(buff, sizeof(buff), "SDL Error create window: %s\n", SDL_GetError());
|
||||
throw std::runtime_error(buff);
|
||||
}
|
||||
|
||||
_window.reset(window);
|
||||
SDL_Renderer *renderer = SDL_CreateRenderer(_window.get(), -1, 0);
|
||||
if (!renderer) {
|
||||
snprintf(buff,sizeof(buff), "Chyba při vytváření rendereru: %s\n", SDL_GetError());
|
||||
throw std::runtime_error(buff);
|
||||
}
|
||||
_renderer.reset(renderer);
|
||||
// Vytvoření softwarového backbufferu (surface)
|
||||
SDL_Surface *backbuffer = SDL_CreateRGBSurfaceWithFormat(0, 640, 480, 16, SDL_PIXELFORMAT_RGB565);
|
||||
if (!backbuffer) {
|
||||
snprintf(buff,sizeof(buff), "Chyba při vytváření surface: %s\n", SDL_GetError());
|
||||
throw std::runtime_error(buff);
|
||||
}
|
||||
_surface.reset(backbuffer);
|
||||
// Vytvoření textury pro zobrazení backbufferu
|
||||
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, 640, 480);
|
||||
if (!texture) {
|
||||
snprintf(buff, sizeof(buff), "Chyba při vytváření textury: %s\n", SDL_GetError());
|
||||
throw std::runtime_error(buff);
|
||||
}
|
||||
_texture.reset(texture);
|
||||
|
||||
SDL_LockSurface(_surface.get());
|
||||
|
||||
if (!_timer_event) _timer_event = SDL_RegisterEvents(1);
|
||||
_fullscreen_mode = mode == fullscreen;
|
||||
}
|
||||
|
||||
void SDLContext::close_screen() {
|
||||
SDL_UnlockSurface(_surface.get());
|
||||
_texture.reset();
|
||||
_surface.reset();
|
||||
_renderer.reset();
|
||||
_window.reset();
|
||||
|
||||
}
|
||||
|
||||
uint16_t* SDLContext::get_surface_addr() {
|
||||
return reinterpret_cast<uint16_t *>(_surface->pixels);
|
||||
}
|
||||
|
||||
|
||||
int32_t SDLContext::get_surface_pitch() {
|
||||
return _surface->pitch;
|
||||
}
|
||||
|
||||
|
||||
void SDLContext::charge_timer() {
|
||||
_active_timer = SDL_AddTimer(1000/TIMERSPEED, [](Uint32 interval, void *param) -> Uint32 {
|
||||
SDLContext *me = reinterpret_cast<SDLContext *>(param);
|
||||
SDL_Event* event = (SDL_Event*)param;
|
||||
event->type = me->_timer_event;
|
||||
SDL_PushEvent(event);
|
||||
return 0;
|
||||
}, this);
|
||||
|
||||
}
|
||||
void SDLContext::pool_events() {
|
||||
if (!_active_timer.has_value()) charge_timer();
|
||||
SDL_Event e;
|
||||
while (true) {
|
||||
if (SDL_WaitEvent(&e)) {
|
||||
if (e.type == SDL_QUIT) {
|
||||
_quit_requested = true;
|
||||
return;
|
||||
}
|
||||
if (e.type == _timer_event) {
|
||||
break;
|
||||
}
|
||||
if (e.type == SDL_KEYDOWN) {
|
||||
if (e.key.keysym.sym == SDLK_RETURN && (e.key.keysym.mod & KMOD_ALT)) {
|
||||
_fullscreen_mode = !_fullscreen_mode;
|
||||
SDL_SetWindowFullscreen(_window.get(), _fullscreen_mode ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
||||
}
|
||||
} else if (e.type == SDL_MOUSEMOTION) {
|
||||
int mouseX = e.motion.x;
|
||||
int mouseY = e.motion.y;
|
||||
int windowWidth;
|
||||
int windowHeight;
|
||||
SDL_GetWindowSize(_window.get(), &windowWidth, &windowHeight);
|
||||
float normalizedX = (float)mouseX / windowWidth;
|
||||
float normalizedY = (float)mouseY / windowHeight;
|
||||
ms_event.event = 1;
|
||||
ms_event.event_type = 1;
|
||||
ms_event.x = (int16_t)(640*normalizedX);
|
||||
ms_event.y = (int16_t)(480*normalizedY);
|
||||
} else if (e.type == SDL_MOUSEBUTTONDOWN || e.type == SDL_MOUSEBUTTONUP) {
|
||||
int mouseX = e.button.x;
|
||||
int mouseY = e.button.y;
|
||||
int button = e.button.button;
|
||||
int up = e.type == SDL_MOUSEBUTTONUP?1:0;
|
||||
ms_event.event = 1;
|
||||
ms_event.event_type = (1<<(2*button-1+up));
|
||||
switch (button) {
|
||||
default: break;
|
||||
case 1: ms_event.tl1 = !up; break;
|
||||
case 2: ms_event.tl2 = !up; break;
|
||||
case 3: ms_event.tl3 = !up; break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
throw std::runtime_error("SDL_WaitEvent error");
|
||||
}
|
||||
}
|
||||
charge_timer();
|
||||
|
||||
}
|
||||
|
||||
void SDLContext::present_rect(uint16_t *pixels, unsigned int pitch,
|
||||
unsigned int x, unsigned int y, unsigned int xs, unsigned ys) {
|
||||
|
||||
auto beg = pixels + y * pitch + y;
|
||||
SDL_Rect r = {static_cast<int>(x),
|
||||
static_cast<int>(y),
|
||||
static_cast<int>(xs),
|
||||
static_cast<int>(ys)};
|
||||
SDL_UpdateTexture(_texture.get(), &r, beg, pitch*2);
|
||||
SDL_RenderClear(_renderer.get());
|
||||
SDL_RenderCopy(_renderer.get(), _texture.get(), NULL, NULL);
|
||||
SDL_RenderPresent(_renderer.get());
|
||||
|
||||
|
||||
}
|
55
platform/sdl/sdl_context.h
Normal file
55
platform/sdl/sdl_context.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <mouse.h>
|
||||
|
||||
class SDLContext {
|
||||
public:
|
||||
|
||||
SDLContext();
|
||||
|
||||
enum DisplayMode {
|
||||
native_window,
|
||||
double_window,
|
||||
fullscreen
|
||||
};
|
||||
|
||||
|
||||
void init_screen(DisplayMode mode, const char *title);
|
||||
|
||||
void close_screen();
|
||||
|
||||
|
||||
uint16_t *get_surface_addr();
|
||||
int32_t get_surface_pitch();
|
||||
|
||||
|
||||
void pool_events();
|
||||
|
||||
void present_rect(uint16_t *pixels, unsigned int pitch, unsigned int x, unsigned int y, unsigned int xs,unsigned ys);
|
||||
|
||||
protected:
|
||||
|
||||
struct SDL_Deleter {
|
||||
void operator()(SDL_Window *);
|
||||
void operator()(SDL_Renderer *);
|
||||
void operator()(SDL_Surface *);
|
||||
void operator()(SDL_Texture *);
|
||||
};
|
||||
|
||||
MS_EVENT ms_event;
|
||||
|
||||
std::unique_ptr<SDL_Window, SDL_Deleter> _window;
|
||||
std::unique_ptr<SDL_Renderer, SDL_Deleter> _renderer;
|
||||
std::unique_ptr<SDL_Surface, SDL_Deleter> _surface;
|
||||
std::unique_ptr<SDL_Texture, SDL_Deleter> _texture;
|
||||
|
||||
std::optional<SDL_TimerID> _active_timer;
|
||||
Uint32 _timer_event = 0;
|
||||
|
||||
bool _quit_requested = false;
|
||||
bool _fullscreen_mode = false;
|
||||
void charge_timer();
|
||||
};
|
78
platform/sdl/sound.cpp
Normal file
78
platform/sdl/sound.cpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
#include "../platform.h"
|
||||
#include <zvuk.h>
|
||||
|
||||
void set_mixing_device(int mix_dev,int mix_freq,...) {
|
||||
|
||||
}
|
||||
char start_mixing() {
|
||||
return 0;
|
||||
}
|
||||
void stop_mixing() {
|
||||
|
||||
}
|
||||
void play_sample(int channel,void *sample,int32_t size,int32_t lstart,int32_t sfreq,int type) {
|
||||
|
||||
}
|
||||
void set_channel_volume(int channel,int left,int right) {
|
||||
|
||||
}
|
||||
void set_end_of_song_callback(const char * (*cb)(void *), void *ctx) {
|
||||
|
||||
}
|
||||
|
||||
void fade_music() {
|
||||
|
||||
}
|
||||
int mix_back_sound(int synchro) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//int open_backsound(char *filename);
|
||||
void change_music(const char *filename) {
|
||||
|
||||
}
|
||||
|
||||
//char *device_name(int device);
|
||||
//void force_music_volume(int volume);
|
||||
|
||||
//void set_backsnd_freq(int freq);
|
||||
|
||||
char get_channel_state(int channel) {
|
||||
return 0;
|
||||
}
|
||||
void get_channel_volume(int channel,int *left,int *right) {
|
||||
|
||||
}
|
||||
void mute_channel(int channel) {
|
||||
|
||||
}
|
||||
void chan_break_loop(int channel) {
|
||||
|
||||
}
|
||||
void chan_break_ext(int channel,void *org_sample,int32_t size_sample) {
|
||||
|
||||
}
|
||||
|
||||
char set_snd_effect(int funct,int data) {
|
||||
return 0;
|
||||
}
|
||||
char check_snd_effect(int funct) {
|
||||
return 0;
|
||||
}
|
||||
int get_snd_effect(int funct) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *PrepareVideoSound(int mixfreq, int buffsize) {
|
||||
return 0;
|
||||
}
|
||||
char LoadNextVideoFrame(void *buffer, char *data, int size, short *xlat, short *accnums, int32_t *writepos) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
void DoneVideoSound(void *buffer) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
15
platform/sdl/sound.h
Normal file
15
platform/sdl/sound.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* sound.h
|
||||
*
|
||||
* Created on: 26. 1. 2025
|
||||
* Author: ondra
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_SDL_SOUND_H_
|
||||
#define PLATFORM_SDL_SOUND_H_
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* PLATFORM_SDL_SOUND_H_ */
|
|
@ -1,6 +1,8 @@
|
|||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests/)
|
||||
|
||||
set(testFiles sdl_minimal_test.cpp sdl_surface_test.cpp
|
||||
set(testFiles sdl_minimal_test.cpp sdl_surface_test.cpp
|
||||
sdl_mouse.cpp
|
||||
sdl_update_texture.cpp
|
||||
)
|
||||
|
||||
foreach (testFile ${testFiles})
|
||||
|
|
79
platform/sdl/tests/sdl_mouse.cpp
Normal file
79
platform/sdl/tests/sdl_mouse.cpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
#include <SDL2/SDL.h>
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||
std::cerr << "SDL_Init Error: " << SDL_GetError() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_Window* window = SDL_CreateWindow("SDL Mouse Event Example", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_RESIZABLE);
|
||||
if (!window) {
|
||||
std::cerr << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
||||
if (!renderer) {
|
||||
std::cerr << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_Event e;
|
||||
bool quit = false;
|
||||
int isFullscreen = 0;
|
||||
|
||||
while (!quit) {
|
||||
while (SDL_PollEvent(&e)) {
|
||||
if (e.type == SDL_QUIT) {
|
||||
quit = true;
|
||||
} else if (e.type == SDL_MOUSEMOTION) {
|
||||
// Získání souřadnic myši
|
||||
int mouseX = e.motion.x, mouseY = e.motion.y;
|
||||
|
||||
// Přepočet souřadnic na poměr vůči rozměrům okna
|
||||
int windowWidth, windowHeight;
|
||||
SDL_GetWindowSize(window, &windowWidth, &windowHeight);
|
||||
|
||||
float normalizedX = (float)mouseX / windowWidth;
|
||||
float normalizedY = (float)mouseY / windowHeight;
|
||||
|
||||
std::cout << "Mouse moved to: (" << mouseX << ", " << mouseY << ") -> Normalized: ("
|
||||
<< normalizedX << ", " << normalizedY << ")" << std::endl;
|
||||
} else if (e.type == SDL_MOUSEBUTTONDOWN || e.type == SDL_MOUSEBUTTONUP) {
|
||||
int mouseX = e.button.x, mouseY = e.button.y;
|
||||
int button = e.button.button;
|
||||
|
||||
if (e.type == SDL_MOUSEBUTTONDOWN) {
|
||||
std::cout << "Mouse button pressed at: (" << mouseX << ", " << mouseY << ") button " << button << std::endl;
|
||||
} else {
|
||||
std::cout << "Mouse button released at: (" << mouseX << ", " << mouseY << ") button " << button << std::endl;
|
||||
}
|
||||
} else if (e.type == SDL_MOUSEWHEEL) {
|
||||
if (e.wheel.y > 0) {
|
||||
std::cout << "Mouse wheel scrolled up." << std::endl;
|
||||
} else if (e.wheel.y < 0) {
|
||||
std::cout << "Mouse wheel scrolled down." << std::endl;
|
||||
}
|
||||
} else if (e.type == SDL_KEYDOWN) {
|
||||
if (e.key.keysym.sym == SDLK_RETURN && (e.key.keysym.mod & KMOD_ALT)) {
|
||||
// Přepnutí mezi fullscreen a oknem
|
||||
isFullscreen = !isFullscreen;
|
||||
SDL_SetWindowFullscreen(window, isFullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Renderování a další logika hry
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#define WIDTH 640
|
||||
#define HEIGHT 480
|
||||
|
||||
#define PITCH 1024 // Pro optimalizaci paměti (pitch může být širší než WIDTH)
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// Inicializace SDL
|
||||
|
@ -14,14 +14,14 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
// Vytvoření SDL okna
|
||||
SDL_Window *window = SDL_CreateWindow("DOS Game Port", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, 0);
|
||||
SDL_Window *window = SDL_CreateWindow("DOS Game Port", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, SDL_WINDOW_RESIZABLE);
|
||||
if (!window) {
|
||||
fprintf(stderr, "Chyba při vytváření okna: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Vytvoření rendereru (pouze pro zobrazení)
|
||||
// Vytvoření SDL rendereru
|
||||
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
||||
if (!renderer) {
|
||||
fprintf(stderr, "Chyba při vytváření rendereru: %s\n", SDL_GetError());
|
||||
|
@ -30,9 +30,9 @@ int main(int argc, char *argv[]) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
// Vytvoření SDL Surface (backbuffer)
|
||||
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565,SDL_TEXTUREACCESS_STREAMING, WIDTH, HEIGHT);
|
||||
if (!texture) {
|
||||
// Vytvoření softwarového backbufferu (surface)
|
||||
SDL_Surface *backbuffer = SDL_CreateRGBSurfaceWithFormat(0, PITCH, HEIGHT, 16, SDL_PIXELFORMAT_RGB565);
|
||||
if (!backbuffer) {
|
||||
fprintf(stderr, "Chyba při vytváření surface: %s\n", SDL_GetError());
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
|
@ -40,31 +40,56 @@ int main(int argc, char *argv[]) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
void *raw_pixels;
|
||||
int pitch;
|
||||
SDL_LockTexture(texture, NULL, &raw_pixels, &pitch);
|
||||
// Přímý přístup do paměti surface
|
||||
Uint16 *pixels = reinterpret_cast<Uint16 *>(raw_pixels);
|
||||
printf("Adresa pixelů: %p, pitch: %d bajtů\n", (void *)pixels, pitch);
|
||||
|
||||
// Software rendering - příklad kreslení do paměti
|
||||
for (int y = 0; y < HEIGHT; y++) {
|
||||
for (int x = 0; x < WIDTH; x++) {
|
||||
Uint16 color = (x ^ y) & 0xFFFF; // Příklad barvy
|
||||
pixels[y * (pitch / 2) + x] = color; // Zápis pixelu
|
||||
}
|
||||
// Vytvoření textury pro zobrazení backbufferu
|
||||
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, WIDTH, HEIGHT);
|
||||
if (!texture) {
|
||||
fprintf(stderr, "Chyba při vytváření textury: %s\n", SDL_GetError());
|
||||
SDL_FreeSurface(backbuffer);
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_UnlockTexture(texture);
|
||||
// Hlavní smyčka
|
||||
int running = 1;
|
||||
int frame = 0;
|
||||
while (running) {
|
||||
frame++;
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
if (event.type == SDL_QUIT) {
|
||||
running = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
||||
SDL_RenderPresent(renderer);
|
||||
// Přímý přístup do paměti backbufferu
|
||||
Uint16 *pixels = (Uint16 *)backbuffer->pixels;
|
||||
int pitch = backbuffer->pitch / 2; // Pitch v počtu pixelů (ne bajtů)
|
||||
|
||||
SDL_Delay(3000); // Zobrazení okna na 3 sekundy
|
||||
// Software rendering - příklad (čtení a zápis do backbufferu)
|
||||
for (int y = 0; y < HEIGHT; y++) {
|
||||
for (int x = 0; x < WIDTH; x++) {
|
||||
Uint16 color = (x ^ y ^ frame) & 0xFFFF; // Vzor barvy (testovací)
|
||||
pixels[y * pitch + x] = color; // Zápis pixelu
|
||||
}
|
||||
}
|
||||
|
||||
// Kopírování backbufferu do textury
|
||||
SDL_UpdateTexture(texture, NULL, backbuffer->pixels, backbuffer->pitch);
|
||||
|
||||
// Vykreslení textury na obrazovku
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
||||
SDL_RenderPresent(renderer);
|
||||
|
||||
// Zpoždění pro demonstraci (30 FPS)
|
||||
SDL_Delay(1000 / 30);
|
||||
}
|
||||
|
||||
// Uvolnění zdrojů
|
||||
SDL_DestroyTexture(texture);
|
||||
SDL_FreeSurface(backbuffer);
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
|
|
91
platform/sdl/tests/sdl_update_texture.cpp
Normal file
91
platform/sdl/tests/sdl_update_texture.cpp
Normal file
|
@ -0,0 +1,91 @@
|
|||
#include <SDL2/SDL.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define WIDTH 640
|
||||
#define HEIGHT 480
|
||||
#define PITCH 1024 // Pro optimalizaci paměti (pitch může být širší než WIDTH)
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// Inicializace SDL
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||
fprintf(stderr, "Chyba při inicializaci SDL: %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Vytvoření SDL okna
|
||||
SDL_Window *window = SDL_CreateWindow("DOS Game Port", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, SDL_WINDOW_RESIZABLE);
|
||||
if (!window) {
|
||||
fprintf(stderr, "Chyba při vytváření okna: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// Vytvoření SDL rendereru
|
||||
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
||||
if (!renderer) {
|
||||
fprintf(stderr, "Chyba při vytváření rendereru: %s\n", SDL_GetError());
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// Vytvoření textury pro zobrazení backbufferu
|
||||
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, WIDTH, HEIGHT);
|
||||
if (!texture) {
|
||||
fprintf(stderr, "Chyba při vytváření textury: %s\n", SDL_GetError());
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16_t *pixels = new uint16_t[HEIGHT*WIDTH];
|
||||
int pitch = WIDTH;
|
||||
|
||||
|
||||
// Hlavní smyčka
|
||||
int running = 1;
|
||||
int frame = 0;
|
||||
while (running) {
|
||||
frame++;
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
if (event.type == SDL_QUIT) {
|
||||
running = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Přímý přístup do paměti backbufferu
|
||||
|
||||
// Software rendering - příklad (čtení a zápis do backbufferu)
|
||||
for (int y = 0; y < HEIGHT; y++) {
|
||||
for (int x = 0; x < WIDTH; x++) {
|
||||
Uint16 color = (x ^ y ^ frame) & 0xFFFF; // Vzor barvy (testovací)
|
||||
pixels[y * pitch + x] = color; // Zápis pixelu
|
||||
}
|
||||
}
|
||||
|
||||
// Kopírování backbufferu do textury
|
||||
SDL_UpdateTexture(texture, NULL, pixels, pitch*2);
|
||||
|
||||
// Vykreslení textury na obrazovku
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
||||
SDL_RenderPresent(renderer);
|
||||
|
||||
// Zpoždění pro demonstraci (30 FPS)
|
||||
SDL_Delay(1000 / 30);
|
||||
}
|
||||
|
||||
// Uvolnění zdrojů
|
||||
SDL_DestroyTexture(texture);
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
delete [] pixels;
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue