From de29b11a88dbdd3af0824e59b51528b91ee73c54 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Thu, 30 Nov 2017 22:49:38 +0100 Subject: First commit. Version works on Linux (keyboard only, not configurable) --- src/sdl/audio.c | 70 +++++++++++++++++ src/sdl/audio.h | 30 ++++++++ src/sdl/graphics.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/sdl/graphics.h | 65 ++++++++++++++++ src/sdl/input.c | 88 +++++++++++++++++++++ src/sdl/input.h | 21 +++++ src/sdl/system.c | 43 +++++++++++ src/sdl/system.h | 15 ++++ 8 files changed, 552 insertions(+) create mode 100644 src/sdl/audio.c create mode 100644 src/sdl/audio.h create mode 100644 src/sdl/graphics.c create mode 100644 src/sdl/graphics.h create mode 100644 src/sdl/input.c create mode 100644 src/sdl/input.h create mode 100644 src/sdl/system.c create mode 100644 src/sdl/system.h (limited to 'src/sdl') diff --git a/src/sdl/audio.c b/src/sdl/audio.c new file mode 100644 index 0000000..8e19bf9 --- /dev/null +++ b/src/sdl/audio.c @@ -0,0 +1,70 @@ +#include "audio.h" +#include + +void PHL_AudioInit() +{ + SDL_InitSubSystem(SDL_INIT_AUDIO); + Mix_Init(0); + Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 4096); +} + +void PHL_AudioClose() +{ + Mix_CloseAudio(); + Mix_Quit(); +} + +//Same as PHL_LoadSound, but expects a file name without extension +PHL_Music PHL_LoadMusic(char* fname, int loop) +{ + PHL_Music ret; + ret.loop = loop; + char buff[4096]; + strcpy(buff, "data/"); + strcat(buff, fname); + strcat(buff, ".mid"); + ret.snd = Mix_LoadMUS(buff); + return ret; +} + +PHL_Sound PHL_LoadSound(char* fname) +{ + char buff[4096]; + strcpy(buff, "data/"); + strcat(buff, fname); + return Mix_LoadWAV(buff); +} + + +void PHL_PlayMusic(PHL_Music snd) +{ + if(snd.snd) + Mix_PlayMusic(snd.snd, snd.loop?-1:0); +} + +void PHL_PlaySound(PHL_Sound snd, int channel) +{ + Mix_PlayChannel(channel, snd, 0); +} + +void PHL_StopMusic() +{ + Mix_HaltMusic(); +} + +void PHL_StopSound(PHL_Sound snd, int channel) +{ + Mix_HaltChannel(channel); +} + +void PHL_FreeMusic(PHL_Music snd) +{ + if(snd.snd) + Mix_FreeMusic(snd.snd); + snd.snd = NULL; +} + +void PHL_FreeSound(PHL_Sound snd) +{ + Mix_FreeChunk(snd); +} diff --git a/src/sdl/audio.h b/src/sdl/audio.h new file mode 100644 index 0000000..2cf30d3 --- /dev/null +++ b/src/sdl/audio.h @@ -0,0 +1,30 @@ +#ifndef SDLAUDIO_H +#define SDLAUDIO_H + +#include + +//#define PHL_Music Mix_Music* +#define PHL_Sound Mix_Chunk* +typedef struct +{ + int loop; + Mix_Music* snd; + +} PHL_Music; + +void PHL_AudioInit(); +void PHL_AudioClose(); + +PHL_Music PHL_LoadMusic(char* fname, int loop); //Same as PHL_LoadSound, but expects a file name without extension +PHL_Sound PHL_LoadSound(char* fname); + +void PHL_PlayMusic(PHL_Music snd); +void PHL_PlaySound(PHL_Sound snd, int channel); + +void PHL_StopMusic(); +void PHL_StopSound(PHL_Sound snd, int channel); + +void PHL_FreeMusic(PHL_Music snd); +void PHL_FreeSound(PHL_Sound snd); + +#endif \ No newline at end of file diff --git a/src/sdl/graphics.c b/src/sdl/graphics.c new file mode 100644 index 0000000..fa03f49 --- /dev/null +++ b/src/sdl/graphics.c @@ -0,0 +1,220 @@ +#include +#include "../PHL.h" +#include "../game.h" +#include "../qda.h" +#include "graphics.h" + +SDL_Surface* screen = NULL; +SDL_Surface* drawbuffer = NULL; +SDL_Surface* backbuffer = NULL; + +SDL_Color PHL_NewRGB(uint8_t r, uint8_t g, uint8_t b) +{ + SDL_Color ret = {.r = r, .b = b, .g = g}; + return ret; +} + +void PHL_GraphicsInit() +{ + if ( SDL_Init(SDL_INIT_VIDEO) < 0) { + fprintf(stderr, "Error"); + SDL_Delay(5000); + exit(EXIT_FAILURE); + } + + SDL_ShowCursor(SDL_DISABLE); + + uint32_t flags = SDL_HWSURFACE|SDL_DOUBLEBUF; + #ifdef PANDORA + flags |= SDL_FULLSCREEEN; + #endif + screen = SDL_SetVideoMode(640, 480, 0, flags); + drawbuffer = screen; + backbuffer = PHL_NewSurface(640, 480); +} + +void PHL_GraphicsExit() +{ + SDL_FreeSurface(backbuffer); + SDL_Quit(); +} + +static uint32_t tframe; +void PHL_StartDrawing() +{ + tframe = SDL_GetTicks() + 1000/60; + PHL_ResetDrawbuffer(); +} +void PHL_EndDrawing() +{ + SDL_Flip(screen); + while(SDL_GetTicks()format, r, g, b)); +} + +PHL_Surface PHL_NewSurface(int w, int h) +{ + return SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0); +} +void PHL_FreeSurface(PHL_Surface surf) +{ + SDL_FreeSurface(surf); +} + +//PHL_Surface PHL_LoadBMP(char* fname); +PHL_Surface PHL_LoadBMP(int index) +{ + SDL_Surface* surf; + + FILE* f; + if ( (f = fopen("data/bmp.qda", "rb")) ) { + uint8_t* QDAFile = (uint8_t*)malloc(headers[index].size); + fseek(f, headers[index].offset, SEEK_SET); + fread(QDAFile, 1, headers[index].size, f); + fclose(f); + + PHL_RGB palette[20][18]; + + uint16_t w, h; + + //Read data from header + memcpy(&w, &QDAFile[18], 2); + memcpy(&h, &QDAFile[22], 2); + + surf = PHL_NewSurface(w * 2, h * 2); + //surf = PHL_NewSurface(200, 200); + + //Load Palette + int dx, dy; + int count = 0; + for (dx = 0; dx < 20; dx++) { + for (dy = 0; dy < 16; dy++) { + palette[dx][dy].b = QDAFile[54 + count]; + palette[dx][dy].g = QDAFile[54 + count + 1]; + palette[dx][dy].r = QDAFile[54 + count + 2]; + count += 4; + } + } + + for (dx = 0; dx < w; dx++) { + for (dy = 0; dy < h; dy++) { + + int pix = dx + w * dy; + int px = QDAFile[1078 + pix] / 16; + int py = QDAFile[1078 + pix] % 16; + //Get transparency from first palette color + if (dx == 0 && dy == 0) { + //Darkness special case + if (index == 27) { + SDL_SetColorKey(surf, SDL_SRCCOLORKEY, SDL_MapRGB(surf->format, 0x00, 0x00, 0x00)); + }else{ + SDL_SetColorKey(surf, SDL_SRCCOLORKEY, SDL_MapRGB(surf->format, palette[0][0].r, palette[0][0].g, palette[0][0].b)); + } + } + + PHL_RGB c = palette[px][py]; + + //PHL_DrawRect(dx * 2, dy * 2, 2, 2, c); + SDL_Rect rect = {dx * 2, (h-1-dy) * 2, 2, 2}; + SDL_FillRect(surf, &rect, SDL_MapRGB(surf->format, c.r, c.g, c.b)); + } + } + free(QDAFile); + } + + return surf; +} + +void PHL_DrawRect(int x, int y, int w, int h, SDL_Color col) +{ + SDL_Rect rect = {x, y, w, h}; + + SDL_FillRect(drawbuffer, &rect, SDL_MapRGB(drawbuffer->format, col.r, col.g, col.b)); +} + +void PHL_DrawSurface(double x, double y, PHL_Surface surface) +{ + if (quakeTimer > 0) { + int val = quakeTimer % 4; + if (val == 0) { + y -= 1; + } else if (val == 2) { + y += 1; + } + } + + SDL_Rect offset; + offset.x = x; + offset.y = y; + + SDL_BlitSurface(surface, NULL, drawbuffer, &offset); +} +void PHL_DrawSurfacePart(double x, double y, int cropx, int cropy, int cropw, int croph, PHL_Surface surface) +{ + if (quakeTimer > 0) { + int val = quakeTimer % 4; + if (val == 0) { + y -= 1; + }else if (val == 2) { + y += 1; + } + } + + SDL_Rect crop, offset; + crop.x = cropx; + crop.y = cropy; + crop.w = cropw; + crop.h = croph; + + offset.x = x; + offset.y = y; + + SDL_BlitSurface(surface, &crop, drawbuffer, &offset); +} + +void PHL_DrawBackground(PHL_Background back, PHL_Background fore) +{ + PHL_DrawSurface(0, 0, backbuffer); +} +void PHL_UpdateBackground(PHL_Background back, PHL_Background fore) +{ + PHL_SetDrawbuffer(backbuffer); + + int xx, yy; + + for (yy = 0; yy < 12; yy++) + { + for (xx = 0; xx < 16; xx++) + { + //Draw Background tiles + PHL_DrawSurfacePart(xx * 40, yy * 40, back.tileX[xx][yy] * 40, back.tileY[xx][yy] * 40, 40, 40, images[imgTiles]); + + //Only draw foreground tile if not a blank tile + if (fore.tileX[xx][yy] != 0 || fore.tileY[xx][yy] != 0) { + PHL_DrawSurfacePart(xx * 40, yy * 40, fore.tileX[xx][yy] * 40, fore.tileY[xx][yy] * 40, 40, 40, images[imgTiles]); + } + } + } + + PHL_ResetDrawbuffer(); +} diff --git a/src/sdl/graphics.h b/src/sdl/graphics.h new file mode 100644 index 0000000..3635294 --- /dev/null +++ b/src/sdl/graphics.h @@ -0,0 +1,65 @@ +#ifndef GRAPHICS_H +#define GRAPHICS_H + +#include + +#define PHL_Surface SDL_Surface* + +#define PHL_RGB SDL_Color + +typedef struct { + int tileX[16][12]; + int tileY[16][12]; +} PHL_Background; + +/* +typedef struct { + unsigned int r, g, b; +} PHL_RGB; +*/ +/* +typedef struct { + OSL_IMAGE* pxdata; + int width; + int height; + PHL_RGB colorKey; +} PHL_Surface; +*/ +extern PHL_Surface screen; + +SDL_Color PHL_NewRGB(uint8_t r, uint8_t g, uint8_t b); +/* +{ + SDL_Color ret = {.r = r, .b = b, .g = g}; + return ret; +} +*/ +void PHL_GraphicsInit(); +void PHL_GraphicsExit(); + +void PHL_StartDrawing(); +void PHL_EndDrawing(); + +void PHL_ForceScreenUpdate(); + +void PHL_SetDrawbuffer(PHL_Surface surf); +void PHL_ResetDrawbuffer(); + +//PHL_RGB PHL_NewRGB(int r, int g, int b); +void PHL_SetColorKey(PHL_Surface surf, int r, int g, int b); + +PHL_Surface PHL_NewSurface(int w, int h); +void PHL_FreeSurface(PHL_Surface surf); + +//PHL_Surface PHL_LoadBMP(char* fname); +PHL_Surface PHL_LoadBMP(int index); + +void PHL_DrawRect(int x, int y, int w, int h, SDL_Color col); + +void PHL_DrawSurface(double x, double y, PHL_Surface surface); +void PHL_DrawSurfacePart(double x, double y, int cropx, int cropy, int cropw, int croph, PHL_Surface surface); + +void PHL_DrawBackground(PHL_Background back, PHL_Background fore); +void PHL_UpdateBackground(PHL_Background back, PHL_Background fore); + +#endif \ No newline at end of file diff --git a/src/sdl/input.c b/src/sdl/input.c new file mode 100644 index 0000000..c5f5a65 --- /dev/null +++ b/src/sdl/input.c @@ -0,0 +1,88 @@ +#include "input.h" +#include + +Button btnUp = {0}, btnDown = {0}, btnLeft = {0}, btnRight = {0}; +Button btnFaceUp = {0}, btnFaceDown = {0}, btnFaceLeft = {0}, btnFaceRight = {0}; +Button btnL = {0}, btnR = {0}; +Button btnStart = {0}, btnSelect = {0}; +Button btnAccept = {0}, btnDecline = {0}; +int axisX = 0, axisY = 0; + +int bUp = 0, bDown = 0, bLeft = 0, bRight = 0; +int bFaceUp = 0, bFaceDown = 0, bFaceLeft = 0, bFaceRight = 0; +int bR = 0, bL = 0; +int bStart = 0, bSelect = 0; +int bAccept = 0, bDecline = 0; + +void Input_KeyEvent(SDL_Event* evt) +{ + int w = (evt->type==SDL_KEYDOWN)?1:0; + switch(evt->key.keysym.sym) + { + case SDLK_UP: bUp = w; break; + case SDLK_DOWN: bDown = w; break; + case SDLK_LEFT: bLeft = w; break; + case SDLK_RIGHT: bRight = w; break; +#ifdef PANDORA + case SDLK_PAGEUP: bFaceUp = w; break; + case SDLK_PAGEDOWN: bFaceDown = w; break; + case SDLK_END: bFaceLeft = w; break; // reversing, so (B) is sword + case SDLK_HOME: bFaceRight = w; break; + case SDLK_RCTRL: bR = w; break; + case SDLK_RSHIFT: bL = w; break; + case SDLK_LCTRL: bSelect = w; break; + case SDLK_LALT: bStart = w; break; +#else + case SDLK_e: bFaceUp = w; break; + case SDLK_x: bFaceDown = w; break; + case SDLK_s: bFaceLeft = w; break; + case SDLK_d: bFaceRight = w; break; + case SDLK_r: bR = w; break; + case SDLK_w: bL = w; break; + case SDLK_SPACE: bSelect = w; break; + case SDLK_RETURN: bStart = w; break; +#endif + } +} + +void updateKey(Button* btn, int state) +{ + if (state) { + if (btn->held == 1) { + btn->pressed = 0; + }else{ + btn->pressed = 1; + } + btn->held = 1; + btn->released = 0; + }else{ + if (btn->held == 1) { + btn->released = 1; + }else{ + btn->released = 0; + } + btn->held = 0; + btn->pressed = 0; + } +} + +void PHL_ScanInput() +{ + updateKey(&btnUp, bUp); + updateKey(&btnDown, bDown); + updateKey(&btnLeft, bLeft); + updateKey(&btnRight, bRight); + + updateKey(&btnStart, bStart); + updateKey(&btnSelect, bSelect); + + updateKey(&btnL, bL); + updateKey(&btnR, bR); + + updateKey(&btnFaceLeft, bFaceLeft); + updateKey(&btnFaceDown, bFaceDown); + updateKey(&btnFaceRight, bFaceRight); + + updateKey(&btnAccept, bFaceLeft); + updateKey(&btnDecline, bFaceDown); +} diff --git a/src/sdl/input.h b/src/sdl/input.h new file mode 100644 index 0000000..ec627f6 --- /dev/null +++ b/src/sdl/input.h @@ -0,0 +1,21 @@ +#ifndef INPUT_H +#define INPUT_H + +#include + +typedef struct { + int pressed, + held, + released; +} Button; + +extern Button btnUp, btnDown, btnLeft, btnRight; +extern Button btnFaceUp, btnFaceDown, btnFaceLeft, btnFaceRight; +extern Button btnL, btnR; +extern Button btnStart, btnSelect; +extern Button btnAccept, btnDecline; +extern int axisX, axisY; + +void PHL_ScanInput(); + +#endif \ No newline at end of file diff --git a/src/sdl/system.c b/src/sdl/system.c new file mode 100644 index 0000000..7e27d05 --- /dev/null +++ b/src/sdl/system.c @@ -0,0 +1,43 @@ +#include +#include "system.h" + + +char quitGame = 0; + +void Input_KeyEvent(SDL_Event* evt); + +int PHL_MainLoop() +{ + SDL_Event evt; + while(SDL_PollEvent(&evt)) + { + switch(evt.type) + { + case SDL_QUIT: + return 0; + case SDL_KEYDOWN: + case SDL_KEYUP: + Input_KeyEvent(&evt); + break; + //TODO: joystick... + } + } + if (quitGame == 1) + { + return 0; + } + return 1; +} +void PHL_ConsoleInit() +{ + +} +void PHL_GameQuit() +{ + quitGame = 1; +} + +void PHL_ErrorScreen(char* message) +{ + fprintf(stderr, "%s\n", message); +} diff --git a/src/sdl/system.h b/src/sdl/system.h new file mode 100644 index 0000000..2657796 --- /dev/null +++ b/src/sdl/system.h @@ -0,0 +1,15 @@ +#ifndef SYSTEM_H +#define SYSTEM_H + +#include +#include "../PHL.h" + +extern char quitGame; + +int PHL_MainLoop(); +void PHL_ConsoleInit(); +void PHL_GameQuit(); + +void PHL_ErrorScreen(char* message); + +#endif \ No newline at end of file -- cgit v1.2.3