#include #include #include #include #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(); }