this repo has no description

Compare changes

Choose any two refs to compare.

+314 -764
+1
.clang-format
···
··· 1 +
+7 -2
.clangd
··· 1 - CompileFlags: 2 Add: 3 - - -I../vendor/cglm-0.9.6/include 4
··· 1 + # Source - https://stackoverflow.com/a/69269142 2 + # Posted by Aincvy, modified by community. See post 'Timeline' for change history 3 + # Retrieved 2026-01-01, License - CC BY-SA 4.0 4 + 5 + CompileFlags: # Tweak the parse settings, example directory given to show format 6 Add: 7 + - "-Ivendor/cimgui-1.92.5" 8 + - "-Ivendor/cimgui-1.92.5/imgui/backends" 9
-1
.gitignore
··· 2 bin/ 3 tmp/ 4 vendor/ 5 - env
··· 2 bin/ 3 tmp/ 4 vendor/
+5 -5
Makefile
··· 2 3 SRC_DIR = src 4 BUILD_DIR ?= tmp/build 5 - REGION ?= 14 6 7 SRCS := $(wildcard $(SRC_DIR)/*.c) 8 OBJS := $(SRCS:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o) 9 - 10 CC = gcc 11 - CFLAGS = -g -Ivendor -Ivendor/cglm-0.9.6/include 12 U9 = ./bin/u9map 13 14 all: $(BUILD_DIR) $(U9) shaders ··· 17 mkdir -p $@ 18 19 $(U9): $(OBJS) 20 - $(CC) $(OBJS) -o $(U9) $(DEFS) -lglfw -lvulkan -lm 21 22 $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c $(wildcard $(SRC_DIR)/*.h) 23 $(CC) $(CFLAGS) -c $< -o $@ ··· 28 glslc $< -o $@ 29 30 run: $(U9) shaders 31 - $(U9) $(REGION) 32 33
··· 2 3 SRC_DIR = src 4 BUILD_DIR ?= tmp/build 5 + MODEL ?= tmp/terrain.14 tmp/fixed.14 6 7 SRCS := $(wildcard $(SRC_DIR)/*.c) 8 OBJS := $(SRCS:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o) 9 CC = gcc 10 + CFLAGS = -g -I vendor/* -I vendor/cimgui-1.92.5/imgui 11 + DEFS = vendor/cimgui-1.92.5/cimgui_impl.o vendor/cimgui-1.92.5/cimgui.so 12 U9 = ./bin/u9map 13 14 all: $(BUILD_DIR) $(U9) shaders ··· 17 mkdir -p $@ 18 19 $(U9): $(OBJS) 20 + $(CC) $(OBJS) -o $(U9) $(DEFS) -lglfw -lvulkan -lm 21 22 $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c $(wildcard $(SRC_DIR)/*.h) 23 $(CC) $(CFLAGS) -c $< -o $@ ··· 28 glslc $< -o $@ 29 30 run: $(U9) shaders 31 + $(U9) $(MODEL) 32 33
+1
compile_flags.txt
···
··· 1 + -I vendor/*
+1 -5
notes.txt
··· 1 - [30 Jan 2026] 2 - Intel Corporation Raptor Lake-P [Iris Xe Graphics] (rev 04) [Jan 2021 release] 3 - execution units: 80 shading units: 640 128bit bus (LPDDR4X) 4 - 5 [29 Dec 2025] 6 T = down+right (no swap no mirror) 7 TR2U1 = up+right -> swap -> down+right (swap on x axis) ··· 72 Intel UHD 620 73 "Due to its lack of dedicated graphics memory or eDRAM cache, the HD 620 has to access the main memory" [8GB] 74 "Intel UHD 620 supports Shader Model 5.1 and DirectX 12" 75 - Execution units: 24 Shader count: 192 76
··· 1 [29 Dec 2025] 2 T = down+right (no swap no mirror) 3 TR2U1 = up+right -> swap -> down+right (swap on x axis) ··· 68 Intel UHD 620 69 "Due to its lack of dedicated graphics memory or eDRAM cache, the HD 620 has to access the main memory" [8GB] 70 "Intel UHD 620 supports Shader Model 5.1 and DirectX 12" 71 + "Shader count: It features 192 shaders (or execution units)." 72
+1 -3
shaders/triangle.frag.glsl
··· 35 36 37 outColor = texture(sampler2D(textures[texIdx], samp), flipped); 38 - // temp set color from vertex list 39 - outColor = vec4(fragColor,1.0); 40 41 - // if(unknown) { 42 // outColor.r = 0; 43 // outColor.b = 0; 44 // }
··· 35 36 37 outColor = texture(sampler2D(textures[texIdx], samp), flipped); 38 39 + // if(mirror) { 40 // outColor.r = 0; 41 // outColor.b = 0; 42 // }
-1
src/glfw.c
··· 17 glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); 18 GLFWwindow *window = glfwCreateWindow(window_size.width, window_size.height, 19 appInfo.pApplicationName, NULL, NULL); 20 - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); 21 glfwSetCursorPosCallback(window, mouse_cursor_position_callback); 22 glfwSetMouseButtonCallback(window, mouse_button_callback); 23 glfwSetKeyCallback(window, keyboard_callback);
··· 17 glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); 18 GLFWwindow *window = glfwCreateWindow(window_size.width, window_size.height, 19 appInfo.pApplicationName, NULL, NULL); 20 glfwSetCursorPosCallback(window, mouse_cursor_position_callback); 21 glfwSetMouseButtonCallback(window, mouse_button_callback); 22 glfwSetKeyCallback(window, keyboard_callback);
+4 -21
src/input.c
··· 43 } 44 45 void mouse_decay() { 46 - INPUT.x_dir = 0; // *= 0.5; 47 - INPUT.y_dir = 0; // *= 0.5; 48 } 49 50 void mouse_push_state(float xpos, float ypos) { ··· 52 cursor->mouse_x = xpos; 53 cursor->mouse_y = ypos; 54 55 - if (INPUT.cursor_history_used_idx < INPUT.cursor_history_idx) { 56 - INPUT.cursor_history_used_idx = INPUT.cursor_history_idx; 57 - } 58 - 59 int idx_last = (INPUT.cursor_history_idx + (MOUSE_CURSOR_HISTORY_SIZE - 1)) % 60 MOUSE_CURSOR_HISTORY_SIZE; 61 struct MouseState *cursor_last = &INPUT.cursor_history[idx_last]; 62 - if (INPUT.cursor_history_used_idx < MOUSE_CURSOR_HISTORY_SIZE - 1) { 63 - cursor_last->mouse_x = cursor->mouse_x; 64 - cursor_last->mouse_y = cursor->mouse_y; 65 - } 66 - // printf("input: #%d %f,%f last: #%d %f,%f\n", INPUT.cursor_history_used_idx, 67 - // cursor->mouse_x, cursor->mouse_y, idx_last, cursor_last->mouse_x, 68 - // cursor_last->mouse_y); 69 - if (INPUT.cursor_history_used_idx < MOUSE_CURSOR_HISTORY_SIZE - 1) { 70 - printf("mouse ignore history %d\n", INPUT.cursor_history_used_idx); 71 - INPUT.x_dir = 0; 72 - INPUT.y_dir = 0; 73 - } else { 74 - INPUT.x_dir = cursor->mouse_x - cursor_last->mouse_x; 75 - INPUT.y_dir = cursor->mouse_y - cursor_last->mouse_y; 76 - } 77 78 INPUT.cursor_history_idx = 79 (INPUT.cursor_history_idx + 1) % MOUSE_CURSOR_HISTORY_SIZE;
··· 43 } 44 45 void mouse_decay() { 46 + INPUT.x_dir *= 0.5; 47 + INPUT.y_dir *= 0.5; 48 } 49 50 void mouse_push_state(float xpos, float ypos) { ··· 52 cursor->mouse_x = xpos; 53 cursor->mouse_y = ypos; 54 55 int idx_last = (INPUT.cursor_history_idx + (MOUSE_CURSOR_HISTORY_SIZE - 1)) % 56 MOUSE_CURSOR_HISTORY_SIZE; 57 struct MouseState *cursor_last = &INPUT.cursor_history[idx_last]; 58 + INPUT.x_dir = cursor->mouse_x - cursor_last->mouse_x; 59 + INPUT.y_dir = cursor->mouse_y - cursor_last->mouse_y; 60 61 INPUT.cursor_history_idx = 62 (INPUT.cursor_history_idx + 1) % MOUSE_CURSOR_HISTORY_SIZE;
+1 -2
src/input.h
··· 1 #include <stdbool.h> 2 #include "glfw.h" 3 4 - #define MOUSE_CURSOR_HISTORY_SIZE 3 5 6 struct MouseState { 7 double mouse_x; ··· 10 11 struct Input { 12 struct MouseState cursor_history[MOUSE_CURSOR_HISTORY_SIZE]; 13 - int cursor_history_used_idx; 14 int cursor_history_idx; 15 double x; 16 double y;
··· 1 #include <stdbool.h> 2 #include "glfw.h" 3 4 + #define MOUSE_CURSOR_HISTORY_SIZE 2 5 6 struct MouseState { 7 double mouse_x; ··· 10 11 struct Input { 12 struct MouseState cursor_history[MOUSE_CURSOR_HISTORY_SIZE]; 13 int cursor_history_idx; 14 double x; 15 double y;
+12 -65
src/main.c
··· 1 - #define GLFW_INCLUDE_VULKAN 2 - #include <GLFW/glfw3.h> 3 - #include <stdio.h> 4 - #include <stdlib.h> 5 - #include <string.h> // memcpy 6 - #include <sys/time.h> 7 - #include <vulkan/vulkan.h> 8 - #include <vulkan/vulkan_core.h> 9 - 10 #include "glfw.h" 11 #include "input.h" 12 #include "player.h" ··· 14 #include "u9.h" 15 #include "util.h" 16 17 - struct Input INPUT = {}; 18 bool quit = false; 19 20 int main(int argc, char *argv[]) { 21 - arg_check(argc, argv); 22 glfwInit(); // GLFW first 23 24 Player player = {}; ··· 28 // Vulkan setup 29 VkApplicationInfo appInfo = {}; 30 VkInstance instance = {}; 31 - VkResult result = init_vk(&appInfo, &instance); 32 - if (result != VK_SUCCESS) { 33 - printf("vkCreateInstance error: %d\n", result); 34 } 35 printf("%s vulkan:%d glfw:%s \n", appInfo.pApplicationName, VK_HEADER_VERSION, 36 glfwGetVersionString()); 37 38 VkSurfaceKHR surface; 39 - VkExtent2D window_size = {1200, 800}; 40 GLFWwindow *window = init_glfw(instance, window_size, appInfo, &surface); 41 42 VkPhysicalDevice video_card; 43 VkDevice device; ··· 84 createUniformBuffers(video_card, device, uniformBuffers, uniformBuffersMemory, 85 uniformBuffersMapped); 86 87 - // items 88 - struct itemtype *itemtypes; 89 - u9_itemtypes(path_merge("static/TYPES.DAT", ""), &itemtypes); 90 - void *itemnames_map; 91 - u9_itemnames(path_merge("static/TYPENAME.FLX", ""), &itemnames_map); 92 - // for (int idx = 0; idx < 8192; idx++) { 93 - // struct itemtype item = itemtypes[idx]; 94 - // if (item.sappear_id > 0) { 95 - // struct itemname *itemname = u9_itemname(itemnames_map, idx); 96 - // printf("%d %s sappear #%d\n", idx, itemname->name, item.sappear_id); 97 - // } 98 - // } 99 - 100 // load the u9 map file from disk 101 struct map map; 102 - u9_map(path_merge("static/terrain.", argv[1]), &map); 103 104 struct texture_img *tex_imgs; 105 struct texmap_node *tex_map; 106 texmap_count_t texmap_count; 107 - u9_texture_images(path_merge("static/bitmap16.flx", ""), &map, &tex_imgs, 108 - &tex_map, &texmap_count); 109 VkImage *textureImages = malloc(sizeof(VkImage) * texmap_count); 110 VkDeviceMemory *textureImageMemorys = 111 malloc(sizeof(VkDeviceMemory) * texmap_count); ··· 122 VkSampler textureSampler; 123 createTextureSampler(device, &textureSampler); 124 125 - // load the height map into CPU ram as an array of Vertices and Indexes 126 struct Vertex *vertices; 127 uint32_t vertices_count; 128 uint32_t *indices; ··· 131 &indices, &indices_count); 132 133 struct fixed fixed; 134 - // u9_fixed(path_merge("static/fixed.", argv[1]), itemnames_map, &fixed); 135 - 136 - void *sappear_map; 137 - u9_sappear(path_merge("static/sappear.flx", ""), &sappear_map); 138 - 139 - struct sappear gamemodel; // unnamed 140 - for (int idx = 0; idx < 10; idx++) { 141 - // u9_sappear_obj(sappear_map, idx, &gamemodel); 142 - } 143 - // u9_sappear_obj(sappear_map, 871, &gamemodel, &vertices, &vertices_count, 144 - // &indices, &indices_count); 145 - // Item #871 Iron key Sappear #365 // 1 submesh 146 - // Item #4707 Stop Sign Sappear #3070 // 1 submesh 147 - // Item #802 Mug Sappear #295 // 1 submesh 148 - // Item #803 Fork Sappear #297 // 1 submesh 149 - // Lord British sppear #1805 // 28 submeshes 150 - // Wolf #2534 // 33 submeshes 151 - // Swan #3634 // 16 submeshes #11-body #12-tail 152 - // Small Spider #2649 // 37 submeshes, 0 rotations 153 - // #2-head&fangs #3-torso #4-leg1_upper 154 - // Gazer #1200 // 27 submeshes 155 - // Dog #3446 // 43 submeshes 156 - uint32_t sappear_id = 3634; 157 - u9_sappear_obj(sappear_map, sappear_id, &gamemodel, 0, 0, &vertices, 158 - &vertices_count, &indices, &indices_count); 159 160 // copy the height map into GPU ram 161 VkBuffer vertexBuffer; ··· 170 VkDescriptorSetLayout descriptorSetLayout; 171 createDescriptorSetLayout(device, texmap_count, &descriptorSetLayout); 172 173 - // Pipeline 174 VkRenderPass renderPass; 175 VkPipelineLayout pipelineLayout; 176 VkPipeline graphicsPipeline; ··· 186 VkDescriptorPool descriptorPool; 187 createDescriptorPool(device, &descriptorPool, texmap_count); 188 VkDescriptorSetLayout descriptorSetLayouts[MAX_FRAMES_IN_FLIGHT] = { 189 - descriptorSetLayout, descriptorSetLayout, descriptorSetLayout}; 190 VkDescriptorSet descriptorSets[MAX_FRAMES_IN_FLIGHT]; 191 createDescriptorSets(device, descriptorSetLayouts, descriptorPool, 192 textureImageViews, texmap_count, textureSampler, ··· 213 214 float t_diff_sec = stopwatch_elapsed_sec(&stopwatch); 215 if (t_diff_sec > 0.2) { 216 - printf("%0.3fsec %0.1ffps\r", t_diff_sec / (float)stopwatch.frames, 217 - stopwatch.frames / t_diff_sec); 218 fflush(stdout); 219 stopwatch_init(&stopwatch); 220 } ··· 226 UINT64_MAX); 227 vkFreeCommandBuffers(device, commandPool, MAX_FRAMES_IN_FLIGHT, 228 commandBuffers); 229 - vkDestroyImage(device, depthImage, NULL); 230 - vkDestroyImageView(device, depthImageView, NULL); 231 - vkFreeMemory(device, depthImageMemory, NULL); 232 - 233 vkDestroyBuffer(device, indexBuffer, NULL); 234 vkFreeMemory(device, indexBufferMemory, NULL); 235 vkDestroyBuffer(device, vertexBuffer, NULL);
··· 1 #include "glfw.h" 2 #include "input.h" 3 #include "player.h" ··· 5 #include "u9.h" 6 #include "util.h" 7 8 + struct Input INPUT; 9 bool quit = false; 10 11 int main(int argc, char *argv[]) { 12 glfwInit(); // GLFW first 13 14 Player player = {}; ··· 18 // Vulkan setup 19 VkApplicationInfo appInfo = {}; 20 VkInstance instance = {}; 21 + if (init_vk(&appInfo, &instance) != VK_SUCCESS) { 22 + printf("vkCreateInstance error"); 23 } 24 printf("%s vulkan:%d glfw:%s \n", appInfo.pApplicationName, VK_HEADER_VERSION, 25 glfwGetVersionString()); 26 27 VkSurfaceKHR surface; 28 + VkExtent2D window_size = {1024, 768}; 29 GLFWwindow *window = init_glfw(instance, window_size, appInfo, &surface); 30 + igCreateContext(NULL); 31 + ImGui_ImplGlfw_InitForVulkan(window, true); 32 33 VkPhysicalDevice video_card; 34 VkDevice device; ··· 75 createUniformBuffers(video_card, device, uniformBuffers, uniformBuffersMemory, 76 uniformBuffersMapped); 77 78 // load the u9 map file from disk 79 struct map map; 80 + u9_map(argv[1], &map); 81 82 struct texture_img *tex_imgs; 83 struct texmap_node *tex_map; 84 texmap_count_t texmap_count; 85 + u9_texture_images(&map, &tex_imgs, &tex_map, &texmap_count); 86 VkImage *textureImages = malloc(sizeof(VkImage) * texmap_count); 87 VkDeviceMemory *textureImageMemorys = 88 malloc(sizeof(VkDeviceMemory) * texmap_count); ··· 99 VkSampler textureSampler; 100 createTextureSampler(device, &textureSampler); 101 102 + // load the height map into CPU ram 103 struct Vertex *vertices; 104 uint32_t vertices_count; 105 uint32_t *indices; ··· 108 &indices, &indices_count); 109 110 struct fixed fixed; 111 + // u9_fixed(argv[2], &fixed); 112 113 // copy the height map into GPU ram 114 VkBuffer vertexBuffer; ··· 123 VkDescriptorSetLayout descriptorSetLayout; 124 createDescriptorSetLayout(device, texmap_count, &descriptorSetLayout); 125 126 VkRenderPass renderPass; 127 VkPipelineLayout pipelineLayout; 128 VkPipeline graphicsPipeline; ··· 138 VkDescriptorPool descriptorPool; 139 createDescriptorPool(device, &descriptorPool, texmap_count); 140 VkDescriptorSetLayout descriptorSetLayouts[MAX_FRAMES_IN_FLIGHT] = { 141 + descriptorSetLayout, descriptorSetLayout}; 142 VkDescriptorSet descriptorSets[MAX_FRAMES_IN_FLIGHT]; 143 createDescriptorSets(device, descriptorSetLayouts, descriptorPool, 144 textureImageViews, texmap_count, textureSampler, ··· 165 166 float t_diff_sec = stopwatch_elapsed_sec(&stopwatch); 167 if (t_diff_sec > 0.2) { 168 + printf("%0.1fsec %0.1ffps\r", t_diff_sec, stopwatch.frames / t_diff_sec); 169 fflush(stdout); 170 stopwatch_init(&stopwatch); 171 } ··· 177 UINT64_MAX); 178 vkFreeCommandBuffers(device, commandPool, MAX_FRAMES_IN_FLIGHT, 179 commandBuffers); 180 vkDestroyBuffer(device, indexBuffer, NULL); 181 vkFreeMemory(device, indexBufferMemory, NULL); 182 vkDestroyBuffer(device, vertexBuffer, NULL);
+4 -8
src/player.c
··· 8 } 9 10 void player_setup(Player player) { 11 - vec3 starting_pos = {0.0f, -0.92f, 0.5f}; 12 - player->pos[0] = starting_pos[0]; 13 - player->pos[1] = starting_pos[1]; 14 - player->pos[2] = starting_pos[2]; 15 - 16 - vec3 starting_dir = {0.0f, 240.0f}; 17 - player->dir[0] = starting_dir[0]; 18 - player->dir[1] = starting_dir[1]; 19 }
··· 8 } 9 10 void player_setup(Player player) { 11 + vec3 starting = {0.0f, 0.12f, 0.1f}; 12 + player->pos[0] = starting[0]; 13 + player->pos[1] = starting[1]; 14 + player->pos[2] = starting[2]; 15 }
-1
src/player.h
··· 8 9 struct Player_T { 10 vec3 pos; 11 - vec3 dir; 12 }; 13 U9M_DEFINE_HANDLE(Player) 14
··· 8 9 struct Player_T { 10 vec3 pos; 11 }; 12 U9M_DEFINE_HANDLE(Player) 13
+67 -104
src/spock.c
··· 1 - #include <cglm/cam.h> 2 #include <cglm/mat4.h> 3 - #include <cglm/vec3.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> ··· 46 createInfo.enabledLayerCount = 1; 47 createInfo.ppEnabledLayerNames = validationLayers; 48 49 - VkResult result = vkCreateInstance(&createInfo, NULL, instance); 50 - if (result == VK_ERROR_LAYER_NOT_PRESENT) { 51 - printf("VkCreateInstance: VK_ERRROR_LAYER_NOT_PRESENT (missing vulkan " 52 - "validation layer package?)"); 53 - } 54 - return result; 55 } 56 57 bool setup_vk(const VkInstance instance, const VkSurfaceKHR surface, 58 VkPhysicalDevice *video_card, VkDevice *device, 59 VkQueue *graphicsQueue, VkQueue *presentQueue) { 60 61 - uint32_t device_count = 0; 62 - vkEnumeratePhysicalDevices(instance, &device_count, NULL); 63 - VkPhysicalDevice devices[device_count]; 64 - int video_card_index = pick_card(instance, devices, device_count); 65 *video_card = devices[video_card_index]; 66 67 make_device(*video_card, surface, device); ··· 100 deviceFeatures.shaderSampledImageArrayDynamicIndexing 101 ? "+shaderSampledImageArray" 102 : ""); 103 - printf("device maxVertexInputBindings %d\n", 104 - deviceProperties.limits.maxVertexInputBindings); 105 return (bool)(discrete_gpu || integrated_gpu) && shader; 106 } 107 108 - int pick_card(VkInstance instance, VkPhysicalDevice devices[], 109 - uint32_t device_count) { 110 - vkEnumeratePhysicalDevices(instance, &device_count, devices); 111 112 - int winner_idx = -1; 113 - printf("vulkan device count: %d\n", device_count); 114 - for (int idx = 0; idx < device_count; idx++) { 115 if (device_minimums(devices[idx])) { 116 - winner_idx = idx; 117 } 118 } 119 - if (winner_idx == -1) { 120 - printf("no acceptable video card found"); 121 - exit(1); 122 - } else { 123 - return winner_idx; 124 - } 125 } 126 127 void findQueueFamilies(VkPhysicalDevice video_card, QueueFamilyIndices *indices, ··· 155 int checkDeviceExtensionSupport(VkPhysicalDevice device) { 156 uint32_t extensionCount; 157 vkEnumerateDeviceExtensionProperties(device, NULL, &extensionCount, NULL); 158 - printf("vulkan device extension count %d\n", extensionCount); 159 160 VkExtensionProperties availableExtensions[200]; 161 vkEnumerateDeviceExtensionProperties(device, NULL, &extensionCount, ··· 235 } 236 vkGetPhysicalDeviceSurfaceFormatsKHR(video_card, surface, &formatCount, 237 support_details.formats); 238 239 VkSurfaceFormatKHR surfaceFormat = support_details.formats[0]; 240 VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR; ··· 561 void memory_report(const VkPhysicalDevice video_card) { 562 VkPhysicalDeviceMemoryProperties memProperties; 563 vkGetPhysicalDeviceMemoryProperties(video_card, &memProperties); 564 - // printf("vulkan memory type count %d\n", memProperties.memoryTypeCount); 565 // for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) { 566 // printf("vulkan memory type #%d heap #%d %s %s %s\n", i, 567 // memProperties.memoryTypes[i].heapIndex, ··· 578 // ? "+HostCoherent" 579 // : ""); 580 // } 581 - // printf("vulkan memory heap count %d\n", memProperties.memoryHeapCount); 582 for (uint32_t i = 0; i < memProperties.memoryHeapCount; i++) { 583 printf("vulkan memory heap #%d size: %luMB %s\n", i, 584 memProperties.memoryHeaps[i].size / 1024 / 1024, ··· 999 // VK_SHADER_STAGE_VERTEX_BIT, 1000 // 0, sizeof(uint32_t), &push_int); 1001 1002 - vkCmdDrawIndexed(commandBuffer, indexBufferCount, 1, 0, 0, 0); 1003 vkCmdEndRenderPass(commandBuffer); 1004 result = vkEndCommandBuffer(commandBuffer); 1005 if (result != VK_SUCCESS) { ··· 1032 void updateUniformBuffer(struct UniformBufferObject *ubo, 1033 mat4 model_orientation, VkExtent2D swapChainExtent, 1034 Player player) { 1035 1036 vec3 x_axis = {1.0f, 0.0f, 0.0f}; 1037 vec3 y_axis = {0.0f, 1.0f, 0.0f}; 1038 vec3 z_axis = {0.0f, 0.0f, 1.0f}; 1039 1040 - // Model rotate 1041 if (INPUT.shift_down) { 1042 float angle_x = INPUT.x_dir * glm_rad(2.0f); 1043 float angle_y = INPUT.y_dir * glm_rad(2.0f); 1044 1045 glm_rotate(model_orientation, angle_x, z_axis); 1046 glm_rotate(model_orientation, -1 * angle_y, x_axis); 1047 - printf("model orientation:(%f,%f,%f) rotate (%f,%f)\n", 1048 - *model_orientation[0], *model_orientation[1], *model_orientation[2], 1049 - angle_x, angle_y); 1050 - } else { 1051 - // View update 1052 - input_player_pos_adjust(player, ubo->view); 1053 } 1054 glm_mat4_copy(model_orientation, ubo->model); 1055 1056 // Perspective 1057 float fovy = glm_rad(35.0f); 1058 float aspect = swapChainExtent.width / (float)swapChainExtent.height; ··· 1061 glm_perspective(fovy, aspect, nearZ, farZ, ubo->proj); 1062 ubo->proj[1][1] *= -1; 1063 1064 - mouse_decay(); 1065 } 1066 1067 void setBindingDescription( ··· 1092 attributeDescriptions[3].offset = offsetof(struct Vertex, texIdx); 1093 } 1094 1095 - void pitch_yaw_looks_at(float yaw, float pitch, vec3 at) { 1096 - at[0] = sin(glm_rad(yaw)) * sin(glm_rad(pitch)); 1097 - at[1] = cos(glm_rad(yaw)); 1098 - at[2] = cos(glm_rad(pitch)); 1099 - } 1100 1101 - void input_player_pos_adjust(Player player, mat4 view) { 1102 - float minimum_movement = 0.01; 1103 - 1104 - // Rotate 1105 - vec3 at = {0.0f, 0.0f, 0.0f}; 1106 - player->dir[0] += INPUT.x_dir * 3; 1107 - player->dir[0] = fmod(player->dir[0], 360.0); 1108 - player->dir[1] += INPUT.y_dir * 2; 1109 - player->dir[1] = fmod(player->dir[1], 360.0); 1110 - 1111 - pitch_yaw_looks_at(player->dir[0], player->dir[1], at); 1112 - 1113 - // Translate 1114 if (INPUT.right_mouse_down) { 1115 - if (INPUT.left_mouse_down) { 1116 - glm_vec3_muladds(at, -minimum_movement, player->pos); 1117 } else { 1118 - glm_vec3_muladds(at, minimum_movement, player->pos); 1119 } 1120 } 1121 1122 if (INPUT.go_left) { 1123 - vec3 left_at; 1124 - double left_angle = player->dir[0] - 90; 1125 - left_angle = fmod(left_angle + 360, 360); 1126 - pitch_yaw_looks_at(left_angle, 90, left_at); 1127 - glm_vec3_muladds(left_at, minimum_movement, player->pos); 1128 } 1129 if (INPUT.go_right) { 1130 - vec3 right_at; 1131 - double right_angle = player->dir[0] + 90; 1132 - right_angle = fmod(right_angle + 360, 360); 1133 - pitch_yaw_looks_at(right_angle, 90, right_at); 1134 - glm_vec3_muladds(right_at, minimum_movement, player->pos); 1135 } 1136 if (INPUT.go_up) { 1137 - vec3 bck_at; 1138 - double back_angle = player->dir[0]; 1139 - back_angle = fmod(back_angle + 360, 360); 1140 - pitch_yaw_looks_at(back_angle, 90, bck_at); 1141 - glm_vec3_muladds(bck_at, minimum_movement, player->pos); 1142 } 1143 if (INPUT.go_down) { 1144 - vec3 fwd_at; 1145 - double fwd_angle = player->dir[0] - 180; 1146 - fwd_angle = fmod(fwd_angle + 360, 360); 1147 - pitch_yaw_looks_at(fwd_angle, 90, fwd_at); 1148 - glm_vec3_muladds(fwd_at, minimum_movement, player->pos); 1149 } 1150 if (INPUT.go_page_up) { 1151 - player->pos[2] = player->pos[2] + minimum_movement; 1152 } 1153 if (INPUT.go_page_down) { 1154 - player->pos[2] = player->pos[2] - minimum_movement; 1155 } 1156 - 1157 - // Compute view 1158 - vec3 up = {0.0f, 0.0f, 1.0f}; 1159 - // printf("player dir[%f,%f] pos[%f,%f,%f]\n", player->dir[0], player->dir[1], 1160 - // player->pos[0], player->pos[1], player->pos[2]); 1161 - glm_look(player->pos, at, up, view); 1162 } 1163 1164 void createVertexBuffer(const VkPhysicalDevice video_card, ··· 1176 &stagingBuffer, &stagingBufferMemory); 1177 1178 printf("gpu vertex mem copy %lu (%d items)\n", bufferSize, vertices_count); 1179 - // for (int idx = 0; idx < vertices_count; idx++) { 1180 - // printf("vertex %d [%f,%f,%f]\n", idx, vertices[idx].pos[0], 1181 - // vertices[idx].pos[1], vertices[idx].pos[2]); 1182 - // } 1183 void *gpu_ram; 1184 vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &gpu_ram); 1185 memcpy(gpu_ram, vertices, (size_t)bufferSize); ··· 1212 &stagingBuffer, &stagingBufferMemory); 1213 printf("gpu index mem copy %lu (%d items @ sizeof %lu)\n", bufferSize, 1214 indices_count, sizeof(indices[0])); 1215 - // for (int idx = 0; idx < indices_count; idx++) { 1216 - // printf("index buf #%d %d\n", idx, indices[idx]); 1217 - // } 1218 void *data; 1219 vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &data); 1220 memcpy(data, indices, (size_t)bufferSize); ··· 1357 uint32_t vertexBufferCount, VkBuffer indexBuffer, uint32_t indexBufferCount, 1358 VkDescriptorSet *descriptorSets, Player player, mat4 model_orientation) { 1359 uint32_t fenceCount = 1; 1360 - VkResult result; 1361 - result = vkWaitForFences(device, fenceCount, &inFlightFences[currentFrame], 1362 - VK_TRUE, UINT64_MAX); 1363 - if (result != VK_SUCCESS) { 1364 - // VK_ERROR_DEVICE_LOST -4 1365 - printf("vkWaitForFences fail %d\n", result); 1366 - } 1367 vkResetFences(device, fenceCount, &inFlightFences[currentFrame]); 1368 1369 uint32_t swapchainImageIndex; ··· 1390 submitInfo.pWaitDstStageMask = waitStages; 1391 submitInfo.commandBufferCount = 1; 1392 submitInfo.pCommandBuffers = &commandBuffers[currentFrame]; 1393 - VkSemaphore signalSemaphores[] = { 1394 - renderFinishedSemaphores[swapchainImageIndex]}; 1395 submitInfo.signalSemaphoreCount = 1; 1396 submitInfo.pSignalSemaphores = signalSemaphores; 1397 if (vkQueueSubmit(graphicsQueue, 1, &submitInfo,
··· 1 #include <cglm/mat4.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> ··· 44 createInfo.enabledLayerCount = 1; 45 createInfo.ppEnabledLayerNames = validationLayers; 46 47 + return vkCreateInstance(&createInfo, NULL, instance); 48 } 49 50 bool setup_vk(const VkInstance instance, const VkSurfaceKHR surface, 51 VkPhysicalDevice *video_card, VkDevice *device, 52 VkQueue *graphicsQueue, VkQueue *presentQueue) { 53 54 + VkPhysicalDevice devices[2]; 55 + int video_card_index = pick_card(instance, devices); 56 *video_card = devices[video_card_index]; 57 58 make_device(*video_card, surface, device); ··· 91 deviceFeatures.shaderSampledImageArrayDynamicIndexing 92 ? "+shaderSampledImageArray" 93 : ""); 94 + 95 return (bool)(discrete_gpu || integrated_gpu) && shader; 96 } 97 98 + int pick_card(VkInstance instance, VkPhysicalDevice devices[]) { 99 + uint32_t deviceCount = 0; 100 + vkEnumeratePhysicalDevices(instance, &deviceCount, NULL); 101 + printf("vulkan devices %d\n", deviceCount); 102 103 + vkEnumeratePhysicalDevices(instance, &deviceCount, devices); 104 + 105 + for (int idx = 0; idx < deviceCount; idx++) { 106 if (device_minimums(devices[idx])) { 107 + return idx; 108 } 109 } 110 + printf("no acceptable video card found"); 111 + exit(1); 112 } 113 114 void findQueueFamilies(VkPhysicalDevice video_card, QueueFamilyIndices *indices, ··· 142 int checkDeviceExtensionSupport(VkPhysicalDevice device) { 143 uint32_t extensionCount; 144 vkEnumerateDeviceExtensionProperties(device, NULL, &extensionCount, NULL); 145 + printf("check extension support count %d\n", extensionCount); 146 147 VkExtensionProperties availableExtensions[200]; 148 vkEnumerateDeviceExtensionProperties(device, NULL, &extensionCount, ··· 222 } 223 vkGetPhysicalDeviceSurfaceFormatsKHR(video_card, surface, &formatCount, 224 support_details.formats); 225 + for (int idx = 0; idx < formatCount; idx++) { 226 + printf("surface format %d colorspace %d\n", 227 + support_details.formats[idx].format, 228 + support_details.formats[idx].colorSpace); 229 + } 230 231 VkSurfaceFormatKHR surfaceFormat = support_details.formats[0]; 232 VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR; ··· 553 void memory_report(const VkPhysicalDevice video_card) { 554 VkPhysicalDeviceMemoryProperties memProperties; 555 vkGetPhysicalDeviceMemoryProperties(video_card, &memProperties); 556 + printf("vulkan memory type count %d\n", memProperties.memoryTypeCount); 557 // for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) { 558 // printf("vulkan memory type #%d heap #%d %s %s %s\n", i, 559 // memProperties.memoryTypes[i].heapIndex, ··· 570 // ? "+HostCoherent" 571 // : ""); 572 // } 573 + printf("vulkan memory heap count %d\n", memProperties.memoryHeapCount); 574 for (uint32_t i = 0; i < memProperties.memoryHeapCount; i++) { 575 printf("vulkan memory heap #%d size: %luMB %s\n", i, 576 memProperties.memoryHeaps[i].size / 1024 / 1024, ··· 991 // VK_SHADER_STAGE_VERTEX_BIT, 992 // 0, sizeof(uint32_t), &push_int); 993 994 + int indices_per_tile = 6; 995 + int vertices_per_tile = 4; 996 + int tile_count = indexBufferCount / indices_per_tile; 997 + int limit = tile_count; 998 + if (INPUT.left_mouse_down) { 999 + limit = tile_count / 2; 1000 + } 1001 + for (int idx = 0; idx < limit; idx++) { 1002 + int index_pos = idx * indices_per_tile; 1003 + vkCmdDrawIndexed(commandBuffer, indices_per_tile, 1, index_pos, 0, 0); 1004 + } 1005 vkCmdEndRenderPass(commandBuffer); 1006 result = vkEndCommandBuffer(commandBuffer); 1007 if (result != VK_SUCCESS) { ··· 1034 void updateUniformBuffer(struct UniformBufferObject *ubo, 1035 mat4 model_orientation, VkExtent2D swapChainExtent, 1036 Player player) { 1037 + mouse_decay(); 1038 1039 vec3 x_axis = {1.0f, 0.0f, 0.0f}; 1040 vec3 y_axis = {0.0f, 1.0f, 0.0f}; 1041 vec3 z_axis = {0.0f, 0.0f, 1.0f}; 1042 1043 if (INPUT.shift_down) { 1044 float angle_x = INPUT.x_dir * glm_rad(2.0f); 1045 float angle_y = INPUT.y_dir * glm_rad(2.0f); 1046 1047 + // Model rotate 1048 glm_rotate(model_orientation, angle_x, z_axis); 1049 glm_rotate(model_orientation, -1 * angle_y, x_axis); 1050 + // glm_rotate(model_orientation, angle_y, y_axis); 1051 } 1052 glm_mat4_copy(model_orientation, ubo->model); 1053 1054 + // View 1055 + vec3 up = {0.0f, 0.0f, 1.0f}; 1056 + keyboard_view_adjust(player->pos); 1057 + vec3 front_face = {-0.0f, -1.0f, -1.0f}; 1058 + vec3 center = {0.0f, 0.0f, 0.0f}; 1059 + glm_vec3_add(player->pos, front_face, center); 1060 + glm_lookat(player->pos, center, up, ubo->view); 1061 + 1062 // Perspective 1063 float fovy = glm_rad(35.0f); 1064 float aspect = swapChainExtent.width / (float)swapChainExtent.height; ··· 1067 glm_perspective(fovy, aspect, nearZ, farZ, ubo->proj); 1068 ubo->proj[1][1] *= -1; 1069 1070 + // printf("INPUT mxd:%f myd:%f rmb:%d lmb:%d left:%d right:%d up:%d " 1071 + // "down:%d eye-x:%f eye-y:%f " 1072 + // "eye-z:%f model-x:%f model-y:%f model-z:%f\n", 1073 + // INPUT.x_dir, INPUT.y_dir, INPUT.right_mouse_down, 1074 + // INPUT.left_mouse_down, INPUT.go_left, INPUT.go_right, INPUT.go_up, 1075 + // INPUT.go_down, player->pos[0], player->pos[1], player->pos[2], 1076 + // (*model_orientation)[0], (*model_orientation)[1], 1077 + // (*model_orientation)[2]); 1078 } 1079 1080 void setBindingDescription( ··· 1105 attributeDescriptions[3].offset = offsetof(struct Vertex, texIdx); 1106 } 1107 1108 + void keyboard_view_adjust(vec3 eye) { 1109 + float minimum_movement = 0.007; 1110 1111 + // ZOOM 1112 if (INPUT.right_mouse_down) { 1113 + if (INPUT.shift_down) { 1114 + eye[1] = eye[1] + minimum_movement; 1115 } else { 1116 + eye[1] = eye[1] - minimum_movement; 1117 } 1118 } 1119 1120 if (INPUT.go_left) { 1121 + eye[0] = eye[0] + minimum_movement; 1122 } 1123 if (INPUT.go_right) { 1124 + eye[0] = eye[0] - minimum_movement; 1125 } 1126 if (INPUT.go_up) { 1127 + eye[1] = eye[1] - minimum_movement; 1128 } 1129 if (INPUT.go_down) { 1130 + eye[1] = eye[1] + minimum_movement; 1131 } 1132 if (INPUT.go_page_up) { 1133 + eye[2] = eye[2] + minimum_movement; 1134 } 1135 if (INPUT.go_page_down) { 1136 + eye[2] = eye[2] - minimum_movement; 1137 } 1138 } 1139 1140 void createVertexBuffer(const VkPhysicalDevice video_card, ··· 1152 &stagingBuffer, &stagingBufferMemory); 1153 1154 printf("gpu vertex mem copy %lu (%d items)\n", bufferSize, vertices_count); 1155 void *gpu_ram; 1156 vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &gpu_ram); 1157 memcpy(gpu_ram, vertices, (size_t)bufferSize); ··· 1184 &stagingBuffer, &stagingBufferMemory); 1185 printf("gpu index mem copy %lu (%d items @ sizeof %lu)\n", bufferSize, 1186 indices_count, sizeof(indices[0])); 1187 void *data; 1188 vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &data); 1189 memcpy(data, indices, (size_t)bufferSize); ··· 1326 uint32_t vertexBufferCount, VkBuffer indexBuffer, uint32_t indexBufferCount, 1327 VkDescriptorSet *descriptorSets, Player player, mat4 model_orientation) { 1328 uint32_t fenceCount = 1; 1329 + vkWaitForFences(device, fenceCount, &inFlightFences[currentFrame], VK_TRUE, 1330 + UINT64_MAX); 1331 vkResetFences(device, fenceCount, &inFlightFences[currentFrame]); 1332 1333 uint32_t swapchainImageIndex; ··· 1354 submitInfo.pWaitDstStageMask = waitStages; 1355 submitInfo.commandBufferCount = 1; 1356 submitInfo.pCommandBuffers = &commandBuffers[currentFrame]; 1357 + VkSemaphore signalSemaphores[] = {renderFinishedSemaphores[currentFrame]}; 1358 submitInfo.signalSemaphoreCount = 1; 1359 submitInfo.pSignalSemaphores = signalSemaphores; 1360 if (vkQueueSubmit(graphicsQueue, 1, &submitInfo,
+8 -5
src/spock.h
··· 3 #define GLM_FORCE_RADIANS 4 #define GLM_FORCE_DEPTH_ZERO_TO_ONE 5 #include <cglm/cglm.h> 6 7 #ifndef _spock_h_ 8 #define _spock_h_ 9 10 #include "player.h" 11 12 - #define MAX_FRAMES_IN_FLIGHT 3 13 14 typedef struct QueueFamilyIndices { 15 uint32_t graphicsFamily; ··· 47 VkQueue *graphicsQueue, VkQueue *presentQueue); 48 49 bool device_minimums(VkPhysicalDevice device); 50 - int pick_card(VkInstance instance, VkPhysicalDevice devices[], 51 - uint32_t device_count); 52 53 void findQueueFamilies(VkPhysicalDevice video_card, QueueFamilyIndices *indices, 54 VkSurfaceKHR surface); ··· 171 const VkSampler textureSampler, 172 const VkBuffer *uniformBuffers, 173 VkDescriptorSet *descriptorSets); 174 - void input_player_pos_adjust(Player player, mat4 view); 175 - void pitch_yaw_looks_at(float yaw, float pitch, vec3 at); 176 177 #endif
··· 3 #define GLM_FORCE_RADIANS 4 #define GLM_FORCE_DEPTH_ZERO_TO_ONE 5 #include <cglm/cglm.h> 6 + #define CIMGUI_DEFINE_ENUMS_AND_STRUCTS 7 + #include <cimgui.h> 8 + #define CIMGUI_USE_GLFW 9 + #include <cimgui_impl.h> 10 + 11 12 #ifndef _spock_h_ 13 #define _spock_h_ 14 15 #include "player.h" 16 17 + #define MAX_FRAMES_IN_FLIGHT 2 18 19 typedef struct QueueFamilyIndices { 20 uint32_t graphicsFamily; ··· 52 VkQueue *graphicsQueue, VkQueue *presentQueue); 53 54 bool device_minimums(VkPhysicalDevice device); 55 + int pick_card(VkInstance instance, VkPhysicalDevice devices[]); 56 57 void findQueueFamilies(VkPhysicalDevice video_card, QueueFamilyIndices *indices, 58 VkSurfaceKHR surface); ··· 175 const VkSampler textureSampler, 176 const VkBuffer *uniformBuffers, 177 VkDescriptorSet *descriptorSets); 178 + void keyboard_view_adjust(vec3 eye); 179 180 #endif
+172 -343
src/u9.c
··· 1 #include <errno.h> 2 - #include <fcntl.h> 3 #include <stdbool.h> 4 5 #include "texmap.h" 6 #include "u9.h" 7 #include "util.h" 8 9 - void u9_sappear(char filename[], void **sappear_map) { 10 - long file_size = mmap_file(filename, sappear_map); 11 - struct flx_header *header = *sappear_map; 12 - printf("sappear: %s size %ld %d flx items\n", filename, file_size, 13 - header->dir_entry_count); 14 - } 15 - 16 - struct sappear_submesh *submesh_lookup(struct sappear *s, uint32_t submesh_id) { 17 - int submesh_count = s->header->submesh_count; 18 - int lod_count = s->header->lod_count; 19 - for (int sm_idx = 0; sm_idx < submesh_count; sm_idx++) { 20 - uint32_t sm_map_offset = sm_idx * (lod_count + 1); 21 - uint32_t sm_offset = s->submesh_offsets[sm_map_offset]; 22 - struct sappear_submesh *ptr = (void *)s->header + sm_offset; 23 - if (ptr->limb_id == submesh_id) { 24 - return ptr; 25 - } 26 - } 27 - return NULL; 28 - } 29 - 30 - void submesh_add_offsets(vec4 *p4, struct sappear *s, uint32_t submesh_id) { 31 - struct sappear_submesh *submesh = submesh_lookup(s, submesh_id); 32 - if (submesh == NULL) { 33 - printf("submesh lookup error %d not found\n", submesh_id); 34 - exit(1); 35 - } 36 - (*p4)[0] += submesh->position[0]; 37 - (*p4)[1] += submesh->position[1]; 38 - (*p4)[2] += submesh->position[2]; 39 - 40 - if (submesh->parent_id) { 41 - submesh_add_offsets(p4, s, submesh->parent_id); 42 - } 43 - } 44 - 45 - #define THREE_SIDES 3 46 - void u9_sappear_obj(void *sappear_map, int flx_id, struct sappear *s, 47 - uint16_t lod, uint16_t face, struct Vertex **vertices, 48 - uint32_t *vertices_count, uint32_t **indices, 49 - uint32_t *indices_count) { 50 - *indices_count = 0; 51 - *indices = NULL; 52 - *vertices_count = 0; 53 - *vertices = NULL; 54 - struct flx_dir_ent *dir_ent = sappear_map + sizeof(struct flx_header); 55 - uint32_t flx_offset = dir_ent[flx_id].offset; 56 - uint32_t flx_length = dir_ent[flx_id].length; 57 - printf("sappear.flx #%d flx_offset:%d flx_length:%d \n", flx_id, flx_offset, 58 - flx_length); 59 - if (flx_offset > 0) { 60 - s->header = sappear_map + flx_offset; 61 - printf("sappear #%d submesh_count:%d lod_count:%d " 62 - "sphere_radius:%f\n", 63 - flx_id, s->header->submesh_count, s->header->lod_count, 64 - s->header->sphere_radius); 65 - s->submesh_offsets = (void *)s->header + sizeof(struct sappear_header); 66 - int submesh_count = s->header->submesh_count; 67 - int lod_count = s->header->lod_count; 68 - for (int sm_idx = 0; sm_idx < submesh_count; sm_idx++) { 69 - uint32_t sm_map_offset = sm_idx * (lod_count + 1); 70 - uint32_t sm_offset = s->submesh_offsets[sm_map_offset]; 71 - struct sappear_submesh *submesh = (void *)s->header + sm_offset; 72 - printf("sappear #%d.%d limb_id:%u parent_id:%u pos:(%f,%f,%f) " 73 - "scale:[%f,%f,%f] rot:(%f,%f,%f)\n", 74 - flx_id, sm_idx, submesh->limb_id, submesh->parent_id, 75 - submesh->position[0], submesh->position[1], submesh->position[2], 76 - submesh->scale_x, submesh->scale_y, submesh->scale_z, 77 - submesh->rot_x, submesh->rot_y, submesh->rot_z); 78 - uint32_t lod_idx = lod; 79 - uint32_t lod_map_offset = sm_idx * (lod_count + 1) + (lod_idx + 1); 80 - uint32_t lod_offset = s->submesh_offsets[lod_map_offset]; 81 - struct sappear_lod *lod = (void *)s->header + lod_offset; 82 - printf("sappear #%d.%d.%d size: %d center:(%f,%f,%f) radius: %f faces: " 83 - "%d vertices: %d face_offset:%d\n", 84 - flx_id, sm_idx, lod_idx, lod->mesh_size, lod->sphere_center[0], 85 - lod->sphere_center[1], lod->sphere_center[2], lod->spehere_radius, 86 - lod->face_count, lod->vertex_count, lod->face_offset); 87 - if (lod->mesh_size > 0) { 88 - uint32_t old_indices_count = *indices_count; 89 - *indices_count += THREE_SIDES * lod->face_count; 90 - *indices = realloc(*indices, sizeof(uint32_t) * *indices_count); 91 - for (int face_idx = 0; face_idx < lod->face_count; face_idx++) { 92 - // int face_idx = face; 93 - uint32_t offset = 94 - lod->face_offset + 4 + (face_idx * sizeof(struct sappear_face)); 95 - struct sappear_face *face = (void *)lod + offset; 96 - // input topology is TRIANGLE_LIST (3 points per triangle) 97 - uint32_t index_idx = face_idx * THREE_SIDES; 98 - (*indices)[old_indices_count + index_idx + 0] = 99 - (*vertices_count) + face->points[0].index; 100 - (*indices)[old_indices_count + index_idx + 1] = 101 - (*vertices_count) + face->points[1].index; 102 - (*indices)[old_indices_count + index_idx + 2] = 103 - (*vertices_count) + face->points[2].index; 104 - } 105 - uint32_t old_vertices_count = *vertices_count; 106 - *vertices_count += lod->vertex_count; 107 - *vertices = realloc(*vertices, sizeof(struct Vertex) * *vertices_count); 108 - 109 - vec4 offsets = {0.0, 0.0, 0.0, 0.0}; 110 - submesh_add_offsets(&offsets, s, submesh->limb_id); 111 - 112 - mat4 transform = GLM_MAT4_IDENTITY_INIT; 113 - vec3 x_axis = {1.0f, 0.0f, 0.0f}; 114 - vec3 y_axis = {0.0f, 1.0f, 0.0f}; 115 - vec3 z_axis = {0.0f, 0.0f, 1.0f}; 116 - vec3 pivot = {lod->sphere_center[0], lod->sphere_center[1], 117 - lod->sphere_center[2]}; 118 - glm_translate(transform, pivot); 119 - 120 - float rot_x = submesh->rot_x * M_PI; 121 - float rot_y = submesh->rot_y * M_PI; 122 - float rot_z = submesh->rot_z * M_PI; 123 - glm_rotate(transform, rot_x, x_axis); 124 - glm_rotate(transform, rot_y, y_axis); 125 - glm_rotate(transform, rot_z, z_axis); 126 - 127 - vec3 neg_pivot = {-pivot[0], -pivot[1], -pivot[2]}; 128 - glm_translate(transform, neg_pivot); 129 - 130 - for (int vertex_idx = 0; vertex_idx < lod->vertex_count; vertex_idx++) { 131 - uint32_t offset = lod->vertex_offset + 4 + 132 - (sizeof(struct sappear_point) * vertex_idx); 133 - struct sappear_point *point = (void *)lod + offset; 134 - 135 - vec4 p4 = {point->x + offsets[0], point->y + offsets[1], 136 - point->z + offsets[2], 1.0f}; 137 - vec4 result; 138 - glm_mat4_mulv(transform, p4, result); 139 - 140 - printf("v #%d/base#%d (%f,%f,%f) (%f,%f,%f)\n", vertex_idx, 141 - old_vertices_count, point->x, point->y, point->z, result[0], 142 - result[1], result[2]); 143 - 144 - float scale = s->header->sphere_radius * 2; 145 - (*vertices)[old_vertices_count + vertex_idx].pos[0] = 146 - result[0] / scale; 147 - (*vertices)[old_vertices_count + vertex_idx].pos[1] = 148 - result[1] / scale; 149 - (*vertices)[old_vertices_count + vertex_idx].pos[2] = 150 - result[2] / scale; 151 - (*vertices)[old_vertices_count + vertex_idx].color[0] = 152 - vertex_idx / 1.0; 153 - (*vertices)[old_vertices_count + vertex_idx].color[1] = 154 - vertex_idx % 2; 155 - (*vertices)[old_vertices_count + vertex_idx].color[2] = 0.0; 156 - } 157 - } 158 - } 159 - } 160 - printf("u9_sappear_obj item #%d vertex:%d index:%d\n", flx_id, 161 - *vertices_count, *indices_count); 162 - } 163 - 164 void u9_palette(char filename[], struct palette *palette) { 165 FILE *fp = fopen(filename, "rb"); 166 fread(palette, sizeof(struct palette), 256, fp); ··· 175 } 176 177 void u9_map(const char filename[], struct map *map) { 178 FILE *fp = fopen(filename, "rb"); 179 load_map(fp, map); 180 fclose(fp); 181 map->filename = filename; 182 } 183 184 - void u9_fixed(const char filename[], void *itemnames_map, struct fixed *fixed) { 185 FILE *fp = fopen(filename, "rb"); 186 load_fixed(fp, fixed); 187 fclose(fp); 188 - printf("%s header.byte_size %d size: %d x %d\n", filename, 189 - fixed->header.byte_size, fixed->header.width, fixed->header.height); 190 int tile_count = fixed->header.width * fixed->header.height; 191 - // for (int idx = 0; idx < tile_count; idx++) { 192 - // printf("tile %d: %x\n", idx, fixed->tiles[idx].unknown); 193 - // } 194 195 int page_count = fixed->header.byte_size / U9_FIXED_PAGE_SIZE; 196 - printf("header.byte_size %d/%d = %d pages on disk\n", fixed->header.byte_size, 197 - U9_FIXED_PAGE_SIZE, page_count); 198 - 199 for (int idx = 0; idx < page_count; idx++) { 200 - printf("page %d base_x: %d (%x) base_y: %d(%x)\n", idx, 201 - fixed->pages[idx].base_x, fixed->pages[idx].base_x, 202 - fixed->pages[idx].base_y, fixed->pages[idx].base_y); 203 for (int oidx = 0; oidx < page_count; oidx++) { 204 struct fixed_object obj = fixed->pages[idx].objects[oidx]; 205 - struct itemname *itemname = u9_itemname(itemnames_map, obj.type); 206 - printf("pg #%d obj #%d next: %d x:%d y:%d z:%d type: %d %s\n", idx, oidx, 207 - obj.link, obj.x, obj.y, obj.z, obj.type, itemname->name); 208 } 209 } 210 } 211 212 - void u9_itemtypes(const char filename[], struct itemtype **itemtypes) { 213 - FILE *fp = fopen(filename, "rb"); 214 - load_itemtypes(fp, itemtypes); 215 - fclose(fp); 216 - } 217 - 218 - void u9_itemnames(const char filename[], void **itemnames_map) { 219 - long file_size = mmap_file(filename, itemnames_map); 220 - struct flx_header *header = *itemnames_map; 221 - printf("u9_itemnames %s size %ld %d items\n", filename, file_size, 222 - header->dir_entry_count); 223 - } 224 - 225 - struct itemname *u9_itemname(void *itemnames_map, int idx) { 226 - struct flx_header *header = itemnames_map; 227 - struct flx_dir_ent *dir_ent = itemnames_map + sizeof(struct flx_header); 228 - int itemname_offset = dir_ent[idx].offset; 229 - struct itemname *itemname = itemnames_map + itemname_offset; 230 - return itemname; 231 - } 232 - 233 - void load_itemtypes(FILE *fp, struct itemtype **itemtypes) { 234 - fseek(fp, 0, SEEK_END); 235 - int file_size = ftell(fp); 236 - rewind(fp); 237 - int count = (file_size - 8) / sizeof(struct itemtype); 238 - int placeholder = printf( 239 - "itemtypes: reading %d items from filesize %d (struct itemtype size " 240 - "%lu)\n", 241 - count, file_size, sizeof(struct itemtype)); 242 - 243 - *itemtypes = malloc(count * sizeof(struct itemtype)); 244 - 245 - // TYPES.DAT first row looks like a header 246 - // 0000000: 9816 0000 6001 0000 0000 0000 0000 5602 ....`.........V. 247 - // 0000010: 2800 fe9e 0000 0000 0000 0000 0100 0d07 (............... 248 - // 0000020: 2800 ffab 0000 0000 0000 0000 0200 8707 (............... 249 - fseek(fp, 8, SEEK_CUR); // skip 8 bytes 250 - 251 - int read_count = 0; 252 - read_count = fread(*itemtypes, sizeof(struct itemtype), count, fp); 253 - } 254 - 255 void load_fixed(FILE *fp, struct fixed *fixed) { 256 int read_count = 0; 257 int count = 1; 258 - read_count = fread(&fixed->header, sizeof(struct fixed_header), count, fp); 259 260 - // unknown tile info 261 count = fixed->header.width * fixed->header.height; 262 fixed->tiles = malloc(sizeof(struct fixed_tile) * count); 263 read_count = fread(fixed->tiles, sizeof(struct fixed_tile), count, fp); 264 265 - // pages of items 266 fixed->pages = malloc(fixed->header.byte_size); 267 - count = fixed->header.byte_size / U9_FIXED_PAGE_SIZE; 268 - read_count = fread(fixed->pages, U9_FIXED_PAGE_SIZE, count, fp); 269 } 270 271 - #define FOUR_CORNERS 4 272 - #define SIX_SIDES 6 273 void u9_map_to_points(const struct map *map, struct texmap_node *texmap, 274 - texmap_count_t texmap_count, struct Vertex **vertices, 275 - uint32_t *vertices_count, uint32_t **indices, 276 uint32_t *indices_count) { 277 uint32_t map_point_count = map_point_count_compute(map); 278 uint32_t tile_width = map->header.width / CHUNK_WIDTH; 279 uint32_t tile_height = map->header.height / CHUNK_HEIGHT; 280 281 - *vertices_count = map_point_count * FOUR_CORNERS; 282 - *vertices = malloc(sizeof(struct Vertex) * (*vertices_count)); 283 - *indices_count = map_point_count * SIX_SIDES; 284 *indices = malloc(sizeof((*indices)[0]) * (*indices_count)); 285 printf("%s: %s [w%d x h%d] [%d chunks] [%d vertices] [%d indices] [%d " 286 "water_level]\n", 287 map->filename, map->header.name, map->header.width, map->header.height, 288 - map->header.chunk_count, *vertices_count, *indices_count, 289 map->header.water_level); 290 - map_to_vertex_list(map, texmap, texmap_count, *vertices); 291 - build_floor(map, *vertices, *indices); 292 } 293 294 void map_to_tile_point(uint32_t my, uint32_t mx, uint32_t twidth, uint32_t *ty, ··· 299 *px = mx % CHUNK_WIDTH; 300 } 301 302 #define VERTEX_IDX_OFFSET_NW 0 303 #define VERTEX_IDX_OFFSET_NE 1 304 #define VERTEX_IDX_OFFSET_SW 2 305 #define VERTEX_IDX_OFFSET_SE 3 306 307 void map_to_vertex_list(const struct map *map, struct texmap_node *texmap, 308 - texmap_count_t texmap_count, struct Vertex *vertices) { 309 - uint32_t map_height = map->header.height; 310 - uint32_t map_width = map->header.width; 311 uint32_t points_count = 0; 312 uint16_t max_point_height = 0; 313 314 - for (int my = 0; my < map_height - 1; my++) { 315 - for (int mx = 0; mx < map_width - 1; mx++) { 316 - set_box_corners(vertices, map, my, mx, texmap, texmap_count); 317 - points_count++; 318 319 - struct map_point *point = point_lookup(map, my, mx); 320 - uint16_t height = point_height(point); 321 - if (height > max_point_height) { 322 - max_point_height = height; 323 } 324 } 325 } ··· 329 map_point_count, max_point_height); 330 } 331 332 - void set_box_corners(struct Vertex *vertices, const struct map *map, int my, 333 - int mx, struct texmap_node *texmap, 334 - texmap_count_t texmap_count) { 335 - int map_width = map->header.width; 336 - int vertex_idx = my * map_width + mx; 337 - int points_idx = vertex_idx * FOUR_CORNERS; 338 - int points_idx_nw = points_idx + VERTEX_IDX_OFFSET_NW; 339 - int points_idx_ne = points_idx + VERTEX_IDX_OFFSET_NE; 340 - int points_idx_sw = points_idx + VERTEX_IDX_OFFSET_SW; 341 - int points_idx_se = points_idx + VERTEX_IDX_OFFSET_SE; 342 - 343 - vertex_set_map_pos(&vertices[points_idx_nw], map, my, mx); 344 - vertex_set_map_pos(&vertices[points_idx_ne], map, my, mx + 1); 345 - vertex_set_map_pos(&vertices[points_idx_sw], map, my + 1, mx); 346 - vertex_set_map_pos(&vertices[points_idx_se], map, my + 1, mx + 1); 347 - vertex_set_tex_box(map, my, mx, vertices, points_idx, texmap, texmap_count); 348 - } 349 - 350 - void build_floor(const struct map *map, struct Vertex *vertices, 351 - uint32_t *indices) { 352 - // uint32_t map_width_in_tiles = map->header.width / CHUNK_WIDTH; 353 - int map_width = map->header.width; 354 - uint32_t index_idx = 0; 355 - uint32_t box_count = 0; 356 - for (int my = 0; my < map->header.height - 1; my++) { 357 - for (int mx = 0; mx < map->header.width - 1; mx++) { 358 - int vertex_idx = my * map_width + mx; 359 - int points_idx = vertex_idx * FOUR_CORNERS; 360 - add_rect(points_idx, indices, index_idx); 361 - index_idx += SIX_SIDES; 362 - box_count++; 363 - } 364 - } 365 - printf("build_floor made %d boxes with %d indices\n", box_count, index_idx); 366 - } 367 - 368 uint32_t vertex_idx(uint32_t twidth, uint32_t ty, uint32_t tx, uint32_t py, 369 uint32_t px) { 370 int tile_idx = (ty * twidth) + tx; ··· 376 return vertex_idx; 377 } 378 379 - void add_rect(uint32_t vert_idx, uint32_t *indices, uint32_t index_idx) { 380 uint32_t nw = vert_idx + VERTEX_IDX_OFFSET_NW; 381 uint32_t ne = vert_idx + VERTEX_IDX_OFFSET_NE; 382 uint32_t sw = vert_idx + VERTEX_IDX_OFFSET_SW; ··· 390 indices[index_idx + 5] = se; 391 } 392 393 - struct map_point *point_lookup(const struct map *map, uint16_t my, 394 - uint16_t mx) { 395 - uint32_t tx, ty, px, py; 396 - uint32_t map_width_in_tiles = map->header.width / CHUNK_WIDTH; 397 - map_to_tile_point(my, mx, map_width_in_tiles, &ty, &tx, &py, &px); 398 - int tile_idx = ty * map_width_in_tiles + tx; 399 - uint16_t chunk_idx = map->tile_indexes[tile_idx].chunk_index; 400 - struct map_chunk *chunk = &(map->chunks[chunk_idx]); 401 - struct map_point *point = &chunk->points[py][px]; 402 - return point; 403 - } 404 - 405 - uint16_t point_height(struct map_point *point) { 406 - return (point->left & 0b111111111111); 407 } 408 409 #define BITS_10 0b1111111111 410 - uint16_t point_texture_id(struct map_point *point) { 411 - return ((point->right & BITS_10 << 6) >> 6); 412 } 413 414 #define BITS_5 0b11111 415 - uint16_t point_texture_frame(struct map_point *point) { 416 - return point->right & BITS_5; 417 } 418 419 - bool point_texture_swap(struct map_point *point) { 420 - return (point->left >> 13) & 1; 421 } 422 423 - bool point_texture_mirror(struct map_point *point) { 424 - return (point->left >> 14) & 1; 425 } 426 427 - bool point_texture_unknown(struct map_point *point) { 428 - return (point->left >> 15) & 1; 429 } 430 431 - void vertex_set_map_pos(struct Vertex *vertex, const struct map *map, int my, 432 - int mx) { 433 - struct map_point *point = point_lookup(map, my, mx); 434 - float x_scaled = mx / (float)map->header.width; 435 - float y_scaled = my / (float)map->header.height; 436 - float z_scaled = point_height(point) / (float)6000; 437 - vertex->pos[0] = 0.5 - x_scaled; 438 - vertex->pos[1] = 0.5 - y_scaled; 439 - vertex->pos[2] = z_scaled; 440 } 441 442 - void vertex_set_tex_box(const struct map *map, int my, int mx, 443 - struct Vertex *vertices, uint32_t vertices_idx, 444 - struct texmap_node *texmap, 445 - texmap_count_t texmap_count) { 446 - struct map_point *point = point_lookup(map, my, mx); 447 - int tex_id = point_texture_id(point); 448 - int frame = point_texture_frame(point); 449 uint16_t tex_img_idx; 450 texmap_get(texmap, texmap_count, tex_id, frame, &tex_img_idx); 451 452 - struct Vertex *point_nw = &vertices[vertices_idx + VERTEX_IDX_OFFSET_NW]; 453 - struct Vertex *point_ne = &vertices[vertices_idx + VERTEX_IDX_OFFSET_NE]; 454 - struct Vertex *point_sw = &vertices[vertices_idx + VERTEX_IDX_OFFSET_SW]; 455 - struct Vertex *point_se = &vertices[vertices_idx + VERTEX_IDX_OFFSET_SE]; 456 457 - bool tex_swap = point_texture_swap(point); 458 - bool tex_mirror = point_texture_mirror(point); 459 - bool tex_unknown = point_texture_unknown(point); 460 - tex_img_idx |= tex_swap << 13; 461 - tex_img_idx |= tex_mirror << 14; 462 tex_img_idx |= tex_unknown << 15; // unknown 463 464 point_nw->texIdx = tex_img_idx; 465 point_ne->texIdx = tex_img_idx; ··· 495 map->tile_indexes = malloc(sizeof(struct map_tile_index) * tiles_count); 496 read_count = 497 fread(map->tile_indexes, sizeof(struct map_tile_index), tiles_count, fp); 498 499 map->chunks = malloc(sizeof(struct map_chunk) * map->header.chunk_count); 500 read_count = 501 fread(map->chunks, sizeof(struct map_chunk), map->header.chunk_count, fp); 502 } 503 504 void load_textures(FILE *fp, struct textures *textures) { ··· 516 sizeof(struct flx_dir_ent) * read_count); 517 } 518 519 - void u9_texture_images(const char filename[], const struct map *map, 520 - struct texture_img **tex_imgs, 521 struct texmap_node **tex_map, 522 texmap_count_t *texmap_count) { 523 uint32_t map_height_in_tiles = map->header.width / CHUNK_HEIGHT; ··· 528 uint16_t texture_height = 128; 529 unique_textures(map, tex_map, texmap_count); 530 *tex_imgs = malloc(sizeof(struct texture_img) * *texmap_count); 531 532 for (int idx = 0; idx < *texmap_count; idx++) { 533 struct texture_img *tex_img = &(*tex_imgs)[idx]; ··· 539 540 uint16_t point_texture_id = (*tex_map)[idx].tex_id; 541 uint16_t point_texture_frame = (*tex_map)[idx].frame; 542 - load_bitmap(filename, point_texture_id, point_texture_frame, 543 - tex_img->pixels); 544 } 545 } 546 547 void unique_textures(const struct map *map, struct texmap_node **texmap, 548 texmap_count_t *texmap_count) { 549 - uint32_t map_height = map->header.width; 550 - uint32_t map_width = map->header.height; 551 *texmap_count = 0; 552 *texmap = NULL; 553 554 - for (int my = 0; my < map_height; my++) { 555 - for (int mx = 0; mx < map_width; mx++) { 556 - struct map_point *point = point_lookup(map, my, mx); 557 - uint16_t texture_id = point_texture_id(point); 558 - uint16_t texture_frame = point_texture_frame(point); 559 560 - if (texmap_find(*texmap, *texmap_count, texture_id, texture_frame)) { 561 - } else { 562 - texmap_add(texmap, texmap_count, texture_id, texture_frame); 563 } 564 } 565 } 566 } 567 568 - void load_bitmap(const char filename[], uint16_t bitmap_idx, 569 - uint16_t bitmap_idx_plane, struct rgba8888 *pixels) { 570 571 - FILE *fp = fopen(filename, "rb"); 572 if (fp == NULL) { 573 printf("bitmap open null %d\n", errno); 574 exit(1);
··· 1 #include <errno.h> 2 #include <stdbool.h> 3 + #include <string.h> 4 5 #include "texmap.h" 6 #include "u9.h" 7 #include "util.h" 8 9 void u9_palette(char filename[], struct palette *palette) { 10 FILE *fp = fopen(filename, "rb"); 11 fread(palette, sizeof(struct palette), 256, fp); ··· 20 } 21 22 void u9_map(const char filename[], struct map *map) { 23 + printf("loading map %s\n", filename); 24 FILE *fp = fopen(filename, "rb"); 25 load_map(fp, map); 26 fclose(fp); 27 map->filename = filename; 28 } 29 30 + void u9_fixed(const char filename[], struct fixed *fixed) { 31 FILE *fp = fopen(filename, "rb"); 32 load_fixed(fp, fixed); 33 fclose(fp); 34 + printf("%s bytes %d size: %d x %d\n", filename, fixed->header.byte_size, 35 + fixed->header.width, fixed->header.height); 36 int tile_count = fixed->header.width * fixed->header.height; 37 + for (int idx = 0; idx < tile_count; idx++) { 38 + printf("tile %d: %x\n", idx, fixed->tiles[idx].unknown); 39 + } 40 41 int page_count = fixed->header.byte_size / U9_FIXED_PAGE_SIZE; 42 + printf("size/%d = %d pages\n", U9_FIXED_PAGE_SIZE, page_count); 43 for (int idx = 0; idx < page_count; idx++) { 44 + printf("page %d base_x: %d base_y: %d\n", idx, fixed->pages[idx].base_x, 45 + fixed->pages[idx].base_y); 46 for (int oidx = 0; oidx < page_count; oidx++) { 47 struct fixed_object obj = fixed->pages[idx].objects[oidx]; 48 + printf("page %d object %d link: %d x:%d y:%d z:%d\n", idx, oidx, obj.link, 49 + obj.x, obj.y, obj.z); 50 } 51 } 52 } 53 54 void load_fixed(FILE *fp, struct fixed *fixed) { 55 int read_count = 0; 56 int count = 1; 57 + read_count = fread(&fixed->header, sizeof(struct fixed), count, fp); 58 59 count = fixed->header.width * fixed->header.height; 60 fixed->tiles = malloc(sizeof(struct fixed_tile) * count); 61 read_count = fread(fixed->tiles, sizeof(struct fixed_tile), count, fp); 62 63 fixed->pages = malloc(fixed->header.byte_size); 64 + int page_count = fixed->header.byte_size / U9_FIXED_PAGE_SIZE; 65 + read_count = fread(fixed->pages, U9_FIXED_PAGE_SIZE, page_count, fp); 66 } 67 68 void u9_map_to_points(const struct map *map, struct texmap_node *texmap, 69 + texmap_count_t texmap_count, struct Vertex **points, 70 + uint32_t *points_count, uint32_t **indices, 71 uint32_t *indices_count) { 72 uint32_t map_point_count = map_point_count_compute(map); 73 uint32_t tile_width = map->header.width / CHUNK_WIDTH; 74 uint32_t tile_height = map->header.height / CHUNK_HEIGHT; 75 76 + *points_count = map_point_count * 4; 77 + *points = malloc(sizeof(struct Vertex) * (*points_count)); 78 + *indices_count = map_point_count * 6; 79 *indices = malloc(sizeof((*indices)[0]) * (*indices_count)); 80 printf("%s: %s [w%d x h%d] [%d chunks] [%d vertices] [%d indices] [%d " 81 "water_level]\n", 82 map->filename, map->header.name, map->header.width, map->header.height, 83 + map->header.chunk_count, *points_count, *indices_count, 84 map->header.water_level); 85 + map_to_vertex_list(map, texmap, texmap_count, *points); 86 + build_floor(map, *points, *indices); 87 } 88 89 void map_to_tile_point(uint32_t my, uint32_t mx, uint32_t twidth, uint32_t *ty, ··· 94 *px = mx % CHUNK_WIDTH; 95 } 96 97 + void build_floor(const struct map *map, struct Vertex *points, 98 + uint32_t *indices) { 99 + uint32_t tile_width = map->header.width / CHUNK_WIDTH; 100 + uint32_t index_idx = 0; 101 + uint32_t box_count = 0; 102 + for (int my = 0; my < map->header.height - 1; my++) { 103 + for (int mx = 0; mx < map->header.width - 1; mx++) { 104 + add_rect(tile_width, my, mx, indices, index_idx); 105 + index_idx += 6; 106 + box_count++; 107 + } 108 + } 109 + printf("build_floor made %d boxes with %d indices\n", box_count, index_idx); 110 + } 111 + 112 #define VERTEX_IDX_OFFSET_NW 0 113 #define VERTEX_IDX_OFFSET_NE 1 114 #define VERTEX_IDX_OFFSET_SW 2 115 #define VERTEX_IDX_OFFSET_SE 3 116 117 void map_to_vertex_list(const struct map *map, struct texmap_node *texmap, 118 + texmap_count_t texmap_count, struct Vertex *points) { 119 + uint32_t tile_width = map->header.width / CHUNK_WIDTH; 120 + uint32_t tile_height = map->header.height / CHUNK_HEIGHT; 121 uint32_t points_count = 0; 122 uint16_t max_point_height = 0; 123 124 + for (int ty = 0; ty < tile_height; ty++) { 125 + for (int tx = 0; tx < tile_width; tx++) { 126 + int tile_idx = ty * tile_width + tx; 127 + uint16_t chunk_idx = map->tile_indexes[tile_idx].chunk_index; 128 + struct map_chunk *chunk = &(map->chunks[chunk_idx]); 129 + 130 + for (int py = 0; py < CHUNK_HEIGHT; py += 1) { 131 + for (int px = 0; px < CHUNK_WIDTH; px += 1) { 132 + int points_idx = vertex_idx(tile_width, ty, tx, py, px) * 4; 133 + int points_idx_nw = points_idx + VERTEX_IDX_OFFSET_NW; 134 + int points_idx_ne = points_idx + VERTEX_IDX_OFFSET_NE; 135 + int points_idx_sw = points_idx + VERTEX_IDX_OFFSET_SW; 136 + int points_idx_se = points_idx + VERTEX_IDX_OFFSET_SE; 137 + 138 + vertex_set_pos(map, tx, ty, chunk, px, py, &points[points_idx_nw]); 139 + vertex_set_pos(map, tx, ty, chunk, px + 1, py, 140 + &points[points_idx_ne]); 141 + vertex_set_pos(map, tx, ty, chunk, px, py + 1, 142 + &points[points_idx_sw]); 143 + vertex_set_pos(map, tx, ty, chunk, px + 1, py + 1, 144 + &points[points_idx_se]); 145 + vertex_set_tex(chunk, px, py, points, points_idx, texmap, 146 + texmap_count, chunk_point_texture_swap(chunk, py, px), 147 + chunk_point_texture_mirror(chunk, py, px), 148 + chunk_point_texture_unknown(chunk, py, px)); 149 + // printf("tile[%2d,%2d] point[%2d,%2d] pos[%f,%f] tex[%f,%f]\n", 150 + // ty, tx, 151 + // py, px, points[points_idx].pos[1], 152 + // points[points_idx].pos[0], points[points_idx].texCoord[1], 153 + // points[points_idx].texCoord[0]); 154 + points_count++; 155 156 + uint16_t point_height = chunk_point_height(chunk, py, px); 157 + if (point_height > max_point_height) { 158 + max_point_height = point_height; 159 + } 160 + } 161 } 162 } 163 } ··· 167 map_point_count, max_point_height); 168 } 169 170 uint32_t vertex_idx(uint32_t twidth, uint32_t ty, uint32_t tx, uint32_t py, 171 uint32_t px) { 172 int tile_idx = (ty * twidth) + tx; ··· 178 return vertex_idx; 179 } 180 181 + void add_rect(int tile_width, int my, int mx, uint32_t *indices, 182 + uint32_t index_idx) { 183 + // printf("add_rect my:%d mx:%d (index_idx:%d)\n", my, mx, index_idx); 184 + uint32_t ty, tx, py, px; 185 + map_to_tile_point(my, mx, tile_width, &ty, &tx, &py, &px); 186 + uint32_t vert_idx = vertex_idx(tile_width, ty, tx, py, px) * 4; 187 uint32_t nw = vert_idx + VERTEX_IDX_OFFSET_NW; 188 uint32_t ne = vert_idx + VERTEX_IDX_OFFSET_NE; 189 uint32_t sw = vert_idx + VERTEX_IDX_OFFSET_SW; ··· 197 indices[index_idx + 5] = se; 198 } 199 200 + uint16_t chunk_point_height(struct map_chunk *chunk, uint16_t py, uint16_t px) { 201 + return (chunk->points[py][px].left & 0b111111111111); 202 } 203 204 #define BITS_10 0b1111111111 205 + uint16_t chunk_point_texture_id(struct map_chunk *chunk, uint16_t py, 206 + uint16_t px) { 207 + return ((chunk->points[py][px].right & BITS_10 << 6) >> 6); 208 } 209 210 #define BITS_5 0b11111 211 + uint16_t chunk_point_texture_frame(struct map_chunk *chunk, uint16_t py, 212 + uint16_t px) { 213 + return ((chunk->points[py][px].right & BITS_5)); 214 } 215 216 + bool chunk_point_texture_swap(struct map_chunk *chunk, uint16_t py, 217 + uint16_t px) { 218 + return (chunk->points[py][px].left >> 13) & 1; 219 } 220 221 + bool chunk_point_texture_mirror(struct map_chunk *chunk, uint16_t py, 222 + uint16_t px) { 223 + return (chunk->points[py][px].left >> 14) & 1; 224 } 225 226 + bool chunk_point_texture_unknown(struct map_chunk *chunk, uint16_t py, 227 + uint16_t px) { 228 + return (chunk->points[py][px].left >> 15) & 1; 229 } 230 231 + void vertex_set_pos(const struct map *map, int tx, int ty, 232 + struct map_chunk *chunk, int px, int py, 233 + struct Vertex *point) { 234 + int map_y = (ty * CHUNK_HEIGHT) + py; 235 + int map_x = (tx * CHUNK_WIDTH) + px; 236 + float map_y_normal = map_y / (float)map->header.width; 237 + float map_x_normal = map_x / (float)map->header.height; 238 + point->pos[0] = 0.5 - map_x_normal; 239 + point->pos[1] = 0.5 - map_y_normal; 240 + float z = chunk_point_height(chunk, py, px); 241 + point->pos[2] = z / 1500.0 / 1.5; 242 + point->color[0] = (point->pos[2] - 0.1) * 1.2; 243 + point->color[1] = map_x % 2 == 0 ? 0.3 : 0.9; // point->pos[1]; 244 + point->color[2] = map_y % 1 == 0 ? 0.3 : 0.9; // point->pos[0]; 245 } 246 247 + void vertex_set_tex(struct map_chunk *chunk, int px, int py, 248 + struct Vertex *points, uint32_t points_idx, 249 + struct texmap_node *texmap, texmap_count_t texmap_count, 250 + bool tex_swap, bool tex_mirror, bool tex_unknown) { 251 + int tex_id = chunk_point_texture_id(chunk, py, px); 252 + int frame = chunk_point_texture_frame(chunk, py, px); 253 uint16_t tex_img_idx; 254 texmap_get(texmap, texmap_count, tex_id, frame, &tex_img_idx); 255 256 + struct Vertex *point_nw = &points[points_idx + VERTEX_IDX_OFFSET_NW]; 257 + struct Vertex *point_ne = &points[points_idx + VERTEX_IDX_OFFSET_NE]; 258 + struct Vertex *point_sw = &points[points_idx + VERTEX_IDX_OFFSET_SW]; 259 + struct Vertex *point_se = &points[points_idx + VERTEX_IDX_OFFSET_SE]; 260 261 + uint16_t orig_tex_idx = tex_img_idx; 262 tex_img_idx |= tex_unknown << 15; // unknown 263 + tex_img_idx |= tex_mirror << 14; 264 + tex_img_idx |= tex_swap << 13; 265 266 point_nw->texIdx = tex_img_idx; 267 point_ne->texIdx = tex_img_idx; ··· 297 map->tile_indexes = malloc(sizeof(struct map_tile_index) * tiles_count); 298 read_count = 299 fread(map->tile_indexes, sizeof(struct map_tile_index), tiles_count, fp); 300 + printf("read (size %lu) %d tile indexes\n", sizeof(struct map_tile_index), 301 + read_count); 302 303 map->chunks = malloc(sizeof(struct map_chunk) * map->header.chunk_count); 304 read_count = 305 fread(map->chunks, sizeof(struct map_chunk), map->header.chunk_count, fp); 306 + printf("read (size %lu) %d chunks\n", sizeof(struct map_chunk), read_count); 307 + 308 + int pos = ftell(fp); 309 + printf("ending position %d\n", pos); 310 } 311 312 void load_textures(FILE *fp, struct textures *textures) { ··· 324 sizeof(struct flx_dir_ent) * read_count); 325 } 326 327 + void u9_texture_images(const struct map *map, struct texture_img **tex_imgs, 328 struct texmap_node **tex_map, 329 texmap_count_t *texmap_count) { 330 uint32_t map_height_in_tiles = map->header.width / CHUNK_HEIGHT; ··· 335 uint16_t texture_height = 128; 336 unique_textures(map, tex_map, texmap_count); 337 *tex_imgs = malloc(sizeof(struct texture_img) * *texmap_count); 338 + printf("%d unique textures\n", *texmap_count); 339 340 for (int idx = 0; idx < *texmap_count; idx++) { 341 struct texture_img *tex_img = &(*tex_imgs)[idx]; ··· 347 348 uint16_t point_texture_id = (*tex_map)[idx].tex_id; 349 uint16_t point_texture_frame = (*tex_map)[idx].frame; 350 + load_bitmap(point_texture_id, point_texture_frame, tex_img->pixels); 351 } 352 } 353 354 void unique_textures(const struct map *map, struct texmap_node **texmap, 355 texmap_count_t *texmap_count) { 356 + uint32_t map_height_in_tiles = map->header.width / CHUNK_HEIGHT; 357 + uint32_t map_width_in_tiles = map->header.height / CHUNK_WIDTH; 358 + uint32_t texture_width = 128; 359 + uint32_t texture_height = 128; 360 + uint16_t chunk_width = 16; // CHUNK_WIDTH 361 + uint16_t chunk_height = 16; // CHUNK_HEIGHT 362 *texmap_count = 0; 363 *texmap = NULL; 364 365 + for (int ty = 0; ty < map_height_in_tiles; ty++) { 366 + for (int tx = 0; tx < map_width_in_tiles; tx++) { 367 + int tile_idx = ty * map_width_in_tiles + tx; 368 + uint16_t chunk_idx = map->tile_indexes[tile_idx].chunk_index; 369 + struct map_chunk *chunk = &(map->chunks[chunk_idx]); 370 371 + for (int py = 0; py < chunk_height; py += 1) { 372 + for (int px = 0; px < chunk_width; px += 1) { 373 + uint16_t point_idx = py * chunk_width + px; 374 + // uint16_t temp_tex[8] = { 1, 2, 3, 375 + // 11, 1, 2, 3}; // ROCK GRASS DIRT SAND 376 + // uint16_t point_texture_id = temp_tex[point_idx]; 377 + uint16_t point_texture_id = chunk_point_texture_id(chunk, py, px); 378 + // uint16_t point_texture_frame = 0; 379 + uint16_t point_texture_frame = 380 + chunk_point_texture_frame(chunk, py, px); 381 + 382 + if (texmap_find(*texmap, *texmap_count, point_texture_id, 383 + point_texture_frame)) { 384 + } else { 385 + texmap_add(texmap, texmap_count, point_texture_id, 386 + point_texture_frame); 387 + // printf("unique: added texture %2d/%2d to texmap #%d\n", 388 + // point_texture_id, point_texture_frame, (*texmap_count) - 389 + // 1); 390 + } 391 + } 392 } 393 } 394 } 395 } 396 397 + void load_bitmap(uint16_t bitmap_idx, uint16_t bitmap_idx_plane, 398 + struct rgba8888 *pixels) { 399 400 + FILE *fp = fopen("tmp/bitmap16.flx", "rb"); 401 if (fp == NULL) { 402 printf("bitmap open null %d\n", errno); 403 exit(1);
+30 -154
src/u9.h
··· 45 uint32_t filesize; 46 uint32_t filesize2; 47 char unknown3[0x20]; 48 - } __attribute__((packed)); 49 50 struct flx_dir_ent { 51 uint32_t offset; 52 uint32_t length; 53 - } __attribute__((packed)); 54 55 struct textures { 56 struct flx_header header; ··· 147 struct fixed_page *pages; 148 }; 149 150 - struct itemtype { 151 - uint32_t unknown1; 152 - uint16_t usecode; 153 - uint16_t sappear_id; 154 - uint16_t flags; 155 - uint8_t weight; 156 - uint8_t volume; 157 - uint8_t book; 158 - uint8_t hitpts; 159 - uint16_t zero; 160 - }; 161 - 162 - struct itemname { 163 - uint32_t unknown1; 164 - uint16_t icon_id; 165 - char name[]; 166 - } __attribute__((packed)); 167 - 168 - struct sappear { 169 - struct sappear_header *header; 170 - uint32_t *submesh_offsets; 171 - }; 172 - 173 - struct sappear_point { 174 - float x; 175 - float y; 176 - float z; 177 - } __attribute__((packed)); 178 - 179 - struct sappear_vertex { 180 - uint32_t index; 181 - uint32_t offset; 182 - vec3 normal; 183 - vec2 uv_coord; 184 - } __attribute__((packed)); 185 - 186 - struct sappear_face { 187 - struct sappear_vertex points[3]; 188 - uint32_t flags; 189 - uint32_t flags2; 190 - vec3 normal; 191 - float w; 192 - uint32_t material_id; 193 - uint8_t rgba[4]; 194 - uint8_t collision[8]; 195 - } __attribute__((packed)); 196 - 197 - struct sappear_material{ 198 - uint16_t texture_id; 199 - uint16_t flags; 200 - uint16_t subtexture_count; 201 - uint16_t flags2; 202 - uint16_t first_face_id; 203 - uint16_t face_count; 204 - } __attribute__((packed)); 205 - 206 - struct sappear_submesh { 207 - uint32_t limb_id; 208 - uint32_t parent_id; 209 - float scale_x; 210 - float scale_y; 211 - float scale_z; 212 - vec3 position; 213 - float rot_w; 214 - float rot_x; 215 - float rot_y; 216 - float rot_z; 217 - } __attribute__((packed)); 218 - 219 - struct sappear_lod { 220 - uint32_t mesh_size; 221 - uint32_t flags; 222 - uint32_t unknown1; 223 - vec3 sphere_center; 224 - float spehere_radius; 225 - vec3 min_bounding_box; 226 - vec3 max_bounding_box; 227 - uint32_t unknown2; 228 - uint32_t unknown3; 229 - uint32_t face_count; 230 - uint32_t mount_face_count; 231 - uint32_t vertex_count; 232 - uint32_t mount_vertex_count; 233 - uint32_t max_face_count; 234 - uint32_t material_count; 235 - uint32_t face_offset; 236 - uint32_t mount_face_offset; 237 - uint32_t vertex_offset; 238 - uint32_t mount_vertex_offset; 239 - uint32_t material_offset; 240 - uint32_t sorted_faces_offsets[4]; 241 - } __attribute__((packed)); 242 - 243 - struct sappear_header { 244 - uint32_t submesh_count; 245 - uint32_t lod_count; 246 - ivec3 cylinder_center; 247 - float cylinder_height; 248 - float cylinder_radius; 249 - ivec3 sphere_center; 250 - float sphere_radius; 251 - float unknown1; 252 - ivec3 min_bounding_box; 253 - ivec3 max_bounding_box; 254 - uint32_t lod_threshold_0; 255 - uint32_t lod_threshold_1; 256 - uint32_t lod_threshold_2; 257 - uint32_t lod_threshold_3; 258 - ivec3 center_of_mass; 259 - uint32_t unknown2; 260 - uint32_t inertia[9]; 261 - uint32_t unknown3; 262 - } __attribute__((packed)); 263 - 264 void rgb555_rgb888(uint16_t color, struct rgba8888 *pixel); 265 - void u9_sappear(char filename[], void **sappear_map); 266 - void u9_sappear_obj(void *sappear_map, int flx_id, struct sappear *s, 267 - uint16_t lod, uint16_t face, struct Vertex **vertices, 268 - uint32_t *vertices_count, uint32_t **indices, 269 - uint32_t *indices_count); 270 void u9_palette(char filename[], struct palette *palette); 271 void u9_textures(const char filename[], struct textures *textures); 272 - void u9_texture_images(const char filename[], const struct map *map, 273 - struct texture_img **tex_imgs, 274 - struct texmap_node **tex_map, 275 texmap_count_t *texmap_count); 276 void u9_map(const char filename[], struct map *map); 277 - void u9_fixed(const char filename[], void *itemnames_map, struct fixed *fixed); 278 void u9_map_to_points(const struct map *map, struct texmap_node *texmap, 279 - texmap_count_t texmap_count, struct Vertex **vertices, 280 - uint32_t *vertices_count, uint32_t **indices, 281 uint32_t *indices_count); 282 - void u9_itemtypes(const char filename[], struct itemtype **itemtypes); 283 - void u9_itemnames(const char filename[], void **itemnames_map); 284 - struct itemname *u9_itemname(void *itemnames_map, int idx); 285 - void itemnames(void *itemnames_map); 286 - void load_itemtypes(FILE *fp, struct itemtype **itemtypes); 287 void load_map(FILE *fp, struct map *map); 288 void load_fixed(FILE *fp, struct fixed *fixed); 289 - void load_bitmap(const char filename[], uint16_t bitmap_idx, 290 - uint16_t bitmap_idx_plane, struct rgba8888 *pixels); 291 void unique_textures(const struct map *map, struct texmap_node **texmap, 292 texmap_count_t *texmap_count); 293 - struct map_point *point_lookup(const struct map *map, uint16_t my, 294 - uint16_t mx); 295 - uint16_t point_height(struct map_point *point); 296 - uint16_t point_texture_id(struct map_point *point); 297 - uint16_t point_texture_frame(struct map_point *point); 298 - bool point_texture_swap(struct map_point *point); 299 - bool point_texture_mirror(struct map_point *point); 300 - bool point_texture_unknown(struct map_point *point); 301 uint32_t map_point_count_compute(const struct map *map); 302 uint32_t map_tiles_count_compute(const struct map *map); 303 void map_to_vertex_list(const struct map *map, struct texmap_node *texmap, 304 - texmap_count_t texmap_count, struct Vertex *vertices); 305 - void build_floor(const struct map *map, struct Vertex *vertices, 306 uint32_t *indices); 307 - void set_box_corners(struct Vertex *vertices, const struct map *map, int mx, int my, 308 - struct texmap_node *texmap, texmap_count_t texmap_count); 309 - void vertex_set_map_pos(struct Vertex *vertex, const struct map *map, int my, 310 - int mx); 311 - void vertex_set_pos(struct Vertex *vertex, float x, float y, float z); 312 - void vertex_set_tex_box(const struct map *map, int my, int mx, 313 - struct Vertex *vertices, uint32_t vertices_idx, 314 - struct texmap_node *texmap, 315 - texmap_count_t texmap_count); 316 void map_to_tile_point(uint32_t my, uint32_t mx, uint32_t twidth, uint32_t *ty, uint32_t *tx, 317 uint32_t *py, uint32_t *px); 318 - void add_rect(uint32_t vert_idx, uint32_t *indices, uint32_t index_idx); 319 uint32_t vertex_idx(uint32_t twidth, uint32_t ty, uint32_t tx, uint32_t py, 320 uint32_t px); 321 void load_textures(FILE *fp, struct textures *textures);
··· 45 uint32_t filesize; 46 uint32_t filesize2; 47 char unknown3[0x20]; 48 + }; 49 50 struct flx_dir_ent { 51 uint32_t offset; 52 uint32_t length; 53 + }; 54 55 struct textures { 56 struct flx_header header; ··· 147 struct fixed_page *pages; 148 }; 149 150 void rgb555_rgb888(uint16_t color, struct rgba8888 *pixel); 151 void u9_palette(char filename[], struct palette *palette); 152 void u9_textures(const char filename[], struct textures *textures); 153 + void u9_texture_images(const struct map *map, struct texture_img **tex_imgs, 154 + struct texmap_node **texmap, 155 texmap_count_t *texmap_count); 156 void u9_map(const char filename[], struct map *map); 157 + void u9_fixed(const char filename[], struct fixed *fixed); 158 void u9_map_to_points(const struct map *map, struct texmap_node *texmap, 159 + texmap_count_t texmap_count, struct Vertex **points, 160 + uint32_t *points_count, uint32_t **indices, 161 uint32_t *indices_count); 162 void load_map(FILE *fp, struct map *map); 163 void load_fixed(FILE *fp, struct fixed *fixed); 164 void unique_textures(const struct map *map, struct texmap_node **texmap, 165 texmap_count_t *texmap_count); 166 + uint16_t chunk_point_height(struct map_chunk *chunk, uint16_t py, uint16_t px); 167 + uint16_t chunk_point_texture_id(struct map_chunk *chunk, uint16_t py, 168 + uint16_t px); 169 + uint16_t chunk_point_texture_frame(struct map_chunk *chunk, uint16_t py, 170 + uint16_t px); 171 + bool chunk_point_texture_swap(struct map_chunk *chunk, uint16_t py, 172 + uint16_t px); 173 + bool chunk_point_texture_mirror(struct map_chunk *chunk, uint16_t py, 174 + uint16_t px); 175 + bool chunk_point_texture_unknown(struct map_chunk *chunk, uint16_t py, 176 + uint16_t px); 177 uint32_t map_point_count_compute(const struct map *map); 178 uint32_t map_tiles_count_compute(const struct map *map); 179 void map_to_vertex_list(const struct map *map, struct texmap_node *texmap, 180 + texmap_count_t texmap_count, struct Vertex *points); 181 + void build_floor(const struct map *map, struct Vertex *points, 182 uint32_t *indices); 183 + void vertex_set_pos(const struct map *map, int tx, int ty, struct map_chunk *chunk, int px, 184 + int py, struct Vertex *point); 185 + void vertex_set_tex(struct map_chunk *chunk, int px, int py, 186 + struct Vertex *points, uint32_t points_idx, 187 + struct texmap_node *texmap, texmap_count_t texmap_count, 188 + bool tex_swap, bool tex_mirror, bool tex_unknown); 189 void map_to_tile_point(uint32_t my, uint32_t mx, uint32_t twidth, uint32_t *ty, uint32_t *tx, 190 uint32_t *py, uint32_t *px); 191 + void add_rect(int twidth, int my, int mx, uint32_t *indices, 192 + uint32_t index_idx); 193 uint32_t vertex_idx(uint32_t twidth, uint32_t ty, uint32_t tx, uint32_t py, 194 uint32_t px); 195 void load_textures(FILE *fp, struct textures *textures); 196 + void load_bitmap(uint16_t bitmap_idx, uint16_t bitmap_idx_plane, 197 + struct rgba8888 *pixels);
-41
src/util.c
··· 1 - #include <fcntl.h> 2 #include <stdint.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 - #include <string.h> 6 - #include <sys/mman.h> 7 - #include <sys/stat.h> 8 - #include <unistd.h> 9 10 #include "util.h" 11 12 - void arg_check(int argc, char *argv[]) { 13 - if (argc < 2) { 14 - printf("u9map <level number>\n"); 15 - exit(1); 16 - } 17 - printf("loading level %s\n", argv[1]); 18 - } 19 - 20 - long mmap_file(const char filename[], void **map) { 21 - int fd = open(filename, O_RDONLY); 22 - struct stat stat; 23 - fstat(fd, &stat); 24 - const int offset = 0; 25 - *map = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, offset); 26 - printf("mmap_file %p\n", *map); 27 - close(fd); 28 - return stat.st_size; 29 - } 30 - 31 int read_file(const char *filename, uint32_t *file_size, char **buffer, 32 uint32_t *bytes_read) { 33 FILE *fp = fopen(filename, "rb"); ··· 47 48 fclose(fp); 49 return 0; 50 - } 51 - 52 - char *path_merge(char *path, char *level) { 53 - char *env_path = getenv("U9MAP_PATH"); 54 - if (!env_path) { 55 - printf( 56 - "please set environment variable U9MAP_PATH to the ultima9 folder\n"); 57 - exit(1); 58 - } 59 - int env_path_len = strlen(env_path); 60 - int path_len = strlen(path); 61 - int level_len = strlen(level); 62 - 63 - char *buf = malloc(env_path_len + path_len + level_len + 1); 64 - sprintf(buf, "%s/%s%s", env_path, path, level); 65 - printf("path: %s\n", buf); 66 - return buf; 67 } 68 69 long timeval_usec(struct timeval *t) {
··· 1 #include <stdint.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 5 #include "util.h" 6 7 int read_file(const char *filename, uint32_t *file_size, char **buffer, 8 uint32_t *bytes_read) { 9 FILE *fp = fopen(filename, "rb"); ··· 23 24 fclose(fp); 25 return 0; 26 } 27 28 long timeval_usec(struct timeval *t) {
-3
src/util.h
··· 7 struct timeval t_now; 8 }; 9 10 - void arg_check(int argc, char *argv[]); 11 int read_file(const char *filename, uint32_t *file_size, char** buffer, uint32_t *bytes_read); 12 long timeval_usec(struct timeval* t); 13 float stopwatch_elapsed_sec(struct stopwatch_t* stopwatch); 14 void stopwatch_init(struct stopwatch_t *stopwatch); 15 - char *path_merge(char *path, char *level); 16 - long mmap_file(const char filename[], void **map);
··· 7 struct timeval t_now; 8 }; 9 10 int read_file(const char *filename, uint32_t *file_size, char** buffer, uint32_t *bytes_read); 11 long timeval_usec(struct timeval* t); 12 float stopwatch_elapsed_sec(struct stopwatch_t* stopwatch); 13 void stopwatch_init(struct stopwatch_t *stopwatch);