#include #include #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" #include "font.h" #include "gif.c" #include struct Mouse { int x, y; bool buttons[3]; }; typedef bool(*LoopFun)(void); SDL_Window* sdlWindow = NULL; SDL_Renderer* sdlRenderer = NULL; SDL_Texture* sdlFontTexture = NULL; SDL_Texture* sdlTilesTexture = NULL; SDL_Event sdlEvent; bool anyKey = false; LoopFun loop; Mouse mouse; int error = 0; int tile_width = 16; int tile_height = 16; int map_width = 240; int map_height = 240; int screen_width = 256; int screen_height = 192; int zoom = 2; char tiles_filename[100] = { 0 }; char map_filename[100] = { 0 }; int tilemap_width = 0; int tilemap_height = 0; int map_x = 0; int map_y = 0; int StrToInt(const char* str) { int val = 0; int size = strlen(str); for (int i = 0; i < size; i++) { if (str[i] < 48 || str[i] > 57) return 0; val = val * 10 + (str[i] - 48); } return val; } void LoadConfig() { FILE* f = fopen("config.ini", "r"); if (!f) { error = 1; return; } char key[50]; char val[255]; while (!feof(f)) { fscanf(f, "%s = %s", key, val); if (strcmp(key, "tile_width") == 0) { tile_width = StrToInt(val); } else if (strcmp(key, "tile_height") == 0) { tile_height = StrToInt(val); } else if (strcmp(key, "map_width") == 0) { map_width = StrToInt(val); } else if (strcmp(key, "map_height") == 0) { map_height = StrToInt(val); } else if (strcmp(key, "screen_width") == 0) { screen_width = StrToInt(val); } else if (strcmp(key, "screen_height") == 0) { screen_height = StrToInt(val); } else if (strcmp(key, "zoom") == 0) { zoom = StrToInt(val); } else if (strcmp(key, "tiles") == 0) { strcpy(tiles_filename, val); } else if (strcmp(key, "map") == 0) { strcpy(map_filename, val); } } fclose(f); } void Init() { LoadConfig(); SDL_Init(SDL_INIT_EVERYTHING); sdlWindow = SDL_CreateWindow("Mappy v0.1", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screen_width*zoom, screen_height*zoom, SDL_WINDOW_SHOWN); sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, SDL_RENDERER_PRESENTVSYNC); //SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); SDL_RenderSetLogicalSize(sdlRenderer, screen_width, screen_height); unsigned short w, h; unsigned char* buffer = LoadGif(font, &w, &h); sdlFontTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, w, h); Uint32* pixels = (Uint32*)malloc(w*h*sizeof(Uint32)); for (int i = 0; i < w*h; i++) { pixels[i] = buffer[i] == 0 ? 0x00000000 : 0xffffffff; } SDL_UpdateTexture(sdlFontTexture, NULL, pixels, w * sizeof(Uint32)); SDL_SetTextureBlendMode(sdlFontTexture, SDL_BLENDMODE_BLEND); free(buffer); free(pixels); int c; FILE* f = fopen(tiles_filename, "rb"); if (!f) { error = 2; } else { buffer = stbi_load_from_file(f, &tilemap_width, &tilemap_height, &c, 4); sdlTilesTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, tilemap_width, tilemap_height); SDL_UpdateTexture(sdlTilesTexture, NULL, buffer, tilemap_width * sizeof(Uint32)); SDL_SetTextureBlendMode(sdlTilesTexture, SDL_BLENDMODE_BLEND); stbi_image_free(buffer); } //SDL_Surface* bmp = SDL_LoadBMP("assets.bmp"); //texture = SDL_CreateTextureFromSurface(renderer, bmp); //SDL_FreeSurface(bmp); } void Quit() { SDL_DestroyTexture(sdlFontTexture); SDL_DestroyRenderer(sdlRenderer); SDL_DestroyWindow(sdlWindow); SDL_Quit(); } void Flip() { SDL_RenderPresent(sdlRenderer); } void Clear() { SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, 255); SDL_RenderClear(sdlRenderer); } void Draw(SDL_Texture* texture, int x, int y, int sx, int sy, int w, int h) { SDL_Rect src, dst; src.x = sx; src.y = sy; dst.x = x; dst.y = y; src.w = dst.w = w; src.h = dst.h = h; SDL_RenderCopy(sdlRenderer, texture, &src, &dst); } void FillRect(int x, int y, int w, int h, Uint8 r, Uint8 g, Uint8 b, Uint8 a = 255) { SDL_Rect src; src.x = x; src.y = y; src.w = w; src.h = h; SDL_SetRenderDrawColor(sdlRenderer, r, g, b, a); SDL_RenderFillRect(sdlRenderer, &src); } void Print(int x, int y, const char* text) { int str_size = strlen(text); for (int i = 0; i < str_size; i++) { char chr = text[i] - 32; Draw(sdlFontTexture, x + (i * 6), y, (chr & 0x0f) * 6, (chr >> 4) * 6, 6, 6); } } bool Button(int x, int y, char* text) { bool inside = (mouse.x >= x) && (mouse.y >= y) && (mouse.x < x + 51) && (mouse.y < y + 8); if (inside) { FillRect(x, y, 51, 9, 128, 64, 64, 255); } else { FillRect(x, y, 51, 9, 255, 64, 64, 255); } Print(x+2, y+2, text); return inside && mouse.buttons[0]; } bool Update() { anyKey = false; while (SDL_PollEvent(&sdlEvent)) { if (sdlEvent.type == SDL_QUIT) {return true; break; } else if (sdlEvent.type == SDL_KEYDOWN) { anyKey = true; if (sdlEvent.key.keysym.scancode == SDL_SCANCODE_ESCAPE) { return true; } } } Uint32 buttons = SDL_GetMouseState(&mouse.x, &mouse.y); mouse.x /= zoom; mouse.y /= zoom; mouse.buttons[0] = (buttons & 1) == 1; mouse.buttons[1] = (buttons & 2) == 2; mouse.buttons[2] = (buttons & 4) == 4; return false; } void PrintFatalError(const char* errorMsg) { int size = strlen(errorMsg); Print((screen_width - (size*6)) / 2, (screen_height - 6) / 2, errorMsg); } void ShowError() { switch (error) { case 1: PrintFatalError("No s'ha trobat l'arxiu config.ini"); break; case 2: PrintFatalError("No s'ha trobat arxiu de tiles"); break; } } int main(int argc, char* argv[]) { Init(); while (!Update()) { Clear(); if (error == 0) { int x = 0, y = 0; if (tilemap_width <= screen_width) { x = (screen_width - tilemap_width) / 2; } else { const int max_offset = tilemap_width - screen_width; const float mouse_ratio = float(mouse.x) / float(screen_width); x = -(mouse_ratio * max_offset); } if (tilemap_height <= screen_height) { y = (screen_height - tilemap_height) / 2; } else { const int max_offset = tilemap_height - screen_height; const float mouse_ratio = float(mouse.y) / float(screen_height); y = -(mouse_ratio * max_offset); } Draw(sdlTilesTexture, x, y, 0, 0, tilemap_width, tilemap_height); /*char num[5]; sprintf(num, "%d", mouse.x); Print(100, 100, num); sprintf(num, ",%d", mouse.y); Print(118, 100, num); if (Button(2, 2, "New")) { strcpy(state, "New pressed"); } if (Button(2, 12, "Open")) { strcpy(state, "open pressed"); } if (Button(2, 22, "Save")) { strcpy(state, "save pressed"); } if (Button(2, 32, "Save As")) { strcpy(state, "Save As pressed"); } FillRect(0, 183, 256, 9, 128, 128, 128, 255); Print(2, 185, state);*/ } else { ShowError(); } Flip(); } Quit(); return 0; }