#define SDL_MAIN_HANDLED #include #include #include "input.h" #include "loader.h" #include "util.h" #include "tilemap.h" #include "incbin.h" #include "libplum.h" SDL_Window *window = NULL; SDL_Renderer *renderer = NULL; #define WINDOW_WIDTH 160 #define WINDOW_HEIGHT 90 #define INIT_SUBSYSTEMS SDL_INIT_VIDEO unsigned input_now = 0; SDL_Scancode keybinds[] = { SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_A, SDL_SCANCODE_S, }; int main(int argc, char **argv) { if (SDL_Init(INIT_SUBSYSTEMS)) { fprintf(stderr, "failed to initialize SDL2: %s\n", SDL_GetError()); return EXIT_FAILURE; } SDL_StopTextInput(); window = SDL_CreateWindow(":3", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN); if (window == NULL) { goto end; } renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_PRESENTVSYNC); if (renderer == NULL) { goto end; } SDL_RenderSetLogicalSize(renderer, WINDOW_WIDTH, WINDOW_HEIGHT); { res_init_texture(); res_init_map(); //init_tilemap(); void *a = util_executableRelativePath("assets.res", *argv, 0); puts(a); if (loadResources(a)) { fputs("loading resources failed\n", stderr); return 1; } free(a); struct blob map = res_get_map("out"); tilemap = load_tilemap(map.data, map.size); printf("load_tilemap %p\n", tilemap); SDL_SetRenderTarget(renderer, NULL); } unsigned error; struct plum_image *image = plum_load_image(game_icon, game_icon_end - game_icon, PLUM_COLOR_32 | PLUM_ALPHA_INVERT, &error); if (image == NULL) { fprintf(stderr, "error: libplum: %s\n", plum_get_error_text(error)); goto icon_done; } SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(image->data, image->width, image->height, 32, image->width * 4, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); if (surface == NULL) { plum_destroy_image(image); fprintf(stderr, "error: SDL2: %s\n", SDL_GetError()); goto icon_done; } SDL_SetWindowIcon(window, surface); SDL_FreeSurface(surface); plum_destroy_image(image); icon_done: SDL_ShowWindow(window); int x = 0, y = 0; while (1) { SDL_Event evt; while (SDL_PollEvent(&evt)) { switch (evt.type) { case SDL_QUIT: // the last window is closed, or the app is asked to terminate fputs("quitting...\n", stderr); goto end; case SDL_KEYDOWN: case SDL_KEYUP: // a key on is pressed or released if (evt.key.repeat) break; // check for ^Q and exit if pressed if (evt.key.state == SDL_PRESSED && evt.key.keysym.sym == SDLK_q && evt.key.keysym.mod & KMOD_CTRL) { goto end; } //static_assert(INPUT_LENGTH <= sizeof(input_now) * CHAR_BIT); // if this trips up, scope creep happened for (unsigned key = 0, bit = 1; key < INPUT_LENGTH; key++, bit <<= 1) { if (evt.key.keysym.scancode == keybinds[key]) { if (evt.key.state == SDL_PRESSED) input_now |= bit; else input_now &= ~bit; } } //fprintf(stderr, "input: %0*b\n", INPUT_LENGTH, input_now); break; case SDL_MOUSEMOTION: // the cursor moves //fprintf(stderr, "mouse at %4i %4i\n", evt.motion.x, evt.motion.y); break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: // a left click or release if (evt.button.state) { //fprintf(stderr, "click %i\n", evt.button.button); } if (!evt.button.state) { //fprintf(stderr, "unclick %i\n", evt.button.button); } break; case SDL_MOUSEWHEEL: // the scroll wheel gets rolled //fprintf(stderr, "scrolled by %2i %2i %4.1f %4.1f\n", evt.wheel.x, evt.wheel.y, evt.wheel.preciseX, evt.wheel.preciseY); break; case SDL_WINDOWEVENT: // window related events switch (evt.window.event) { case SDL_WINDOWEVENT_SHOWN: //fprintf(stderr, "window %u shown\n", evt.window.windowID); break; case SDL_WINDOWEVENT_HIDDEN: //fprintf(stderr, "window %u hidden\n", evt.window.windowID); break; case SDL_WINDOWEVENT_EXPOSED: //fprintf(stderr, "window %u exposed\n", evt.window.windowID); break; case SDL_WINDOWEVENT_MOVED: // a window is moved //fprintf(stderr, "window %u moved %4i %4i\n", evt.window.windowID, evt.window.data1, evt.window.data2); break; case SDL_WINDOWEVENT_RESIZED: // a window is resized //fprintf(stderr, "window %u resized %4i %4i\n", evt.window.windowID, evt.window.data1, evt.window.data2); break; case SDL_WINDOWEVENT_SIZE_CHANGED: // ? break; case SDL_WINDOWEVENT_MINIMIZED: //fprintf(stderr, "window %u minimized\n", evt.window.windowID); break; case SDL_WINDOWEVENT_MAXIMIZED: //fprintf(stderr, "window %u maximized\n", evt.window.windowID); break; case SDL_WINDOWEVENT_RESTORED: //fprintf(stderr, "window %u restored\n", evt.window.windowID); break; case SDL_WINDOWEVENT_ENTER: case SDL_WINDOWEVENT_LEAVE: // cursor enters or leaves a window case SDL_WINDOWEVENT_FOCUS_GAINED: case SDL_WINDOWEVENT_FOCUS_LOST: // keyboard break; case SDL_WINDOWEVENT_CLOSE: // a window is asked to close //fprintf(stderr, "window %u closed\n", evt.window.windowID); break; case SDL_WINDOWEVENT_TAKE_FOCUS: //fprintf(stderr, "window %u offered focus\n", evt.window.windowID); break; case SDL_WINDOWEVENT_HIT_TEST: //fprintf(stderr, "window %u hit test\n", evt.window.windowID); break; default: fprintf(stderr, "window %u event %i\n", evt.window.windowID, evt.window.event); } break; default: fprintf(stderr, "unknown event type %i\n", evt.type); } } SDL_SetRenderTarget(renderer, NULL); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_RenderClear(renderer); SDL_SetRenderDrawColor(renderer, 0, 128, 255, 0); SDL_RenderFillRect(renderer, &(SDL_Rect) {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT}); SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); x += input_right(input_now) - input_left(input_now); y += input_down(input_now) - input_up(input_now); if (x < 0) {x = 0;} else if (x + WINDOW_WIDTH > tilemap->width * 8) {x = tilemap->width * 8 - WINDOW_WIDTH;} if (y < 0) {y = 0;} else if (y + WINDOW_HEIGHT > tilemap->height * 8) {y = tilemap->height * 8 - WINDOW_HEIGHT;} //SDL_RenderCopy(renderer, tilemap->wang_tileset, &(SDL_Rect) {0, 0, 128, 90}, &(SDL_Rect) {0, 0, 128, 90}); for (int i = 0; i < tilemap->layers; i++) { SDL_RenderCopy(renderer, tilemap->tilemaps[i], &(SDL_Rect) {x * tilemap->parallax[i].x, y * tilemap->parallax[i].y, WINDOW_WIDTH, WINDOW_HEIGHT}, &(SDL_Rect) {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT}); } //SDL_RenderCopy(renderer, res_get_texture("meow").data, &(SDL_Rect) {0, 0, 128, 90}, &(SDL_Rect) {0, 0, 128, 90}); // then we wait for the next video frame SDL_RenderPresent(renderer); } end: free_tilemap(tilemap), tilemap = NULL; SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); //SDL_QuitSubSystem(INIT_SUBSYSTEMS); return 0; }