diff --git a/src/dusk/animation/easing.c b/src/dusk/animation/easing.c index cddc0661..19cbf12a 100644 --- a/src/dusk/animation/easing.c +++ b/src/dusk/animation/easing.c @@ -5,7 +5,7 @@ #include "easing.h" #include "assert/assert.h" -#include +#include "util/math.h" const easingfn_t EASING_FUNCTIONS[EASING_COUNT] = { easingLinear, @@ -36,15 +36,15 @@ float_t easingLinear(const float_t t) { } float_t easingInSine(const float_t t) { - return 1.0f - cosf(t * EASING_PI * 0.5f); + return 1.0f - cosf(t * MATH_PI * 0.5f); } float_t easingOutSine(const float_t t) { - return sinf(t * EASING_PI * 0.5f); + return sinf(t * MATH_PI * 0.5f); } float_t easingInOutSine(const float_t t) { - return -(cosf(EASING_PI * t) - 1.0f) * 0.5f; + return -(cosf(MATH_PI * t) - 1.0f) * 0.5f; } float_t easingInQuad(const float_t t) { diff --git a/src/dusk/assert/assert.c b/src/dusk/assert/assert.c index 52de7d90..cdbc902a 100644 --- a/src/dusk/assert/assert.c +++ b/src/dusk/assert/assert.c @@ -9,13 +9,16 @@ #include "log/log.h" #include "util/string.h" #include "util/memory.h" + #ifdef DUSK_THREAD_PTHREAD - #include "thread/thread.h" + pthread_t ASSERT_MAIN_THREAD_ID = 0; #endif #ifndef DUSK_ASSERTIONS_FAKED void assertInit(void) { - assertMainThreadInit(); + #ifdef DUSK_THREAD_PTHREAD + ASSERT_MAIN_THREAD_ID = pthread_self(); + #endif } #ifdef DUSK_TEST_ASSERT @@ -140,25 +143,28 @@ assertTrueImpl(file, line, stringCompare(a, b) == 0, message); } - #ifdef DUSK_THREAD_PTHREAD - void assertMainThreadInit(void) { - THREAD_MAIN_THREAD_ID = pthread_self(); - } + void assertIsMainThreadImpl( + const char *file, + const int32_t line, + const char *message + ) { + #ifdef DUSK_THREAD_PTHREAD + assertTrueImpl( + file, line, pthread_self() == ASSERT_MAIN_THREAD_ID, message + ); + #endif + } - void assertIsMainThreadImpl( - const char *file, - const int32_t line, - const char *message - ) { - assertTrueImpl(file, line, pthread_self() == THREAD_MAIN_THREAD_ID, message); - } + void assertNotMainThreadImpl( + const char *file, + const int32_t line, + const char *message + ) { + #ifdef DUSK_THREAD_PTHREAD + assertTrueImpl( + file, line, pthread_self() != ASSERT_MAIN_THREAD_ID, message + ); + #endif + } +#endif - void assertNotMainThreadImpl( - const char *file, - const int32_t line, - const char *message - ) { - assertTrueImpl(file, line, pthread_self() != THREAD_MAIN_THREAD_ID, message); - } - #endif -#endif \ No newline at end of file diff --git a/src/dusk/assert/assert.h b/src/dusk/assert/assert.h index 1a0f3c57..757292f1 100644 --- a/src/dusk/assert/assert.h +++ b/src/dusk/assert/assert.h @@ -16,6 +16,11 @@ #endif #endif +#ifdef DUSK_THREAD_PTHREAD + #include "thread/thread.h" + extern pthread_t ASSERT_MAIN_THREAD_ID; +#endif + #ifndef DUSK_ASSERTIONS_FAKED /** * Initializes the assert system. Must be the very first call in engine @@ -23,51 +28,6 @@ */ void assertInit(void); - /** - * Records the calling thread as the main (game) thread. Call once, early - * in engine startup, before any assertIsMainThread / assertNotMainThread - * checks are made. - */ - #ifdef DUSK_THREAD_PTHREAD - void assertMainThreadInit(void); - #else - #define assertMainThreadInit() ((void)0) - #endif - - /** - * Asserts that the current thread is the main thread. - * - * @param message Message to throw against assertion failure. - */ - #ifdef DUSK_THREAD_PTHREAD - void assertIsMainThreadImpl( - const char *file, - const int32_t line, - const char *message - ); - #define assertIsMainThread(message) \ - assertIsMainThreadImpl(__FILE__, __LINE__, message) - #else - #define assertIsMainThread(message) ((void)0) - #endif - - /** - * Asserts that the current thread is NOT the main thread. - * - * @param message Message to throw against assertion failure. - */ - #ifdef DUSK_THREAD_PTHREAD - void assertNotMainThreadImpl( - const char *file, - const int32_t line, - const char *message - ); - #define assertNotMainThread(message) \ - assertNotMainThreadImpl(__FILE__, __LINE__, message) - #else - #define assertNotMainThread(message) ((void)0) - #endif - /** * Assert a given value to be true. * @@ -172,6 +132,28 @@ const char *message ); + /** + * Asserts that the current thread is the main thread. + * + * @param message Message to throw against assertion failure. + */ + void assertIsMainThreadImpl( + const char *file, + const int32_t line, + const char *message + ); + + /** + * Asserts that the current thread is NOT the main thread. + * + * @param message Message to throw against assertion failure. + */ + void assertNotMainThreadImpl( + const char *file, + const int32_t line, + const char *message + ); + /** * Asserts a given value to be true. * @@ -256,6 +238,22 @@ #define assertStringEqual(a, b, message) \ assertStringEqualImpl(__FILE__, __LINE__, a, b, message) + /** + * Asserts that the current thread is the main thread. + * + * @param message Message to throw against assertion failure. + */ + #define assertIsMainThread(message) \ + assertIsMainThreadImpl(__FILE__, __LINE__, message) + + /** + * Asserts that the current thread is NOT the main thread. + * + * @param message Message to throw against assertion failure. + */ + #define assertNotMainThread(message) \ + assertNotMainThreadImpl(__FILE__, __LINE__, message) + #else // If assertions are faked, we define the macros to do nothing. #define assertInit() ((void)0) @@ -270,11 +268,13 @@ #define assertDeprecated(message) ((void)0) #define assertStrLenMax(str, len, message) ((void)0) #define assertStrLenMin(str, len, message) ((void)0) + #define assertStringEqual(a, b, message) ((void)0) + #define assertIsMainThread(message) ((void)0) + #define assertNotMainThread(message) ((void)0) #endif // Static Assertions - #define assertStructSize(struct, size) \ _Static_assert(sizeof(struct) == size, "Size of " #struct " must be " #size) diff --git a/src/dusk/asset/assetfile.c b/src/dusk/asset/assetfile.c index b0a5ce8c..569ba6bf 100644 --- a/src/dusk/asset/assetfile.c +++ b/src/dusk/asset/assetfile.c @@ -117,6 +117,48 @@ errorret_t assetFileDispose(assetfile_t *file) { errorOk(); } +errorret_t assetFileReadEntire( + assetfile_t *file, + uint8_t **outBuffer, + size_t *outSize +) { + assertNotNull(file, "Asset file cannot be NULL."); + assertNotNull(outBuffer, "outBuffer cannot be NULL."); + assertNotNull(outSize, "outSize cannot be NULL."); + assertTrue(file->size > 0, "Asset file has no size; call assetFileInit first."); + + // File should be closed currently. + assertNull(file->zipFile, "Asset file must be closed before reading entire."); + + // Open file + errorret_t ret = assetFileOpen(file); + if(errorIsNotOk(ret)) { + errorChain(ret); + } + + // Set output. + size_t size = (size_t)file->size; + uint8_t *buffer = (uint8_t *)memoryAllocate(size); + + // Read entire file. + ret = assetFileRead(file, buffer, size); + if(errorIsNotOk(ret)) { + memoryFree(buffer); + errorChain(ret); + } + + // Close the file. + ret = assetFileClose(file); + if(errorIsNotOk(ret)) { + memoryFree(buffer); + errorChain(ret); + } + + *outBuffer = buffer; + *outSize = size; + errorOk(); +} + // Line Reader; void assetFileLineReaderInit( assetfilelinereader_t *reader, diff --git a/src/dusk/asset/assetfile.h b/src/dusk/asset/assetfile.h index afeddbe7..806b9cb9 100644 --- a/src/dusk/asset/assetfile.h +++ b/src/dusk/asset/assetfile.h @@ -86,12 +86,27 @@ errorret_t assetFileClose(assetfile_t *file); /** * Disposes the asset file structure, closing any open handles and zeroing * out the structure. - * + * * @param file The asset file to dispose. * @return An error code if the file could not be disposed properly. */ errorret_t assetFileDispose(assetfile_t *file); +/** + * Reads the entire contents of the asset file into a newly allocated buffer. + * The caller is responsible for freeing the buffer with memoryFree. + * + * @param file The asset file to read. Must be initialized but not open. + * @param outBuffer Receives a pointer to the allocated buffer. + * @param outSize Receives the number of bytes written to the buffer. + * @return An error code if the file could not be read. + */ +errorret_t assetFileReadEntire( + assetfile_t *file, + uint8_t **outBuffer, + size_t *outSize +); + typedef struct { assetfile_t *file; uint8_t *readBuffer; diff --git a/src/dusk/asset/loader/assetentry.c b/src/dusk/asset/loader/assetentry.c index 10a7644b..ea310955 100644 --- a/src/dusk/asset/loader/assetentry.c +++ b/src/dusk/asset/loader/assetentry.c @@ -29,7 +29,8 @@ void assetEntryInit( entry->state = ASSET_ENTRY_STATE_NOT_STARTED; if(input) { entry->inputData = *input; - entry->input = &entry->inputData; + } else { + memoryZero(&entry->inputData, sizeof(assetloaderinput_t)); } refInit(&entry->refs, entry, NULL, NULL, NULL); @@ -54,8 +55,6 @@ void assetEntryLock(assetentry_t *entry) { assertNotNull(entry, "Entry cannot be NULL"); assertTrue(entry->type != ASSET_LOADER_TYPE_NULL, "Invalid loader type."); - entry->wasLocked = true; - refLock(&entry->refs); } diff --git a/src/dusk/asset/loader/assetentry.h b/src/dusk/asset/loader/assetentry.h index ba8e2ed1..1f1abbdd 100644 --- a/src/dusk/asset/loader/assetentry.h +++ b/src/dusk/asset/loader/assetentry.h @@ -26,26 +26,12 @@ typedef enum { typedef struct assetentry_s assetentry_t; struct assetentry_s { - // Filename and cache key char_t name[ASSET_FILE_NAME_MAX]; - // What type of asset is this? assetloadertype_t type; - // Data assetloaderoutput_t data; - // What state is this asset entry in currently? assetentrystate_t state; - // What is referencing this asset entry. ref_t refs; - // True once assetEntryLock has been called at least once. The reaper only - // collects entries that have been explicitly locked (and later unlocked to - // zero). Entries that nobody has ever locked are left alone so raw-pointer - // callers (tests, requireLoaded before locking) are not surprised. - bool_t wasLocked; - // Owned copy of the loader input. input points here when non-NULL. assetloaderinput_t inputData; - // Pointer to inputData, or NULL if no input was provided. - assetloaderinput_t *input; - /** * Fired once when loading completes successfully (params = assetentry_t *). * Always invoked on the main thread. diff --git a/src/dusk/asset/loader/assetloading.h b/src/dusk/asset/loader/assetloading.h index b517c09f..bf15937f 100644 --- a/src/dusk/asset/loader/assetloading.h +++ b/src/dusk/asset/loader/assetloading.h @@ -13,13 +13,9 @@ typedef struct assetentry_s assetentry_t; typedef struct assetloading_s { - // Protects entry pointer and entry->state from concurrent access. threadmutex_t mutex; - // What type of asset is being loaded. assetloadertype_t type; - // Referral back to the asset entry that will be kept alive after load done. assetentry_t *entry; - // Information used during the load operation only. assetloaderloading_t loading; } assetloading_t; diff --git a/src/dusk/asset/loader/display/assetmeshloader.c b/src/dusk/asset/loader/display/assetmeshloader.c index 4bc13c37..c9a86043 100644 --- a/src/dusk/asset/loader/display/assetmeshloader.c +++ b/src/dusk/asset/loader/display/assetmeshloader.c @@ -21,7 +21,7 @@ errorret_t assetMeshLoaderAsync(assetloading_t *loading) { assetmeshoutput_t *out = &loading->entry->data.mesh; assetfile_t *file = &loading->loading.mesh.file; - assetmeshinputaxis_t axis = loading->entry->input->mesh; + assetmeshinputaxis_t axis = loading->entry->inputData.mesh; assetLoaderErrorChain(loading, assetFileInit(file, loading->entry->name, NULL, NULL)); assetLoaderErrorChain(loading, assetFileOpen(file)); diff --git a/src/dusk/asset/loader/display/assettextureloader.c b/src/dusk/asset/loader/display/assettextureloader.c index bde00990..62546aba 100644 --- a/src/dusk/asset/loader/display/assettextureloader.c +++ b/src/dusk/asset/loader/display/assettextureloader.c @@ -77,7 +77,7 @@ errorret_t assetTextureLoaderAsync(assetloading_t *loading) { // Determine channels int channelsDesired; - switch(loading->entry->input->texture) { + switch(loading->entry->inputData.texture) { case TEXTURE_FORMAT_RGBA: channelsDesired = 4; break; @@ -148,7 +148,7 @@ errorret_t assetTextureLoaderSync(assetloading_t *loading) { (texture_t*)&loading->entry->data.texture, loading->loading.texture.width, loading->loading.texture.height, - loading->entry->input->texture, + loading->entry->inputData.texture, (texturedata_t){ .rgbaColors = (color_t*)loading->loading.texture.data } diff --git a/src/dusk/engine/engine.c b/src/dusk/engine/engine.c index b82415c6..74ad1a07 100644 --- a/src/dusk/engine/engine.c +++ b/src/dusk/engine/engine.c @@ -98,8 +98,8 @@ errorret_t engineDispose(void) { consoleDispose(); errorChain(displayDispose()); // errorChain(saveDispose()); - errorChain(assetDispose()); errorChain(scriptDispose()); + errorChain(assetDispose()); errorOk(); } diff --git a/src/dusk/thread/thread.c b/src/dusk/thread/thread.c index 54fefbee..aed2e937 100644 --- a/src/dusk/thread/thread.c +++ b/src/dusk/thread/thread.c @@ -96,8 +96,6 @@ bool_t threadShouldStop(thread_t *thread) { } #ifdef DUSK_THREAD_PTHREAD - pthread_t THREAD_MAIN_THREAD_ID = 0; - void * threadHandler(thread_t *thread) { assertNotNull(thread, "Thread cannot be NULL."); diff --git a/src/dusk/thread/thread.h b/src/dusk/thread/thread.h index 97b29290..3337e591 100644 --- a/src/dusk/thread/thread.h +++ b/src/dusk/thread/thread.h @@ -89,8 +89,6 @@ void threadStop(thread_t *thread); bool_t threadShouldStop(thread_t *thread); #ifdef DUSK_THREAD_PTHREAD - extern pthread_t THREAD_MAIN_THREAD_ID; - /** * Handles the thread's lifecycle for pthreads. * @param thread Pointer to the thread structure to handle. diff --git a/src/dusk/util/math.h b/src/dusk/util/math.h index ab8cf45e..ac5520b9 100644 --- a/src/dusk/util/math.h +++ b/src/dusk/util/math.h @@ -8,6 +8,8 @@ #pragma once #include "dusk.h" +#define MATH_PI M_PI + /** * Finds the next power of two greater than or equal to the given value. *