Migrate to SDL2 and deploy as WASM
All checks were successful
Build & deploy web version / Build WebAssembly & deploy (push) Successful in 1m8s
All checks were successful
Build & deploy web version / Build WebAssembly & deploy (push) Successful in 1m8s
This commit is contained in:
parent
81f4f20899
commit
c9b542eccf
1 changed files with 1411 additions and 483 deletions
|
|
@ -1,48 +1,208 @@
|
|||
#include "auxSDL.h"
|
||||
#include "../camera.h"
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/html5.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
mousePos mouse; /**< Az egér koordinátáit tárolja, így egyszerűbb, mint közvetlen az eventek figyelése. */
|
||||
|
||||
static SDL_Window* window;
|
||||
static SDL_Renderer* renderer;
|
||||
static SDL_Texture* frameTexture;
|
||||
static int textureWidth, textureHeight;
|
||||
|
||||
/** \brief https://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlcreatecursor.html
|
||||
* Hogy erre miért van szükség, az egy nagyon jó kérdés. Ha ehelyett a "SDL_ShowCursor(SDL_DISABLE);"-t
|
||||
* használnám az egér random ugrálna néha néha, így viszont ezt nem teszi.
|
||||
*/
|
||||
static SDL_Cursor* createCursor() {
|
||||
Uint8 data[4*32] = {0};
|
||||
Uint8 mask[4*32] = {0};
|
||||
return SDL_CreateCursor(data, mask, 32, 32, 0, 0);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
///A böngésző pixelarányát adja vissza, a szoftveres rajzolás miatt megszabott plafonig.
|
||||
static double drawingPixelRatio() {
|
||||
double ratio = emscripten_get_device_pixel_ratio();
|
||||
return ratio > maxDevicePixelRatio ? maxDevicePixelRatio : ratio;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void moveToResourceDirectory() {
|
||||
#ifndef __EMSCRIPTEN__
|
||||
char* base = SDL_GetBasePath();
|
||||
if(base != NULL) {
|
||||
if(chdir(base) != 0) fprintf(stderr, "Nem sikerult a munkakonyvtar valtas!\n");
|
||||
SDL_free(base);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Létrehozza a játék futtatásához szükséges környezetet.
|
||||
* Megnézi az elérhető legnagyobb felbontást, azzal a felbontással létrehoz egy ablakot, illetve
|
||||
* meghív pár, az inicializáláshoz szükséges függvényt.
|
||||
* \return kurzor amit fel kell később szabadítanunk
|
||||
/** \brief Gondoskodik róla, hogy a textúra legalább a kért méretű legyen.
|
||||
* Böngészőben a textúra eldobása átméretezéskor elveszejti a webgl kontextust, ezért
|
||||
* a textúrát egyszer, jó bőre foglaljuk, és utána már csak egy részét használjuk.
|
||||
*/
|
||||
SDL_Cursor* openWindow() {
|
||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
|
||||
SDL_Rect** screenSizes = SDL_ListModes(NULL, SDL_FULLSCREEN);
|
||||
static void ensureTexture(int width, int height) {
|
||||
if(frameTexture != NULL && width <= textureWidth && height <= textureHeight) return;
|
||||
|
||||
screen = SDL_SetVideoMode(screenSizes[0] -> w, screenSizes[0] -> h, 0, SDL_FULLSCREEN);
|
||||
if(width > textureWidth) textureWidth = width;
|
||||
if(height > textureHeight) textureHeight = height;
|
||||
|
||||
if (!screen) {
|
||||
fprintf(stderr, "Nem sikerult megnyitni az ablakot!\n");
|
||||
SDL_DestroyTexture(frameTexture);
|
||||
frameTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STREAMING, textureWidth, textureHeight);
|
||||
|
||||
if(frameTexture == NULL) {
|
||||
fprintf(stderr, "Nem sikerult letrehozni a texturat: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief A megadott méretű rajzfelületet hozza létre a régi helyére.
|
||||
* A rajzfelület mindig pontosan akkora, mint a megjelenítő felülete, így nincs se
|
||||
* fekete csík, se átméretezés.
|
||||
*/
|
||||
static void createDrawingSurface(int width, int height) {
|
||||
if(width < 1) width = 1;
|
||||
if(height < 1) height = 1;
|
||||
|
||||
ensureTexture(width, height);
|
||||
|
||||
SDL_FreeSurface(screen);
|
||||
screen = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, SDL_PIXELFORMAT_ARGB8888);
|
||||
|
||||
if(screen == NULL) {
|
||||
fprintf(stderr, "Nem sikerult letrehozni a rajzfeluletet: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
SDL_WM_SetCaption("Platform játék", "Schmelczer András: Platform játék");
|
||||
SDL_Cursor* cursor = createCursor();
|
||||
SDL_SetCursor(cursor);
|
||||
openFonts();
|
||||
SDL_WM_GrabInput(SDL_GRAB_FULLSCREEN);
|
||||
return cursor;
|
||||
SDL_RenderSetLogicalSize(renderer, width, height);
|
||||
}
|
||||
|
||||
///A játék időzítéséhez szükséges.
|
||||
Uint32 timer(Uint32 ms, void* param) {
|
||||
SDL_Event event;
|
||||
event.type = SDL_USEREVENT;
|
||||
SDL_PushEvent(&event);
|
||||
return ms;
|
||||
/** \brief Az ablak méretének változását követi le, képkockánként meghívva.
|
||||
* Böngészőben a vászon css-méretéhez igazítja az ablakot, majd ha kell, új rajzfelületet
|
||||
* készít, a betűtípusokat a magassághoz igazítja, és a kamerával újraszámoltatja,
|
||||
* hogy mennyi látszik a pályából.
|
||||
*/
|
||||
void handleResize() {
|
||||
#ifdef __EMSCRIPTEN__
|
||||
double cssWidth, cssHeight;
|
||||
if(emscripten_get_element_css_size("#canvas", &cssWidth, &cssHeight) == EMSCRIPTEN_RESULT_SUCCESS) {
|
||||
double ratio = drawingPixelRatio();
|
||||
int wantedWidth = (int)(cssWidth * ratio);
|
||||
int wantedHeight = (int)(cssHeight * ratio);
|
||||
|
||||
int currentWidth, currentHeight;
|
||||
SDL_GetWindowSize(window, ¤tWidth, ¤tHeight);
|
||||
|
||||
if(wantedWidth > 0 && wantedHeight > 0 && (wantedWidth != currentWidth || wantedHeight != currentHeight))
|
||||
SDL_SetWindowSize(window, wantedWidth, wantedHeight);
|
||||
}
|
||||
#endif
|
||||
|
||||
int outputWidth, outputHeight;
|
||||
SDL_GetRendererOutputSize(renderer, &outputWidth, &outputHeight);
|
||||
|
||||
if(screen != NULL && screen -> w == outputWidth && screen -> h == outputHeight) return;
|
||||
|
||||
bool heightChanged = screen == NULL || screen -> h != outputHeight;
|
||||
createDrawingSurface(outputWidth, outputHeight);
|
||||
|
||||
if(heightChanged) {
|
||||
freeFonts();
|
||||
openFonts();
|
||||
}
|
||||
|
||||
refreshCameraForScreen();
|
||||
}
|
||||
|
||||
/** \brief Létrehozza a játék futtatásához szükséges környezetet.
|
||||
* Létrehoz egy ablakot a hozzá tartozó rajzfelülettel, illetve
|
||||
* meghív pár, az inicializáláshoz szükséges függvényt.
|
||||
*/
|
||||
void openWindow() {
|
||||
if(SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||
fprintf(stderr, "Nem sikerult inicializalni az SDL-t: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
moveToResourceDirectory();
|
||||
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
|
||||
|
||||
int windowWidth = defaultWindowWidth;
|
||||
int windowHeight = defaultWindowHeight;
|
||||
Uint32 windowFlags = 0;
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
double cssWidth, cssHeight;
|
||||
if(emscripten_get_element_css_size("#canvas", &cssWidth, &cssHeight) == EMSCRIPTEN_RESULT_SUCCESS) {
|
||||
double ratio = drawingPixelRatio();
|
||||
windowWidth = (int) (cssWidth * ratio);
|
||||
windowHeight = (int) (cssHeight * ratio);
|
||||
}
|
||||
#else
|
||||
windowFlags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
|
||||
|
||||
SDL_Rect usableBounds;
|
||||
if(SDL_GetDisplayUsableBounds(0, &usableBounds) == 0) {
|
||||
float fit = smallerF((float) usableBounds.w / defaultWindowWidth, (float) usableBounds.h / defaultWindowHeight);
|
||||
if(fit < 1.0f) {
|
||||
windowWidth = (int) (defaultWindowWidth * fit);
|
||||
windowHeight = (int) (defaultWindowHeight * fit);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const char* forcedSize = SDL_getenv("GAME_WINDOW");
|
||||
if(forcedSize != NULL) sscanf(forcedSize, "%dx%d", &windowWidth, &windowHeight);
|
||||
|
||||
window = SDL_CreateWindow("Platform játék",
|
||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
windowWidth, windowHeight,
|
||||
windowFlags);
|
||||
|
||||
if(window == NULL) {
|
||||
fprintf(stderr, "Nem sikerult megnyitni az ablakot: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||
if(renderer == NULL) renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
|
||||
if(renderer == NULL) {
|
||||
fprintf(stderr, "Nem sikerult letrehozni a renderert: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
int screenPixelWidth, screenPixelHeight;
|
||||
emscripten_get_screen_size(&screenPixelWidth, &screenPixelHeight);
|
||||
double screenRatio = drawingPixelRatio();
|
||||
textureWidth = (int)(screenPixelWidth * screenRatio);
|
||||
textureHeight = (int)(screenPixelHeight * screenRatio);
|
||||
#else
|
||||
SDL_DisplayMode desktop;
|
||||
if(SDL_GetDesktopDisplayMode(0, &desktop) == 0) {
|
||||
textureWidth = desktop.w;
|
||||
textureHeight = desktop.h;
|
||||
}
|
||||
#endif
|
||||
|
||||
int outputWidth, outputHeight;
|
||||
SDL_GetRendererOutputSize(renderer, &outputWidth, &outputHeight);
|
||||
createDrawingSurface(outputWidth, outputHeight);
|
||||
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
openFonts();
|
||||
}
|
||||
|
||||
void presentFrame() {
|
||||
SDL_Rect used = {0, 0, screen -> w, screen -> h};
|
||||
SDL_UpdateTexture(frameTexture, &used, screen -> pixels, screen -> pitch);
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderCopy(renderer, frameTexture, &used, NULL);
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
void closeWindow() {
|
||||
SDL_FreeSurface(screen);
|
||||
SDL_DestroyTexture(frameTexture);
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
}
|
||||
|
||||
///Frissití az egér pozicióját.
|
||||
|
|
@ -58,10 +218,11 @@ mousePos getMousePosition() {
|
|||
|
||||
///Lerajzolja a képernyőre az egeret, erre azért van szükség, mert az SDL csak fekete-fehér egérmutatót kezel.
|
||||
void drawMouse(bool isBW) {
|
||||
Sint16 x1 = mouse.x - mouseSize / 2;
|
||||
Sint16 x2 = mouse.x + mouseSize / 2;
|
||||
Sint16 y1 = mouse.y - mouseSize / 2;
|
||||
Sint16 y2 = mouse.y + mouseSize / 2;
|
||||
Sint16 size = larger(4, mouseSize * screen -> h / designHeight);
|
||||
Sint16 x1 = mouse.x - size / 2;
|
||||
Sint16 x2 = mouse.x + size / 2;
|
||||
Sint16 y1 = mouse.y - size / 2;
|
||||
Sint16 y2 = mouse.y + size / 2;
|
||||
boxColor(screen, x1, y1, x2, y2, isBW ? 0x7F7F7FFF : 0xFFFF00FF);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue