From 317dad434788daa8e9c1af9b229ad7b92196e019 Mon Sep 17 00:00:00 2001 From: XProger Date: Tue, 6 Mar 2018 09:44:37 +0300 Subject: [PATCH] #15 mutex & cache code refactoring; #23 colored fog closes #92 --- src/cache.h | 5 +- src/core.h | 11 +++ src/gameflow.h | 35 +++++++ src/lara.h | 3 + src/level.h | 19 +++- .../android/app/src/main/cpp/main.cpp | 98 ------------------ src/platform/nix/main.cpp | 99 +------------------ src/platform/osx/main.cpp | 97 +----------------- src/platform/psp/main.cpp | 50 ---------- src/platform/rpi/main.cpp | 99 +------------------ src/platform/web/main.cpp | 51 +--------- src/platform/win/main.cpp | 48 --------- src/shader.h | 1 + src/shaders/shader.glsl | 5 +- src/utils.h | 99 +++++++++++++++++++ 15 files changed, 173 insertions(+), 547 deletions(-) diff --git a/src/cache.h b/src/cache.h index 43e69e7..80f999b 100644 --- a/src/cache.h +++ b/src/cache.h @@ -10,7 +10,6 @@ #define SHADOW_TEX_SIZE 1024 -#define FOG_DIST (18 * 1024) #define WATER_FOG_DIST (6 * 1024) //#define WATER_USE_GRID #define UNDERWATER_COLOR "#define UNDERWATER_COLOR vec3(0.6, 0.9, 0.9)\n" @@ -76,7 +75,6 @@ struct ShaderCache { compile(Core::passCompose, Shader::ENTITY, fx | FX_NONE); compile(Core::passCompose, Shader::ENTITY, fx | FX_UNDERWATER); - compile(Core::passCompose, Shader::ENTITY, fx | FX_UNDERWATER | FX_ALPHA_TEST | FX_CLIP_PLANE); compile(Core::passCompose, Shader::ENTITY, fx | FX_UNDERWATER | FX_ALPHA_TEST); compile(Core::passCompose, Shader::ENTITY, fx | FX_ALPHA_TEST); compile(Core::passCompose, Shader::SPRITE, fx | FX_ALPHA_TEST); @@ -146,7 +144,7 @@ struct ShaderCache { src = SHADER; typ = typeNames[type]; - sprintf(def, "%s#define PASS_%s\n#define TYPE_%s\n#define MAX_LIGHTS %d\n#define MAX_RANGES %d\n#define MAX_OFFSETS %d\n#define MAX_CONTACTS %d\n#define FOG_DIST (1.0/%d.0)\n#define WATER_FOG_DIST (1.0/%d.0)\n#define SHADOW_TEX_SIZE %d.0\n", ext, passNames[pass], typ, MAX_LIGHTS, MAX_ANIM_TEX_RANGES, MAX_ANIM_TEX_OFFSETS, MAX_CONTACTS, FOG_DIST, WATER_FOG_DIST, SHADOW_TEX_SIZE); + sprintf(def, "%s#define PASS_%s\n#define TYPE_%s\n#define MAX_LIGHTS %d\n#define MAX_RANGES %d\n#define MAX_OFFSETS %d\n#define MAX_CONTACTS %d\n#define WATER_FOG_DIST (1.0/%d.0)\n#define SHADOW_TEX_SIZE %d.0\n", ext, passNames[pass], typ, MAX_LIGHTS, MAX_ANIM_TEX_RANGES, MAX_ANIM_TEX_OFFSETS, MAX_CONTACTS, WATER_FOG_DIST, SHADOW_TEX_SIZE); #ifdef MERGE_SPRITES if (type == Shader::SPRITE) strcat(def, "#define ALIGN_SPRITES 1\n"); @@ -216,6 +214,7 @@ struct ShaderCache { shader->setParam(uLightProj, Core::mLightProj); shader->setParam(uViewPos, Core::viewPos); shader->setParam(uParam, Core::params); + shader->setParam(uFogParams, Core::fogParams); #else Core::setAlphaTest((fx & FX_ALPHA_TEST) != 0); #endif diff --git a/src/core.h b/src/core.h index 0109611..8777b96 100644 --- a/src/core.h +++ b/src/core.h @@ -6,10 +6,16 @@ #endif #include + +#define OS_FILEIO_CACHE +#define OS_PTHREAD_MT + #ifdef WIN32 #include #include #include + + #undef OS_PTHREAD_MT #elif ANDROID #define MOBILE #include @@ -143,6 +149,8 @@ #define glGetProgramBinary(...) #define glProgramBinary(...) + + #undef OS_FILEIO_CACHE #elif _PSP #include #include @@ -151,6 +159,8 @@ #define TEX_SWIZZLE //#define EDRAM_MESH #define EDRAM_TEX + + #undef OS_PTHREAD_MT #endif #ifdef USE_INFLATE @@ -614,6 +624,7 @@ namespace Core { vec4 lightPos[MAX_LIGHTS]; vec4 lightColor[MAX_LIGHTS]; vec4 params; + vec4 fogParams; vec4 contacts[MAX_CONTACTS]; Texture *whiteTex; diff --git a/src/gameflow.h b/src/gameflow.h index f3f3ae6..95d2de4 100644 --- a/src/gameflow.h +++ b/src/gameflow.h @@ -827,6 +827,41 @@ namespace TR { return NULL; } + + #define FOG_DIST (1.0f / (18 * 1024)) + #define FOG_BLACK vec4(0.0f, 0.0f, 0.0f, FOG_DIST) + #define FOG_SANDY vec4(0.2f, 0.1f, 0.0f, FOG_DIST) + #define FOG_GREEN vec4(0.0f, 0.1f, 0.0f, FOG_DIST) + #define FOG_RED vec4(0.2f, 0.0f, 0.0f, FOG_DIST) + + vec4 getFogParams(LevelID id) { + switch (id) { + case LVL_TR1_1 : + case LVL_TR1_2 : + case LVL_TR1_3A : + case LVL_TR1_3B : + case LVL_TR1_CUT_1 : return FOG_BLACK; + case LVL_TR1_4 : + case LVL_TR1_5 : + case LVL_TR1_6 : return FOG_SANDY; + case LVL_TR1_7A : + case LVL_TR1_7B : + case LVL_TR1_CUT_2 : return FOG_GREEN; + case LVL_TR1_8A : + case LVL_TR1_8B : + case LVL_TR1_8C : return FOG_SANDY; + case LVL_TR1_10A : return FOG_BLACK; + case LVL_TR1_CUT_3 : + case LVL_TR1_10B : + case LVL_TR1_CUT_4 : + case LVL_TR1_10C : return FOG_RED; + case LVL_TR1_EGYPT : + case LVL_TR1_CAT : + case LVL_TR1_END : + case LVL_TR1_END2 : return FOG_SANDY; + } + return FOG_BLACK; + } } #undef CHECK_FILE diff --git a/src/lara.h b/src/lara.h index 8ffe252..5ba1d7f 100644 --- a/src/lara.h +++ b/src/lara.h @@ -2600,6 +2600,9 @@ struct Lara : Character { case TR::LVL_TR1_6 : reset(73, vec3(73372, 122, 51687), PI * 0.5f); // level 6 (midas hand) break; + case TR::LVL_TR1_7A : + reset(99, vec3(45562, -3328, 63366), 225 * DEG2RAD); // level 7a (flipmap) + break; case TR::LVL_TR1_7B : reset(77, vec3(36943, -4096, 62821), 270 * DEG2RAD); // level 7b (heavy trigger) break; diff --git a/src/level.h b/src/level.h index 8976610..3a74056 100644 --- a/src/level.h +++ b/src/level.h @@ -612,6 +612,8 @@ struct Level : IGame { memset(players, 0, sizeof(players)); player = NULL; + Core::fogParams = TR::getFogParams(level.id); + initTextures(); mesh = new MeshBuilder(level, atlas); initOverrides(); @@ -1815,10 +1817,19 @@ struct Level : IGame { prepareRooms(roomsList, roomsCount); updateLighting(); - for (int transp = 0; transp < 3; transp++) { - renderRooms(roomsList, roomsCount, transp); - renderEntities(transp); - } + + // opaque pass + renderRooms(roomsList, roomsCount, 0); + renderEntities(0); + // alpha blending pass + renderRooms(roomsList, roomsCount, 1); + renderEntities(1); + // additive blending pass + vec4 oldFog = Core::fogParams; + Core::fogParams = FOG_BLACK; // don't apply fog for additive + renderRooms(roomsList, roomsCount, 2); + renderEntities(2); + Core::fogParams = oldFog; Core::setBlending(bmNone); if (water && waterCache && waterCache->visible) { diff --git a/src/platform/android/app/src/main/cpp/main.cpp b/src/platform/android/app/src/main/cpp/main.cpp index af97551..6ce1b75 100644 --- a/src/platform/android/app/src/main/cpp/main.cpp +++ b/src/platform/android/app/src/main/cpp/main.cpp @@ -11,54 +11,6 @@ JNIEXPORT return_type JNICALL \ Java_org_xproger_openlara_Wrapper_##method_name -// multi-threading -void* osMutexInit() { - pthread_mutex_t *mutex = new pthread_mutex_t(); - pthread_mutex_init(mutex, NULL); - return mutex; -} - -void osMutexFree(void *obj) { - pthread_mutex_destroy((pthread_mutex_t*)obj); - delete (pthread_mutex_t*)obj; -} - -void osMutexLock(void *obj) { - pthread_mutex_lock((pthread_mutex_t*)obj); -} - -void osMutexUnlock(void *obj) { - pthread_mutex_unlock((pthread_mutex_t*)obj); -} - -void* osRWLockInit() { - pthread_rwlock_t *lock = new pthread_rwlock_t(); - pthread_rwlock_init(lock, NULL); - return lock; -} - -void osRWLockFree(void *obj) { - pthread_rwlock_destroy((pthread_rwlock_t*)obj); - delete (pthread_rwlock_t*)obj; -} - -void osRWLockRead(void *obj) { - pthread_rwlock_rdlock((pthread_rwlock_t*)obj); -} - -void osRWUnlockRead(void *obj) { - pthread_rwlock_unlock((pthread_rwlock_t*)obj); -} - -void osRWLockWrite(void *obj) { - pthread_rwlock_wrlock((pthread_rwlock_t*)obj); -} - -void osRWUnlockWrite(void *obj) { - pthread_rwlock_unlock((pthread_rwlock_t*)obj); -} - - // timing time_t startTime; @@ -68,7 +20,6 @@ int osGetTime() { return int((t.tv_sec - startTime) * 1000 + t.tv_usec / 1000); } - // joystick bool osJoyReady(int index) { return index == 0; @@ -78,55 +29,6 @@ void osJoyVibrate(int index, float L, float R) { // } - -// storage -void osCacheWrite(Stream *stream) { - char path[255]; - strcpy(path, Stream::cacheDir); - strcat(path, stream->name); - FILE *f = fopen(path, "wb"); - if (f) { - fwrite(stream->data, 1, stream->size, f); - fclose(f); - if (stream->callback) - stream->callback(new Stream(stream->name, NULL, 0), stream->userData); - } else - if (stream->callback) - stream->callback(NULL, stream->userData); - - delete stream; -} - -void osCacheRead(Stream *stream) { - char path[255]; - strcpy(path, Stream::cacheDir); - strcat(path, stream->name); - FILE *f = fopen(path, "rb"); - if (f) { - fseek(f, 0, SEEK_END); - int size = ftell(f); - fseek(f, 0, SEEK_SET); - char *data = new char[size]; - fread(data, 1, size, f); - fclose(f); - if (stream->callback) - stream->callback(new Stream(stream->name, data, size), stream->userData); - delete[] data; - } else - if (stream->callback) - stream->callback(NULL, stream->userData); - delete stream; -} - -void osSaveGame(Stream *stream) { - return osCacheWrite(stream); -} - -void osLoadGame(Stream *stream) { - return osCacheRead(stream); -} - - extern "C" { char Stream::cacheDir[255]; diff --git a/src/platform/nix/main.cpp b/src/platform/nix/main.cpp index c76fa91..e5362bf 100644 --- a/src/platform/nix/main.cpp +++ b/src/platform/nix/main.cpp @@ -15,54 +15,6 @@ #define WND_TITLE "OpenLara" -// multi-threading -void* osMutexInit() { - pthread_mutex_t *mutex = new pthread_mutex_t(); - pthread_mutex_init(mutex, NULL); - return mutex; -} - -void osMutexFree(void *obj) { - pthread_mutex_destroy((pthread_mutex_t*)obj); - delete (pthread_mutex_t*)obj; -} - -void osMutexLock(void *obj) { - pthread_mutex_lock((pthread_mutex_t*)obj); -} - -void osMutexUnlock(void *obj) { - pthread_mutex_unlock((pthread_mutex_t*)obj); -} - -void* osRWLockInit() { - pthread_rwlock_t *lock = new pthread_rwlock_t(); - pthread_rwlock_init(lock, NULL); - return lock; -} - -void osRWLockFree(void *obj) { - pthread_rwlock_destroy((pthread_rwlock_t*)obj); - delete (pthread_rwlock_t*)obj; -} - -void osRWLockRead(void *obj) { - pthread_rwlock_rdlock((pthread_rwlock_t*)obj); -} - -void osRWUnlockRead(void *obj) { - pthread_rwlock_unlock((pthread_rwlock_t*)obj); -} - -void osRWLockWrite(void *obj) { - pthread_rwlock_wrlock((pthread_rwlock_t*)obj); -} - -void osRWUnlockWrite(void *obj) { - pthread_rwlock_unlock((pthread_rwlock_t*)obj); -} - - // timing unsigned int startTime; @@ -72,56 +24,7 @@ int osGetTime() { return int((t.tv_sec - startTime) * 1000 + t.tv_usec / 1000); } - -// storage -void osCacheWrite(Stream *stream) { - char path[255]; - strcpy(path, Stream::cacheDir); - strcat(path, stream->name); - FILE *f = fopen(path, "wb"); - if (f) { - fwrite(stream->data, 1, stream->size, f); - fclose(f); - if (stream->callback) - stream->callback(new Stream(stream->name, NULL, 0), stream->userData); - } else - if (stream->callback) - stream->callback(NULL, stream->userData); - - delete stream; -} - -void osCacheRead(Stream *stream) { - char path[255]; - strcpy(path, Stream::cacheDir); - strcat(path, stream->name); - FILE *f = fopen(path, "rb"); - if (f) { - fseek(f, 0, SEEK_END); - int size = ftell(f); - fseek(f, 0, SEEK_SET); - char *data = new char[size]; - fread(data, 1, size, f); - fclose(f); - if (stream->callback) - stream->callback(new Stream(stream->name, data, size), stream->userData); - delete[] data; - } else - if (stream->callback) - stream->callback(NULL, stream->userData); - delete stream; -} - -void osSaveGame(Stream *stream) { - return osCacheWrite(stream); -} - -void osLoadGame(Stream *stream) { - return osCacheRead(stream); -} - - -// Sound +// sound #define SND_FRAME_SIZE 4 #define SND_DATA_SIZE (1024 * SND_FRAME_SIZE) diff --git a/src/platform/osx/main.cpp b/src/platform/osx/main.cpp index 57ab7ab..17dcd49 100644 --- a/src/platform/osx/main.cpp +++ b/src/platform/osx/main.cpp @@ -4,54 +4,7 @@ WindowRef window; AGLContext context; -// multi-threading -void* osMutexInit() { - pthread_mutex_t *mutex = new pthread_mutex_t(); - pthread_mutex_init(mutex, NULL); - return mutex; -} - -void osMutexFree(void *obj) { - pthread_mutex_destroy((pthread_mutex_t*)obj); - delete (pthread_mutex_t*)obj; -} - -void osMutexLock(void *obj) { - pthread_mutex_lock((pthread_mutex_t*)obj); -} - -void osMutexUnlock(void *obj) { - pthread_mutex_unlock((pthread_mutex_t*)obj); -} - -void* osRWLockInit() { - pthread_rwlock_t *lock = new pthread_rwlock_t(); - pthread_rwlock_init(lock, NULL); - return lock; -} - -void osRWLockFree(void *obj) { - pthread_rwlock_destroy((pthread_rwlock_t*)obj); - delete (pthread_rwlock_t*)obj; -} - -void osRWLockRead(void *obj) { - pthread_rwlock_rdlock((pthread_rwlock_t*)obj); -} - -void osRWUnlockRead(void *obj) { - pthread_rwlock_unlock((pthread_rwlock_t*)obj); -} - -void osRWLockWrite(void *obj) { - pthread_rwlock_wrlock((pthread_rwlock_t*)obj); -} - -void osRWUnlockWrite(void *obj) { - pthread_rwlock_unlock((pthread_rwlock_t*)obj); -} - -// Sound +// sound #define SND_SIZE 8192 static AudioQueueRef audioQueue; @@ -193,7 +146,6 @@ OSStatus eventHandler(EventHandlerCallRef handler, EventRef event, void* userDat return CallNextEventHandler(handler, event); } - // timing int osGetTime() { UInt64 t; @@ -201,53 +153,6 @@ int osGetTime() { return int(t / 1000); } -// storage -void osCacheWrite(Stream *stream) { - char path[255]; - strcpy(path, Stream::cacheDir); - strcat(path, stream->name); - FILE *f = fopen(path, "wb"); - if (f) { - fwrite(stream->data, 1, stream->size, f); - fclose(f); - if (stream->callback) - stream->callback(new Stream(stream->name, NULL, 0), stream->userData); - } else - if (stream->callback) - stream->callback(NULL, stream->userData); - - delete stream; -} - -void osCacheRead(Stream *stream) { - char path[255]; - strcpy(path, Stream::cacheDir); - strcat(path, stream->name); - FILE *f = fopen(path, "rb"); - if (f) { - fseek(f, 0, SEEK_END); - int size = ftell(f); - fseek(f, 0, SEEK_SET); - char *data = new char[size]; - fread(data, 1, size, f); - fclose(f); - if (stream->callback) - stream->callback(new Stream(stream->name, data, size), stream->userData); - delete[] data; - } else - if (stream->callback) - stream->callback(NULL, stream->userData); - delete stream; -} - -void osSaveGame(Stream *stream) { - return osCacheWrite(stream); -} - -void osLoadGame(Stream *stream) { - return osCacheRead(stream); -} - char Stream::contentDir[255]; char Stream::cacheDir[255]; diff --git a/src/platform/psp/main.cpp b/src/platform/psp/main.cpp index eb3be03..352bb6b 100644 --- a/src/platform/psp/main.cpp +++ b/src/platform/psp/main.cpp @@ -83,7 +83,6 @@ void osRWUnlockWrite(void *obj) { osMutexUnlock(obj); } - // timing int osStartTime = 0; int osTimerFreq; @@ -94,55 +93,6 @@ int osGetTime() { return int(time * 1000 / osTimerFreq - osStartTime); } - -// storage -void osCacheWrite(Stream *stream) { - char path[255]; - strcpy(path, Stream::cacheDir); - strcat(path, stream->name); - FILE *f = fopen(path, "wb"); - if (f) { - fwrite(stream->data, 1, stream->size, f); - fclose(f); - if (stream->callback) - stream->callback(new Stream(stream->name, NULL, 0), stream->userData); - } else - if (stream->callback) - stream->callback(NULL, stream->userData); - - delete stream; -} - -void osCacheRead(Stream *stream) { - char path[255]; - strcpy(path, Stream::cacheDir); - strcat(path, stream->name); - FILE *f = fopen(path, "rb"); - if (f) { - fseek(f, 0, SEEK_END); - int size = ftell(f); - fseek(f, 0, SEEK_SET); - char *data = new char[size]; - fread(data, 1, size, f); - fclose(f); - if (stream->callback) - stream->callback(new Stream(stream->name, data, size), stream->userData); - delete[] data; - } else - if (stream->callback) - stream->callback(NULL, stream->userData); - delete stream; -} - -void osSaveGame(Stream *stream) { - return osCacheWrite(stream); -} - -void osLoadGame(Stream *stream) { - return osCacheRead(stream); -} - - // input bool osJoyReady(int index) { return index == 0; diff --git a/src/platform/rpi/main.cpp b/src/platform/rpi/main.cpp index 082b7db..4752b21 100644 --- a/src/platform/rpi/main.cpp +++ b/src/platform/rpi/main.cpp @@ -15,54 +15,6 @@ #define WND_TITLE "OpenLara" -// multi-threading -void* osMutexInit() { - pthread_mutex_t *mutex = new pthread_mutex_t(); - pthread_mutex_init(mutex, NULL); - return mutex; -} - -void osMutexFree(void *obj) { - pthread_mutex_destroy((pthread_mutex_t*)obj); - delete (pthread_mutex_t*)obj; -} - -void osMutexLock(void *obj) { - pthread_mutex_lock((pthread_mutex_t*)obj); -} - -void osMutexUnlock(void *obj) { - pthread_mutex_unlock((pthread_mutex_t*)obj); -} - -void* osRWLockInit() { - pthread_rwlock_t *lock = new pthread_rwlock_t(); - pthread_rwlock_init(lock, NULL); - return lock; -} - -void osRWLockFree(void *obj) { - pthread_rwlock_destroy((pthread_rwlock_t*)obj); - delete (pthread_rwlock_t*)obj; -} - -void osRWLockRead(void *obj) { - pthread_rwlock_rdlock((pthread_rwlock_t*)obj); -} - -void osRWUnlockRead(void *obj) { - pthread_rwlock_unlock((pthread_rwlock_t*)obj); -} - -void osRWLockWrite(void *obj) { - pthread_rwlock_wrlock((pthread_rwlock_t*)obj); -} - -void osRWUnlockWrite(void *obj) { - pthread_rwlock_unlock((pthread_rwlock_t*)obj); -} - - // timing unsigned int startTime; @@ -72,56 +24,7 @@ int osGetTime() { return int((t.tv_sec - startTime) * 1000 + t.tv_usec / 1000); } - -// storage -void osCacheWrite(Stream *stream) { - char path[255]; - strcpy(path, Stream::cacheDir); - strcat(path, stream->name); - FILE *f = fopen(path, "wb"); - if (f) { - fwrite(stream->data, 1, stream->size, f); - fclose(f); - if (stream->callback) - stream->callback(new Stream(stream->name, NULL, 0), stream->userData); - } else - if (stream->callback) - stream->callback(NULL, stream->userData); - - delete stream; -} - -void osCacheRead(Stream *stream) { - char path[255]; - strcpy(path, Stream::cacheDir); - strcat(path, stream->name); - FILE *f = fopen(path, "rb"); - if (f) { - fseek(f, 0, SEEK_END); - int size = ftell(f); - fseek(f, 0, SEEK_SET); - char *data = new char[size]; - fread(data, 1, size, f); - fclose(f); - if (stream->callback) - stream->callback(new Stream(stream->name, data, size), stream->userData); - delete[] data; - } else - if (stream->callback) - stream->callback(NULL, stream->userData); - delete stream; -} - -void osSaveGame(Stream *stream) { - return osCacheWrite(stream); -} - -void osLoadGame(Stream *stream) { - return osCacheRead(stream); -} - - -// Sound +// sound snd_pcm_uframes_t SND_FRAMES = 512; snd_pcm_t *sndOut; Sound::Frame *sndData; diff --git a/src/platform/web/main.cpp b/src/platform/web/main.cpp index ab31568..0dbcd98 100644 --- a/src/platform/web/main.cpp +++ b/src/platform/web/main.cpp @@ -10,61 +10,12 @@ EGLDisplay display; EGLSurface surface; EGLContext context; - -// multi-threading -void* osMutexInit() { - pthread_mutex_t *mutex = new pthread_mutex_t(); - pthread_mutex_init(mutex, NULL); - return mutex; -} - -void osMutexFree(void *obj) { - pthread_mutex_destroy((pthread_mutex_t*)obj); - delete (pthread_mutex_t*)obj; -} - -void osMutexLock(void *obj) { - pthread_mutex_lock((pthread_mutex_t*)obj); -} - -void osMutexUnlock(void *obj) { - pthread_mutex_unlock((pthread_mutex_t*)obj); -} - -void* osRWLockInit() { - pthread_rwlock_t *lock = new pthread_rwlock_t(); - pthread_rwlock_init(lock, NULL); - return lock; -} - -void osRWLockFree(void *obj) { - pthread_rwlock_destroy((pthread_rwlock_t*)obj); - delete (pthread_rwlock_t*)obj; -} - -void osRWLockRead(void *obj) { - pthread_rwlock_rdlock((pthread_rwlock_t*)obj); -} - -void osRWUnlockRead(void *obj) { - pthread_rwlock_unlock((pthread_rwlock_t*)obj); -} - -void osRWLockWrite(void *obj) { - pthread_rwlock_wrlock((pthread_rwlock_t*)obj); -} - -void osRWUnlockWrite(void *obj) { - pthread_rwlock_unlock((pthread_rwlock_t*)obj); -} - - // timing int osGetTime() { return (int)emscripten_get_now(); } -// cache & data +// storage and data downloading const char *IDB = "db"; void onError(void *arg) { diff --git a/src/platform/win/main.cpp b/src/platform/win/main.cpp index caf879c..0a3be57 100644 --- a/src/platform/win/main.cpp +++ b/src/platform/win/main.cpp @@ -112,54 +112,6 @@ int osGetTime() { #endif } - -// storage -void osCacheWrite(Stream *stream) { - char path[255]; - strcpy(path, Stream::cacheDir); - strcat(path, stream->name); - FILE *f = fopen(path, "wb"); - if (f) { - fwrite(stream->data, 1, stream->size, f); - fclose(f); - if (stream->callback) - stream->callback(new Stream(stream->name, NULL, 0), stream->userData); - } else - if (stream->callback) - stream->callback(NULL, stream->userData); - - delete stream; -} - -void osCacheRead(Stream *stream) { - char path[255]; - strcpy(path, Stream::cacheDir); - strcat(path, stream->name); - FILE *f = fopen(path, "rb"); - if (f) { - fseek(f, 0, SEEK_END); - int size = ftell(f); - fseek(f, 0, SEEK_SET); - char *data = new char[size]; - fread(data, 1, size, f); - fclose(f); - if (stream->callback) - stream->callback(new Stream(stream->name, data, size), stream->userData); - delete[] data; - } else - if (stream->callback) - stream->callback(NULL, stream->userData); - delete stream; -} - -void osSaveGame(Stream *stream) { - return osCacheWrite(stream); -} - -void osLoadGame(Stream *stream) { - return osCacheRead(stream); -} - // common input functions InputKey keyToInputKey(int code) { static const int codes[] = { diff --git a/src/shader.h b/src/shader.h index eaf2acb..296ecb8 100644 --- a/src/shader.h +++ b/src/shader.h @@ -26,6 +26,7 @@ E( uLightProj ) \ E( uMaterial ) \ E( uAmbient ) \ + E( uFogParams ) \ E( uViewPos ) \ E( uLightPos ) \ E( uLightColor ) \ diff --git a/src/shaders/shader.glsl b/src/shaders/shader.glsl index f03a2a0..7a15025 100644 --- a/src/shaders/shader.glsl +++ b/src/shaders/shader.glsl @@ -21,6 +21,7 @@ uniform vec3 uViewPos; uniform vec4 uParam; // x - time, y - water height, z - clip plane sign, w - clip plane height uniform vec4 uLightPos[MAX_LIGHTS]; uniform vec4 uLightColor[MAX_LIGHTS]; // xyz - color, w - radius * intensity +uniform vec4 uFogParams; uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha @@ -100,7 +101,7 @@ uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha #endif #ifndef PASS_SHADOW - vViewVec = vec4((uViewPos - coord.xyz) * FOG_DIST, coord.y); + vViewVec = vec4((uViewPos - coord.xyz) * uFogParams.w, coord.y); #endif #ifdef PASS_AMBIENT @@ -471,7 +472,7 @@ uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha #ifdef UNDERWATER color.xyz = mix(UNDERWATER_COLOR * 0.2, color.xyz, vLightVec.w); #else - color.xyz = mix(vec3(0.0), color.xyz, vLightVec.w); + color.xyz = mix(uFogParams.xyz, color.xyz, vLightVec.w); #endif #endif /* catsuit test diff --git a/src/utils.h b/src/utils.h index 37e0938..4a58d43 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1299,6 +1299,105 @@ struct Stream { }; +#ifdef OS_FILEIO_CACHE +void osCacheWrite(Stream *stream) { + char path[255]; + strcpy(path, Stream::cacheDir); + strcat(path, stream->name); + FILE *f = fopen(path, "wb"); + if (f) { + fwrite(stream->data, 1, stream->size, f); + fclose(f); + if (stream->callback) + stream->callback(new Stream(stream->name, NULL, 0), stream->userData); + } else + if (stream->callback) + stream->callback(NULL, stream->userData); + + delete stream; +} + +void osCacheRead(Stream *stream) { + char path[255]; + strcpy(path, Stream::cacheDir); + strcat(path, stream->name); + FILE *f = fopen(path, "rb"); + if (f) { + fseek(f, 0, SEEK_END); + int size = ftell(f); + fseek(f, 0, SEEK_SET); + char *data = new char[size]; + fread(data, 1, size, f); + fclose(f); + if (stream->callback) + stream->callback(new Stream(stream->name, data, size), stream->userData); + delete[] data; + } else + if (stream->callback) + stream->callback(NULL, stream->userData); + delete stream; +} + +void osSaveGame(Stream *stream) { + return osCacheWrite(stream); +} + +void osLoadGame(Stream *stream) { + return osCacheRead(stream); +} +#endif + + +#ifdef OS_PTHREAD_MT +// multi-threading +void* osMutexInit() { + pthread_mutex_t *mutex = new pthread_mutex_t(); + pthread_mutex_init(mutex, NULL); + return mutex; +} + +void osMutexFree(void *obj) { + pthread_mutex_destroy((pthread_mutex_t*)obj); + delete (pthread_mutex_t*)obj; +} + +void osMutexLock(void *obj) { + pthread_mutex_lock((pthread_mutex_t*)obj); +} + +void osMutexUnlock(void *obj) { + pthread_mutex_unlock((pthread_mutex_t*)obj); +} + +void* osRWLockInit() { + pthread_rwlock_t *lock = new pthread_rwlock_t(); + pthread_rwlock_init(lock, NULL); + return lock; +} + +void osRWLockFree(void *obj) { + pthread_rwlock_destroy((pthread_rwlock_t*)obj); + delete (pthread_rwlock_t*)obj; +} + +void osRWLockRead(void *obj) { + pthread_rwlock_rdlock((pthread_rwlock_t*)obj); +} + +void osRWUnlockRead(void *obj) { + pthread_rwlock_unlock((pthread_rwlock_t*)obj); +} + +void osRWLockWrite(void *obj) { + pthread_rwlock_wrlock((pthread_rwlock_t*)obj); +} + +void osRWUnlockWrite(void *obj) { + pthread_rwlock_unlock((pthread_rwlock_t*)obj); +} +#endif + + struct BitStream { uint8 *data; uint8 *end;