Author: mesyeti <mesyeti@mesyeti.uk>
wip broken software backend
Makefile | 2 source/app.c | 14 +- source/app.h | 4 source/backend.c | 40 ++++-- source/backend.h | 54 ++------ source/backends/glLegacy.c | 231 +++++++++------------------------------ source/backends/glLegacy.h | 29 ---- source/backends/soft.c | 196 +++++++++++++++++++++++++++++++++ source/backends/soft.h | 6 + source/backends/stub.c | 139 +++-------------------- source/backends/stub.h | 4 source/bitmapFont.c | 38 +++--- source/bitmapFont.h | 1 source/font.c | 30 +++++ source/main.c | 28 ++++ source/screen.c | 44 +++--- source/screen.h | 9 source/text.c | 55 --------- | 1
diff --git a/Makefile b/Makefile index b89644fb3d2fbe3fefc9f998df99f69022c19bd7..06b43e87ef90af4e127b7a56d2987c0f2369a0b9 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ override CFLAGS += -std=c99 -Wall -Wextra -Wuninitialized -Wundef -pedantic -Ilib -Werror=return-type override LDLIBS += -lm -override CPPFLAGS += -DYT_BACKEND_GL_11 +#override CPPFLAGS += -DYT_BACKEND_GL_11 override CPPFLAGS += -DYT_WINDOW_SDL2 -DYT_INPUT_SDL2 -DYT_EVENT_SDL2 override CPPFLAGS += -DSDL_MAIN_HANDLED -D_POSIX_C_SOURCE=199309L diff --git a/source/app.c b/source/app.c index eb3fe559b5ed833ad311535130f65520577af76f..10882cadef6bfebe8c77d8f33699e36c5b7d7c6a 100644 --- a/source/app.c +++ b/source/app.c @@ -15,6 +15,12 @@ Screen_Init(); } void App_Update(void) { + static uint64_t oldFrameTime = 0; + + uint64_t newFrameTime = Platform_GetTime(); + uint64_t frameTimeDiff = newFrameTime - oldFrameTime; + app.delta = frameTimeDiff / 1000000.0f; + Event e; while (Event_Poll(&e)) { @@ -24,12 +30,8 @@ default: continue; } } - Backend_Begin(); - Backend_Clear(0, 0, 0); - - Screen_Render(); - - Backend_FinishRender(); + Backend_Render(); + oldFrameTime = newFrameTime; } void App_Free(void) { diff --git a/source/app.h b/source/app.h index 7470181ff74045295309cd2f6a01a57d15948304..28816ffff0c2827cd98044db089f436ef1aa6c8a 100644 --- a/source/app.h +++ b/source/app.h @@ -3,9 +3,11 @@ #define YT_APP_H #include "video.h" #include "common.h" +#include "platform.h" typedef struct { - bool running; + bool running; + float delta; } App; extern App app; diff --git a/source/backend.c b/source/backend.c index dc71c0b9a001274147f77bcf3656a61eed1c1f0f..76f3f9d00ff9be9198b0eff97fff14e628709d0c 100644 --- a/source/backend.c +++ b/source/backend.c @@ -1,21 +1,35 @@ #include "backend.h" -BackendOptions backendOptions = { - .vsync = true, - .name = "gl1" -}; +static Backend backend; -void Backend_VLine(int x, int y, int thick, int len, Colour colour) { - Backend_RenderRect((Rect) {x, y, thick, len}, colour); +void Backend_Use(Backend p_backend) { + backend = p_backend; } -void Backend_HLine(int x, int y, int thick, int len, Colour colour) { - Backend_RenderRect((Rect) {x, y, len, thick}, colour); +void Backend_Init(bool beforeWindow) { + backend.init(beforeWindow); } -void Backend_RenderRectOL(Rect rect, Colour colour) { - Backend_HLine(rect.x, rect.y, 1, rect.w, colour); - Backend_VLine(rect.x, rect.y, 1, rect.h, colour); - Backend_HLine(rect.x, rect.y + rect.h - 1, 1, rect.w, colour); - Backend_VLine(rect.x + rect.w - 1, rect.y, 1, rect.h, colour); +void Backend_Free(void) { + backend.free(); +} + +Texture* Backend_LoadTexture(uint8_t* data, int w, int h, int aW, int aH, int ch) { + return backend.loadTexture(data, w, h, aW, aH, ch); +} + +void Backend_FreeTexture(Texture* texture) { + backend.freeTexture(texture); +} + +Vec2 Backend_GetTextureSize(Texture* texture) { + return backend.getTextureSize(texture); +} + +void Backend_OnWindowResize(void) { + backend.onWindowResize(); +} + +void Backend_Render(void) { + backend.render(); } diff --git a/source/backend.h b/source/backend.h index 20e886e2cafdfb920f3f74c5211678f0f799e2d9..fc69e3fce90219a92a5c6be18ab26ae3d6193460 100644 --- a/source/backend.h +++ b/source/backend.h @@ -1,16 +1,6 @@ #ifndef YT_BACKEND_H #define YT_BACKEND_H -// defined: -// (struct) Texture -#if defined(YT_BACKEND_GL_11) - #include "backends/glLegacy.h" -#elif defined(YT_BACKEND_STUB) - #include "backends/stub.h" -#else - #error "No backend" -#endif - #include "types.h" #include "video.h" #include "window.h" @@ -21,45 +11,29 @@ bool enabled; } BackendViewport; typedef struct { - bool vsync; - char name[20]; -} BackendOptions; - -extern BackendOptions backendOptions; - -typedef struct { bool doTint; Colour tint; } TextureRenderOpt; -// implemented per backend +typedef void Texture; + +typedef struct { + void (*init)(bool beforeWindow); + void (*free)(void); + Texture* (*loadTexture)(uint8_t* data, int w, int h, int aW, int aH, int ch); + void (*freeTexture)(Texture* texture); + Vec2 (*getTextureSize)(Texture* texture); + void (*onWindowResize)(void); + void (*render)(void); +} Backend; + +void Backend_Use(Backend p_backend); void Backend_Init(bool beforeWindow); void Backend_Free(void); -void Backend_SetTarget(Window* window); Texture* Backend_LoadTexture(uint8_t* data, int w, int h, int aW, int aH, int ch); void Backend_FreeTexture(Texture* texture); Vec2 Backend_GetTextureSize(Texture* texture); void Backend_OnWindowResize(void); - -void Backend_DrawTexture( - Texture* texture, TextureRenderOpt* p_opt, Rect* p_src, Rect* p_dest -); - -void Backend_Begin(void); -void Backend_Clear(uint8_t r, uint8_t g, uint8_t b); -void Backend_SetViewport(int x, int y, int w, int h); -void Backend_EnableViewport(bool enable); -void Backend_RenderRect(Rect rect, Colour colour); -void Backend_RenderLine(Vec2 a, Vec2 b, Colour colour); -void Backend_EnableAlpha(bool enable); -void Backend_FinishRender(void); - -BackendViewport Backend_SaveViewport(void); -void Backend_RestoreViewport(BackendViewport viewport); - -// portable -void Backend_HLine(int x, int y, int thick, int len, Colour colour); -void Backend_VLine(int x, int y, int thick, int len, Colour colour); -void Backend_RenderRectOL(Rect rect, Colour colour); +void Backend_Render(void); #endif diff --git a/source/backends/glLegacy.c b/source/backends/glLegacy.c index a64b18c47af50ed6319adbdf572b5dc545dd5963..67ccb46c3fefa8f4b716368a9a19a98a37d4cbbc 100644 --- a/source/backends/glLegacy.c +++ b/source/backends/glLegacy.c @@ -7,9 +7,37 @@ #ifdef YT_BACKEND_GL_11 #include "glLegacy.h" +#define GL_GLEXT_PROTOTYPES +#ifdef YT_BACKEND_GL_11 + #ifdef PLATFORM_OSX + #include <OpenGL/gl.h> + #include <OpenGL/glext.h> + #else + #include <GL/gl.h> + #include <GL/glext.h> + #endif +#endif + +#ifndef USE_KHR_DEBUG + #if !defined(NDEBUG) && defined(GL_KHR_debug) && GL_KHR_debug + #define USE_KHR_DEBUG 1 + #else + #define USE_KHR_DEBUG 0 + #endif +#endif + #ifndef GL_CLAMP_TO_EDGE_SGIS #define GL_CLAMP_TO_EDGE_SGIS GL_CLAMP_TO_EDGE #endif + +typedef struct { + bool used; + GLuint name; + int width; + int height; + int actualWidth; + int actualHeight; +} BTexture; static void GL_Error(GLenum error, const char* file, int line) { const char* errorStr; @@ -53,12 +81,12 @@ BackendViewport viewport; SDL_GLContext ctx; - Texture textures[32]; + BTexture textures[32]; } State; static State state; -void Backend_Init(bool beforeWindow) { +static void Init(bool beforeWindow) { if (beforeWindow) { int major = 1; int minor = 1; @@ -141,22 +169,12 @@ glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } -void Backend_Free(void) { +static void Free(void) { SDL_GL_DeleteContext(state.ctx); // Model_Free(&state.model); } -void Backend_SetTarget(Window* window) { - (void) window; // unimplemented - - static bool warning = false; - if (!warning) { - warning = true; - Warn("Backend_SetTarget unsupported"); - } -} - -Texture* Backend_LoadTexture(uint8_t* data, int w, int h, int aW, int aH, int ch) { +static Texture* LoadTexture(uint8_t* data, int w, int h, int aW, int aH, int ch) { GLuint tex; GL(glGenTextures(1, &tex)); GL(glBindTexture(GL_TEXTURE_2D, tex)); @@ -173,7 +191,7 @@ free(data); GL(glBindTexture(GL_TEXTURE_2D, 0)); // now put this texture in the texture array - for (size_t i = 0; i < sizeof(state.textures) / sizeof(Texture); ++ i) { + for (size_t i = 0; i < sizeof(state.textures) / sizeof(BTexture); ++ i) { if (!state.textures[i].used) { state.textures[i].used = true; state.textures[i].name = tex; @@ -181,7 +199,7 @@ state.textures[i].width = w; state.textures[i].height = h; state.textures[i].actualWidth = aW; state.textures[i].actualHeight = aH; - return &state.textures[i]; + return (Texture*) &state.textures[i]; } } @@ -189,175 +207,36 @@ Error("No more room for textures"); return NULL; } -void Backend_FreeTexture(Texture* texture) { - GL(glDeleteTextures(1, &texture->name)); - texture->used = false; -} +static void FreeTexture(Texture* texture) { + BTexture* tex = (BTexture*) texture; -Vec2 Backend_GetTextureSize(Texture* texture) { - return (Vec2) {texture->width, texture->height}; + GL(glDeleteTextures(1, &tex->name)); + tex->used = false; } -void Backend_DrawTexture( - Texture* texture, TextureRenderOpt* p_opt, Rect* p_src, Rect* p_dest -) { - TextureRenderOpt opt; - if (p_opt == NULL) { - opt.doTint = false; - } - else { - opt = *p_opt; - } - - Rect src; - if (p_src == NULL) { - src = (Rect) {0, 0, texture->width, texture->height}; - } - else { - src = *p_src; - } - - Rect dest; - if (p_dest == NULL) { - dest = (Rect) {0, 0, video.windows[0].width, video.windows[0].height}; - } - else { - dest = *p_dest; - } - - GL(glBindTexture(GL_TEXTURE_2D, texture->name)); - - glBegin(GL_TRIANGLE_FAN); - - if (opt.doTint) { - glColor3ub(opt.tint.r, opt.tint.g, opt.tint.b); - } - else { - glColor3ub(255, 255, 255); - } - - glTexCoord2f( - ((float) src.x) / ((float) texture->actualWidth), - ((float) src.y) / ((float) texture->actualHeight) - ); - glVertex2i(dest.x, dest.y); - glTexCoord2f( - ((float) (src.x + src.w)) / ((float) texture->actualWidth), - ((float) src.y) / ((float) texture->actualHeight) - ); - glVertex2i(dest.x + dest.w, dest.y); - glTexCoord2f( - ((float) (src.x + src.w)) / ((float) texture->actualWidth), - ((float) (src.y + src.h)) / ((float) texture->actualHeight) - ); - glVertex2i(dest.x + dest.w, dest.y + dest.h); - glTexCoord2f( - ((float) src.x) / ((float) texture->actualWidth), - ((float) (src.y + src.h)) / ((float) texture->actualHeight) - ); - glVertex2i(dest.x, dest.y + dest.h); - GL(glEnd()); - - GL(glBindTexture(GL_TEXTURE_2D, 0)); +static Vec2 GetTextureSize(Texture* texture) { + BTexture* tex = (BTexture*) texture; + return (Vec2) {tex->width, tex->height}; } -void Backend_Begin(void) { - glViewport(0, 0, video.windows[0].aWidth, video.windows[0].aHeight); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glDisable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - glEnable(GL_BLEND); - GL(glMatrixMode(GL_MODELVIEW)); - GL(glLoadIdentity()); - GL(glMatrixMode(GL_PROJECTION)); - GL(glLoadIdentity()); - - float floatW = (float) video.windows[0].width; - float floatH = (float) video.windows[0].height; - - GL(glOrtho(0.0, floatW, floatH, 0.0, -1.0, 1.0)); -} - -void Backend_Clear(uint8_t r, uint8_t g, uint8_t b) { - glClearColor(((float) r) / 256.0, ((float) g) / 256.0, ((float) b) / 256.0, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +static void OnWindowResize(void) { + } -void Backend_SetViewport(int x, int y, int w, int h) { - state.viewport.rect = (Rect) {x, y, w, h}; - GL(glScissor(x, video.windows[0].height - 1 - (y + h), w, h)); +static void Render(void) { + } -void Backend_EnableViewport(bool enable) { - state.viewport.enabled = enable; - - if (enable) { - GL(glEnable(GL_SCISSOR_TEST)); - } - else { - GL(glDisable(GL_SCISSOR_TEST)); - } -} - -void Backend_RenderRect(Rect rect, Colour colour) { - GL(glDisable(GL_TEXTURE_2D)); - glBegin(GL_TRIANGLE_FAN); - - if (state.alpha) { - glColor4ub(colour.r, colour.g, colour.b, colour.a); - } - else { - glColor3ub(colour.r, colour.g, colour.b); - } - - glVertex2i(rect.x, rect.y); - glVertex2i(rect.x + rect.w, rect.y); - glVertex2i(rect.x + rect.w, rect.y + rect.h); - glVertex2i(rect.x, rect.y + rect.h); - GL(glEnd()); - GL(glEnable(GL_TEXTURE_2D)); -} - -void Backend_RenderLine(Vec2 a, Vec2 b, Colour colour) { - GL(glDisable(GL_TEXTURE_2D)); - glBegin(GL_LINES); - glColor3ub(colour.r, colour.g, colour.b); - glVertex2i(a.x, a.y); - glVertex2i(b.x, b.y); - GL(glEnd()); - GL(glEnable(GL_TEXTURE_2D)); -} - -void Backend_EnableAlpha(bool enable) { - state.alpha = enable; - - if (enable) { - GL(glEnable(GL_BLEND)); - } - else { - GL(glDisable(GL_BLEND)); - } -} - -void Backend_FinishRender(void) { - GL(glFinish()); - SDL_GL_SwapWindow(video.windows[0].window); -} - -BackendViewport Backend_SaveViewport(void) { - return state.viewport; -} - -void Backend_RestoreViewport(BackendViewport viewport) { - state.viewport = viewport; - - Backend_SetViewport( - state.viewport.rect.x, state.viewport.rect.y, - state.viewport.rect.w, state.viewport.rect.h - ); - Backend_EnableViewport(state.viewport.enabled); +Backend Backend_GLLegacy(void) { + return (Backend) { + .init = &Init, + .free = &Free, + .loadTexture = &LoadTexture, + .freeTexture = &FreeTexture, + .getTextureSize = &GetTextureSize, + .onWindowResize = &OnWindowResize, + .render = &Render + }; } #endif diff --git a/source/backends/glLegacy.h b/source/backends/glLegacy.h index 0e5275fc0b61e9cb26cf8c92ed3e17c4edeec0c8..e89aba4d67784b718526dc50357953ec18ca57f6 100644 --- a/source/backends/glLegacy.h +++ b/source/backends/glLegacy.h @@ -2,33 +2,8 @@ #ifndef YT_BACKENDS_GL_LEGACY_H #define YT_BACKENDS_GL_LEGACY_H #include "../common.h" +#include "../backend.h" -#define GL_GLEXT_PROTOTYPES -#ifdef YT_BACKEND_GL_11 - #ifdef PLATFORM_OSX - #include <OpenGL/gl.h> - #include <OpenGL/glext.h> - #else - #include <GL/gl.h> - #include <GL/glext.h> - #endif -#endif - -#ifndef USE_KHR_DEBUG - #if !defined(NDEBUG) && defined(GL_KHR_debug) && GL_KHR_debug - #define USE_KHR_DEBUG 1 - #else - #define USE_KHR_DEBUG 0 - #endif -#endif - -typedef struct { - bool used; - GLuint name; - int width; - int height; - int actualWidth; - int actualHeight; -} Texture; +Backend Backend_GLLegacy(void); #endif diff --git a/source/backends/soft.c b/source/backends/soft.c new file mode 100644 index 0000000000000000000000000000000000000000..bb7573138c565991bc5596f62c30381e6ea07ab2 --- /dev/null +++ b/source/backends/soft.c @@ -0,0 +1,196 @@ +#include <stdio.h> +#include "../log.h" +#include "../mem.h" +#include "../font.h" +#include "../theme.h" +#include "../screen.h" +#include "../backend.h" + +#include "stub.h" + +typedef struct { + bool used; + int width; + int height; + int aWidth; + int aHeight; + uint32_t* pixels; +} BTexture; + +typedef struct { + BTexture textures[32]; + uint32_t* buffer; + int bufferW; + int bufferH; + + // SDL stuff + SDL_Renderer* renderer; + SDL_Texture* texture; +} State; + +static State state; + +static void DrawPixel(int x, int y, uint32_t colour) { + if ((x < 0) || (y < 0) || (y >= state.bufferH) || (x >= state.bufferW)) return; + + state.buffer[(y * state.bufferW) + x] = colour; +} + +static void Init(bool beforeWindow) { + if (beforeWindow) return; + + state.renderer = SDL_CreateRenderer( + video.windows[0].window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC + ); + + if (!state.renderer) { + Error("Failed to init renderer: %s", SDL_GetError()); + } + + state.texture = SDL_CreateTexture( + state.renderer, SDL_PIXELFORMAT_ABGR8888, + SDL_TEXTUREACCESS_STREAMING, video.windows[0].width, video.windows[0].height + ); + + if (state.texture == NULL) { + fprintf(stderr, "Failed to create texture: %s\n", SDL_GetError()); + exit(1); + } + + for (size_t i = 0; i < sizeof(state.textures) / sizeof(BTexture); ++ i) { + state.textures[i].used = false; + } + + state.buffer = SafeMalloc(video.windows[0].width * video.windows[0].height * sizeof(uint32_t)); + state.bufferW = video.windows[0].width; + state.bufferH = video.windows[0].height; +} + +static void Free(void) { + for (size_t i = 0; i < sizeof(state.textures) / sizeof(BTexture); ++ i) { + if (state.textures[i].used) { + free(state.textures[i].pixels); + } + } + + free(state.buffer); + + SDL_DestroyTexture(state.texture); + SDL_DestroyRenderer(state.renderer); +} + +static uint32_t ColourToPixel(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { + return r | (g << 8) | (b << 16) | (a << 24); + //return r + (rand() % 20) | (g + (rand() % 20) << 8) | (b + (rand() % 20) << 16) | (a << 24); +} + +static Texture* LoadTexture(uint8_t* data, int w, int h, int aW, int aH, int ch) { + uint32_t* pixels = SafeMalloc(w * h * sizeof(uint32_t)); + + for (int i = 0; i < w * h; ++ i, data += ch) { + pixels[i] = ColourToPixel(data[0], data[1], data[2], ch == 4? data[3] : 255); + } + + for (size_t i = 0; i < sizeof(state.textures) / sizeof(BTexture); ++ i) { + if (!state.textures[i].used) { + state.textures[i].used = true; + state.textures[i].width = w; + state.textures[i].height = h; + state.textures[i].aWidth = aW; + state.textures[i].aHeight = aH; + state.textures[i].pixels = pixels; + return (Texture*) &state.textures[i]; + } + } + + Error("No more room for textures"); + return NULL; +} + +static void FreeTexture(Texture* texture) { + BTexture* tex = (BTexture*) texture; + free(tex->pixels); + tex->used = false; +} + +static Vec2 GetTextureSize(Texture* texture) { + BTexture* tex = (BTexture*) texture; + return (Vec2) {tex->width, tex->height}; +} + +static void OnWindowResize(void) { + +} + +static void FillRect(int x, int y, int w, int h, Colour colour) { + for (int iy = 0; iy < h; ++ iy) { + for (int ix = 0; ix < w; ++ ix) { + DrawPixel(ix + x, iy + y, ColourToPixel(colour.r, colour.g, colour.b, colour.a)); + } + } +} + +static void Blit(BTexture* texture, int x, int y, Rect src, Colour tint) { + (void) tint; // TODO + + for (int iy = 0; iy < src.h; ++ iy) { + for (int ix = 0; ix < src.w; ++ ix) { + if ((src.x + ix >= texture->width) || (src.y + iy >= texture->height)) continue; + + int sx = ix + src.x; + int sy = iy + src.y; + + // DrawPixel(ix + x, iy + y, texture->pixels[(sy * texture->width) + sx]); + DrawPixel(ix + x, iy + y, texture->pixels[(sy * texture->width) + sx]); + } + } +} + +static void Render(void) { + for (int i = 0; i < state.bufferW * state.bufferH; ++ i) { + state.buffer[i] = ColourToPixel(theme.bg.r, theme.bg.g, theme.bg.b, 255); + } + + int cw; + int ch; + Font_CharSize(&screen.font, &cw, &ch); + + for (int y = 0; y < screen.buffer.height; ++ y) { + for (int x = 0; x < screen.buffer.width; ++ x) { + int cx = x * cw; + int cy = y * ch; + + BufCell* cell = Buffer_Get(&screen.buffer, x, y); + + ColourRGB fg = Screen_GetColour(true, cell->fgMode, cell->fg); + ColourRGB bg = Screen_GetColour(false, cell->bgMode, cell->bg); + + FillRect(cx, cy, cw, ch, (Colour) {bg.r, bg.g, bg.b, 255}); + + Rect src; + src.x = ((int) (ch % 16)) * cw; + src.y = ((int) (ch / 16)) * ch; + src.w = cw; + src.h = ch; + + Blit((BTexture*) screen.font.v.bm.texture, cx, cy, src, (Colour) {fg.r, fg.g, fg.b, 255}); + } + } + + SDL_RenderClear(state.renderer); + SDL_UpdateTexture(state.texture, NULL, state.buffer, state.bufferW * 4); + SDL_RenderCopy(state.renderer, state.texture, NULL, NULL); + SDL_RenderPresent(state.renderer); +} + +Backend Backend_Soft(void) { + return (Backend) { + .init = &Init, + .free = &Free, + .loadTexture = &LoadTexture, + .freeTexture = &FreeTexture, + .getTextureSize = &GetTextureSize, + .onWindowResize = &OnWindowResize, + .render = &Render + }; +} diff --git a/source/backends/soft.h b/source/backends/soft.h new file mode 100644 index 0000000000000000000000000000000000000000..2d75ecb7b31966491cedf3e62f659bac45715f06 --- /dev/null +++ b/source/backends/soft.h @@ -0,0 +1,6 @@ +#ifndef YT_BACKEND_SOFT_H +#define YT_BACKEND_SOFT_H + +Backend Backend_Soft(void); + +#endif diff --git a/source/backends/stub.c b/source/backends/stub.c index cef9bcf20d6656bc713220bb20785b174ff581dd..6d7dfe19e8f2b7b5174ed71d944f0d5eec673443 100644 --- a/source/backends/stub.c +++ b/source/backends/stub.c @@ -1,143 +1,50 @@ #include "../backend.h" -#ifdef YT_BACKEND_STUB #include "stub.h" -void Backend_Init(bool beforeWindow) { - (void) beforeWindow; -} +static void Init(bool beforeWindow) { -void Backend_Free(void) { - } -void Backend_SetTarget(Window* window) { - (void) window; +static void Free(void) { + } -Texture* Backend_LoadTexture(uint8_t* data, int width, int height, int ch) { +static Texture* LoadTexture(uint8_t* data, int w, int h, int aW, int aH, int ch) { (void) data; - (void) width; - (void) height; + (void) w; + (void) h; + (void) aW; + (void) aH; (void) ch; + return NULL; } -void Backend_FreeTexture(Texture* texture) { +static void FreeTexture(Texture* texture) { (void) texture; } -Vec2 Backend_GetTextureSize(Texture* texture) { - (void) texture; +static Vec2 GetTextureSize(Texture* texture) { return (Vec2) {0, 0}; } -void Backend_RenderScene(void) { +static void OnWindowResize(void) { } -void Backend_OnMapFree(void) { - -} - -void Backend_OnWindowResize(void) { +static void Render(void) { } -void Backend_RenderModel(Model* model, ModelRenderOpt* opt) { - (void) model; - (void) opt; -} - -void Backend_UseHoldModel(const char* path, ModelRenderOpt opt) { - (void) path; - (void) opt; +Backend Backend_Stub(void) { + return (Backend) { + .init = &Init, + .free = &Free, + .loadTexture = &LoadTexture, + .freeTexture = &FreeTexture, + .getTextureSize = &GetTextureSize, + .onWindowResize = &OnWindowResize, + .render = &Render + }; } - -void Backend_DrawTexture( - Texture* texture, TextureRenderOpt* p_opt, Rect* p_src, Rect* p_dest -) { - (void) texture; - - TextureRenderOpt opt; - if (p_opt == NULL) { - opt.doTint = false; - } - else { - opt = *p_opt; - } - - Rect src; - if (p_src == NULL) { - src = (Rect) {0, 0, texture->width, texture->height}; - } - else { - src = *p_src; - } - - Rect dest; - if (p_dest == NULL) { - dest = (Rect) {0, 0, video.width, video.height}; - } - else { - dest = *p_dest; - } -} - -void Backend_Begin(void) { - -} - -void Backend_Begin2D(bool originTop) { - (void) originTop; -} - -void Backend_Clear(uint8_t r, uint8_t g, uint8_t b) { - (void) r; - (void) g; - (void) b; -} - -void Backend_SetViewport(int x, int y, int w, int h) { - (void) x; - (void) y; - (void) w; - (void) h; -} - -void Backend_EnableViewport(bool enable) { - (void) enable; -} - -void Backend_RenderRect(Rect rect, Colour colour) { - (void) rect; - (void) colour; -} - -void Backend_RenderLine(Vec2 a, Vec2 b, Colour colour) { - (void) a; - (void) b; - (void) colour; -} - -void Backend_EnableAlpha(bool enable) { - (void) enable; -} - -void Backend_InitSkybox(void) { - -} - -void Backend_FinishRender(void) { - -} - -BackendViewport Backend_SaveViewport(void) { - return (BackendViewport) {}; -} - -void Backend_RestoreViewport(BackendViewport viewport) { - (void) viewport; -} - -#endif diff --git a/source/backends/stub.h b/source/backends/stub.h index 77d457fc539a168878dc66b12a87fa2dce5163da..02e23172f70774b75d485e8102649e261a911c2a 100644 --- a/source/backends/stub.h +++ b/source/backends/stub.h @@ -1,8 +1,6 @@ #ifndef YT_BACKEND_STUB_H #define YT_BACKEND_STUB_H -typedef struct { - int empty; -} Texture; +Backend Backend_Stub(void); #endif diff --git a/source/bitmapFont.c b/source/bitmapFont.c index c222e275de8aadebb696cf9ca79fea5104866713..ea110c77efee3033816b6bd29b220b2651c29b6c 100644 --- a/source/bitmapFont.c +++ b/source/bitmapFont.c @@ -26,22 +26,22 @@ void BMFont_Free(BMFont* font) { Backend_FreeTexture(font->texture); } -void BMFont_RenderChar(BMFont* font, char ch, int x, int y, ColourRGB colour) { - Rect dest; - dest.x = x; - dest.y = y; - dest.w = font->charWidth; - dest.h = font->charHeight; - - Rect src; - src.x = ((int) (ch % 16)) * font->charWidth; - src.y = ((int) (ch / 16)) * font->charHeight; - src.w = font->charWidth; - src.h = font->charHeight; - - TextureRenderOpt opt; - opt.doTint = true; - opt.tint = (Colour) {colour.r, colour.g, colour.b, 255}; - - Backend_DrawTexture(font->texture, &opt, &src, &dest); -} +// void BMFont_RenderChar(BMFont* font, char ch, int x, int y, ColourRGB colour) { +// Rect dest; +// dest.x = x; +// dest.y = y; +// dest.w = font->charWidth; +// dest.h = font->charHeight; +// +// Rect src; +// src.x = ((int) (ch % 16)) * font->charWidth; +// src.y = ((int) (ch / 16)) * font->charHeight; +// src.w = font->charWidth; +// src.h = font->charHeight; +// +// TextureRenderOpt opt; +// opt.doTint = true; +// opt.tint = (Colour) {colour.r, colour.g, colour.b, 255}; +// +// Backend_DrawTexture(font->texture, &opt, &src, &dest); +// } diff --git a/source/bitmapFont.h b/source/bitmapFont.h index c0b408155d3fdc775cf08a7e2031123a7342c696..b32ebfef0c13cc3345891643d7a9a39ab1ecbc9d 100644 --- a/source/bitmapFont.h +++ b/source/bitmapFont.h @@ -12,6 +12,5 @@ } BMFont; BMFont BMFont_Load(const char* path, bool* success); void BMFont_Free(BMFont* font); -void BMFont_RenderChar(BMFont* font, char ch, int x, int y, ColourRGB colour); #endif diff --git a/source/font.c b/source/font.c new file mode 100644 index 0000000000000000000000000000000000000000..ea4649d176ff5fea3620fc215e8769607bf62e92 --- /dev/null +++ b/source/font.c @@ -0,0 +1,30 @@ +#include <assert.h> +#include "font.h" + +Font Font_FromBMFont(BMFont bm) { + Font ret; + ret.type = FONT_BITMAP; + ret.v.bm = bm; + return ret; +} + +void Font_Free(Font* font) { + switch (font->type) { + case FONT_BITMAP: { + BMFont_Free(&font->v.bm); + break; + } + default: assert(0); + } +} + +void Font_CharSize(Font* font, int* w, int* h) { + switch (font->type) { + case FONT_BITMAP: { + if (w) *w = font->v.bm.charWidth; + if (h) *h = font->v.bm.charHeight; + break; + } + default: assert(0); + } +} diff --git a/source/font.h b/source/font.h new file mode 100644 index 0000000000000000000000000000000000000000..0b85f5d75bb9adbc92f5899febbedb421f8da29a --- /dev/null +++ b/source/font.h @@ -0,0 +1,24 @@ +#ifndef YT_TEXT_H +#define YT_TEXT_H + +#include "char.h" +#include "bitmapFont.h" + +enum { + FONT_BITMAP = 0, + FONT_TTF +}; + +typedef struct { + int type; + + union { + BMFont bm; + } v; +} Font; + +Font Font_FromBMFont(BMFont bm); +void Font_Free(Font* font); +void Font_CharSize(Font* font, int* w, int* h); + +#endif diff --git a/source/main.c b/source/main.c index aa9f267a558405d678b52d18aae41f062bdb5c06..00de404068ffb890046e9a822813284e647fea25 100644 --- a/source/main.c +++ b/source/main.c @@ -1,6 +1,34 @@ #include "app.h" +#include "log.h" +#include "backend.h" + +#ifdef YT_BACKEND_GL_11 + #include "backends/glLegacy.h" +#endif + +#include "backends/soft.h" +#include "backends/stub.h" int main(void) { + struct { + const char* name; + Backend backend; + } backends[] = { + #ifdef YT_BACKEND_GL_11 + {"gl1.1", Backend_GLLegacy()}, + #endif + {"soft", Backend_Soft()}, + {"stub", Backend_Stub()} + }; + + Log("Available backends:"); + for (int i = 0; i < sizeof(backends) / sizeof(*backends); ++ i) { + Log("- %s", backends[i].name); + } + Log("Selecting '%s'", backends[0].name); + + Backend_Use(backends[0].backend); + App_Init(); while (app.running) { diff --git a/source/screen.c b/source/screen.c index 74f2d1947ad82614ccc73e3d3cc8a54c112bc99c..91ff0e30648f3712ead9f7bf7521dd38c23617a7 100644 --- a/source/screen.c +++ b/source/screen.c @@ -32,7 +32,7 @@ Font_Free(&screen.font); Buffer_Free(&screen.buffer); } -static ColourRGB GetColour(bool fg, uint8_t mode, BufCol col) { +ColourRGB Screen_GetColour(bool fg, uint8_t mode, BufCol col) { switch (mode) { case BUF_DEFAULT: return fg? theme.fg : theme.bg; case BUF_16COL: return theme.pal16[col.idx % 16]; @@ -44,25 +44,25 @@ assert(0); } void Screen_Render(void) { - int cw; - int ch; - Font_CharSize(&screen.font, &cw, &ch); - - for (int y = 0; y < screen.buffer.height; ++ y) { - for (int x = 0; x < screen.buffer.width; ++ x) { - int cx = x * cw; - int cy = y * ch; - - BufCell* cell = Buffer_Get(&screen.buffer, x, y); - - ColourRGB fg = GetColour(true, cell->fgMode, cell->fg); - ColourRGB bg = GetColour(false, cell->bgMode, cell->bg); - - Rect rect = {cx, cy, cw, ch}; - Colour c = (Colour) {bg.r, bg.g, bg.b, 255}; - Backend_RenderRect(rect, c); - - Font_RenderChar(&screen.font, cell->ch, cx, cy, fg); - } - } +// int cw; +// int ch; +// Font_CharSize(&screen.font, &cw, &ch); +// +// for (int y = 0; y < screen.buffer.height; ++ y) { +// for (int x = 0; x < screen.buffer.width; ++ x) { +// int cx = x * cw; +// int cy = y * ch; +// +// BufCell* cell = Buffer_Get(&screen.buffer, x, y); +// +// ColourRGB fg = GetColour(true, cell->fgMode, cell->fg); +// ColourRGB bg = GetColour(false, cell->bgMode, cell->bg); +// +// Rect rect = {cx, cy, cw, ch}; +// Colour c = (Colour) {bg.r, bg.g, bg.b, 255}; +// Backend_RenderRect(rect, c); +// +// Font_RenderChar(&screen.font, cell->ch, cx, cy, fg); +// } +// } } diff --git a/source/screen.h b/source/screen.h index 5cbe75da0bd9da871c2c05fd275d4413012d6b6b..f7e08e93fc8d019cc90989be6556d2e6f58b0652 100644 --- a/source/screen.h +++ b/source/screen.h @@ -1,7 +1,7 @@ #ifndef YT_SCREEN_H #define YT_SCREEN_H -#include "text.h" +#include "font.h" #include "buffer.h" typedef struct { @@ -11,8 +11,9 @@ } Screen; extern Screen screen; -void Screen_Init(void); -void Screen_Free(void); -void Screen_Render(void); +void Screen_Init(void); +void Screen_Free(void); +ColourRGB Screen_GetColour(bool fg, uint8_t mode, BufCol col); +void Screen_Render(void); #endif diff --git a/source/text.c b/source/text.c deleted file mode 100644 index 2783f76001aef709349c90c1a73167b645ace6f1..0000000000000000000000000000000000000000 --- a/source/text.c +++ /dev/null @@ -1,55 +0,0 @@ -#include <assert.h> -#include "text.h" - -Font Font_FromBMFont(BMFont bm) { - Font ret; - ret.type = FONT_BITMAP; - ret.v.bm = bm; - return ret; -} - -void Font_Free(Font* font) { - switch (font->type) { - case FONT_BITMAP: { - BMFont_Free(&font->v.bm); - break; - } - default: assert(0); - } -} - -void Font_CharSize(Font* font, int* w, int* h) { - switch (font->type) { - case FONT_BITMAP: { - if (w) *w = font->v.bm.charWidth; - if (h) *h = font->v.bm.charHeight; - break; - } - default: assert(0); - } -} - -void Font_RenderChar(Font* font, UChar ch, int x, int y, ColourRGB colour) { - switch (font->type) { - case FONT_BITMAP: { - if (ch > 255) { - ch = '?'; - } - - BMFont_RenderChar(&font->v.bm, (char) ch, x, y, colour); - break; - } - default: assert(0); - } -} - -// void Font_RenderString(Font* font, const char* str, int x, int y) { -// int cw; -// Font_CharSize(font, &cw, NULL); -// -// while (*str) { -// Font_RenderChar(font, *str, x, y); -// ++ str; -// x += cw; -// } -// } diff --git a/source/text.h b/source/text.h deleted file mode 100644 index a26131ef8fd1751c9fc90b9339645d768dc98dd3..0000000000000000000000000000000000000000 --- a/source/text.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef YT_TEXT_H -#define YT_TEXT_H - -#include "char.h" -#include "bitmapFont.h" - -enum { - FONT_BITMAP = 0, - FONT_TTF -}; - -typedef struct { - int type; - - union { - BMFont bm; - } v; -} Font; - -Font Font_FromBMFont(BMFont bm); -void Font_Free(Font* font); -void Font_CharSize(Font* font, int* w, int* h); -void Font_RenderChar(Font* font, UChar ch, int x, int y, ColourRGB colour); - -#endif