add gb_makepak

This commit is contained in:
Nishi 2026-01-10 00:55:45 +09:00
commit b66cf8068a
Signed by: nishi
GPG key ID: 27EF69B208EB9343
16 changed files with 349 additions and 5 deletions

View file

@ -37,6 +37,6 @@ install(
add_subdirectory(tools)
install(
FILES resource/shadow.vs resource/shadow.fs
DIRECTORY resource/
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/GearBox
)

View file

@ -0,0 +1,19 @@
#ifndef __GEARBOX_FILE_H__
#define __GEARBOX_FILE_H__
#include <GearBox/MachDep.h>
#include <GearBox/TypeDefs.h>
#ifdef __cplusplus
extern "C" {
#endif
GBDECL GBFile GBFileOpen(GBEngine engine, const char* path);
GBDECL int GBFileRead(GBFile file, void* out, int size);
GBDECL void GBFileClose(GBFile file);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -11,5 +11,7 @@
#include <GearBox/Server.h>
#include <GearBox/Math.h>
#include <GearBox/GL.h>
#include <GearBox/File.h>
#include <GearBox/Resource.h>
#endif

View file

@ -0,0 +1,18 @@
#ifndef __GEARBOX_RESOURCE_H__
#define __GEARBOX_RESOURCE_H__
#include <GearBox/MachDep.h>
#include <GearBox/TypeDefs.h>
#ifdef __cplusplus
extern "C" {
#endif
GBDECL GBResource GBResourceOpen(GBEngine engine, const char* path);
GBDECL void GBResourceClose(GBResource resource);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,17 @@
#ifndef __GEARBOX_STRING_H__
#define __GEARBOX_STRING_H__
#include <GearBox/MachDep.h>
#include <GearBox/TypeDefs.h>
#ifdef __cplusplus
extern "C" {
#endif
GBDECL char* GBStringDuplicate(const char* str);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,16 +1,23 @@
#ifndef __GEARBOX_TYPEDEFS_H__
#define __GEARBOX_TYPEDEFS_H__
#include <GearBox/MachDep.h>
typedef struct _GBVersion GBVersion;
typedef struct _GBEngineParam GBEngineParam;
typedef struct _GBResourceKV GBResourceKV;
#ifdef _GEARBOX
typedef struct _GBClient* GBClient;
typedef struct _GBServer* GBServer;
typedef struct _GBEngine* GBEngine;
typedef struct _GBClient* GBClient;
typedef struct _GBServer* GBServer;
typedef struct _GBEngine* GBEngine;
typedef struct _GBFile* GBFile;
typedef struct _GBResource* GBResource;
#else
typedef void* GBClient;
typedef void* GBServer;
typedef void* GBEngine;
typedef void* GBFile;
typedef void* GBResource;
#endif
typedef void (*GBGLSwapBufferCallback)(void);
@ -19,6 +26,11 @@ typedef void (*GBTickCallback)(void);
typedef long (*GBGetTickCallback)(void);
typedef void (*GBSleepCallback)(int ms);
struct _GBResourceKV {
char* key;
GBResource value;
};
#ifdef _GEARBOX
struct _GBClient {
GBEngine engine;
@ -32,6 +44,15 @@ struct _GBEngine {
GBEngineParam* param;
GBClient client;
GBServer server;
GBResourceKV* resource;
};
struct _GBFile {
FILE* fp;
};
struct _GBResource {
GBFile file;
};
#endif

View file

@ -5,6 +5,9 @@
#include <GearBox/Client.h>
#include <GearBox/Server.h>
#include <GearBox/GL.h>
#include <GearBox/Resource.h>
#include <stb_ds.h>
void GBInit(void) {
GBVersion version;
@ -17,7 +20,8 @@ void GBInit(void) {
}
GBEngine GBEngineCreate(GBEngineParam* param) {
GBEngine engine = malloc(sizeof(*engine));
GBEngine engine = malloc(sizeof(*engine));
GBResource resource;
memset(engine, 0, sizeof(*engine));
@ -28,6 +32,11 @@ GBEngine GBEngineCreate(GBEngineParam* param) {
param->ready(1024, 768);
}
sh_new_strdup(engine->resource);
resource = GBResourceOpen(engine, "base.pak");
shput(engine->resource, "base", resource);
if(engine != NULL && param->client && (engine->client = GBClientCreate(engine)) == NULL) {
GBLog(GBLogError, "Failed to create client");
@ -52,6 +61,8 @@ GBEngine GBEngineCreate(GBEngineParam* param) {
}
void GBEngineDestroy(GBEngine engine) {
shfree(engine->resource);
if(engine->server != NULL) GBServerDestroy(engine->server);
if(engine->client != NULL) GBClientDestroy(engine->client);
if(engine->param != NULL) free(engine->param);

View file

@ -1 +1,42 @@
#include <GearBox/File.h>
#include <GearBox/String.h>
#include <GearBox/Log.h>
GBFile GBFileOpen(GBEngine engine, const char* path) {
GBFile file = malloc(sizeof(*file));
char* s;
char* nam;
memset(file, 0, sizeof(*file));
GBLog(GBLogInfo, "Opening %s", path);
s = GBStringDuplicate(path);
if(engine != NULL && ((nam = strstr(s, ":/")) != NULL || (nam = strstr(s, ":\\")) != NULL)) {
nam[0] = 0;
nam[1] = 0;
nam += 2;
printf("%s\n", nam);
}
free(s);
if((file->fp = fopen(path, "rb")) != NULL) {
return file;
}
GBLog(GBLogWarn, "Could not open %s", path);
GBFileClose(file);
return NULL;
}
int GBFileRead(GBFile file, void* out, int size) {
if(file->fp != NULL) return fread(out, 1, size, file->fp);
}
void GBFileClose(GBFile file) {
if(file->fp != NULL) fclose(file->fp);
free(file);
}

22
engine/src/resource.c Normal file
View file

@ -0,0 +1,22 @@
#include <GearBox/Resource.h>
#include <GearBox/File.h>
GBResource GBResourceOpen(GBEngine engine, const char* path) {
GBResource resource = malloc(sizeof(*resource));
memset(resource, 0, sizeof(*resource));
if((resource->file = GBFileOpen(engine, path)) == NULL) {
GBResourceClose(resource);
return NULL;
}
return resource;
}
void GBResourceClose(GBResource resource) {
if(resource->file != NULL) GBFileClose(resource->file);
free(resource);
}

2
engine/src/stb_ds.c Normal file
View file

@ -0,0 +1,2 @@
#define STB_DS_IMPLEMENTATION
#include "stb_ds.h"

9
engine/src/string.c Normal file
View file

@ -0,0 +1,9 @@
#include <GearBox/String.h>
char* GBStringDuplicate(const char* str) {
char* s = malloc(strlen(str) + 1);
strcpy(s, str);
return s;
}

View file

@ -5,6 +5,13 @@ include(GNUInstallDirs)
macro(compile_tool name)
file(GLOB ${name}_SRC ${name}/*.c)
add_executable(${name} ${${name}_SRC})
install_target(${name})
endmacro()
file(GLOB lz4_SRC ../lz4/*.c)
compile_tool(gb_dumpfont)
compile_tool(gb_makepak)
target_include_directories(gb_makepak PRIVATE ../lz4)
target_sources(gb_makepak PRIVATE ${lz4_SRC})

View file

@ -0,0 +1,173 @@
#include <stb_ds.h>
#include <lz4.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/stat.h>
#include <dirent.h>
#endif
#include <stdio.h>
typedef struct kv {
char* key;
} kv_t;
static FILE* out;
static void scan(const char* path, const char* pre);
static void pack(const char* fullpath, const char* path) {
int m;
FILE* f = fopen(fullpath, "rb");
int insz;
int outsz;
unsigned char* input;
unsigned char* output;
printf("%32s ", path);
fflush(stdout);
fseek(f, 0, SEEK_END);
insz = ftell(f);
fseek(f, 0, SEEK_SET);
m = LZ4_compressBound(insz);
input = malloc(insz);
output = malloc(m);
fread(input, 1, m, f);
outsz = LZ4_compress_default(input, output, insz, m);
if(outsz > 0) {
int sz = outsz;
int i;
char fn[128];
memset(fn, 0, 128);
memcpy(fn, path, strlen(path));
fwrite(fn, 1, 128, out);
for(i = 0; i < 4; i++) {
unsigned char n = (sz >> 24) & 0xff;
fwrite(&n, 1, 1, out);
sz = sz << 8;
}
fwrite(output, 1, outsz, out);
printf("done (%6d -> %6d)\n", insz, outsz);
} else {
printf("failed\n");
}
free(input);
free(output);
fclose(f);
}
static int is_dir(const char* path) {
#ifdef _WIN32
DWORD dw;
if((dw = GetFileAttributes(path)) == INVALID_FILE_ATTRIBUTES && !(dw & FILE_ATTRIBUTE_DIRECTORY)) return 0;
return 1;
#else
struct stat s;
if(stat(path, &s) == 0 && S_ISDIR(s.st_mode)) return 1;
return 0;
#endif
}
static void found(const char* path, const char* pre, const char* input) {
char* p = malloc(strlen(pre) + strlen(input) + 1 + 1);
char* fp = malloc(strlen(path) + 1 + strlen(input) + 1);
p[0] = 0;
strcat(p, pre);
strcat(p, input);
fp[0] = 0;
strcat(fp, path);
strcat(fp, "/");
strcat(fp, input);
if(is_dir(fp)) {
strcat(p, "/");
scan(fp, p);
} else {
pack(fp, p);
}
free(fp);
free(p);
}
static void scan(const char* path, const char* pre) {
#ifdef _WIN32
WIN32_FIND_DATA ffd;
HANDLE hFind;
char* w = malloc(strlen(path) + 2 + 1);
w[0] = 0;
strcat(w, path);
strcat(w, "/*");
if((hFind = FindFirstFile(w, &ffd)) == INVALID_HANDLE_VALUE) {
free(w);
return;
}
do {
if(strcmp(ffd.cFileName, ".") != 0 && strcmp(ffd.cFileName, "..") != 0) {
found(path, pre, ffd.cFileName);
}
} while(FindNextFile(hFind, &ffd) != 0);
FindClose(hFind);
#else
DIR* dir;
if((dir = opendir(path)) != NULL) {
struct dirent* d;
while((d = readdir(dir)) != NULL) {
if(strcmp(d->d_name, "..") != 0 && strcmp(d->d_name, ".") != 0) {
found(path, pre, d->d_name);
}
}
closedir(dir);
}
#endif
}
int main(int argc, char** argv) {
unsigned char nul[128];
if(argc >= 2) out = fopen(argv[1], "wb");
if(argc == 2) {
scan(".", "");
} else if(argc > 2) {
int i;
for(i = 1; i < argc; i++) scan(argv[i], "");
} else {
printf("Usage: %s output [input]\n", argv[0]);
return 1;
}
memset(nul, 0, 128);
fwrite(nul, 1, 128, out);
fclose(out);
}

View file

@ -0,0 +1,2 @@
#define STB_DS_IMPLEMENTATION
#include "stb_ds.h"