Compare commits

..

No commits in common. "31c4bde4bfe120ebc995915cbf848c23c2e1ef06" and "9810331253940a0a4517cf1c02529134dc6ae510" have entirely different histories.

6 changed files with 140 additions and 47 deletions

View File

@ -75,6 +75,7 @@ add_shader(grid)
add_executable(mikemon add_executable(mikemon
src/log.cpp src/log.cpp
src/load_entire_file.cpp
src/smol-atlas.cpp src/smol-atlas.cpp
src/math_graphics.cpp src/math_graphics.cpp
src/main.cpp src/main.cpp

32
src/load_entire_file.cpp Normal file
View File

@ -0,0 +1,32 @@
#define _CRT_SECURE_NO_WARNINGS
#include "load_entire_file.h"
#include <stdio.h>
#include <stdlib.h>
String load_entire_file(const char* filename) {
auto file = fopen(filename, "rb");
if (!file)
return {};
if (fseek(file, 0, SEEK_END))
return {};
auto file_length = ftell(file);
if (file_length == -1)
return {};
if (fseek(file, 0, SEEK_SET))
return {};
auto file_mem = malloc(file_length);
if (!file_mem)
return {};
if (fread(file_mem, file_length, 1, file) != 1) {
free(file_mem);
return {};
}
return { (size_t)file_length, (char*)file_mem };
}

4
src/load_entire_file.h Normal file
View File

@ -0,0 +1,4 @@
#pragma once
#include "m_string.h"
String load_entire_file(const char* filename);

68
src/m_string.h Normal file
View File

@ -0,0 +1,68 @@
#pragma once
#define min(a,b) (((a) < (b)) ? (a) : (b))
#include <stddef.h>
struct String {
size_t length;
char* data;
constexpr String() : length(0), data(0) {};
constexpr String(size_t length, char* data) : length(length), data(data) {};
template<size_t _len> constexpr String(const char(&data)[_len]) : length(_len - 1), data((char*)data) {};
char operator[](int index) {
if (index < 0) {
return 0;
}
if (index < length) {
return data[index];
}
return 0;
}
};
inline String operator""_str(const char* str, size_t length) {
return { length, (char*)str };
}
inline bool operator==(String a, String b) {
if (a.length != b.length)
return false;
if (a.data == b.data)
return true;
for (int i = 0; i < a.length; i++)
if (a[i] != b[i])
return false;
return true;
}
inline void advance(String& s, int num = 1) {
int to_advance = min(s.length, num);
s.data = s.data + to_advance;
s.length = s.length - to_advance;
}
inline bool starts_with(String s, String start) {
if (s.length < start.length) {
return false;
}
for (int i = 0; i < start.length; i++) {
if (s[i] != start[i]) {
return false;
}
}
return true;
}
template <typename T>
inline T read(String& file) {
if (file.length < sizeof(T))
return {};
T value = *(T*)file.data;
advance(file, sizeof(T));
return value;
}

View File

@ -10,7 +10,9 @@
#include "defer.h" #include "defer.h"
#include "log.h" #include "log.h"
#include "m_string.h"
#include "math_graphics.h" #include "math_graphics.h"
#include "load_entire_file.h"
#include "stb_image.h" #include "stb_image.h"
#include "../assets/shader/basic.h" #include "../assets/shader/basic.h"
@ -20,8 +22,6 @@
using namespace M; using namespace M;
#define ASSETS_PATH "../assets/"
#define NEAR_PLANE (0.01f) #define NEAR_PLANE (0.01f)
#define TILE_SIZE (32) #define TILE_SIZE (32)
@ -160,7 +160,7 @@ struct Map {
Uint32 *tiles; Uint32 *tiles;
char *name; char *save_path;
SDL_GPUBuffer *gpu_buffer; SDL_GPUBuffer *gpu_buffer;
}; };
@ -190,25 +190,25 @@ typedef struct {
} TileInfo; } TileInfo;
static TileInfo tile_infos[] = { static TileInfo tile_infos[] = {
{ 0x0001, "tiles/error.png" }, { 0x0001, "../assets/tiles/error.png" },
{ 0x0000, "tiles/empty.png" }, { 0x0000, "../assets/tiles/empty.png" },
{ 0x0100, "tiles/grass_1.png" }, { 0x0100, "../assets/tiles/grass_1.png" },
{ 0x0101, "tiles/grass_2.png" }, { 0x0101, "../assets/tiles/grass_2.png" },
{ 0x0102, "tiles/grass_3.png" }, { 0x0102, "../assets/tiles/grass_3.png" },
{ 0x0103, "tiles/grass_4.png" }, { 0x0103, "../assets/tiles/grass_4.png" },
{ 0x0200, "tiles/ground_1.png" }, { 0x0200, "../assets/tiles/ground_1.png" },
{ 0x0201, "tiles/ground_2.png" }, { 0x0201, "../assets/tiles/ground_2.png" },
{ 0x0202, "tiles/ground_3.png" }, { 0x0202, "../assets/tiles/ground_3.png" },
{ 0x0300, "tiles/water_1.png" }, { 0x0300, "../assets/tiles/water_1.png" },
{ 0x0301, "tiles/water_2.png" }, { 0x0301, "../assets/tiles/water_2.png" },
{ 0x0400, "tiles/grass_ground_1.png" }, { 0x0400, "../assets/tiles/grass_ground_1.png" },
{ 0x0401, "tiles/grass_ground_2.png" }, { 0x0401, "../assets/tiles/grass_ground_2.png" },
{ 0x0402, "tiles/grass_ground_3.png" }, { 0x0402, "../assets/tiles/grass_ground_3.png" },
{ 0x0410, "tiles/grass_ground_outer_corner.png" }, { 0x0410, "../assets/tiles/grass_ground_outer_corner.png" },
{ 0x0411, "tiles/grass_ground_outer_corner_2.png" }, { 0x0411, "../assets/tiles/grass_ground_outer_corner_2.png" },
{ 0x0420, "tiles/grass_ground_inner_corner.png" }, { 0x0420, "../assets/tiles/grass_ground_inner_corner.png" },
{ 0x0421, "tiles/grass_ground_inner_corner_2.png" }, { 0x0421, "../assets/tiles/grass_ground_inner_corner_2.png" },
{ 0x0422, "tiles/grass_ground_inner_corner_3.png" }, { 0x0422, "../assets/tiles/grass_ground_inner_corner_3.png" },
}; };
static V4 cpu_tile_infos_buffer[SDL_arraysize(tile_infos)]; static V4 cpu_tile_infos_buffer[SDL_arraysize(tile_infos)];
@ -302,10 +302,7 @@ static SDL_GPUBuffer *create_buffer(SDL_GPUBufferUsageFlags usage, Uint32 num_by
} }
static bool save_map(Map map) { static bool save_map(Map map) {
char path[256] = ASSETS_PATH "maps/"; SDL_IOStream *file = SDL_IOFromFile(map.save_path, "wb");
SDL_strlcat(path, map.name, SDL_arraysize(path));
SDL_IOStream *file = SDL_IOFromFile(path, "wb");
if (!file) { if (!file) {
log_error("Failed to open map file for writing."); log_error("Failed to open map file for writing.");
return false; return false;
@ -342,17 +339,14 @@ static bool save_map(Map map) {
return true; return true;
} }
static bool load_map(const char *name, Map *result) { static bool load_map(const char *path, Map *result) {
char path[256] = ASSETS_PATH "maps/";
SDL_strlcat(path, name, SDL_arraysize(path));
SDL_IOStream *file = SDL_IOFromFile(path, "rb"); SDL_IOStream *file = SDL_IOFromFile(path, "rb");
if (!file) { if (!file) {
log_error("Failed to open map file for reading."); log_error("Failed to open map file for reading.");
return false; return false;
} }
defer(SDL_CloseIO(file)); defer(SDL_CloseIO(file));
result->name = SDL_strdup(name); result->save_path = SDL_strdup(path);
if (!SDL_ReadS32LE(file, &result->width)) { if (!SDL_ReadS32LE(file, &result->width)) {
log_error("Failed read width from map file."); log_error("Failed read width from map file.");
@ -388,7 +382,7 @@ static bool load_map(const char *name, Map *result) {
} }
char buffer_name[256] = "Map "; char buffer_name[256] = "Map ";
SDL_strlcat(buffer_name, result->name, SDL_arraysize(buffer_name)); SDL_strlcat(buffer_name, result->save_path, SDL_arraysize(buffer_name));
result->gpu_buffer = create_buffer(SDL_GPU_BUFFERUSAGE_VERTEX, result->width * result->height * 4, result->tiles, buffer_name); result->gpu_buffer = create_buffer(SDL_GPU_BUFFERUSAGE_VERTEX, result->width * result->height * 4, result->tiles, buffer_name);
if (!result->gpu_buffer) { if (!result->gpu_buffer) {
@ -405,7 +399,7 @@ static void unload_map(Map *map) {
map->width = 0; map->width = 0;
map->height = 0; map->height = 0;
free(map->tiles); free(map->tiles);
SDL_free(map->name); SDL_free(map->save_path);
SDL_ReleaseGPUBuffer(device, map->gpu_buffer); SDL_ReleaseGPUBuffer(device, map->gpu_buffer);
} }
@ -583,19 +577,16 @@ static SDL_GPUTexture *create_shader_texture(const char *name, const char *data,
} }
static SDL_GPUTexture *create_shader_texture(const char *path) { static SDL_GPUTexture *create_shader_texture(const char *path) {
char path_to_load[256] = ASSETS_PATH;
SDL_strlcat(path_to_load, path, SDL_arraysize(path_to_load));
int width = 0, height = 0, channels = 0; int width = 0, height = 0, channels = 0;
stbi_uc *data = stbi_load(path_to_load, &width, &height, &channels, 0); stbi_uc *data = stbi_load(path, &width, &height, &channels, 0);
if (!data) { if (!data) {
log_error("Failed to load texture (\"%s\").", path_to_load); log_error("Failed to load texture (\"%s\").", path);
return NULL; return NULL;
} }
SDL_GPUTexture *result = create_shader_texture(path, (char *)data, width, height, channels); SDL_GPUTexture *result = create_shader_texture(path, (char *)data, width, height, channels);
if (!result) { if (!result) {
log_error("Failed to load texture (\"%s\").", path_to_load); log_error("Failed to load texture (\"%s\").", path);
stbi_image_free(data); stbi_image_free(data);
return NULL; return NULL;
} }
@ -1208,13 +1199,10 @@ bool recreate_tile_textures() {
} }
for (Uint32 i = 0; i < SDL_arraysize(tile_infos); i++) { for (Uint32 i = 0; i < SDL_arraysize(tile_infos); i++) {
char path[256] = ASSETS_PATH;
SDL_strlcat(path, tile_infos[i].asset_path, SDL_arraysize(path));
int width = 0, height = 0; int width = 0, height = 0;
stbi_uc *data = stbi_load(path, &width, &height, NULL, 4); stbi_uc *data = stbi_load(tile_infos[i].asset_path, &width, &height, NULL, 4);
if (!data) { if (!data) {
log_error("Failed to load texture (\"%s\"). Exiting.", path); log_error("Failed to load texture (\"%s\"). Exiting.", tile_infos[i].asset_path);
SDL_ReleaseGPUTexture(device, tile_textures_array); SDL_ReleaseGPUTexture(device, tile_textures_array);
SDL_CancelGPUCommandBuffer(command_buffer); SDL_CancelGPUCommandBuffer(command_buffer);
return false; return false;
@ -1321,12 +1309,12 @@ int main(int argc, char **argv) {
return 1; return 1;
} }
if (!load_map("map.sv", &current_map)) { if (!load_map("../assets/map/map.sv", &current_map)) {
log_error("Failed to load initial map. Exiting."); log_error("Failed to load initial map. Exiting.");
return 1; return 1;
} }
SDL_GPUTexture *player_texture = create_shader_texture("decorations/strawberry.png"); SDL_GPUTexture *player_texture = create_shader_texture("../assets/decorations/strawberry.png");
if (!player_texture) { if (!player_texture) {
log_error("Failed to create shader texture. Exiting."); log_error("Failed to create shader texture. Exiting.");
return 1; return 1;
@ -1706,7 +1694,7 @@ int main(int argc, char **argv) {
} }
if (event.key.key == SDLK_F4) { if (event.key.key == SDLK_F4) {
char *map_path = SDL_strdup(current_map.name); char *map_path = SDL_strdup(current_map.save_path);
unload_map(&current_map); unload_map(&current_map);
load_map(map_path, &current_map); load_map(map_path, &current_map);
SDL_free(map_path); SDL_free(map_path);