115 lines
4.0 KiB
C
115 lines
4.0 KiB
C
#include "window.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#define ERROR(...) fprintf(stderr, __VA_ARGS__)
|
|
|
|
Window *windowNew(const char *title, int width, int height) {
|
|
Window *window = malloc(sizeof(Window));
|
|
if (!window) {
|
|
ERROR("error: out of memory\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
window->obj = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED,
|
|
SDL_WINDOWPOS_UNDEFINED, width, height,
|
|
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
|
|
if (!window->obj) {
|
|
ERROR("error: sdl2: %s\n", SDL_GetError());
|
|
free(window);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
window->render = SDL_CreateRenderer(
|
|
window->obj, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
|
if (!window->render) {
|
|
ERROR("error: sdl2: %s\n", SDL_GetError());
|
|
SDL_DestroyWindow(window->obj);
|
|
free(window);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
window->background = NULL;
|
|
window->focus.x = 0.0f;
|
|
window->focus.y = 0.0f;
|
|
window->targetFocus.x = 0.0f;
|
|
window->targetFocus.y = 0.0f;
|
|
window->zoom = 1.0f;
|
|
window->state = WINDOW_STATE_NORMAL;
|
|
return window;
|
|
}
|
|
|
|
void windowDelete(Window *window) {
|
|
SDL_DestroyRenderer(window->render);
|
|
SDL_DestroyWindow(window->obj);
|
|
free(window);
|
|
}
|
|
|
|
static void zoomRect(const Window *window, SDL_Rect *rect) {
|
|
int winW, winH;
|
|
SDL_GetWindowSize(window->obj, &winW, &winH);
|
|
int texW, texH;
|
|
SDL_QueryTexture(window->background, NULL, NULL, &texW, &texH);
|
|
const Point *focus = &window->focus;
|
|
rect->x = (texW * focus->x) - (texW / window->zoom / 2);
|
|
rect->y = (texH * focus->y) - (texH / window->zoom / 2);
|
|
rect->w = texW / window->zoom;
|
|
rect->h = texH / window->zoom;
|
|
}
|
|
|
|
void windowDraw(Window *window) {
|
|
window->lastTime = window->nowTime;
|
|
window->nowTime = SDL_GetPerformanceCounter();
|
|
window->delta = (double)(((window->nowTime - window->lastTime) * 1000) /
|
|
SDL_GetPerformanceFrequency());
|
|
SDL_SetRenderDrawColor(window->render, 0xFF, 0xFF, 0xFF, SDL_ALPHA_OPAQUE);
|
|
SDL_RenderClear(window->render);
|
|
if (window->background) {
|
|
if (window->state == WINDOW_STATE_ZOOMING_IN) {
|
|
window->zoom += MAX_ZOOM * (window->delta / ZOOM_TIME);
|
|
window->focus.x += (window->targetFocus.x - window->startFocus.x) *
|
|
(window->delta / ZOOM_TIME);
|
|
window->focus.y += (window->targetFocus.y - window->startFocus.y) *
|
|
(window->delta / ZOOM_TIME);
|
|
if (window->zoom >= MAX_ZOOM) {
|
|
window->state = WINDOW_STATE_ZOOMED;
|
|
}
|
|
} else if (window->state == WINDOW_STATE_ZOOMING_OUT) {
|
|
window->zoom -= MAX_ZOOM * (window->delta / ZOOM_TIME);
|
|
window->focus.x += (window->targetFocus.x - window->startFocus.x) *
|
|
(window->delta / ZOOM_TIME);
|
|
window->focus.y += (window->targetFocus.y - window->startFocus.y) *
|
|
(window->delta / ZOOM_TIME);
|
|
if (window->zoom <= 1.0f) {
|
|
window->state = WINDOW_STATE_NORMAL;
|
|
}
|
|
}
|
|
if (window->state == WINDOW_STATE_NORMAL) {
|
|
SDL_RenderCopy(window->render, window->background, NULL, NULL);
|
|
} else {
|
|
SDL_Rect area;
|
|
zoomRect(window, &area);
|
|
SDL_RenderCopy(window->render, window->background, &area, NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
void windowUpdate(Window *window) {
|
|
SDL_RenderPresent(window->render);
|
|
}
|
|
|
|
void windowZoomTo(Window *window, float x, float y) {
|
|
window->zoom = 1.0f;
|
|
window->startFocus.x = 0.5f;
|
|
window->startFocus.y = 0.5f;
|
|
window->focus = window->startFocus;
|
|
window->targetFocus.x = x;
|
|
window->targetFocus.y = y;
|
|
window->state = WINDOW_STATE_ZOOMING_IN;
|
|
}
|
|
|
|
void windowZoomOut(Window *window) {
|
|
window->startFocus = window->focus;
|
|
window->targetFocus.x = 0.5f;
|
|
window->targetFocus.y = 0.5f;
|
|
window->state = WINDOW_STATE_ZOOMING_OUT;
|
|
}
|