#include #include #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) { float fontScale = 1; gfx->window = SDL_CreateWindow("Shrooms VB", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 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; } gfx->renderer = SDL_CreateRenderer(gfx->window, -1, 0); if (!gfx->renderer) { fprintf(stderr, "Error creating renderer: %s\n", SDL_GetError()); goto cleanup_window; } /* 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); } 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; } 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; } 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); } 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) { /* 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); nk_sdl_render(NK_ANTI_ALIASING_ON); SDL_RenderPresent(gfx->renderer); }