sync fwk
parent
bc1ff71f74
commit
67f60ac798
68
engine/v4k.c
68
engine/v4k.c
|
@ -20146,6 +20146,27 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model)
|
|||
for(int i = 0; i < (int)hdr->num_meshes; i++) {
|
||||
struct iqmmesh *m = &meshes[i];
|
||||
|
||||
// reuse texture+material if already decoded
|
||||
bool reused = 0;
|
||||
for( int j = 0; !reused && j < model->num_textures; ++j ) {
|
||||
if( !strcmpi(model->texture_names[j], &str[m->material])) {
|
||||
|
||||
*out++ = model->materials[j].layer[0].texture;
|
||||
|
||||
{
|
||||
model->num_textures++;
|
||||
array_push(model->texture_names, STRDUP(&str[m->material]));
|
||||
|
||||
array_push(model->materials, model->materials[j]);
|
||||
array_back(model->materials)->name = STRDUP(&str[m->material]);
|
||||
}
|
||||
|
||||
reused = true;
|
||||
}
|
||||
}
|
||||
if( reused ) continue;
|
||||
|
||||
// decode texture+material
|
||||
int flags = TEXTURE_MIPMAPS|TEXTURE_REPEAT; // LINEAR, NEAREST
|
||||
int invalid = texture_checker().id;
|
||||
|
||||
|
@ -20157,7 +20178,7 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model)
|
|||
array(char) embedded_texture = base64_decode(material_embedded_texture, strlen(material_embedded_texture));
|
||||
//printf("%s %d\n", material_embedded_texture, array_count(embedded_texture));
|
||||
//hexdump(embedded_texture, array_count(embedded_texture));
|
||||
*out = texture_compressed_from_mem( embedded_texture, array_count(embedded_texture), 0 ).id;
|
||||
*out = texture_compressed_from_mem( embedded_texture, array_count(embedded_texture), flags ).id;
|
||||
array_free(embedded_texture);
|
||||
}
|
||||
|
||||
|
@ -20210,6 +20231,7 @@ bool model_load_textures(iqm_t *q, const struct iqmheader *hdr, model_t *model)
|
|||
*out = texture_checker().id; // placeholder
|
||||
}
|
||||
|
||||
inscribe_tex:;
|
||||
{
|
||||
model->num_textures++;
|
||||
array_push(model->texture_names, STRDUP(&str[m->material]));
|
||||
|
@ -20277,7 +20299,7 @@ model_t model_from_mem(const void *mem, int len, int flags) {
|
|||
// if( shaderprog < 0 ) {
|
||||
const char *symbols[] = { "{{include-shadowmap}}", vfs_read("shaders/fs_0_0_shadowmap_lit.glsl") }; // #define RIM
|
||||
int shaderprog = shader(strlerp(1,symbols,vfs_read("shaders/vs_323444143_16_3322_model.glsl")), strlerp(1,symbols,vfs_read("shaders/fs_32_4_model.glsl")), //fs,
|
||||
"att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_texcoord2,att_bitangent","fragColor",
|
||||
"att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent,att_texcoord2","fragColor",
|
||||
va("SHADING_PHONG,%s", (flags&MODEL_RIMLIGHT)?"RIM":""));
|
||||
// }
|
||||
// ASSERT(shaderprog > 0);
|
||||
|
@ -20686,7 +20708,7 @@ lightmap_t lightmap(int hmsize, float cnear, float cfar, vec3 color, int passes,
|
|||
|
||||
const char *symbols[] = { "{{include-shadowmap}}", vfs_read("shaders/fs_0_0_shadowmap_lit.glsl") }; // #define RIM
|
||||
lm.shader = shader(strlerp(1,symbols,vfs_read("shaders/vs_323444143_16_3322_model.glsl")), strlerp(1,symbols,vfs_read("shaders/fs_32_4_model.glsl")), //fs,
|
||||
"att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_texcoord2,att_bitangent","fragColor",
|
||||
"att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent,att_texcoord2","fragColor",
|
||||
va("%s", "LIGHTMAP_BAKING"));
|
||||
|
||||
return lm;
|
||||
|
@ -20720,6 +20742,10 @@ void lightmap_bake(lightmap_t *lm, int bounces, void (*drawscene)(lightmap_t *lm
|
|||
texture_destroy(&m->lightmap);
|
||||
}
|
||||
m->lightmap = texture_create(w, h, 4, 0, TEXTURE_LINEAR|TEXTURE_FLOAT);
|
||||
glBindTexture(GL_TEXTURE_2D, m->lightmap.id);
|
||||
unsigned char emissive[] = { 0, 0, 0, 255 };
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, emissive);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
for (int b = 0; b < bounces; b++) {
|
||||
|
@ -28758,42 +28784,6 @@ vec3 editor_pick(float mouse_x, float mouse_y) {
|
|||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
int editor_ui_bits8(const char *label, uint8_t *enabled) { // @to deprecate
|
||||
int clicked = 0;
|
||||
uint8_t copy = *enabled;
|
||||
|
||||
// @fixme: better way to retrieve widget width? nk_layout_row_dynamic() seems excessive
|
||||
nk_layout_row_dynamic(ui_ctx, 1, 1);
|
||||
struct nk_rect bounds = nk_widget_bounds(ui_ctx);
|
||||
|
||||
// actual widget: label + 8 checkboxes
|
||||
enum { HEIGHT = 18, BITS = 8, SPAN = 118 }; // bits widget below needs at least 118px wide
|
||||
nk_layout_row_begin(ui_ctx, NK_STATIC, HEIGHT, 1+BITS);
|
||||
|
||||
int offset = bounds.w > SPAN ? bounds.w - SPAN : 0;
|
||||
nk_layout_row_push(ui_ctx, offset);
|
||||
if( ui_label_(label, NK_TEXT_LEFT) ) clicked = 1<<31;
|
||||
|
||||
for( int i = 0; i < BITS; ++i ) {
|
||||
nk_layout_row_push(ui_ctx, 10);
|
||||
// bit
|
||||
int val = (*enabled >> i) & 1;
|
||||
int chg = nk_checkbox_label(ui_ctx, "", &val);
|
||||
*enabled = (*enabled & ~(1 << i)) | ((!!val) << i);
|
||||
// tooltip
|
||||
struct nk_rect bb = { offset + 10 + i * 14, bounds.y, 14, HEIGHT }; // 10:padding,14:width
|
||||
if (nk_input_is_mouse_hovering_rect(&ui_ctx->input, bb) && !ui_popups()) {
|
||||
const char *tips[BITS] = {"Init","Tick","Draw","Quit","","","",""};
|
||||
if(tips[i][0]) nk_tooltipf(ui_ctx, "%s", tips[i]);
|
||||
}
|
||||
}
|
||||
|
||||
nk_layout_row_end(ui_ctx);
|
||||
return clicked | (copy ^ *enabled);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
typedef union engine_var {
|
||||
int i;
|
||||
|
|
|
@ -14,8 +14,11 @@ cp bin/libassimp.dylib ../libassimp.5.dylib
|
|||
cp bin/libassimp.dylib ../libassimp.5.0.1.dylib
|
||||
cd ..
|
||||
|
||||
cc ass2iqe.c -o ass2iqe.linux -O2 -I assimp/include/ libassimp.so -lm
|
||||
cc ass2iqe.c -o ass2iqe.osx -O2 -I assimp/include/ libassimp.dylib -lm
|
||||
cc ass2iqe.c -o ass2iqe.linux -O2 -I. -I ../engine/split -I assimp/include/ libassimp.so -lm
|
||||
cc ass2iqe.c -o ass2iqe.osx -O2 -I. -I ../engine/split -I assimp/include/ libassimp.dylib -lm
|
||||
|
||||
cc iqe2iqm.c -o iqe2iqm.linux -O2 -I. -I ../engine/split -lm
|
||||
cc iqe2iqm.c -o iqe2iqm.osx -O2 -I. -I ../engine/split -lm
|
||||
|
||||
exit
|
||||
|
||||
|
@ -24,6 +27,9 @@ exit
|
|||
@echo off
|
||||
cd "%~dp0"
|
||||
|
||||
if not exist assimp-vc14?-mt.lib (
|
||||
if not exist "fart.exe" echo fart tool required && exit /b
|
||||
|
||||
git clone https://github.com/assimp/assimp && md assimp\.build && pushd assimp\.build && git checkout 05115b07
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release && (make || msbuild assimp.sln -m -p:Configuration=Release)
|
||||
popd
|
||||
|
@ -32,4 +38,8 @@ xcopy /y assimp\.build\bin\release\*.dll
|
|||
xcopy /y assimp\.build\lib\release\*.lib
|
||||
|
||||
copy /y assimp\include\assimp\config.h.in assimp\config.h && fart -- assimp\config.h "cmakedefine" "//#define"
|
||||
cl ass2iqe.c -I . -I assimp\include assimp-vc14?-mt.lib /O2 /Oy /MT /DNDEBUG
|
||||
)
|
||||
|
||||
cl ass2iqe.c -I. -I ..\engine\split -I assimp\include assimp-vc14?-mt.lib /O2 /Oy /MT /DNDEBUG
|
||||
|
||||
cl iqe2iqm.cpp /O2 /Oy /MT /DNDEBUG
|
||||
|
|
|
@ -17,8 +17,20 @@ exit
|
|||
@echo off
|
||||
cd "%~dp0"
|
||||
|
||||
git clone https://github.com/septag/glslcc && md glslcc\.build && pushd glslcc\.build
|
||||
if not exist glslcc (
|
||||
git clone https://github.com/septag/glslcc
|
||||
)
|
||||
|
||||
if "%1"=="debug" (
|
||||
if not exist glslcc\.debug md glslcc\.debug
|
||||
pushd glslcc\.debug
|
||||
cmake .. -B . && (make || msbuild glslcc.sln)
|
||||
popd
|
||||
xcopy /y glslcc\.debug\src\Debug\glslcc.exe
|
||||
) else (
|
||||
if not exist glslcc\.build md glslcc\.build
|
||||
pushd glslcc\.build
|
||||
cmake .. -B . -DCMAKE_BUILD_TYPE=Release && (make || msbuild glslcc.sln -m -p:Configuration=Release)
|
||||
popd
|
||||
|
||||
xcopy /y glslcc\.build\src\Release\glslcc.exe
|
||||
)
|
||||
|
|
|
@ -231,7 +231,8 @@ int main(int argc, char* argv[]) {
|
|||
return error ? fprintf(stderr, "%s\n", error), -1 : 0;
|
||||
}
|
||||
|
||||
// cl ase2ini.c -I ..\engine\split /DNDEBUG /O2 /Ox /MT
|
||||
// cl ase2ini.c -I ..\engine\split /DNDEBUG /O2 /Ox /MT /LD
|
||||
// tcc ase2ini.c -I ..\engine\split -DNDEBUG
|
||||
// cl ase2ini.c -I ..\engine\split /DNDEBUG /O2 /Ox /MT /LD
|
||||
// cl ase2ini.c -I ..\engine\split /DNDEBUG /O2 /Ox /MT
|
||||
// cc ase2ini.c -I ../engine/split -lm -O3 -oase2ini.linux
|
||||
// cc ase2ini.c -I ../engine/split -lm -O3 -oase2ini.osx
|
||||
|
|
Binary file not shown.
|
@ -16,8 +16,12 @@
|
|||
#define FREE free
|
||||
#define MALLOC malloc
|
||||
#include "3rd_base64.h"
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "3rd_stb_image.h"
|
||||
//
|
||||
#ifdef _MSC_VER
|
||||
#define strcmpi _stricmp
|
||||
#else
|
||||
#define strcmpi strcasecmp
|
||||
#endif
|
||||
|
||||
int verbose = 0;
|
||||
int need_to_bake_skin = 0;
|
||||
|
@ -37,6 +41,9 @@ int doaxis = 0; // flip bone axis from X to Y to match blender
|
|||
int dounscale = 0; // remove scaling from bind pose
|
||||
int dohips = 0; // reparent thighs to pelvis (see zo_hom_marche)
|
||||
|
||||
char *output = NULL; // output filename
|
||||
char *input = NULL; // input filename
|
||||
|
||||
char *only_one_node = NULL;
|
||||
int list_all_meshes = 0;
|
||||
int list_all_positions = 0;
|
||||
|
@ -1085,57 +1092,48 @@ void export_node(FILE *out, const struct aiScene *scene, const struct aiNode *no
|
|||
|
||||
// look for embedded textures. referenced like *1, *2, *3... where N is texture ID
|
||||
// note: mHeight can be zero, in this case texture->pcData is not RGB values but
|
||||
// compressed JPEG/PNG/etc. data. Using stb_image to decode such image in that case.
|
||||
// compressed JPEG/PNG/etc. data. Could use stb_image to decode such image in that case.
|
||||
|
||||
unsigned tex_id = ~0u;
|
||||
|
||||
if( buffer[0] ) {
|
||||
if( strchr(buffer, '*') ) {
|
||||
tex_id = atoi(buffer+1);
|
||||
} else {
|
||||
const char *fname = buffer + (buffer[0] == '+');
|
||||
|
||||
if( !strchr(buffer, '*') ) {
|
||||
for( int j = 0; j < scene->mNumTextures; ++j ) {
|
||||
struct aiTexture *tex = scene->mTextures[j];
|
||||
if( strstr(tex->mFilename.data, buffer + !isalpha(buffer[0])) ) {
|
||||
snprintf(buffer, sizeof(buffer-1), "*%d", j);
|
||||
|
||||
const char *basename = tex->mFilename.data;
|
||||
if( strrchr(basename, '/') ) basename = strrchr(basename, '/')+1;
|
||||
if( strrchr(basename,'\\') ) basename = strrchr(basename,'\\')+1;
|
||||
|
||||
if( !strcmpi(basename, fname) ) {
|
||||
tex_id = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( strchr(buffer, '*') ) {
|
||||
int tex_id = atoi(buffer+1);
|
||||
if( tex_id < scene->mNumTextures ) {
|
||||
struct aiTexture *tex = scene->mTextures[tex_id];
|
||||
struct aiTexel *data = tex->pcData;
|
||||
const char *hint = tex->achFormatHint; // "rgba8888" or "png"
|
||||
unsigned w = tex->mWidth + !tex->mWidth;
|
||||
unsigned h = tex->mHeight + !tex->mHeight;
|
||||
|
||||
// stbi_uc *decoded = 0;
|
||||
if( !tex->mHeight )
|
||||
{
|
||||
int len = (int)w;
|
||||
embedded = base64_encode(data, len); // leak
|
||||
// int x = 0, y = 0, n = 0;
|
||||
// decoded = stbi_load_from_memory((const stbi_uc *)data, len, &x, &y, &n, 4);
|
||||
// w = x; h = y; data = (struct aiTexel *)decoded;
|
||||
}
|
||||
|
||||
#if 1
|
||||
if(!embedded)
|
||||
embedded = base64_encode(data, w * h * sizeof(struct aiTexel)); // leak
|
||||
#else
|
||||
fprintf(stderr, "%dx%d (%s)\n", w,h,hint);
|
||||
char name[260]; sprintf(name, "tex_%d.%s", tex_id, hint);
|
||||
FILE *out = fopen(name, "wb");
|
||||
for(unsigned y = 0; y < h; ++y)
|
||||
for(unsigned x = 0; x < w; ++x)
|
||||
fwrite(&data[x+y*w].b, 1, 4, out);
|
||||
fclose(out);
|
||||
#endif
|
||||
if( tex_id < scene->mNumTextures ) {
|
||||
struct aiTexture *tex = scene->mTextures[tex_id];
|
||||
const char *hint = tex->achFormatHint; // "rgba8888" or "png", "bmp", etc.
|
||||
|
||||
// if( decoded ) stbi_image_free(decoded);
|
||||
if( !tex->mHeight )
|
||||
{
|
||||
embedded = base64_encode(tex->pcData, (int)tex->mWidth ); // @leak
|
||||
}
|
||||
else
|
||||
{
|
||||
embedded = base64_encode(tex->pcData, (int)(tex->mWidth * tex->mHeight * sizeof(struct aiTexel))); // @leak
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
aiGetMaterialString(material, AI_MATKEY_NAME, &str);
|
||||
fprintf(out, "material \"%s%s%s%s%s\"\n", str.data, buffer, colorbuffer, embedded ? "+b64:":"", embedded ? embedded:"");
|
||||
fprintf(out, "material \"%s%s%s%s%s\"\n", buffer[0] == '*' ? "" : str.data, buffer, colorbuffer, embedded ? "+b64:":"", embedded ? embedded:"");
|
||||
}
|
||||
|
||||
struct vb *vb = (struct vb*) malloc(mesh->mNumVertices * sizeof(*vb));
|
||||
|
@ -1348,8 +1346,6 @@ int main(int argc, char **argv)
|
|||
char *p;
|
||||
int c;
|
||||
|
||||
char *output = NULL;
|
||||
char *input = NULL;
|
||||
int onlyanim = 0;
|
||||
int onlymesh = 0;
|
||||
|
||||
|
|
Binary file not shown.
|
@ -30,9 +30,9 @@ int main(int argc, const char **argv) {
|
|||
|
||||
/*
|
||||
compiled with:
|
||||
cc -ObjC cook.c -I../engine -o cook.osx -framework Cocoa -framework IOKit -framework audiotoolbox -O3
|
||||
cc -ObjC cook.c -I../engine -o cook.osx -framework Cocoa -framework IOKit -framework audiotoolbox -framework coreaudio -O3
|
||||
cc cook.c -I../engine -o cook.linux -lm -lpthread -ldl -lX11 -O3
|
||||
tcc cook.c -I..\engine
|
||||
cl cook.c -I..\engine /openmp /Os /Ox /O2 /Oy /MT /DNDEBUG /GL /GF /Gw /arch:AVX2 /link /OPT:ICF /LTCG
|
||||
del cook.o & del cook.obj & del cook.lib & del cook.exp
|
||||
del *.o & del *.obj & del *.lib & del *.exp & del *.pdb
|
||||
*/
|
BIN
tools/glslcc.exe
BIN
tools/glslcc.exe
Binary file not shown.
|
@ -17,6 +17,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||
// - So, I increased the vector growsize & removed all deallocations to "fix" random crashes
|
||||
// - Not quite sure still, so I also removed custom allocators
|
||||
// - Also, switched string hashing to fnv1a, hoping to distribute hashmap buckets more uniformly
|
||||
// - Note: crashes behaves worse on x64. x86 seems to be more predictable.
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
@ -29,11 +30,108 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
//#define ASSERT assert
|
||||
#define ASSERT(x) do{}while(0)
|
||||
#define delete_array (0),(void) // hac
|
||||
#define ASSERT(x) do{ if(!(x)) exit(-fprintf(stderr, "assertion failed: `" #x "` %s:%d\n%s\n", __FILE__, __LINE__, callstack(+16))); } while(0) // assert(x)
|
||||
//#define ASSERT(x) do{}while(0) // hack
|
||||
#define delete_array (0),(void) // hack to minimize crashes
|
||||
//#define delete_array delete[]
|
||||
|
||||
#ifdef _WIN32 // && !defined __TINYC__
|
||||
#define SYS_MEM_REALLOC realloc
|
||||
#define __thread __declspec(thread)
|
||||
#define concat(a,b) conc4t(a,b)
|
||||
#define conc4t(a,b) a##b ///-
|
||||
#define macro(name) concat(name, __LINE__)
|
||||
#define do_once static int macro(init) = 1; for(;macro(init);macro(init) = 0)
|
||||
#include <winsock2.h> // windows.h alternative
|
||||
#include <dbghelp.h>
|
||||
#pragma comment(lib, "DbgHelp")
|
||||
#pragma comment(lib, "Kernel32")
|
||||
static int backtrace( void **addr, int maxtraces ) {
|
||||
static bool init = 0;
|
||||
do_once SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_INCLUDE_32BIT_MODULES);
|
||||
do_once init = SymInitialize(GetCurrentProcess(), NULL, TRUE);
|
||||
if(!init) return 0; // error: cannot initialize DbgHelp.lib
|
||||
|
||||
typedef USHORT (WINAPI *pFN)(__in ULONG, __in ULONG, __out PVOID*, __out_opt PULONG); // _MSC_VER
|
||||
static pFN rtlCaptureStackBackTrace = 0;
|
||||
if( !rtlCaptureStackBackTrace ) {
|
||||
rtlCaptureStackBackTrace = (pFN)GetProcAddress(LoadLibraryA("kernel32.dll"), "RtlCaptureStackBackTrace");
|
||||
}
|
||||
if( !rtlCaptureStackBackTrace ) {
|
||||
return 0;
|
||||
}
|
||||
return rtlCaptureStackBackTrace(1, maxtraces, (PVOID *)addr, (DWORD *) 0);
|
||||
}
|
||||
static char **backtrace_symbols(void *const *list,int size) {
|
||||
HANDLE process = GetCurrentProcess();
|
||||
|
||||
struct symbol_t {
|
||||
SYMBOL_INFO info;
|
||||
TCHAR symbolname[256], terminator;
|
||||
} si = { {0} };
|
||||
si.info.SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
si.info.MaxNameLen = sizeof(si.symbolname) / sizeof(TCHAR); // number of chars, not bytes
|
||||
|
||||
IMAGEHLP_LINE l64 = { 0 };
|
||||
l64.SizeOfStruct = sizeof(IMAGEHLP_LINE);
|
||||
|
||||
static __thread char **symbols = 0; //[32][64] = {0};
|
||||
if( !symbols ) {
|
||||
symbols = (char**)SYS_MEM_REALLOC(0, 128 * sizeof(char*));
|
||||
for( int i = 0; i < 128; ++i) symbols[i] = (char*)SYS_MEM_REALLOC(0, 128 * sizeof(char));
|
||||
}
|
||||
|
||||
if(size > 128) size = 128;
|
||||
for( int i = 0; i < size; ++i ) {
|
||||
|
||||
char *ptr = symbols[i];
|
||||
*ptr = '\0';
|
||||
|
||||
if (SymFromAddr(process, (DWORD64)(uintptr_t)list[i], 0, &si.info)) {
|
||||
//char undecorated[1024];
|
||||
//UnDecorateSymbolName(si.info.Name, undecorated, sizeof(undecorated)-1, UNDNAME_COMPLETE);
|
||||
char* undecorated = (char*)si.info.Name;
|
||||
ptr += snprintf(ptr, 128, "%s", undecorated);
|
||||
} else {
|
||||
ptr += snprintf(ptr, 128, "%s", "(?""?)");
|
||||
}
|
||||
|
||||
DWORD dw = 0;
|
||||
if (SymGetLineFromAddr(process, (DWORD64)(uintptr_t)list[i], &dw, &l64)) {
|
||||
ptr += snprintf(ptr, 128 - (ptr - symbols[i]), " (%s:%u)", l64.FileName, (unsigned)l64.LineNumber);
|
||||
}
|
||||
}
|
||||
|
||||
return symbols;
|
||||
}
|
||||
char *callstack( int traces ) {
|
||||
static __thread char *output = 0;
|
||||
if(!output ) output = (char*)SYS_MEM_REALLOC( 0, 128 * (64+2) );
|
||||
if( output ) output[0] = '\0';
|
||||
char *ptr = output;
|
||||
|
||||
enum { skip = 1 }; /* exclude 1 trace from stack (this function) */
|
||||
enum { maxtraces = 128 };
|
||||
|
||||
int inc = 1;
|
||||
if( traces < 0 ) traces = -traces, inc = -1;
|
||||
if( traces == 0 ) return "";
|
||||
if( traces > maxtraces ) traces = maxtraces;
|
||||
|
||||
void* stacks[maxtraces/* + 1*/]; // = { 0 };
|
||||
traces = backtrace( stacks, traces );
|
||||
char **symbols = backtrace_symbols( stacks, traces ); // @todo: optimization: map(void*,char*) cache; and retrieve only symbols not in cache
|
||||
|
||||
char demangled[1024] = "??";
|
||||
int L = 0, B = inc>0 ? skip - 1 : traces, E = inc>0 ? traces : skip - 1;
|
||||
for( int i = B; ( i += inc ) != E; ) {
|
||||
ptr += sprintf(ptr, "%03d: %#016llx %s\n", ++L, (unsigned long long)(uintptr_t)stacks[i], symbols[i]); // format gymnastics because %p is not standard when printing pointers
|
||||
}
|
||||
|
||||
return output ? output : "";
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __IQM_H__
|
||||
#define __IQM_H__
|
||||
|
@ -308,7 +406,9 @@ template <class T> struct vector : public std::vector<T>
|
|||
{
|
||||
static const int MINSIZE = 8;
|
||||
|
||||
mutable //< @r-lyeh
|
||||
T *buf;
|
||||
mutable //< @r-lyeh
|
||||
int alen, ulen;
|
||||
|
||||
vector() : buf(NULL), alen(0), ulen(0)
|
||||
|
@ -327,6 +427,9 @@ template <class T> struct vector : public std::vector<T>
|
|||
setsize(0);
|
||||
if(v.length() > alen) growbuf(v.length());
|
||||
loopv(v) add(v[i]);
|
||||
|
||||
if(ulen==alen) growbuf(ulen+1); //< @r-lyeh
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -361,8 +464,14 @@ template <class T> struct vector : public std::vector<T>
|
|||
bool empty() const { return ulen==0; }
|
||||
int capacity() const { return alen; }
|
||||
int length() const { return ulen; }
|
||||
T &operator[](int i) { ASSERT(i>=0 && i<ulen); return buf[i]; }
|
||||
const T &operator[](int i) const { ASSERT(i >= 0 && i<ulen); return buf[i]; }
|
||||
T &operator[](int i) {
|
||||
if(i<ulen) reserve(i+1); //< @r-lyeh
|
||||
//ASSERT(i>=0 && i<ulen);
|
||||
return buf[i]; }
|
||||
const T &operator[](int i) const {
|
||||
if(i<ulen) reserve(i+1); //< @r-lyeh
|
||||
//ASSERT(i >= 0 && i<ulen);
|
||||
return buf[i]; }
|
||||
|
||||
void setsize(int i) { ASSERT(i <= ulen); ulen = i; }
|
||||
|
||||
|
@ -378,6 +487,7 @@ template <class T> struct vector : public std::vector<T>
|
|||
bool inbuf(const T *e) const { return e >= buf && e < &buf[ulen]; }
|
||||
|
||||
void growbuf(int sz)
|
||||
const //< @r-lyeh
|
||||
{
|
||||
int olen = alen;
|
||||
if(!alen) alen = max(MINSIZE, sz);
|
||||
|
@ -393,6 +503,7 @@ template <class T> struct vector : public std::vector<T>
|
|||
}
|
||||
|
||||
T *reserve(int sz)
|
||||
const //< @r-lyeh
|
||||
{
|
||||
if(ulen+sz > alen) growbuf(ulen+sz);
|
||||
return &buf[ulen];
|
||||
|
@ -487,7 +598,7 @@ template <class K, class T> struct hashtable
|
|||
typedef T value;
|
||||
typedef const T const_value;
|
||||
|
||||
enum { CHUNKSIZE = 64, MAXLOADFACTOR = 75, RESIZEFACTOR = 4, MAXSIZE = 64<<20 };
|
||||
enum { CHUNKSIZE = 64, MAXLOADFACTOR = 75, RESIZERATIO = 4, MAXSIZE = 128<<20 };
|
||||
|
||||
struct chain { T data; K key; chain *next; };
|
||||
struct chainchunk { chain chains[CHUNKSIZE]; chainchunk *next; };
|
||||
|
@ -517,7 +628,12 @@ template <class K, class T> struct hashtable
|
|||
|
||||
chain *insert(const K &key, uint h)
|
||||
{
|
||||
if(size <= MAXSIZE / RESIZEFACTOR && numelems * 100 > size * MAXLOADFACTOR) { rehash(); h = hthash(key)&(size-1); }
|
||||
if(size*RESIZERATIO < MAXSIZE && float(++numelems) / size * 100.0 > MAXLOADFACTOR) { rehash(); h = hthash(key)&(size-1); }
|
||||
return insert(unused, chunks, table, key, h);
|
||||
}
|
||||
|
||||
static chain *insert(chain *&unused, chainchunk *&chunks, chain **&table, const K& key, uint h)
|
||||
{
|
||||
if(!unused)
|
||||
{
|
||||
chainchunk *chunk = new chainchunk;
|
||||
|
@ -532,7 +648,6 @@ template <class K, class T> struct hashtable
|
|||
c->key = key;
|
||||
c->next = table[h];
|
||||
table[h] = c;
|
||||
numelems++;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -612,23 +727,27 @@ template <class K, class T> struct hashtable
|
|||
|
||||
void rehash()
|
||||
{
|
||||
int oldsize = size;
|
||||
chain **oldtable = table;
|
||||
int newsize = size*RESIZERATIO;
|
||||
chain **newtable = new chain* [newsize];
|
||||
loopi(newsize) newtable[i] = NULL;
|
||||
|
||||
size *= RESIZEFACTOR;
|
||||
table = new chain*[size];
|
||||
loopi(size) table[i] = NULL;
|
||||
|
||||
loopi(oldsize) for (chain *c = oldtable[i]; c;)
|
||||
chainchunk *newchunks = NULL;
|
||||
chain *newunused = NULL;
|
||||
loopi(size) for (chain *c = table[i]; c;)
|
||||
{
|
||||
chain *p = c;
|
||||
const K& k = c->key;
|
||||
uint h = hthash(k)&(newsize-1);
|
||||
insert(newunused, newchunks, newtable, k, h)->data = c->data;
|
||||
c = c->next;
|
||||
uint h = hthash(p->key)&(size-1);
|
||||
p->next = table[h];
|
||||
table[h] = p;
|
||||
}
|
||||
|
||||
delete_array oldtable;
|
||||
delete[] table;
|
||||
deletechunks();
|
||||
|
||||
size = newsize;
|
||||
table = newtable;
|
||||
chunks = newchunks;
|
||||
unused = newunused;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2552,13 +2671,16 @@ struct filespec
|
|||
|
||||
bool parseiqe(stream *f)
|
||||
{
|
||||
enum { sizeof_tex = (8*1024) * (8*1024) * (4) }; // max cap: 8K texture, RGBA8888,
|
||||
const unsigned sizeof_buf = ceil(sizeof_tex / 3) * 4; // then, max capacity encoded as base64
|
||||
static char *buf = new char [sizeof_buf];
|
||||
|
||||
const char *curmesh = getnamekey(""), *curmaterial = getnamekey("");
|
||||
bool needmesh = true;
|
||||
int fmoffset = 0;
|
||||
char buf[512];
|
||||
if(!f->getline(buf, sizeof(buf))) return false;
|
||||
if(!f->getline(buf, sizeof_buf)) return false;
|
||||
if(!strchr(buf, '#') || strstr(buf, "# Inter-Quake Export") != strchr(buf, '#')) return false;
|
||||
while(f->getline(buf, sizeof(buf)))
|
||||
while(f->getline(buf, sizeof_buf))
|
||||
{
|
||||
char *c = buf;
|
||||
while(isspace(*c)) ++c;
|
||||
|
@ -3339,3 +3461,6 @@ int main(int argc, char **argv)
|
|||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// cl iqe2iqm.cpp /DDEBUG /MT /Zi /fsanitize=address
|
||||
// cl iqe2iqm.cpp /O2 /Oy /MT /DNDEBUG
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue