203 lines
5.8 KiB
C
203 lines
5.8 KiB
C
|
#include <stdio.h>
|
||
|
#include <time.h>
|
||
|
|
||
|
#include <SDL2/SDL.h>
|
||
|
#include <SDL2/SDL_image.h>
|
||
|
|
||
|
#include "draw.h"
|
||
|
|
||
|
#define PRESCALE 4
|
||
|
#define FORMAT SDL_PIXELFORMAT_RGB565
|
||
|
|
||
|
#define WHITE rgb565(255, 255, 255)
|
||
|
#define BLACK rgb565(0, 0, 0)
|
||
|
|
||
|
typedef struct {
|
||
|
int size;
|
||
|
float* points;
|
||
|
} Polygon;
|
||
|
|
||
|
typedef struct {
|
||
|
int size;
|
||
|
Polygon* polygons;
|
||
|
} Data;
|
||
|
|
||
|
Data data;
|
||
|
|
||
|
void load(char* filename) {
|
||
|
FILE* fp = fopen(filename, "r");
|
||
|
if (!fp) {
|
||
|
perror(filename);
|
||
|
exit(1);
|
||
|
}
|
||
|
if (1 != fscanf(fp, "%d", &data.size)) goto load_error;
|
||
|
data.polygons = malloc(sizeof(Polygon) * data.size);
|
||
|
for (int i = 0; i < data.size; i++) {
|
||
|
float tmp; // skip bbox
|
||
|
if (4 != fscanf(fp, "%f %f %f %f", &tmp, &tmp, &tmp, &tmp)) goto load_error;
|
||
|
if (1 != fscanf(fp, "%d", &data.polygons[i].size)) goto load_error;
|
||
|
data.polygons[i].size *= 2; // number of values is number of points * 2
|
||
|
data.polygons[i].points = malloc(sizeof(float) * data.polygons[i].size);
|
||
|
for (int j = 0; j < data.polygons[i].size; j++) {
|
||
|
if (1 != fscanf(fp, "%f", &data.polygons[i].points[j])) goto load_error;
|
||
|
}
|
||
|
}
|
||
|
return;
|
||
|
load_error:
|
||
|
perror(filename);
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
float center[2] = {WIDTH / 2, 0};
|
||
|
float zoom = 1;
|
||
|
|
||
|
void init() {
|
||
|
load("ne_10m_land.txt");
|
||
|
}
|
||
|
|
||
|
void deinit() {
|
||
|
}
|
||
|
|
||
|
void update(float dt) {
|
||
|
}
|
||
|
|
||
|
void redraw() {
|
||
|
clear_screen();
|
||
|
for (int i = 0; i < data.size; i++) {
|
||
|
float transformed[data.polygons[i].size];
|
||
|
for (int j = 0; j < data.polygons[i].size; j += 2) {
|
||
|
transformed[j] = data.polygons[i].points[j] * zoom * WIDTH / 360 + WIDTH / 2 + center[0] * zoom;
|
||
|
transformed[j + 1] = -data.polygons[i].points[j + 1] * zoom * HEIGHT / 180 + HEIGHT / 2 + center[1] * zoom;
|
||
|
}
|
||
|
//fill(data.polygons[i].size, transformed, WIDTH * zoom, rgb565((i * 128397) % 255, (i * 123551) % 255, (i * 1097123) % 255));
|
||
|
fill(data.polygons[i].size, transformed, WIDTH * zoom, rgb565(255, 255, 255));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//#define on_key(event)
|
||
|
//#define on_mouse(event, kind)
|
||
|
#define on_text(event)
|
||
|
|
||
|
int mouse_pressed = 0;
|
||
|
int mouse_start_x, mouse_start_y;
|
||
|
int center_start_x, center_start_y;
|
||
|
|
||
|
void on_key(SDL_Event event) {
|
||
|
switch (event.key.keysym.sym) {
|
||
|
case SDLK_1: zoom = 1; break;
|
||
|
case SDLK_2: zoom = 4; break;
|
||
|
case SDLK_3: zoom = 16; break;
|
||
|
case SDLK_4: zoom = 64; break;
|
||
|
case SDLK_5: zoom = 128; break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void on_mouse(SDL_Event event, int kind) {
|
||
|
switch (kind) {
|
||
|
case 1:
|
||
|
mouse_pressed = 1;
|
||
|
mouse_start_x = event.motion.x;
|
||
|
mouse_start_y = event.motion.y;
|
||
|
center_start_x = center[0];
|
||
|
center_start_y = center[1];
|
||
|
break;
|
||
|
case 2:
|
||
|
mouse_pressed = 0;
|
||
|
break;
|
||
|
case 0:
|
||
|
if (mouse_pressed) {
|
||
|
center[0] = ((event.motion.x - mouse_start_x) / zoom + center_start_x);
|
||
|
center[1] = ((event.motion.y - mouse_start_y) / zoom + center_start_y);
|
||
|
}
|
||
|
break;
|
||
|
case 3:
|
||
|
zoom += event.wheel.preciseY / 8;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int main(int argc, char** argv) {
|
||
|
|
||
|
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||
|
fprintf(stderr, "Failed to init SDL\n");
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
if(IMG_Init(IMG_INIT_PNG) < 0) {
|
||
|
fprintf(stderr, "Failed to init SDL_Image\n");
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
init();
|
||
|
|
||
|
SDL_Window* window = SDL_CreateWindow("RPG", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 2 * WIDTH, 2 * HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE );
|
||
|
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
||
|
|
||
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
|
||
|
SDL_Texture* scaled = SDL_CreateTexture(renderer, FORMAT, SDL_TEXTUREACCESS_TARGET, PRESCALE * WIDTH, PRESCALE * HEIGHT);
|
||
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
|
||
|
|
||
|
SDL_RenderSetLogicalSize(renderer, WIDTH, HEIGHT);
|
||
|
//SDL_RenderSetIntegerScale(renderer, 1);
|
||
|
//SDL_MaximizeWindow(window);
|
||
|
SDL_StartTextInput();
|
||
|
|
||
|
SDL_SetRenderTarget(renderer, scaled);
|
||
|
|
||
|
int fullscreen = 0;
|
||
|
|
||
|
SDL_Texture* screen_texture = SDL_CreateTexture(renderer, FORMAT, SDL_TEXTUREACCESS_STATIC, WIDTH, HEIGHT);
|
||
|
|
||
|
while (1) {
|
||
|
Uint64 frame_start = SDL_GetPerformanceCounter();
|
||
|
|
||
|
SDL_Event event;
|
||
|
while (SDL_PollEvent(&event)) {
|
||
|
if (event.type == SDL_QUIT) { deinit(); exit(0);
|
||
|
} else if(event.type == SDL_WINDOWEVENT) {
|
||
|
} else if (event.type == SDL_KEYDOWN) {
|
||
|
if (event.key.keysym.sym == SDLK_RETURN && event.key.keysym.mod & KMOD_ALT) {
|
||
|
fullscreen = SDL_WINDOW_FULLSCREEN_DESKTOP - fullscreen;
|
||
|
SDL_SetWindowFullscreen(window, fullscreen);
|
||
|
} else if (event.key.keysym.sym == SDLK_q && event.key.keysym.mod & KMOD_CTRL) {
|
||
|
deinit(); exit(0);
|
||
|
} else on_key(event);
|
||
|
} else if (event.type == SDL_KEYUP) { on_key(event);
|
||
|
} else if (event.type == SDL_TEXTINPUT) { on_text(event);
|
||
|
} else if (event.type == SDL_MOUSEBUTTONDOWN) { on_mouse(event, 1);
|
||
|
} else if (event.type == SDL_MOUSEMOTION) { on_mouse(event, 0);
|
||
|
} else if (event.type == SDL_MOUSEBUTTONUP) { on_mouse(event, 2);
|
||
|
} else if (event.type == SDL_MOUSEWHEEL) { on_mouse(event, 3);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||
|
SDL_RenderClear(renderer);
|
||
|
|
||
|
SDL_UpdateTexture(screen_texture, NULL, framebuffer, WIDTH * sizeof(Color));
|
||
|
SDL_RenderCopy(renderer, screen_texture, NULL, NULL);
|
||
|
|
||
|
SDL_SetRenderTarget(renderer, NULL);
|
||
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||
|
SDL_RenderClear(renderer);
|
||
|
SDL_RenderCopy(renderer, scaled, NULL, NULL);
|
||
|
SDL_RenderPresent(renderer);
|
||
|
|
||
|
SDL_SetRenderTarget(renderer, scaled);
|
||
|
|
||
|
update(1.0f / 60);
|
||
|
redraw();
|
||
|
|
||
|
Uint64 frame_end = SDL_GetPerformanceCounter();
|
||
|
Uint64 duration = (frame_end - frame_start) * 1000 / SDL_GetPerformanceFrequency();
|
||
|
if (duration > 0) printf("%ld fps\n", 1000 / duration);
|
||
|
if(duration < 1000 / 60) SDL_Delay(1000 / 60 - duration);
|
||
|
}
|
||
|
|
||
|
deinit();
|
||
|
|
||
|
SDL_DestroyRenderer(renderer);
|
||
|
SDL_DestroyWindow(window);
|
||
|
SDL_Quit();
|
||
|
}
|