lemur/graphics.c

174 lines
5.6 KiB
C
Raw Normal View History

#include <graphics.h>
2024-10-26 05:20:25 +00:00
#define WINDOW_WIDTH 1536
#define WINDOW_HEIGHT 896
static void copyScreenTexture(uint8_t *dst, const uint8_t *src, int pitch) {
int x, y, i;
uint8_t color;
int delta = pitch / 384;
for (y = 0; y < 224; ++y) {
for (x = 0; x < 384; x += 1) {
color = src[(y * 384) + x];
for (i = 0; i < delta; ++i) {
dst[(y * pitch) + (x * delta) + i] = color;
}
}
}
}
int gfxInit(GraphicsContext *gfx) {
2024-10-26 05:20:25 +00:00
float fontScale = 1;
gfx->window = SDL_CreateWindow("Shrooms VB",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
2024-10-26 05:20:25 +00:00
WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
if (!gfx->window) {
fprintf(stderr, "Error creating window: %s\n", SDL_GetError());
return 1;
}
2024-10-23 23:47:28 +00:00
gfx->renderer = SDL_CreateRenderer(gfx->window, -1, 0);
if (!gfx->renderer) {
fprintf(stderr, "Error creating renderer: %s\n", SDL_GetError());
goto cleanup_window;
}
2024-10-26 05:20:25 +00:00
/* scale the renderer output for High-DPI displays */
{
int renderW, renderH;
int windowW, windowH;
float scaleX, scaleY;
SDL_GetRendererOutputSize(gfx->renderer, &renderW, &renderH);
SDL_GetWindowSize(gfx->window, &windowW, &windowH);
scaleX = (float)(renderW) / (float)(windowW);
scaleY = (float)(renderH) / (float)(windowH);
SDL_RenderSetScale(gfx->renderer, scaleX, scaleY);
}
2024-10-26 05:20:25 +00:00
gfx->nk = nk_sdl_init(gfx->window, gfx->renderer);
{
struct nk_font_atlas *atlas;
struct nk_font *font;
struct nk_font_config config = nk_font_config(0);
nk_sdl_font_stash_begin(&atlas);
font = nk_font_atlas_add_default(atlas, 13 * fontScale, &config);
nk_sdl_font_stash_end();
font->handle.height /= fontScale;
nk_style_set_font(gfx->nk, &font->handle);
}
gfx->bg.r = 0.10f;
gfx->bg.g = 0.18f;
gfx->bg.b = 0.24f;
gfx->bg.a = 1.0f;
gfx->leftEye = SDL_CreateTexture(gfx->renderer, SDL_PIXELFORMAT_RGB24, SDL_TEXTUREACCESS_STREAMING, 384, 224);
if (!gfx->leftEye) {
fprintf(stderr, "Error creating left eye texture: %s\n", SDL_GetError());
goto cleanup_window;
}
2024-10-19 22:04:15 +00:00
SDL_SetTextureColorMod(gfx->leftEye, 0xff, 0, 0);
gfx->rightEye = SDL_CreateTexture(gfx->renderer, SDL_PIXELFORMAT_RGB24, SDL_TEXTUREACCESS_STREAMING, 384, 224);
if (!gfx->rightEye) {
fprintf(stderr, "Error creating left eye texture: %s\n", SDL_GetError());
goto cleanup_left_eye;
}
2024-10-19 22:04:15 +00:00
SDL_SetTextureColorMod(gfx->rightEye, 0, 0xc6, 0xf0);
SDL_SetTextureBlendMode(gfx->rightEye, SDL_BLENDMODE_ADD);
return 0;
cleanup_left_eye:
SDL_DestroyTexture(gfx->leftEye);
cleanup_window:
SDL_DestroyWindow(gfx->window);
return 1;
}
void gfxDestroy(GraphicsContext *gfx) {
SDL_DestroyTexture(gfx->rightEye);
SDL_DestroyTexture(gfx->leftEye);
SDL_DestroyWindow(gfx->window);
}
static void gfxUpdateEye(SDL_Texture *eye, const uint8_t *bytes) {
void *target;
int pitch;
if (SDL_LockTexture(eye, NULL, &target, &pitch)) {
fprintf(stderr, "Error locking buffer for eye: %s\n", SDL_GetError());
return;
}
copyScreenTexture(target, bytes, pitch);
SDL_UnlockTexture(eye);
}
void gfxUpdateLeftEye(GraphicsContext *gfx, const uint8_t *bytes) {
gfxUpdateEye(gfx->leftEye, bytes);
}
void gfxUpdateRightEye(GraphicsContext *gfx, const uint8_t *bytes) {
gfxUpdateEye(gfx->rightEye, bytes);
}
2024-10-26 05:20:25 +00:00
void gfxMenuInputBegin(GraphicsContext *gfx) {
nk_input_begin(gfx->nk);
}
void gfxMenuHandleEvent(GraphicsContext *gfx, SDL_Event *event) {
(void) gfx;
nk_sdl_handle_event(event);
}
void gfxMenuInputEnd(GraphicsContext *gfx) {
nk_sdl_handle_grab();
nk_input_end(gfx->nk);
}
void gfxRender(GraphicsContext *gfx) {
2024-10-26 05:20:25 +00:00
/* GUI */
if (nk_begin(gfx->nk, "Demo", nk_rect(50, 50, 230, 250),
NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
{
enum {EASY, HARD};
static int op = EASY;
static int property = 20;
nk_layout_row_static(gfx->nk, 30, 80, 1);
if (nk_button_label(gfx->nk, "button"))
fprintf(stdout, "button pressed\n");
nk_layout_row_dynamic(gfx->nk, 30, 2);
if (nk_option_label(gfx->nk, "easy", op == EASY)) op = EASY;
if (nk_option_label(gfx->nk, "hard", op == HARD)) op = HARD;
nk_layout_row_dynamic(gfx->nk, 25, 1);
nk_property_int(gfx->nk, "Compression:", 0, &property, 100, 10, 1);
nk_layout_row_dynamic(gfx->nk, 20, 1);
nk_label(gfx->nk, "background:", NK_TEXT_LEFT);
nk_layout_row_dynamic(gfx->nk, 25, 1);
if (nk_combo_begin_color(gfx->nk, nk_rgb_cf(gfx->bg), nk_vec2(nk_widget_width(gfx->nk),400))) {
nk_layout_row_dynamic(gfx->nk, 120, 1);
gfx->bg = nk_color_picker(gfx->nk, gfx->bg, NK_RGBA);
nk_layout_row_dynamic(gfx->nk, 25, 1);
gfx->bg.r = nk_propertyf(gfx->nk, "#R:", 0, gfx->bg.r, 1.0f, 0.01f,0.005f);
gfx->bg.g = nk_propertyf(gfx->nk, "#G:", 0, gfx->bg.g, 1.0f, 0.01f,0.005f);
gfx->bg.b = nk_propertyf(gfx->nk, "#B:", 0, gfx->bg.b, 1.0f, 0.01f,0.005f);
gfx->bg.a = nk_propertyf(gfx->nk, "#A:", 0, gfx->bg.a, 1.0f, 0.01f,0.005f);
nk_combo_end(gfx->nk);
}
}
nk_end(gfx->nk);
SDL_SetRenderDrawColor(gfx->renderer, gfx->bg.r * 255, gfx->bg.g * 255, gfx->bg.b * 255, gfx->bg.a * 255);
SDL_RenderClear(gfx->renderer);
2024-10-26 05:20:25 +00:00
nk_sdl_render(NK_ANTI_ALIASING_ON);
SDL_RenderPresent(gfx->renderer);
}