Wrap long lines to fit within 80 columns across the codebase
Pure whitespace/line-break reformatting (braces, newlines, and line continuations matching this codebase's existing wrap conventions) - no logic, string content, or identifiers changed anywhere. Confirmed via diff against the pre-change tree and by rebuilding + re-running the affected test suites, which produce identical pass/fail results. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
+19
-6
@@ -8,7 +8,10 @@ cmake_minimum_required(VERSION 3.13)
|
|||||||
|
|
||||||
set(CMAKE_C_STANDARD 11)
|
set(CMAKE_C_STANDARD 11)
|
||||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
|
set(CMAKE_MODULE_PATH
|
||||||
|
${CMAKE_MODULE_PATH}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules
|
||||||
|
)
|
||||||
cmake_policy(SET CMP0079 NEW)
|
cmake_policy(SET CMP0079 NEW)
|
||||||
# set(FETCHCONTENT_UPDATES_DISCONNECTED ON)
|
# set(FETCHCONTENT_UPDATES_DISCONNECTED ON)
|
||||||
|
|
||||||
@@ -18,7 +21,9 @@ option(DUSK_NETWORK "Enable network support" ON)
|
|||||||
set(DUSK_GAME_NAME "Dusk" CACHE STRING "Game display name")
|
set(DUSK_GAME_NAME "Dusk" CACHE STRING "Game display name")
|
||||||
set(DUSK_GAME_AUTHOR "YourWishes" CACHE STRING "Game author / coder")
|
set(DUSK_GAME_AUTHOR "YourWishes" CACHE STRING "Game author / coder")
|
||||||
set(DUSK_GAME_SHORT_DESCRIPTION "Dusk game" CACHE STRING "One-line description")
|
set(DUSK_GAME_SHORT_DESCRIPTION "Dusk game" CACHE STRING "One-line description")
|
||||||
set(DUSK_GAME_LONG_DESCRIPTION "No description yet." CACHE STRING "Full description")
|
set(DUSK_GAME_LONG_DESCRIPTION
|
||||||
|
"No description yet." CACHE STRING "Full description"
|
||||||
|
)
|
||||||
|
|
||||||
# Prep cache
|
# Prep cache
|
||||||
set(DUSK_CACHE_TARGET "dusk-target")
|
set(DUSK_CACHE_TARGET "dusk-target")
|
||||||
@@ -32,13 +37,19 @@ set(DUSK_TEMP_DIR "${DUSK_BUILD_DIR}/temp")
|
|||||||
set(DUSK_TOOLS_DIR "${DUSK_ROOT_DIR}/tools")
|
set(DUSK_TOOLS_DIR "${DUSK_ROOT_DIR}/tools")
|
||||||
set(DUSK_DATA_DIR "${DUSK_ROOT_DIR}/data")
|
set(DUSK_DATA_DIR "${DUSK_ROOT_DIR}/data")
|
||||||
set(DUSK_ASSETS_DIR "${DUSK_ROOT_DIR}/assets")
|
set(DUSK_ASSETS_DIR "${DUSK_ROOT_DIR}/assets")
|
||||||
set(DUSK_BUILT_ASSETS_DIR "${DUSK_BUILD_DIR}/built_assets" CACHE INTERNAL ${DUSK_CACHE_TARGET})
|
set(DUSK_BUILT_ASSETS_DIR "${DUSK_BUILD_DIR}/built_assets"
|
||||||
|
CACHE INTERNAL ${DUSK_CACHE_TARGET}
|
||||||
|
)
|
||||||
set(DUSK_GENERATED_HEADERS_DIR "${DUSK_BUILD_DIR}/generated")
|
set(DUSK_GENERATED_HEADERS_DIR "${DUSK_BUILD_DIR}/generated")
|
||||||
set(DUSK_BUILD_BINARY ${DUSK_BUILD_DIR}/Dusk CACHE INTERNAL ${DUSK_CACHE_TARGET})
|
set(DUSK_BUILD_BINARY ${DUSK_BUILD_DIR}/Dusk
|
||||||
|
CACHE INTERNAL ${DUSK_CACHE_TARGET}
|
||||||
|
)
|
||||||
set(DUSK_ASSETS "" CACHE INTERNAL ${DUSK_CACHE_TARGET})
|
set(DUSK_ASSETS "" CACHE INTERNAL ${DUSK_CACHE_TARGET})
|
||||||
set(DUSK_LIBRARY_TARGET_NAME "DuskCore" CACHE INTERNAL ${DUSK_CACHE_TARGET})
|
set(DUSK_LIBRARY_TARGET_NAME "DuskCore" CACHE INTERNAL ${DUSK_CACHE_TARGET})
|
||||||
set(DUSK_BINARY_TARGET_NAME "Dusk" CACHE INTERNAL ${DUSK_CACHE_TARGET})
|
set(DUSK_BINARY_TARGET_NAME "Dusk" CACHE INTERNAL ${DUSK_CACHE_TARGET})
|
||||||
set(DUSK_ASSETS_ZIP "${DUSK_BUILD_DIR}/dusk.dsk" CACHE INTERNAL ${DUSK_CACHE_TARGET})
|
set(DUSK_ASSETS_ZIP "${DUSK_BUILD_DIR}/dusk.dsk"
|
||||||
|
CACHE INTERNAL ${DUSK_CACHE_TARGET}
|
||||||
|
)
|
||||||
|
|
||||||
if(NOT DEFINED DUSK_TARGET_SYSTEM)
|
if(NOT DEFINED DUSK_TARGET_SYSTEM)
|
||||||
set(DUSK_TARGET_SYSTEM "linux")
|
set(DUSK_TARGET_SYSTEM "linux")
|
||||||
@@ -73,7 +84,9 @@ if(DUSK_BUILD_TESTS)
|
|||||||
${DUSK_LIBRARY_TARGET_NAME}
|
${DUSK_LIBRARY_TARGET_NAME}
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
set(DUSK_LIBRARY_TARGET_NAME "${DUSK_BINARY_TARGET_NAME}" CACHE INTERNAL ${DUSK_CACHE_TARGET})
|
set(DUSK_LIBRARY_TARGET_NAME "${DUSK_BINARY_TARGET_NAME}"
|
||||||
|
CACHE INTERNAL ${DUSK_CACHE_TARGET}
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT DEFINED DUSK_VERSION)
|
if(NOT DEFINED DUSK_VERSION)
|
||||||
|
|||||||
+4
-1
@@ -25,7 +25,10 @@ elseif(DUSK_TARGET_SYSTEM STREQUAL "vita")
|
|||||||
add_subdirectory(dusksdl2)
|
add_subdirectory(dusksdl2)
|
||||||
add_subdirectory(duskgl)
|
add_subdirectory(duskgl)
|
||||||
|
|
||||||
elseif(DUSK_TARGET_SYSTEM STREQUAL "wii" OR DUSK_TARGET_SYSTEM STREQUAL "gamecube")
|
elseif(
|
||||||
|
DUSK_TARGET_SYSTEM STREQUAL "wii" OR
|
||||||
|
DUSK_TARGET_SYSTEM STREQUAL "gamecube"
|
||||||
|
)
|
||||||
add_subdirectory(duskdolphin)
|
add_subdirectory(duskdolphin)
|
||||||
add_subdirectory(duskmad)
|
add_subdirectory(duskmad)
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ if(NOT stb_image_FOUND)
|
|||||||
if(STB_IMAGE_FOUND)
|
if(STB_IMAGE_FOUND)
|
||||||
target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC stb_image)
|
target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC stb_image)
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "stb_image not found. Please ensure stb is correctly fetched.")
|
message(FATAL_ERROR
|
||||||
|
"stb_image not found. Please ensure stb is correctly fetched."
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -35,7 +37,9 @@ if(NOT yyjson_FOUND)
|
|||||||
if(yyjson_FOUND)
|
if(yyjson_FOUND)
|
||||||
target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC yyjson::yyjson)
|
target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC yyjson::yyjson)
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "yyjson not found. Please ensure yyjson is correctly fetched.")
|
message(FATAL_ERROR
|
||||||
|
"yyjson not found. Please ensure yyjson is correctly fetched."
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@@ -364,7 +364,9 @@ errorret_t assetUpdate(void) {
|
|||||||
assetentry_t *errEntry = loading->entry;
|
assetentry_t *errEntry = loading->entry;
|
||||||
loading->entry = NULL;
|
loading->entry = NULL;
|
||||||
threadMutexUnlock(&loading->mutex);
|
threadMutexUnlock(&loading->mutex);
|
||||||
if(errEntry->onError) errEntry->onError(errEntry, errEntry->onErrorUser);
|
if(errEntry->onError) {
|
||||||
|
errEntry->onError(errEntry, errEntry->onErrorUser);
|
||||||
|
}
|
||||||
loading++;
|
loading++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+31
-14
@@ -114,15 +114,18 @@ errorret_t assetDskOpenFromPathRange(
|
|||||||
);
|
);
|
||||||
if(compressedSource == NULL) {
|
if(compressedSource == NULL) {
|
||||||
errorThrow(
|
errorThrow(
|
||||||
"Failed to create compressed dusk.dsk source: %s", zip_error_strerror(&zipError)
|
"Failed to create compressed dusk.dsk source: %s",
|
||||||
|
zip_error_strerror(&zipError)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
*outCompressed = zip_open_from_source(compressedSource, ZIP_RDONLY, &zipError);
|
*outCompressed =
|
||||||
|
zip_open_from_source(compressedSource, ZIP_RDONLY, &zipError);
|
||||||
if(*outCompressed == NULL) {
|
if(*outCompressed == NULL) {
|
||||||
zip_source_free(compressedSource);
|
zip_source_free(compressedSource);
|
||||||
errorThrow(
|
errorThrow(
|
||||||
"Failed to open compressed dusk.dsk archive: %s", zip_error_strerror(&zipError)
|
"Failed to open compressed dusk.dsk archive: %s",
|
||||||
|
zip_error_strerror(&zipError)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +139,8 @@ errorret_t assetDskOpenFromPathRange(
|
|||||||
zip_close(*outCompressed);
|
zip_close(*outCompressed);
|
||||||
*outCompressed = NULL;
|
*outCompressed = NULL;
|
||||||
errorThrow(
|
errorThrow(
|
||||||
"Failed to create stored dusk.dsk source: %s", zip_error_strerror(&zipError)
|
"Failed to create stored dusk.dsk source: %s",
|
||||||
|
zip_error_strerror(&zipError)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +150,8 @@ errorret_t assetDskOpenFromPathRange(
|
|||||||
zip_close(*outCompressed);
|
zip_close(*outCompressed);
|
||||||
*outCompressed = NULL;
|
*outCompressed = NULL;
|
||||||
errorThrow(
|
errorThrow(
|
||||||
"Failed to open stored dusk.dsk archive: %s", zip_error_strerror(&zipError)
|
"Failed to open stored dusk.dsk archive: %s",
|
||||||
|
zip_error_strerror(&zipError)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +166,9 @@ errorret_t assetDskOpenFromPathRange(
|
|||||||
zip_close(*outCompressed);
|
zip_close(*outCompressed);
|
||||||
*outStored = NULL;
|
*outStored = NULL;
|
||||||
*outCompressed = NULL;
|
*outCompressed = NULL;
|
||||||
errorThrow("Failed to re-open dusk.dsk to verify stored checksum: %s", path);
|
errorThrow(
|
||||||
|
"Failed to re-open dusk.dsk to verify stored checksum: %s", path
|
||||||
|
);
|
||||||
}
|
}
|
||||||
fseek(storedFile, (long) (baseOffset + header.storedOffset), SEEK_SET);
|
fseek(storedFile, (long) (baseOffset + header.storedOffset), SEEK_SET);
|
||||||
size_t storedRead = fread(storedBytes, 1, header.storedSize, storedFile);
|
size_t storedRead = fread(storedBytes, 1, header.storedSize, storedFile);
|
||||||
@@ -172,17 +179,22 @@ errorret_t assetDskOpenFromPathRange(
|
|||||||
zip_close(*outCompressed);
|
zip_close(*outCompressed);
|
||||||
*outStored = NULL;
|
*outStored = NULL;
|
||||||
*outCompressed = NULL;
|
*outCompressed = NULL;
|
||||||
errorThrow("Failed to read dusk.dsk stored archive to verify checksum: %s", path);
|
errorThrow(
|
||||||
|
"Failed to read dusk.dsk stored archive to verify checksum: %s", path
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t checksum = (uint32_t) crc32(0L, storedBytes, (uInt) header.storedSize);
|
uint32_t checksum =
|
||||||
|
(uint32_t) crc32(0L, storedBytes, (uInt) header.storedSize);
|
||||||
memoryFree(storedBytes);
|
memoryFree(storedBytes);
|
||||||
if(checksum != header.storedChecksum) {
|
if(checksum != header.storedChecksum) {
|
||||||
zip_close(*outStored);
|
zip_close(*outStored);
|
||||||
zip_close(*outCompressed);
|
zip_close(*outCompressed);
|
||||||
*outStored = NULL;
|
*outStored = NULL;
|
||||||
*outCompressed = NULL;
|
*outCompressed = NULL;
|
||||||
errorThrow("dusk.dsk stored archive failed checksum verification: %s", path);
|
errorThrow(
|
||||||
|
"dusk.dsk stored archive failed checksum verification: %s", path
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
@@ -235,15 +247,18 @@ errorret_t assetDskOpenFromBuffer(
|
|||||||
);
|
);
|
||||||
if(compressedSource == NULL) {
|
if(compressedSource == NULL) {
|
||||||
errorThrow(
|
errorThrow(
|
||||||
"Failed to create compressed dusk.dsk source: %s", zip_error_strerror(&zipError)
|
"Failed to create compressed dusk.dsk source: %s",
|
||||||
|
zip_error_strerror(&zipError)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
*outCompressed = zip_open_from_source(compressedSource, ZIP_RDONLY, &zipError);
|
*outCompressed =
|
||||||
|
zip_open_from_source(compressedSource, ZIP_RDONLY, &zipError);
|
||||||
if(*outCompressed == NULL) {
|
if(*outCompressed == NULL) {
|
||||||
zip_source_free(compressedSource);
|
zip_source_free(compressedSource);
|
||||||
errorThrow(
|
errorThrow(
|
||||||
"Failed to open compressed dusk.dsk archive: %s", zip_error_strerror(&zipError)
|
"Failed to open compressed dusk.dsk archive: %s",
|
||||||
|
zip_error_strerror(&zipError)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +269,8 @@ errorret_t assetDskOpenFromBuffer(
|
|||||||
zip_close(*outCompressed);
|
zip_close(*outCompressed);
|
||||||
*outCompressed = NULL;
|
*outCompressed = NULL;
|
||||||
errorThrow(
|
errorThrow(
|
||||||
"Failed to create stored dusk.dsk source: %s", zip_error_strerror(&zipError)
|
"Failed to create stored dusk.dsk source: %s",
|
||||||
|
zip_error_strerror(&zipError)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,7 +280,8 @@ errorret_t assetDskOpenFromBuffer(
|
|||||||
zip_close(*outCompressed);
|
zip_close(*outCompressed);
|
||||||
*outCompressed = NULL;
|
*outCompressed = NULL;
|
||||||
errorThrow(
|
errorThrow(
|
||||||
"Failed to open stored dusk.dsk archive: %s", zip_error_strerror(&zipError)
|
"Failed to open stored dusk.dsk archive: %s",
|
||||||
|
zip_error_strerror(&zipError)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,8 @@
|
|||||||
// 'name' to a sibling assets/cutscenes/<name>.jsonc asset at parse time -
|
// 'name' to a sibling assets/cutscenes/<name>.jsonc asset at parse time -
|
||||||
// see the CUTSCENE_ITEM_TYPE_CUTSCENE case below.
|
// see the CUTSCENE_ITEM_TYPE_CUTSCENE case below.
|
||||||
// Indexed directly by cutsceneitemtype_t rather than searched by value.
|
// Indexed directly by cutsceneitemtype_t rather than searched by value.
|
||||||
static const assetcutsceneitemtypeentry_t ASSET_CUTSCENE_ITEM_TYPE_TABLE[CUTSCENE_ITEM_TYPE_COUNT] = {
|
static const assetcutsceneitemtypeentry_t
|
||||||
|
ASSET_CUTSCENE_ITEM_TYPE_TABLE[CUTSCENE_ITEM_TYPE_COUNT] = {
|
||||||
[CUTSCENE_ITEM_TYPE_NULL] = { "NULL" },
|
[CUTSCENE_ITEM_TYPE_NULL] = { "NULL" },
|
||||||
[CUTSCENE_ITEM_TYPE_TEXT] = { "TEXT" },
|
[CUTSCENE_ITEM_TYPE_TEXT] = { "TEXT" },
|
||||||
[CUTSCENE_ITEM_TYPE_TEXT_MINI] = { "TEXT_MINI" },
|
[CUTSCENE_ITEM_TYPE_TEXT_MINI] = { "TEXT_MINI" },
|
||||||
@@ -134,13 +135,15 @@ static const assetcutsceneenumentry_t ASSET_CUTSCENE_UI_EMOJI_TABLE[] = {
|
|||||||
#define ASSET_CUTSCENE_UI_EMOJI_TABLE_COUNT \
|
#define ASSET_CUTSCENE_UI_EMOJI_TABLE_COUNT \
|
||||||
(sizeof(ASSET_CUTSCENE_UI_EMOJI_TABLE) / sizeof(assetcutsceneenumentry_t))
|
(sizeof(ASSET_CUTSCENE_UI_EMOJI_TABLE) / sizeof(assetcutsceneenumentry_t))
|
||||||
|
|
||||||
static const assetcutsceneenumentry_t ASSET_CUTSCENE_BATTLE_ENCOUNTER_TABLE[] = {
|
static const assetcutsceneenumentry_t
|
||||||
|
ASSET_CUTSCENE_BATTLE_ENCOUNTER_TABLE[] = {
|
||||||
{ "REGULAR", BATTLE_ENCOUNTER_REGULAR },
|
{ "REGULAR", BATTLE_ENCOUNTER_REGULAR },
|
||||||
{ "PLAYER_ADVANTAGE", BATTLE_ENCOUNTER_PLAYER_ADVANTAGE },
|
{ "PLAYER_ADVANTAGE", BATTLE_ENCOUNTER_PLAYER_ADVANTAGE },
|
||||||
{ "BACK_ATTACK", BATTLE_ENCOUNTER_BACK_ATTACK },
|
{ "BACK_ATTACK", BATTLE_ENCOUNTER_BACK_ATTACK },
|
||||||
};
|
};
|
||||||
#define ASSET_CUTSCENE_BATTLE_ENCOUNTER_TABLE_COUNT \
|
#define ASSET_CUTSCENE_BATTLE_ENCOUNTER_TABLE_COUNT \
|
||||||
(sizeof(ASSET_CUTSCENE_BATTLE_ENCOUNTER_TABLE) / sizeof(assetcutsceneenumentry_t))
|
(sizeof(ASSET_CUTSCENE_BATTLE_ENCOUNTER_TABLE) / \
|
||||||
|
sizeof(assetcutsceneenumentry_t))
|
||||||
|
|
||||||
static const assetcutsceneenumentry_t ASSET_CUTSCENE_BATTLE_STATE_TABLE[] = {
|
static const assetcutsceneenumentry_t ASSET_CUTSCENE_BATTLE_STATE_TABLE[] = {
|
||||||
{ "NONE", BATTLE_STATE_NONE },
|
{ "NONE", BATTLE_STATE_NONE },
|
||||||
@@ -168,7 +171,8 @@ static const assetcutsceneenumentry_t ASSET_CUTSCENE_UI_SCREEN_TYPE_TABLE[] = {
|
|||||||
{ "MAIN_MENU", UI_SCREEN_TYPE_MAIN_MENU },
|
{ "MAIN_MENU", UI_SCREEN_TYPE_MAIN_MENU },
|
||||||
};
|
};
|
||||||
#define ASSET_CUTSCENE_UI_SCREEN_TYPE_TABLE_COUNT \
|
#define ASSET_CUTSCENE_UI_SCREEN_TYPE_TABLE_COUNT \
|
||||||
(sizeof(ASSET_CUTSCENE_UI_SCREEN_TYPE_TABLE) / sizeof(assetcutsceneenumentry_t))
|
(sizeof(ASSET_CUTSCENE_UI_SCREEN_TYPE_TABLE) / \
|
||||||
|
sizeof(assetcutsceneenumentry_t))
|
||||||
|
|
||||||
static const assetcutsceneenumentry_t ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE[] = {
|
static const assetcutsceneenumentry_t ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE[] = {
|
||||||
{ "BGM_0", AUDIO_MIXER_CHANNEL_BGM_0 },
|
{ "BGM_0", AUDIO_MIXER_CHANNEL_BGM_0 },
|
||||||
@@ -180,7 +184,8 @@ static const assetcutsceneenumentry_t ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE[] = {
|
|||||||
{ "SFX_3", AUDIO_MIXER_CHANNEL_SFX_3 },
|
{ "SFX_3", AUDIO_MIXER_CHANNEL_SFX_3 },
|
||||||
};
|
};
|
||||||
#define ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE_COUNT \
|
#define ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE_COUNT \
|
||||||
(sizeof(ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE) / sizeof(assetcutsceneenumentry_t))
|
(sizeof(ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE) / \
|
||||||
|
sizeof(assetcutsceneenumentry_t))
|
||||||
|
|
||||||
// Sentinels accepted in place of a literal index/id - see
|
// Sentinels accepted in place of a literal index/id - see
|
||||||
// cutscenesystem.h's CUTSCENE_ENTITY_INTERACT/INTERACTED/CUTSCENE_AREA_
|
// cutscenesystem.h's CUTSCENE_ENTITY_INTERACT/INTERACTED/CUTSCENE_AREA_
|
||||||
@@ -381,15 +386,20 @@ errorret_t assetCutsceneParseItem(
|
|||||||
(uint32_t)index
|
(uint32_t)index
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
item->textMini.position[0] = (float_t)yyjson_get_num(yyjson_arr_get(position, 0));
|
item->textMini.position[0] =
|
||||||
item->textMini.position[1] = (float_t)yyjson_get_num(yyjson_arr_get(position, 1));
|
(float_t)yyjson_get_num(yyjson_arr_get(position, 0));
|
||||||
item->textMini.position[2] = (float_t)yyjson_get_num(yyjson_arr_get(position, 2));
|
item->textMini.position[1] =
|
||||||
item->textMini.duration = (float_t)yyjson_get_num(yyjson_obj_get(itemObj, "duration"));
|
(float_t)yyjson_get_num(yyjson_arr_get(position, 1));
|
||||||
|
item->textMini.position[2] =
|
||||||
|
(float_t)yyjson_get_num(yyjson_arr_get(position, 2));
|
||||||
|
item->textMini.duration =
|
||||||
|
(float_t)yyjson_get_num(yyjson_obj_get(itemObj, "duration"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_TEXT_MINI_HIDE:
|
case CUTSCENE_ITEM_TYPE_TEXT_MINI_HIDE:
|
||||||
item->textMiniHide.index = (uint8_t)yyjson_get_int(yyjson_obj_get(itemObj, "index"));
|
item->textMiniHide.index =
|
||||||
|
(uint8_t)yyjson_get_int(yyjson_obj_get(itemObj, "index"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_WAIT:
|
case CUTSCENE_ITEM_TYPE_WAIT:
|
||||||
@@ -400,7 +410,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
const char_t *name = yyjson_get_str(yyjson_obj_get(itemObj, "name"));
|
const char_t *name = yyjson_get_str(yyjson_obj_get(itemObj, "name"));
|
||||||
if(name == NULL) {
|
if(name == NULL) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (CUTSCENE): missing 'name'", (uint32_t)index
|
loading, "Cutscene item %u (CUTSCENE): missing 'name'",
|
||||||
|
(uint32_t)index
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,12 +426,14 @@ errorret_t assetCutsceneParseItem(
|
|||||||
int32_t pathLen = stringFormat(NULL, 0, "cutscenes/%s.jsonc", name);
|
int32_t pathLen = stringFormat(NULL, 0, "cutscenes/%s.jsonc", name);
|
||||||
if(pathLen < 0 || (size_t)pathLen >= ASSET_FILE_NAME_MAX) {
|
if(pathLen < 0 || (size_t)pathLen >= ASSET_FILE_NAME_MAX) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (CUTSCENE): 'name' too long", (uint32_t)index
|
loading, "Cutscene item %u (CUTSCENE): 'name' too long",
|
||||||
|
(uint32_t)index
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
stringFormat(path, sizeof(path), "cutscenes/%s.jsonc", name);
|
stringFormat(path, sizeof(path), "cutscenes/%s.jsonc", name);
|
||||||
|
|
||||||
assetentry_t *refEntry = assetLock(path, ASSET_LOADER_TYPE_CUTSCENE, NULL);
|
assetentry_t *refEntry =
|
||||||
|
assetLock(path, ASSET_LOADER_TYPE_CUTSCENE, NULL);
|
||||||
assetLoaderErrorChain(loading, assetRequireLoaded(refEntry));
|
assetLoaderErrorChain(loading, assetRequireLoaded(refEntry));
|
||||||
item->cutscene = &refEntry->data.cutscene.cutscene;
|
item->cutscene = &refEntry->data.cutscene.cutscene;
|
||||||
break;
|
break;
|
||||||
@@ -428,7 +441,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT:
|
case CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT:
|
||||||
if(!assetCutsceneResolveEntityIndex(
|
if(!assetCutsceneResolveEntityIndex(
|
||||||
yyjson_obj_get(itemObj, "entityIndex"), &item->entityTeleport.entityIndex
|
yyjson_obj_get(itemObj, "entityIndex"),
|
||||||
|
&item->entityTeleport.entityIndex
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (ENTITY_TELEPORT): invalid 'entityIndex'",
|
loading, "Cutscene item %u (ENTITY_TELEPORT): invalid 'entityIndex'",
|
||||||
@@ -439,8 +453,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
yyjson_obj_get(itemObj, "target"), &item->entityTeleport.target
|
yyjson_obj_get(itemObj, "target"), &item->entityTeleport.target
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (ENTITY_TELEPORT): 'target' must be [x, y, z]",
|
loading, "Cutscene item %u (ENTITY_TELEPORT): 'target' must be "
|
||||||
(uint32_t)index
|
"[x, y, z]", (uint32_t)index
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -455,7 +469,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
yyjson_val *walkAround = yyjson_obj_get(itemObj, "walkAround");
|
yyjson_val *walkAround = yyjson_obj_get(itemObj, "walkAround");
|
||||||
item->entityWalkTo.walkAround = walkAround == NULL ? true : yyjson_get_bool(walkAround);
|
item->entityWalkTo.walkAround =
|
||||||
|
walkAround == NULL ? true : yyjson_get_bool(walkAround);
|
||||||
|
|
||||||
yyjson_val *positions = yyjson_obj_get(itemObj, "positions");
|
yyjson_val *positions = yyjson_obj_get(itemObj, "positions");
|
||||||
size_t count = yyjson_arr_size(positions);
|
size_t count = yyjson_arr_size(positions);
|
||||||
@@ -504,9 +519,11 @@ errorret_t assetCutsceneParseItem(
|
|||||||
item->fade.to.g = (uint8_t)yyjson_get_int(yyjson_arr_get(to, 1));
|
item->fade.to.g = (uint8_t)yyjson_get_int(yyjson_arr_get(to, 1));
|
||||||
item->fade.to.b = (uint8_t)yyjson_get_int(yyjson_arr_get(to, 2));
|
item->fade.to.b = (uint8_t)yyjson_get_int(yyjson_arr_get(to, 2));
|
||||||
item->fade.to.a = (uint8_t)yyjson_get_int(yyjson_arr_get(to, 3));
|
item->fade.to.a = (uint8_t)yyjson_get_int(yyjson_arr_get(to, 3));
|
||||||
item->fade.duration = (float_t)yyjson_get_num(yyjson_obj_get(itemObj, "duration"));
|
item->fade.duration =
|
||||||
|
(float_t)yyjson_get_num(yyjson_obj_get(itemObj, "duration"));
|
||||||
|
|
||||||
const char_t *easingName = yyjson_get_str(yyjson_obj_get(itemObj, "easing"));
|
const char_t *easingName =
|
||||||
|
yyjson_get_str(yyjson_obj_get(itemObj, "easing"));
|
||||||
int32_t easingValue = EASING_LINEAR;
|
int32_t easingValue = EASING_LINEAR;
|
||||||
if(easingName != NULL && !assetCutsceneLookupEnumInsensitive(
|
if(easingName != NULL && !assetCutsceneLookupEnumInsensitive(
|
||||||
ASSET_CUTSCENE_EASING_TABLE, ASSET_CUTSCENE_EASING_TABLE_COUNT,
|
ASSET_CUTSCENE_EASING_TABLE, ASSET_CUTSCENE_EASING_TABLE_COUNT,
|
||||||
@@ -534,7 +551,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
while((flagVal = yyjson_arr_iter_next(&iter)) != NULL) {
|
while((flagVal = yyjson_arr_iter_next(&iter)) != NULL) {
|
||||||
int32_t flagValue;
|
int32_t flagValue;
|
||||||
if(!assetCutsceneLookupEnumInsensitive(
|
if(!assetCutsceneLookupEnumInsensitive(
|
||||||
ASSET_CUTSCENE_PAUSE_FLAG_TABLE, ASSET_CUTSCENE_PAUSE_FLAG_TABLE_COUNT,
|
ASSET_CUTSCENE_PAUSE_FLAG_TABLE,
|
||||||
|
ASSET_CUTSCENE_PAUSE_FLAG_TABLE_COUNT,
|
||||||
yyjson_get_str(flagVal), &flagValue
|
yyjson_get_str(flagVal), &flagValue
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
@@ -549,8 +567,10 @@ errorret_t assetCutsceneParseItem(
|
|||||||
}
|
}
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ITEM_GIVE:
|
case CUTSCENE_ITEM_TYPE_ITEM_GIVE:
|
||||||
item->itemGive.item = (itemid_t)yyjson_get_int(yyjson_obj_get(itemObj, "item"));
|
item->itemGive.item =
|
||||||
item->itemGive.quantity = (uint8_t)yyjson_get_int(yyjson_obj_get(itemObj, "quantity"));
|
(itemid_t)yyjson_get_int(yyjson_obj_get(itemObj, "item"));
|
||||||
|
item->itemGive.quantity =
|
||||||
|
(uint8_t)yyjson_get_int(yyjson_obj_get(itemObj, "quantity"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ENTITY_REMOVE:
|
case CUTSCENE_ITEM_TYPE_ENTITY_REMOVE:
|
||||||
@@ -567,7 +587,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
case CUTSCENE_ITEM_TYPE_ENTITY_ADD: {
|
case CUTSCENE_ITEM_TYPE_ENTITY_ADD: {
|
||||||
int32_t entityTypeValue;
|
int32_t entityTypeValue;
|
||||||
if(!assetCutsceneLookupEnumInsensitive(
|
if(!assetCutsceneLookupEnumInsensitive(
|
||||||
ASSET_CUTSCENE_ENTITY_TYPE_TABLE, ASSET_CUTSCENE_ENTITY_TYPE_TABLE_COUNT,
|
ASSET_CUTSCENE_ENTITY_TYPE_TABLE,
|
||||||
|
ASSET_CUTSCENE_ENTITY_TYPE_TABLE_COUNT,
|
||||||
yyjson_get_str(yyjson_obj_get(itemObj, "entityType")), &entityTypeValue
|
yyjson_get_str(yyjson_obj_get(itemObj, "entityType")), &entityTypeValue
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
@@ -580,8 +601,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
yyjson_obj_get(itemObj, "position"), &item->entityAdd.position
|
yyjson_obj_get(itemObj, "position"), &item->entityAdd.position
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (ENTITY_ADD): 'position' must be [x, y, z]",
|
loading, "Cutscene item %u (ENTITY_ADD): 'position' must be "
|
||||||
(uint32_t)index
|
"[x, y, z]", (uint32_t)index
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -612,14 +633,15 @@ errorret_t assetCutsceneParseItem(
|
|||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO_ENTITY:
|
case CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO_ENTITY:
|
||||||
if(!assetCutsceneResolveEntityIndex(
|
if(!assetCutsceneResolveEntityIndex(
|
||||||
yyjson_obj_get(itemObj, "entityIndex"), &item->entityWalkToEntity.entityIndex
|
yyjson_obj_get(itemObj, "entityIndex"),
|
||||||
|
&item->entityWalkToEntity.entityIndex
|
||||||
) || !assetCutsceneResolveEntityIndex(
|
) || !assetCutsceneResolveEntityIndex(
|
||||||
yyjson_obj_get(itemObj, "targetEntityIndex"),
|
yyjson_obj_get(itemObj, "targetEntityIndex"),
|
||||||
&item->entityWalkToEntity.targetEntityIndex
|
&item->entityWalkToEntity.targetEntityIndex
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (ENTITY_WALK_TO_ENTITY): invalid entity index",
|
loading, "Cutscene item %u (ENTITY_WALK_TO_ENTITY): invalid entity "
|
||||||
(uint32_t)index
|
"index", (uint32_t)index
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
item->entityWalkToEntity.offsetX =
|
item->entityWalkToEntity.offsetX =
|
||||||
@@ -642,7 +664,10 @@ errorret_t assetCutsceneParseItem(
|
|||||||
case CUTSCENE_ITEM_TYPE_MAP_AREA_WAIT: {
|
case CUTSCENE_ITEM_TYPE_MAP_AREA_WAIT: {
|
||||||
yyjson_val *areaIds = yyjson_obj_get(itemObj, "areaIds");
|
yyjson_val *areaIds = yyjson_obj_get(itemObj, "areaIds");
|
||||||
size_t count = yyjson_arr_size(areaIds);
|
size_t count = yyjson_arr_size(areaIds);
|
||||||
if(!yyjson_is_arr(areaIds) || count == 0 || count > CUTSCENE_MAP_AREA_WAIT_MAX) {
|
if(
|
||||||
|
!yyjson_is_arr(areaIds) || count == 0 ||
|
||||||
|
count > CUTSCENE_MAP_AREA_WAIT_MAX
|
||||||
|
) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (MAP_AREA_WAIT): 'areaIds' must have "
|
loading, "Cutscene item %u (MAP_AREA_WAIT): 'areaIds' must have "
|
||||||
"1-%u entries", (uint32_t)index, (uint32_t)CUTSCENE_MAP_AREA_WAIT_MAX
|
"1-%u entries", (uint32_t)index, (uint32_t)CUTSCENE_MAP_AREA_WAIT_MAX
|
||||||
@@ -671,8 +696,10 @@ errorret_t assetCutsceneParseItem(
|
|||||||
case CUTSCENE_ITEM_TYPE_START_BATTLE: {
|
case CUTSCENE_ITEM_TYPE_START_BATTLE: {
|
||||||
int32_t encounterValue;
|
int32_t encounterValue;
|
||||||
if(!assetCutsceneLookupEnumInsensitive(
|
if(!assetCutsceneLookupEnumInsensitive(
|
||||||
ASSET_CUTSCENE_BATTLE_ENCOUNTER_TABLE, ASSET_CUTSCENE_BATTLE_ENCOUNTER_TABLE_COUNT,
|
ASSET_CUTSCENE_BATTLE_ENCOUNTER_TABLE,
|
||||||
yyjson_get_str(yyjson_obj_get(itemObj, "encounterType")), &encounterValue
|
ASSET_CUTSCENE_BATTLE_ENCOUNTER_TABLE_COUNT,
|
||||||
|
yyjson_get_str(yyjson_obj_get(itemObj, "encounterType")),
|
||||||
|
&encounterValue
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (START_BATTLE): invalid 'encounterType'",
|
loading, "Cutscene item %u (START_BATTLE): invalid 'encounterType'",
|
||||||
@@ -691,7 +718,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
enemyCount > CUTSCENE_START_BATTLE_ENEMY_COUNT_MAX) {
|
enemyCount > CUTSCENE_START_BATTLE_ENEMY_COUNT_MAX) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (START_BATTLE): 'enemies' must have 1-%u "
|
loading, "Cutscene item %u (START_BATTLE): 'enemies' must have 1-%u "
|
||||||
"entries", (uint32_t)index, (uint32_t)CUTSCENE_START_BATTLE_ENEMY_COUNT_MAX
|
"entries", (uint32_t)index,
|
||||||
|
(uint32_t)CUTSCENE_START_BATTLE_ENEMY_COUNT_MAX
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
item->startBattle.enemyCount = (uint8_t)enemyCount;
|
item->startBattle.enemyCount = (uint8_t)enemyCount;
|
||||||
@@ -708,13 +736,20 @@ errorret_t assetCutsceneParseItem(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
cutscenestartbattleenemy_t *enemy = &item->startBattle.enemies[e];
|
cutscenestartbattleenemy_t *enemy = &item->startBattle.enemies[e];
|
||||||
enemy->stats.attack = (uint16_t)yyjson_get_int(yyjson_obj_get(stats, "attack"));
|
enemy->stats.attack =
|
||||||
enemy->stats.defense = (uint16_t)yyjson_get_int(yyjson_obj_get(stats, "defense"));
|
(uint16_t)yyjson_get_int(yyjson_obj_get(stats, "attack"));
|
||||||
enemy->stats.magic = (uint16_t)yyjson_get_int(yyjson_obj_get(stats, "magic"));
|
enemy->stats.defense =
|
||||||
enemy->stats.speed = (uint16_t)yyjson_get_int(yyjson_obj_get(stats, "speed"));
|
(uint16_t)yyjson_get_int(yyjson_obj_get(stats, "defense"));
|
||||||
enemy->stats.luck = (uint16_t)yyjson_get_int(yyjson_obj_get(stats, "luck"));
|
enemy->stats.magic =
|
||||||
enemy->healthMax = (uint16_t)yyjson_get_int(yyjson_obj_get(enemyVal, "healthMax"));
|
(uint16_t)yyjson_get_int(yyjson_obj_get(stats, "magic"));
|
||||||
enemy->mpMax = (uint16_t)yyjson_get_int(yyjson_obj_get(enemyVal, "mpMax"));
|
enemy->stats.speed =
|
||||||
|
(uint16_t)yyjson_get_int(yyjson_obj_get(stats, "speed"));
|
||||||
|
enemy->stats.luck =
|
||||||
|
(uint16_t)yyjson_get_int(yyjson_obj_get(stats, "luck"));
|
||||||
|
enemy->healthMax =
|
||||||
|
(uint16_t)yyjson_get_int(yyjson_obj_get(enemyVal, "healthMax"));
|
||||||
|
enemy->mpMax =
|
||||||
|
(uint16_t)yyjson_get_int(yyjson_obj_get(enemyVal, "mpMax"));
|
||||||
e++;
|
e++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -725,17 +760,20 @@ errorret_t assetCutsceneParseItem(
|
|||||||
yyjson_obj_get(itemObj, "entityIndex"), &item->emoji.entityIndex
|
yyjson_obj_get(itemObj, "entityIndex"), &item->emoji.entityIndex
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (EMOJI): invalid 'entityIndex'", (uint32_t)index
|
loading, "Cutscene item %u (EMOJI): invalid 'entityIndex'",
|
||||||
|
(uint32_t)index
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
item->emoji.duration = (float_t)yyjson_get_num(yyjson_obj_get(itemObj, "duration"));
|
item->emoji.duration =
|
||||||
|
(float_t)yyjson_get_num(yyjson_obj_get(itemObj, "duration"));
|
||||||
int32_t emojiValue;
|
int32_t emojiValue;
|
||||||
if(!assetCutsceneLookupEnumInsensitive(
|
if(!assetCutsceneLookupEnumInsensitive(
|
||||||
ASSET_CUTSCENE_UI_EMOJI_TABLE, ASSET_CUTSCENE_UI_EMOJI_TABLE_COUNT,
|
ASSET_CUTSCENE_UI_EMOJI_TABLE, ASSET_CUTSCENE_UI_EMOJI_TABLE_COUNT,
|
||||||
yyjson_get_str(yyjson_obj_get(itemObj, "emojiType")), &emojiValue
|
yyjson_get_str(yyjson_obj_get(itemObj, "emojiType")), &emojiValue
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (EMOJI): invalid 'emojiType'", (uint32_t)index
|
loading, "Cutscene item %u (EMOJI): invalid 'emojiType'",
|
||||||
|
(uint32_t)index
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
item->emoji.emojiType = (uiemojitype_t)emojiValue;
|
item->emoji.emojiType = (uiemojitype_t)emojiValue;
|
||||||
@@ -743,14 +781,17 @@ errorret_t assetCutsceneParseItem(
|
|||||||
}
|
}
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_SHAKE:
|
case CUTSCENE_ITEM_TYPE_SHAKE:
|
||||||
item->shake.amount = (uint8_t)yyjson_get_int(yyjson_obj_get(itemObj, "amount"));
|
item->shake.amount =
|
||||||
item->shake.duration = (float_t)yyjson_get_num(yyjson_obj_get(itemObj, "duration"));
|
(uint8_t)yyjson_get_int(yyjson_obj_get(itemObj, "amount"));
|
||||||
|
item->shake.duration =
|
||||||
|
(float_t)yyjson_get_num(yyjson_obj_get(itemObj, "duration"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_BATTLE_WAIT_STATE: {
|
case CUTSCENE_ITEM_TYPE_BATTLE_WAIT_STATE: {
|
||||||
int32_t stateValue;
|
int32_t stateValue;
|
||||||
if(!assetCutsceneLookupEnumInsensitive(
|
if(!assetCutsceneLookupEnumInsensitive(
|
||||||
ASSET_CUTSCENE_BATTLE_STATE_TABLE, ASSET_CUTSCENE_BATTLE_STATE_TABLE_COUNT,
|
ASSET_CUTSCENE_BATTLE_STATE_TABLE,
|
||||||
|
ASSET_CUTSCENE_BATTLE_STATE_TABLE_COUNT,
|
||||||
yyjson_get_str(yyjson_obj_get(itemObj, "state")), &stateValue
|
yyjson_get_str(yyjson_obj_get(itemObj, "state")), &stateValue
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
@@ -780,7 +821,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
itemObj, "title", "", item->modal.title, CUTSCENE_MODAL_TITLE_MAX_CHARS
|
itemObj, "title", "", item->modal.title, CUTSCENE_MODAL_TITLE_MAX_CHARS
|
||||||
);
|
);
|
||||||
if(!assetCutsceneCopyStringField(
|
if(!assetCutsceneCopyStringField(
|
||||||
itemObj, "message", NULL, item->modal.message, CUTSCENE_MODAL_MESSAGE_MAX_CHARS
|
itemObj, "message", NULL, item->modal.message,
|
||||||
|
CUTSCENE_MODAL_MESSAGE_MAX_CHARS
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (MODAL): missing/too-long 'message'",
|
loading, "Cutscene item %u (MODAL): missing/too-long 'message'",
|
||||||
@@ -821,7 +863,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
size_t o = 0;
|
size_t o = 0;
|
||||||
while((optionVal = yyjson_arr_iter_next(&iter)) != NULL) {
|
while((optionVal = yyjson_arr_iter_next(&iter)) != NULL) {
|
||||||
const char_t *text = yyjson_get_str(yyjson_obj_get(optionVal, "text"));
|
const char_t *text = yyjson_get_str(yyjson_obj_get(optionVal, "text"));
|
||||||
const char_t *marker = yyjson_get_str(yyjson_obj_get(optionVal, "marker"));
|
const char_t *marker =
|
||||||
|
yyjson_get_str(yyjson_obj_get(optionVal, "marker"));
|
||||||
if(text == NULL || marker == NULL) {
|
if(text == NULL || marker == NULL) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (MODAL_OPTIONS_MARKERS): options[%u] "
|
loading, "Cutscene item %u (MODAL_OPTIONS_MARKERS): options[%u] "
|
||||||
@@ -843,7 +886,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
case CUTSCENE_ITEM_TYPE_UI_SHOW: {
|
case CUTSCENE_ITEM_TYPE_UI_SHOW: {
|
||||||
int32_t screenValue;
|
int32_t screenValue;
|
||||||
if(!assetCutsceneLookupEnumInsensitive(
|
if(!assetCutsceneLookupEnumInsensitive(
|
||||||
ASSET_CUTSCENE_UI_SCREEN_TYPE_TABLE, ASSET_CUTSCENE_UI_SCREEN_TYPE_TABLE_COUNT,
|
ASSET_CUTSCENE_UI_SCREEN_TYPE_TABLE,
|
||||||
|
ASSET_CUTSCENE_UI_SCREEN_TYPE_TABLE_COUNT,
|
||||||
yyjson_get_str(yyjson_obj_get(itemObj, "name")), &screenValue
|
yyjson_get_str(yyjson_obj_get(itemObj, "name")), &screenValue
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
@@ -859,7 +903,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
itemObj, "text", NULL, item->print.text, CUTSCENE_PRINT_MAX_CHARS
|
itemObj, "text", NULL, item->print.text, CUTSCENE_PRINT_MAX_CHARS
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (PRINT): missing/too-long 'text'", (uint32_t)index
|
loading, "Cutscene item %u (PRINT): missing/too-long 'text'",
|
||||||
|
(uint32_t)index
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -882,7 +927,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
yyjson_get_str(yyjson_obj_get(itemObj, "sceneType")), &sceneValue
|
yyjson_get_str(yyjson_obj_get(itemObj, "sceneType")), &sceneValue
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (SCENE): invalid 'sceneType'", (uint32_t)index
|
loading, "Cutscene item %u (SCENE): invalid 'sceneType'",
|
||||||
|
(uint32_t)index
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
item->sceneChange.type = (scenetype_t)sceneValue;
|
item->sceneChange.type = (scenetype_t)sceneValue;
|
||||||
@@ -890,8 +936,10 @@ errorret_t assetCutsceneParseItem(
|
|||||||
}
|
}
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_SAVE_DEVICE_CHECK: {
|
case CUTSCENE_ITEM_TYPE_SAVE_DEVICE_CHECK: {
|
||||||
const char_t *successMarker = yyjson_get_str(yyjson_obj_get(itemObj, "successMarker"));
|
const char_t *successMarker =
|
||||||
const char_t *failureMarker = yyjson_get_str(yyjson_obj_get(itemObj, "failureMarker"));
|
yyjson_get_str(yyjson_obj_get(itemObj, "successMarker"));
|
||||||
|
const char_t *failureMarker =
|
||||||
|
yyjson_get_str(yyjson_obj_get(itemObj, "failureMarker"));
|
||||||
if(successMarker == NULL || failureMarker == NULL) {
|
if(successMarker == NULL || failureMarker == NULL) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (SAVE_DEVICE_CHECK): needs "
|
loading, "Cutscene item %u (SAVE_DEVICE_CHECK): needs "
|
||||||
@@ -904,8 +952,10 @@ errorret_t assetCutsceneParseItem(
|
|||||||
}
|
}
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_SAVE_LOAD_ALL_SLOTS: {
|
case CUTSCENE_ITEM_TYPE_SAVE_LOAD_ALL_SLOTS: {
|
||||||
const char_t *successMarker = yyjson_get_str(yyjson_obj_get(itemObj, "successMarker"));
|
const char_t *successMarker =
|
||||||
const char_t *failureMarker = yyjson_get_str(yyjson_obj_get(itemObj, "failureMarker"));
|
yyjson_get_str(yyjson_obj_get(itemObj, "successMarker"));
|
||||||
|
const char_t *failureMarker =
|
||||||
|
yyjson_get_str(yyjson_obj_get(itemObj, "failureMarker"));
|
||||||
if(successMarker == NULL || failureMarker == NULL) {
|
if(successMarker == NULL || failureMarker == NULL) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (SAVE_LOAD_ALL_SLOTS): needs "
|
loading, "Cutscene item %u (SAVE_LOAD_ALL_SLOTS): needs "
|
||||||
@@ -928,21 +978,25 @@ errorret_t assetCutsceneParseItem(
|
|||||||
}
|
}
|
||||||
int32_t channelValue;
|
int32_t channelValue;
|
||||||
if(!assetCutsceneLookupEnumInsensitive(
|
if(!assetCutsceneLookupEnumInsensitive(
|
||||||
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE, ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE_COUNT,
|
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE,
|
||||||
|
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE_COUNT,
|
||||||
yyjson_get_str(yyjson_obj_get(itemObj, "channel")), &channelValue
|
yyjson_get_str(yyjson_obj_get(itemObj, "channel")), &channelValue
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (AUDIO_PLAY): invalid 'channel'", (uint32_t)index
|
loading, "Cutscene item %u (AUDIO_PLAY): invalid 'channel'",
|
||||||
|
(uint32_t)index
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
item->audioPlay.channel = (audiomixerchannel_t)channelValue;
|
item->audioPlay.channel = (audiomixerchannel_t)channelValue;
|
||||||
|
|
||||||
yyjson_val *volume = yyjson_obj_get(itemObj, "volume");
|
yyjson_val *volume = yyjson_obj_get(itemObj, "volume");
|
||||||
item->audioPlay.volume = volume == NULL ? 1.0f : (float_t)yyjson_get_num(volume);
|
item->audioPlay.volume =
|
||||||
|
volume == NULL ? 1.0f : (float_t)yyjson_get_num(volume);
|
||||||
yyjson_val *pan = yyjson_obj_get(itemObj, "pan");
|
yyjson_val *pan = yyjson_obj_get(itemObj, "pan");
|
||||||
item->audioPlay.pan = pan == NULL ? 0.0f : (float_t)yyjson_get_num(pan);
|
item->audioPlay.pan = pan == NULL ? 0.0f : (float_t)yyjson_get_num(pan);
|
||||||
yyjson_val *looping = yyjson_obj_get(itemObj, "looping");
|
yyjson_val *looping = yyjson_obj_get(itemObj, "looping");
|
||||||
item->audioPlay.looping = looping == NULL ? false : yyjson_get_bool(looping);
|
item->audioPlay.looping =
|
||||||
|
looping == NULL ? false : yyjson_get_bool(looping);
|
||||||
yyjson_val *loopCount = yyjson_obj_get(itemObj, "loopCount");
|
yyjson_val *loopCount = yyjson_obj_get(itemObj, "loopCount");
|
||||||
item->audioPlay.loopCount =
|
item->audioPlay.loopCount =
|
||||||
loopCount == NULL ? 0 : (uint8_t)yyjson_get_int(loopCount);
|
loopCount == NULL ? 0 : (uint8_t)yyjson_get_int(loopCount);
|
||||||
@@ -950,7 +1004,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
item->audioPlay.loopStart =
|
item->audioPlay.loopStart =
|
||||||
loopStart == NULL ? -1.0f : (float_t)yyjson_get_num(loopStart);
|
loopStart == NULL ? -1.0f : (float_t)yyjson_get_num(loopStart);
|
||||||
yyjson_val *loopTo = yyjson_obj_get(itemObj, "loopTo");
|
yyjson_val *loopTo = yyjson_obj_get(itemObj, "loopTo");
|
||||||
item->audioPlay.loopTo = loopTo == NULL ? 0.0f : (float_t)yyjson_get_num(loopTo);
|
item->audioPlay.loopTo =
|
||||||
|
loopTo == NULL ? 0.0f : (float_t)yyjson_get_num(loopTo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -960,7 +1015,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
case CUTSCENE_ITEM_TYPE_AUDIO_FADE_WAIT: {
|
case CUTSCENE_ITEM_TYPE_AUDIO_FADE_WAIT: {
|
||||||
int32_t channelValue;
|
int32_t channelValue;
|
||||||
if(!assetCutsceneLookupEnumInsensitive(
|
if(!assetCutsceneLookupEnumInsensitive(
|
||||||
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE, ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE_COUNT,
|
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE,
|
||||||
|
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE_COUNT,
|
||||||
yyjson_get_str(yyjson_obj_get(itemObj, "channel")), &channelValue
|
yyjson_get_str(yyjson_obj_get(itemObj, "channel")), &channelValue
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
@@ -989,26 +1045,33 @@ errorret_t assetCutsceneParseItem(
|
|||||||
case CUTSCENE_ITEM_TYPE_AUDIO_FADE: {
|
case CUTSCENE_ITEM_TYPE_AUDIO_FADE: {
|
||||||
int32_t channelValue;
|
int32_t channelValue;
|
||||||
if(!assetCutsceneLookupEnumInsensitive(
|
if(!assetCutsceneLookupEnumInsensitive(
|
||||||
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE, ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE_COUNT,
|
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE,
|
||||||
|
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE_COUNT,
|
||||||
yyjson_get_str(yyjson_obj_get(itemObj, "channel")), &channelValue
|
yyjson_get_str(yyjson_obj_get(itemObj, "channel")), &channelValue
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (AUDIO_FADE): invalid 'channel'", (uint32_t)index
|
loading, "Cutscene item %u (AUDIO_FADE): invalid 'channel'",
|
||||||
|
(uint32_t)index
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
item->audioFade.channel = (audiomixerchannel_t)channelValue;
|
item->audioFade.channel = (audiomixerchannel_t)channelValue;
|
||||||
item->audioFade.from = (float_t)yyjson_get_num(yyjson_obj_get(itemObj, "from"));
|
item->audioFade.from =
|
||||||
item->audioFade.to = (float_t)yyjson_get_num(yyjson_obj_get(itemObj, "to"));
|
(float_t)yyjson_get_num(yyjson_obj_get(itemObj, "from"));
|
||||||
item->audioFade.duration = (float_t)yyjson_get_num(yyjson_obj_get(itemObj, "duration"));
|
item->audioFade.to =
|
||||||
|
(float_t)yyjson_get_num(yyjson_obj_get(itemObj, "to"));
|
||||||
|
item->audioFade.duration =
|
||||||
|
(float_t)yyjson_get_num(yyjson_obj_get(itemObj, "duration"));
|
||||||
|
|
||||||
const char_t *easingName = yyjson_get_str(yyjson_obj_get(itemObj, "easing"));
|
const char_t *easingName =
|
||||||
|
yyjson_get_str(yyjson_obj_get(itemObj, "easing"));
|
||||||
int32_t easingValue = EASING_LINEAR;
|
int32_t easingValue = EASING_LINEAR;
|
||||||
if(easingName != NULL && !assetCutsceneLookupEnumInsensitive(
|
if(easingName != NULL && !assetCutsceneLookupEnumInsensitive(
|
||||||
ASSET_CUTSCENE_EASING_TABLE, ASSET_CUTSCENE_EASING_TABLE_COUNT,
|
ASSET_CUTSCENE_EASING_TABLE, ASSET_CUTSCENE_EASING_TABLE_COUNT,
|
||||||
easingName, &easingValue
|
easingName, &easingValue
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (AUDIO_FADE): invalid 'easing'", (uint32_t)index
|
loading, "Cutscene item %u (AUDIO_FADE): invalid 'easing'",
|
||||||
|
(uint32_t)index
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
item->audioFade.easing = (easingtype_t)easingValue;
|
item->audioFade.easing = (easingtype_t)easingValue;
|
||||||
@@ -1018,7 +1081,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
case CUTSCENE_ITEM_TYPE_AUDIO_SET_PAN: {
|
case CUTSCENE_ITEM_TYPE_AUDIO_SET_PAN: {
|
||||||
int32_t channelValue;
|
int32_t channelValue;
|
||||||
if(!assetCutsceneLookupEnumInsensitive(
|
if(!assetCutsceneLookupEnumInsensitive(
|
||||||
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE, ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE_COUNT,
|
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE,
|
||||||
|
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE_COUNT,
|
||||||
yyjson_get_str(yyjson_obj_get(itemObj, "channel")), &channelValue
|
yyjson_get_str(yyjson_obj_get(itemObj, "channel")), &channelValue
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
@@ -1027,14 +1091,16 @@ errorret_t assetCutsceneParseItem(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
item->audioSetPan.channel = (audiomixerchannel_t)channelValue;
|
item->audioSetPan.channel = (audiomixerchannel_t)channelValue;
|
||||||
item->audioSetPan.pan = (float_t)yyjson_get_num(yyjson_obj_get(itemObj, "pan"));
|
item->audioSetPan.pan =
|
||||||
|
(float_t)yyjson_get_num(yyjson_obj_get(itemObj, "pan"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_AUDIO_SET_LOOP: {
|
case CUTSCENE_ITEM_TYPE_AUDIO_SET_LOOP: {
|
||||||
int32_t channelValue;
|
int32_t channelValue;
|
||||||
if(!assetCutsceneLookupEnumInsensitive(
|
if(!assetCutsceneLookupEnumInsensitive(
|
||||||
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE, ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE_COUNT,
|
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE,
|
||||||
|
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE_COUNT,
|
||||||
yyjson_get_str(yyjson_obj_get(itemObj, "channel")), &channelValue
|
yyjson_get_str(yyjson_obj_get(itemObj, "channel")), &channelValue
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
@@ -1044,7 +1110,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
}
|
}
|
||||||
item->audioSetLoop.channel = (audiomixerchannel_t)channelValue;
|
item->audioSetLoop.channel = (audiomixerchannel_t)channelValue;
|
||||||
yyjson_val *looping = yyjson_obj_get(itemObj, "looping");
|
yyjson_val *looping = yyjson_obj_get(itemObj, "looping");
|
||||||
item->audioSetLoop.looping = looping == NULL ? true : yyjson_get_bool(looping);
|
item->audioSetLoop.looping =
|
||||||
|
looping == NULL ? true : yyjson_get_bool(looping);
|
||||||
yyjson_val *loopCount = yyjson_obj_get(itemObj, "loopCount");
|
yyjson_val *loopCount = yyjson_obj_get(itemObj, "loopCount");
|
||||||
item->audioSetLoop.loopCount =
|
item->audioSetLoop.loopCount =
|
||||||
loopCount == NULL ? 0 : (uint8_t)yyjson_get_int(loopCount);
|
loopCount == NULL ? 0 : (uint8_t)yyjson_get_int(loopCount);
|
||||||
@@ -1052,24 +1119,29 @@ errorret_t assetCutsceneParseItem(
|
|||||||
item->audioSetLoop.loopStart =
|
item->audioSetLoop.loopStart =
|
||||||
loopStart == NULL ? -1.0f : (float_t)yyjson_get_num(loopStart);
|
loopStart == NULL ? -1.0f : (float_t)yyjson_get_num(loopStart);
|
||||||
yyjson_val *loopTo = yyjson_obj_get(itemObj, "loopTo");
|
yyjson_val *loopTo = yyjson_obj_get(itemObj, "loopTo");
|
||||||
item->audioSetLoop.loopTo = loopTo == NULL ? 0.0f : (float_t)yyjson_get_num(loopTo);
|
item->audioSetLoop.loopTo =
|
||||||
|
loopTo == NULL ? 0.0f : (float_t)yyjson_get_num(loopTo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CUTSCENE_ITEM_TYPE_AUDIO_SET: {
|
case CUTSCENE_ITEM_TYPE_AUDIO_SET: {
|
||||||
int32_t channelValue;
|
int32_t channelValue;
|
||||||
if(!assetCutsceneLookupEnumInsensitive(
|
if(!assetCutsceneLookupEnumInsensitive(
|
||||||
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE, ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE_COUNT,
|
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE,
|
||||||
|
ASSET_CUTSCENE_AUDIO_CHANNEL_TABLE_COUNT,
|
||||||
yyjson_get_str(yyjson_obj_get(itemObj, "channel")), &channelValue
|
yyjson_get_str(yyjson_obj_get(itemObj, "channel")), &channelValue
|
||||||
)) {
|
)) {
|
||||||
assetLoaderErrorThrow(
|
assetLoaderErrorThrow(
|
||||||
loading, "Cutscene item %u (AUDIO_SET): invalid 'channel'", (uint32_t)index
|
loading, "Cutscene item %u (AUDIO_SET): invalid 'channel'",
|
||||||
|
(uint32_t)index
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
item->audioSet.channel = (audiomixerchannel_t)channelValue;
|
item->audioSet.channel = (audiomixerchannel_t)channelValue;
|
||||||
item->audioSet.pan = (float_t)yyjson_get_num(yyjson_obj_get(itemObj, "pan"));
|
item->audioSet.pan =
|
||||||
|
(float_t)yyjson_get_num(yyjson_obj_get(itemObj, "pan"));
|
||||||
yyjson_val *looping = yyjson_obj_get(itemObj, "looping");
|
yyjson_val *looping = yyjson_obj_get(itemObj, "looping");
|
||||||
item->audioSet.looping = looping == NULL ? true : yyjson_get_bool(looping);
|
item->audioSet.looping =
|
||||||
|
looping == NULL ? true : yyjson_get_bool(looping);
|
||||||
yyjson_val *loopCount = yyjson_obj_get(itemObj, "loopCount");
|
yyjson_val *loopCount = yyjson_obj_get(itemObj, "loopCount");
|
||||||
item->audioSet.loopCount =
|
item->audioSet.loopCount =
|
||||||
loopCount == NULL ? 0 : (uint8_t)yyjson_get_int(loopCount);
|
loopCount == NULL ? 0 : (uint8_t)yyjson_get_int(loopCount);
|
||||||
@@ -1077,7 +1149,8 @@ errorret_t assetCutsceneParseItem(
|
|||||||
item->audioSet.loopStart =
|
item->audioSet.loopStart =
|
||||||
loopStart == NULL ? -1.0f : (float_t)yyjson_get_num(loopStart);
|
loopStart == NULL ? -1.0f : (float_t)yyjson_get_num(loopStart);
|
||||||
yyjson_val *loopTo = yyjson_obj_get(itemObj, "loopTo");
|
yyjson_val *loopTo = yyjson_obj_get(itemObj, "loopTo");
|
||||||
item->audioSet.loopTo = loopTo == NULL ? 0.0f : (float_t)yyjson_get_num(loopTo);
|
item->audioSet.loopTo =
|
||||||
|
loopTo == NULL ? 0.0f : (float_t)yyjson_get_num(loopTo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1112,7 +1185,9 @@ errorret_t assetCutsceneLoaderAsync(assetloading_t *loading) {
|
|||||||
assertNotNull(loading, "Loading cannot be NULL");
|
assertNotNull(loading, "Loading cannot be NULL");
|
||||||
assertNotMainThread("Should be called from an async thread.");
|
assertNotMainThread("Should be called from an async thread.");
|
||||||
|
|
||||||
if(loading->loading.cutscene.state != ASSET_CUTSCENE_LOADING_STATE_READ_FILE) {
|
if(
|
||||||
|
loading->loading.cutscene.state != ASSET_CUTSCENE_LOADING_STATE_READ_FILE
|
||||||
|
) {
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1124,7 +1199,9 @@ errorret_t assetCutsceneLoaderAsync(assetloading_t *loading) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if(file->size > ASSET_CUTSCENE_FILE_SIZE_MAX) {
|
if(file->size > ASSET_CUTSCENE_FILE_SIZE_MAX) {
|
||||||
assetLoaderErrorThrow(loading, "Cutscene JSON exceeds maximum allowed size");
|
assetLoaderErrorThrow(
|
||||||
|
loading, "Cutscene JSON exceeds maximum allowed size"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t fileSize = (size_t)file->size;
|
size_t fileSize = (size_t)file->size;
|
||||||
@@ -1199,7 +1276,9 @@ errorret_t assetCutsceneLoaderSync(assetloading_t *loading) {
|
|||||||
yyjson_get_str(flagVal), &flagValue
|
yyjson_get_str(flagVal), &flagValue
|
||||||
)) {
|
)) {
|
||||||
assetCutsceneFreeParsed(out);
|
assetCutsceneFreeParsed(out);
|
||||||
assetLoaderErrorThrow(loading, "Cutscene JSON has an invalid 'pause' flag");
|
assetLoaderErrorThrow(
|
||||||
|
loading, "Cutscene JSON has an invalid 'pause' flag"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
pause |= (cutscenepause_t)flagValue;
|
pause |= (cutscenepause_t)flagValue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,7 +115,8 @@ errorret_t assetModelLoaderSync(assetloading_t *loading) {
|
|||||||
assetUnlockEntry(jsonEntry);
|
assetUnlockEntry(jsonEntry);
|
||||||
|
|
||||||
// Lock and load the mesh sub-asset.
|
// Lock and load the mesh sub-asset.
|
||||||
assetentry_t *meshEntry = assetLock(meshName, ASSET_LOADER_TYPE_MESH, NULL);
|
assetentry_t *meshEntry =
|
||||||
|
assetLock(meshName, ASSET_LOADER_TYPE_MESH, NULL);
|
||||||
ret = assetRequireLoaded(meshEntry);
|
ret = assetRequireLoaded(meshEntry);
|
||||||
if(errorIsNotOk(ret)) {
|
if(errorIsNotOk(ret)) {
|
||||||
assetUnlockEntry(meshEntry);
|
assetUnlockEntry(meshEntry);
|
||||||
|
|||||||
@@ -502,7 +502,8 @@ errorret_t assetLocaleCacheFind(
|
|||||||
if(i > 0) {
|
if(i > 0) {
|
||||||
assetlocalecacheentry_t hit = *entry;
|
assetlocalecacheentry_t hit = *entry;
|
||||||
memoryMove(
|
memoryMove(
|
||||||
&cache->entries[1], &cache->entries[0], i * sizeof(assetlocalecacheentry_t)
|
&cache->entries[1], &cache->entries[0],
|
||||||
|
i * sizeof(assetlocalecacheentry_t)
|
||||||
);
|
);
|
||||||
cache->entries[0] = hit;
|
cache->entries[0] = hit;
|
||||||
}
|
}
|
||||||
@@ -533,7 +534,8 @@ void assetLocaleCacheInsert(
|
|||||||
if(strlen(value) >= ASSET_LOCALE_CACHE_VALUE_MAX) return;
|
if(strlen(value) >= ASSET_LOCALE_CACHE_VALUE_MAX) return;
|
||||||
|
|
||||||
if(file->cache == NULL) {
|
if(file->cache == NULL) {
|
||||||
file->cache = (assetlocalecache_t *)memoryAllocate(sizeof(assetlocalecache_t));
|
file->cache =
|
||||||
|
(assetlocalecache_t *)memoryAllocate(sizeof(assetlocalecache_t));
|
||||||
memoryZero(file->cache, sizeof(assetlocalecache_t));
|
memoryZero(file->cache, sizeof(assetlocalecache_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,9 +30,15 @@ static const uint16_t ASSET_MP3_BITRATE_MPEG2_L3[16] = {
|
|||||||
0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0
|
0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint32_t ASSET_MP3_SAMPLE_RATE_MPEG1[4] = { 44100, 48000, 32000, 0 };
|
static const uint32_t ASSET_MP3_SAMPLE_RATE_MPEG1[4] = {
|
||||||
static const uint32_t ASSET_MP3_SAMPLE_RATE_MPEG2[4] = { 22050, 24000, 16000, 0 };
|
44100, 48000, 32000, 0
|
||||||
static const uint32_t ASSET_MP3_SAMPLE_RATE_MPEG25[4] = { 11025, 12000, 8000, 0 };
|
};
|
||||||
|
static const uint32_t ASSET_MP3_SAMPLE_RATE_MPEG2[4] = {
|
||||||
|
22050, 24000, 16000, 0
|
||||||
|
};
|
||||||
|
static const uint32_t ASSET_MP3_SAMPLE_RATE_MPEG25[4] = {
|
||||||
|
11025, 12000, 8000, 0
|
||||||
|
};
|
||||||
|
|
||||||
errorret_t assetMp3LoaderAsync(assetloading_t *loading) {
|
errorret_t assetMp3LoaderAsync(assetloading_t *loading) {
|
||||||
assertNotNull(loading, "Loading cannot be NULL");
|
assertNotNull(loading, "Loading cannot be NULL");
|
||||||
@@ -124,7 +130,9 @@ errorret_t assetMp3ParseHeader(assetfile_t *file, assetmp3file_t *mp3File) {
|
|||||||
(size_t) file->size > searchBase ? (size_t) file->size - searchBase : 0
|
(size_t) file->size > searchBase ? (size_t) file->size - searchBase : 0
|
||||||
);
|
);
|
||||||
if(searchWindowSize < 4) {
|
if(searchWindowSize < 4) {
|
||||||
errorThrow("MP3 file is too short to contain a frame header: %s", file->filename);
|
errorThrow(
|
||||||
|
"MP3 file is too short to contain a frame header: %s", file->filename
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *window = (uint8_t *) memoryAllocate(searchWindowSize);
|
uint8_t *window = (uint8_t *) memoryAllocate(searchWindowSize);
|
||||||
@@ -142,11 +150,14 @@ errorret_t assetMp3ParseHeader(assetfile_t *file, assetmp3file_t *mp3File) {
|
|||||||
|
|
||||||
const uint8_t versionBits = (window[i + 1] >> 3) & 0x3;
|
const uint8_t versionBits = (window[i + 1] >> 3) & 0x3;
|
||||||
const uint8_t layerBits = (window[i + 1] >> 1) & 0x3;
|
const uint8_t layerBits = (window[i + 1] >> 1) & 0x3;
|
||||||
if(versionBits == 1 || layerBits != 1) continue; // reserved version, or not Layer III
|
// reserved version, or not Layer III
|
||||||
|
if(versionBits == 1 || layerBits != 1) continue;
|
||||||
|
|
||||||
const uint8_t bitrateIndex = (window[i + 2] >> 4) & 0xF;
|
const uint8_t bitrateIndex = (window[i + 2] >> 4) & 0xF;
|
||||||
const uint8_t sampleRateIndex = (window[i + 2] >> 2) & 0x3;
|
const uint8_t sampleRateIndex = (window[i + 2] >> 2) & 0x3;
|
||||||
if(bitrateIndex == 0 || bitrateIndex == 15 || sampleRateIndex == 3) continue;
|
if(
|
||||||
|
bitrateIndex == 0 || bitrateIndex == 15 || sampleRateIndex == 3
|
||||||
|
) continue;
|
||||||
|
|
||||||
const uint8_t channelMode = (window[i + 3] >> 6) & 0x3;
|
const uint8_t channelMode = (window[i + 3] >> 6) & 0x3;
|
||||||
const bool_t isMpeg1 = versionBits == 3;
|
const bool_t isMpeg1 = versionBits == 3;
|
||||||
@@ -187,8 +198,10 @@ errorret_t assetMp3ParseHeader(assetfile_t *file, assetmp3file_t *mp3File) {
|
|||||||
if((flags & 0x1) != 0 && xingOffset + 12 <= searchWindowSize) {
|
if((flags & 0x1) != 0 && xingOffset + 12 <= searchWindowSize) {
|
||||||
const uint8_t *framesBytes = window + xingOffset + 8;
|
const uint8_t *framesBytes = window + xingOffset + 8;
|
||||||
const uint32_t xingFrameCount = (
|
const uint32_t xingFrameCount = (
|
||||||
((uint32_t) framesBytes[0] << 24) | ((uint32_t) framesBytes[1] << 16) |
|
((uint32_t) framesBytes[0] << 24) |
|
||||||
((uint32_t) framesBytes[2] << 8) | (uint32_t) framesBytes[3]
|
((uint32_t) framesBytes[1] << 16) |
|
||||||
|
((uint32_t) framesBytes[2] << 8) |
|
||||||
|
(uint32_t) framesBytes[3]
|
||||||
);
|
);
|
||||||
// The Xing/Info header's frame count includes the header's own
|
// The Xing/Info header's frame count includes the header's own
|
||||||
// frame (this one, at `i`) - which libmad (and sceMp3) will
|
// frame (this one, at `i`) - which libmad (and sceMp3) will
|
||||||
@@ -201,7 +214,8 @@ errorret_t assetMp3ParseHeader(assetfile_t *file, assetmp3file_t *mp3File) {
|
|||||||
// as "never loops"), since real decode output can never catch up
|
// as "never loops"), since real decode output can never catch up
|
||||||
// to an overstated total.
|
// to an overstated total.
|
||||||
if(xingFrameCount > 0) {
|
if(xingFrameCount > 0) {
|
||||||
mp3File->totalFrames = (size_t) (xingFrameCount - 1) * mp3File->samplesPerFrame;
|
mp3File->totalFrames =
|
||||||
|
(size_t) (xingFrameCount - 1) * mp3File->samplesPerFrame;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -215,7 +229,8 @@ errorret_t assetMp3ParseHeader(assetfile_t *file, assetmp3file_t *mp3File) {
|
|||||||
|
|
||||||
if(!found) {
|
if(!found) {
|
||||||
errorThrow(
|
errorThrow(
|
||||||
"MP3 file has no valid MPEG-1/2/2.5 Layer III frame within the first %u bytes: %s",
|
"MP3 file has no valid MPEG-1/2/2.5 Layer III frame within the first "
|
||||||
|
"%u bytes: %s",
|
||||||
(uint32_t) searchWindowSize, file->filename
|
(uint32_t) searchWindowSize, file->filename
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -229,9 +244,11 @@ errorret_t assetMp3ParseHeader(assetfile_t *file, assetmp3file_t *mp3File) {
|
|||||||
// of an exact one).
|
// of an exact one).
|
||||||
if(mp3File->totalFrames == 0) {
|
if(mp3File->totalFrames == 0) {
|
||||||
const float_t durationSeconds = (
|
const float_t durationSeconds = (
|
||||||
((float_t) mp3File->dataSize * 8.0f) / ((float_t) mp3File->bitrateKbps * 1000.0f)
|
((float_t) mp3File->dataSize * 8.0f) /
|
||||||
|
((float_t) mp3File->bitrateKbps * 1000.0f)
|
||||||
);
|
);
|
||||||
mp3File->totalFrames = (size_t) (durationSeconds * (float_t) mp3File->sampleRate);
|
mp3File->totalFrames =
|
||||||
|
(size_t) (durationSeconds * (float_t) mp3File->sampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
|
|||||||
@@ -268,7 +268,8 @@ errorret_t audioStreamUpdate(audiostream_t *stream) {
|
|||||||
stream->onLoop(stream);
|
stream->onLoop(stream);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
stream->state &= ~(AUDIO_STREAM_STATE_PLAYING | AUDIO_STREAM_STATE_BUFFERED);
|
stream->state &=
|
||||||
|
~(AUDIO_STREAM_STATE_PLAYING | AUDIO_STREAM_STATE_BUFFERED);
|
||||||
|
|
||||||
if(stream->onEnd != NULL) {
|
if(stream->onEnd != NULL) {
|
||||||
stream->onEnd(stream);
|
stream->onEnd(stream);
|
||||||
|
|||||||
@@ -86,7 +86,9 @@ errorret_t audioStreamMp3Seek(audiostream_t *stream, const size_t frame) {
|
|||||||
|
|
||||||
while(stream->mp3.position < frame) {
|
while(stream->mp3.position < frame) {
|
||||||
size_t decodedFrames = 0;
|
size_t decodedFrames = 0;
|
||||||
errorChain(audioStreamMp3DecoderDecodeFrame(stream, discard, &decodedFrames));
|
errorChain(
|
||||||
|
audioStreamMp3DecoderDecodeFrame(stream, discard, &decodedFrames)
|
||||||
|
);
|
||||||
if(decodedFrames == 0) {
|
if(decodedFrames == 0) {
|
||||||
// Ran out of stream before reaching the target - clamp rather than
|
// Ran out of stream before reaching the target - clamp rather than
|
||||||
// erroring, same tolerance audioStreamPcmRead() has for a
|
// erroring, same tolerance audioStreamPcmRead() has for a
|
||||||
@@ -108,7 +110,9 @@ errorret_t audioStreamMp3Seek(audiostream_t *stream, const size_t frame) {
|
|||||||
discard, discard + (framesNeeded * channels),
|
discard, discard + (framesNeeded * channels),
|
||||||
keepFrames * channels * sizeof(int16_t)
|
keepFrames * channels * sizeof(int16_t)
|
||||||
);
|
);
|
||||||
memoryCopy(stream->mp3.pending, discard, keepFrames * channels * sizeof(int16_t));
|
memoryCopy(
|
||||||
|
stream->mp3.pending, discard, keepFrames * channels * sizeof(int16_t)
|
||||||
|
);
|
||||||
stream->mp3.pendingFrames = keepFrames;
|
stream->mp3.pendingFrames = keepFrames;
|
||||||
stream->mp3.pendingPosition = 0;
|
stream->mp3.pendingPosition = 0;
|
||||||
stream->mp3.position = frame;
|
stream->mp3.position = frame;
|
||||||
@@ -142,8 +146,10 @@ errorret_t audioStreamMp3Read(
|
|||||||
if(decodedFrames == 0) break; // Genuine end of stream.
|
if(decodedFrames == 0) break; // Genuine end of stream.
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t framesAvailable = stream->mp3.pendingFrames - stream->mp3.pendingPosition;
|
const size_t framesAvailable =
|
||||||
const size_t framesToCopy = mathMin(frameCount - framesWritten, framesAvailable);
|
stream->mp3.pendingFrames - stream->mp3.pendingPosition;
|
||||||
|
const size_t framesToCopy =
|
||||||
|
mathMin(frameCount - framesWritten, framesAvailable);
|
||||||
|
|
||||||
memoryCopy(
|
memoryCopy(
|
||||||
buffer + (framesWritten * channels),
|
buffer + (framesWritten * channels),
|
||||||
|
|||||||
@@ -8,9 +8,14 @@
|
|||||||
#include "audiostreamtype.h"
|
#include "audiostreamtype.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
|
|
||||||
const audiostreamassettypeinfo_t AUDIO_STREAM_TYPE_FOR_ASSET_TYPE[ASSET_LOADER_TYPE_COUNT] = {
|
const audiostreamassettypeinfo_t
|
||||||
[ASSET_LOADER_TYPE_WAV] = { .type = AUDIO_STREAM_TYPE_PCM, .extension = ".wav" },
|
AUDIO_STREAM_TYPE_FOR_ASSET_TYPE[ASSET_LOADER_TYPE_COUNT] = {
|
||||||
[ASSET_LOADER_TYPE_MP3] = { .type = AUDIO_STREAM_TYPE_MP3, .extension = ".mp3" }
|
[ASSET_LOADER_TYPE_WAV] = {
|
||||||
|
.type = AUDIO_STREAM_TYPE_PCM, .extension = ".wav"
|
||||||
|
},
|
||||||
|
[ASSET_LOADER_TYPE_MP3] = {
|
||||||
|
.type = AUDIO_STREAM_TYPE_MP3, .extension = ".mp3"
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
assetloadertype_t audioStreamAssetTypeForPath(const char_t *path) {
|
assetloadertype_t audioStreamAssetTypeForPath(const char_t *path) {
|
||||||
@@ -24,11 +29,15 @@ assetloadertype_t audioStreamAssetTypeForPath(const char_t *path) {
|
|||||||
return ASSET_LOADER_TYPE_NULL;
|
return ASSET_LOADER_TYPE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
audistreamtype_t audioStreamTypeForAssetType(const assetloadertype_t assetType) {
|
audistreamtype_t audioStreamTypeForAssetType(
|
||||||
|
const assetloadertype_t assetType
|
||||||
|
) {
|
||||||
return AUDIO_STREAM_TYPE_FOR_ASSET_TYPE[assetType].type;
|
return AUDIO_STREAM_TYPE_FOR_ASSET_TYPE[assetType].type;
|
||||||
}
|
}
|
||||||
|
|
||||||
assetloadertype_t audioStreamAssetTypeForStreamType(const audistreamtype_t streamType) {
|
assetloadertype_t audioStreamAssetTypeForStreamType(
|
||||||
|
const audistreamtype_t streamType
|
||||||
|
) {
|
||||||
if(streamType == AUDIO_STREAM_TYPE_NULL) return ASSET_LOADER_TYPE_NULL;
|
if(streamType == AUDIO_STREAM_TYPE_NULL) return ASSET_LOADER_TYPE_NULL;
|
||||||
|
|
||||||
for(assetloadertype_t i = 0; i < ASSET_LOADER_TYPE_COUNT; i++) {
|
for(assetloadertype_t i = 0; i < ASSET_LOADER_TYPE_COUNT; i++) {
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ typedef struct {
|
|||||||
// use of this for the canonical "is this asset type supported" check. Use
|
// use of this for the canonical "is this asset type supported" check. Use
|
||||||
// the functions below rather than indexing this directly, except where
|
// the functions below rather than indexing this directly, except where
|
||||||
// you already have an assetloadertype_t in hand.
|
// you already have an assetloadertype_t in hand.
|
||||||
extern const audiostreamassettypeinfo_t AUDIO_STREAM_TYPE_FOR_ASSET_TYPE[ASSET_LOADER_TYPE_COUNT];
|
extern const audiostreamassettypeinfo_t
|
||||||
|
AUDIO_STREAM_TYPE_FOR_ASSET_TYPE[ASSET_LOADER_TYPE_COUNT];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines which asset loader type a file path's extension corresponds
|
* Determines which asset loader type a file path's extension corresponds
|
||||||
@@ -65,4 +66,6 @@ audistreamtype_t audioStreamTypeForAssetType(const assetloadertype_t assetType);
|
|||||||
* @return The matching assetloadertype_t, or ASSET_LOADER_TYPE_NULL if
|
* @return The matching assetloadertype_t, or ASSET_LOADER_TYPE_NULL if
|
||||||
* streamType is AUDIO_STREAM_TYPE_NULL or otherwise unmapped.
|
* streamType is AUDIO_STREAM_TYPE_NULL or otherwise unmapped.
|
||||||
*/
|
*/
|
||||||
assetloadertype_t audioStreamAssetTypeForStreamType(const audistreamtype_t streamType);
|
assetloadertype_t audioStreamAssetTypeForStreamType(
|
||||||
|
const audistreamtype_t streamType
|
||||||
|
);
|
||||||
|
|||||||
@@ -73,27 +73,33 @@ void sphereBuffer(
|
|||||||
const float_t u1 = (float_t)j / (float_t)sectors;
|
const float_t u1 = (float_t)j / (float_t)sectors;
|
||||||
const float_t u2 = (float_t)(j + 1) / (float_t)sectors;
|
const float_t u2 = (float_t)(j + 1) / (float_t)sectors;
|
||||||
|
|
||||||
vertices[vi].pos[0] = center[0] + x11; vertices[vi].pos[1] = center[1] + y1;
|
vertices[vi].pos[0] = center[0] + x11;
|
||||||
|
vertices[vi].pos[1] = center[1] + y1;
|
||||||
vertices[vi].pos[2] = center[2] + z11;
|
vertices[vi].pos[2] = center[2] + z11;
|
||||||
vertices[vi].uv[0] = u1; vertices[vi].uv[1] = v1; vi++;
|
vertices[vi].uv[0] = u1; vertices[vi].uv[1] = v1; vi++;
|
||||||
|
|
||||||
vertices[vi].pos[0] = center[0] + x21; vertices[vi].pos[1] = center[1] + y2;
|
vertices[vi].pos[0] = center[0] + x21;
|
||||||
|
vertices[vi].pos[1] = center[1] + y2;
|
||||||
vertices[vi].pos[2] = center[2] + z21;
|
vertices[vi].pos[2] = center[2] + z21;
|
||||||
vertices[vi].uv[0] = u1; vertices[vi].uv[1] = v2; vi++;
|
vertices[vi].uv[0] = u1; vertices[vi].uv[1] = v2; vi++;
|
||||||
|
|
||||||
vertices[vi].pos[0] = center[0] + x12; vertices[vi].pos[1] = center[1] + y1;
|
vertices[vi].pos[0] = center[0] + x12;
|
||||||
|
vertices[vi].pos[1] = center[1] + y1;
|
||||||
vertices[vi].pos[2] = center[2] + z12;
|
vertices[vi].pos[2] = center[2] + z12;
|
||||||
vertices[vi].uv[0] = u2; vertices[vi].uv[1] = v1; vi++;
|
vertices[vi].uv[0] = u2; vertices[vi].uv[1] = v1; vi++;
|
||||||
|
|
||||||
vertices[vi].pos[0] = center[0] + x12; vertices[vi].pos[1] = center[1] + y1;
|
vertices[vi].pos[0] = center[0] + x12;
|
||||||
|
vertices[vi].pos[1] = center[1] + y1;
|
||||||
vertices[vi].pos[2] = center[2] + z12;
|
vertices[vi].pos[2] = center[2] + z12;
|
||||||
vertices[vi].uv[0] = u2; vertices[vi].uv[1] = v1; vi++;
|
vertices[vi].uv[0] = u2; vertices[vi].uv[1] = v1; vi++;
|
||||||
|
|
||||||
vertices[vi].pos[0] = center[0] + x21; vertices[vi].pos[1] = center[1] + y2;
|
vertices[vi].pos[0] = center[0] + x21;
|
||||||
|
vertices[vi].pos[1] = center[1] + y2;
|
||||||
vertices[vi].pos[2] = center[2] + z21;
|
vertices[vi].pos[2] = center[2] + z21;
|
||||||
vertices[vi].uv[0] = u1; vertices[vi].uv[1] = v2; vi++;
|
vertices[vi].uv[0] = u1; vertices[vi].uv[1] = v2; vi++;
|
||||||
|
|
||||||
vertices[vi].pos[0] = center[0] + x22; vertices[vi].pos[1] = center[1] + y2;
|
vertices[vi].pos[0] = center[0] + x22;
|
||||||
|
vertices[vi].pos[1] = center[1] + y2;
|
||||||
vertices[vi].pos[2] = center[2] + z22;
|
vertices[vi].pos[2] = center[2] + z22;
|
||||||
vertices[vi].uv[0] = u2; vertices[vi].uv[1] = v2; vi++;
|
vertices[vi].uv[0] = u2; vertices[vi].uv[1] = v2; vi++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,8 @@ errorret_t spriteBatchBuffer(
|
|||||||
|
|
||||||
// Buffer to the mesh vertices.
|
// Buffer to the mesh vertices.
|
||||||
spriteBatchBufferToMesh(
|
spriteBatchBufferToMesh(
|
||||||
sprites + (count - remaining), batchCount, v, batchCount * QUAD_VERTEX_COUNT
|
sprites + (count - remaining), batchCount, v,
|
||||||
|
batchCount * QUAD_VERTEX_COUNT
|
||||||
);
|
);
|
||||||
SPRITEBATCH.spriteCount += batchCount;
|
SPRITEBATCH.spriteCount += batchCount;
|
||||||
remaining -= batchCount;
|
remaining -= batchCount;
|
||||||
|
|||||||
@@ -82,9 +82,11 @@ const uint8_t FONT_DEFAULT_GLYPHS[FONT_DEFAULT_TILE_COUNT][
|
|||||||
// Caps Lock's row widths becomes a column height here, centered
|
// Caps Lock's row widths becomes a column height here, centered
|
||||||
// vertically). Backslash was never drawn anyway, and isn't a key this
|
// vertically). Backslash was never drawn anyway, and isn't a key this
|
||||||
// virtual keyboard can type - see FONT_ICON_BACKSPACE.
|
// virtual keyboard can type - see FONT_ICON_BACKSPACE.
|
||||||
{ 0x00, 0x00, 0x08, 0x1F, 0x3F, 0x3F, 0x1F, 0x08, 0x00, 0x00 }, // FONT_ICON_BACKSPACE
|
// FONT_ICON_BACKSPACE
|
||||||
|
{ 0x00, 0x00, 0x08, 0x1F, 0x3F, 0x3F, 0x1F, 0x08, 0x00, 0x00 },
|
||||||
{ 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00 }, // ]
|
{ 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00 }, // ]
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // ^ (not drawn in source font)
|
// ^ (not drawn in source font)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E }, // _
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E }, // _
|
||||||
// Custom icon glyph, not a real backtick - an up arrow for Shift, same
|
// Custom icon glyph, not a real backtick - an up arrow for Shift, same
|
||||||
// head as Caps Lock's (see FONT_ICON_CAPSLOCK) but with a shaft 2px
|
// head as Caps Lock's (see FONT_ICON_CAPSLOCK) but with a shaft 2px
|
||||||
@@ -92,7 +94,8 @@ const uint8_t FONT_DEFAULT_GLYPHS[FONT_DEFAULT_TILE_COUNT][
|
|||||||
// lighter/broken version of Caps Lock's thicker uninterrupted one.
|
// lighter/broken version of Caps Lock's thicker uninterrupted one.
|
||||||
// Backtick was never drawn anyway, and isn't a key this virtual
|
// Backtick was never drawn anyway, and isn't a key this virtual
|
||||||
// keyboard can type - see FONT_ICON_SHIFT.
|
// keyboard can type - see FONT_ICON_SHIFT.
|
||||||
{ 0x0C, 0x1E, 0x3F, 0x0C, 0x0C, 0x0C, 0x0C, 0x00, 0x0C, 0x00 }, // FONT_ICON_SHIFT
|
// FONT_ICON_SHIFT
|
||||||
|
{ 0x0C, 0x1E, 0x3F, 0x0C, 0x0C, 0x0C, 0x0C, 0x00, 0x0C, 0x00 },
|
||||||
{ 0x00, 0x00, 0x00, 0x1E, 0x22, 0x22, 0x22, 0x1E, 0x00, 0x00 }, // a
|
{ 0x00, 0x00, 0x00, 0x1E, 0x22, 0x22, 0x22, 0x1E, 0x00, 0x00 }, // a
|
||||||
{ 0x00, 0x20, 0x20, 0x3C, 0x22, 0x22, 0x22, 0x3C, 0x00, 0x00 }, // b
|
{ 0x00, 0x20, 0x20, 0x3C, 0x22, 0x22, 0x22, 0x3C, 0x00, 0x00 }, // b
|
||||||
{ 0x00, 0x00, 0x00, 0x1C, 0x22, 0x20, 0x22, 0x1C, 0x00, 0x00 }, // c
|
{ 0x00, 0x00, 0x00, 0x1C, 0x22, 0x20, 0x22, 0x1C, 0x00, 0x00 }, // c
|
||||||
@@ -125,21 +128,25 @@ const uint8_t FONT_DEFAULT_GLYPHS[FONT_DEFAULT_TILE_COUNT][
|
|||||||
// hooks left into a leftward-pointing arrowhead, i.e. "<-|" rotated
|
// hooks left into a leftward-pointing arrowhead, i.e. "<-|" rotated
|
||||||
// into an L. Pipe was never drawn anyway, and isn't a key this
|
// into an L. Pipe was never drawn anyway, and isn't a key this
|
||||||
// virtual keyboard can type - see FONT_ICON_NEWLINE.
|
// virtual keyboard can type - see FONT_ICON_NEWLINE.
|
||||||
{ 0x02, 0x02, 0x02, 0x02, 0x0E, 0x1E, 0x08, 0x00, 0x00, 0x00 }, // FONT_ICON_NEWLINE
|
// FONT_ICON_NEWLINE
|
||||||
|
{ 0x02, 0x02, 0x02, 0x02, 0x0E, 0x1E, 0x08, 0x00, 0x00, 0x00 },
|
||||||
{ 0x00, 0x10, 0x08, 0x08, 0x04, 0x08, 0x08, 0x10, 0x00, 0x00 }, // }
|
{ 0x00, 0x10, 0x08, 0x08, 0x04, 0x08, 0x08, 0x10, 0x00, 0x00 }, // }
|
||||||
// Custom icon glyph, not a real tilde - a spacebar symbol for the
|
// Custom icon glyph, not a real tilde - a spacebar symbol for the
|
||||||
// keyboard's space key: an underscore with a tick at each end, like
|
// keyboard's space key: an underscore with a tick at each end, like
|
||||||
// "|___|". Tilde was never drawn anyway, and was explicitly dropped
|
// "|___|". Tilde was never drawn anyway, and was explicitly dropped
|
||||||
// from this virtual keyboard's own key set - see FONT_ICON_SPACE.
|
// from this virtual keyboard's own key set - see FONT_ICON_SPACE.
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x3F }, // FONT_ICON_SPACE
|
// FONT_ICON_SPACE
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x3F },
|
||||||
// Custom icon glyph, not a real ASCII character - a thick, solid,
|
// Custom icon glyph, not a real ASCII character - a thick, solid,
|
||||||
// uninterrupted up arrow for Caps Lock (contrast FONT_ICON_SHIFT's
|
// uninterrupted up arrow for Caps Lock (contrast FONT_ICON_SHIFT's
|
||||||
// same head but a thinner, gapped shaft). Assigned to char code 127
|
// same head but a thinner, gapped shaft). Assigned to char code 127
|
||||||
// (DEL) since that codepoint is never legitimately typed text and
|
// (DEL) since that codepoint is never legitimately typed text and
|
||||||
// (unlike 128+) is still a positive value regardless of whether this
|
// (unlike 128+) is still a positive value regardless of whether this
|
||||||
// platform's plain `char` is signed - see FONT_ICON_CAPSLOCK.
|
// platform's plain `char` is signed - see FONT_ICON_CAPSLOCK.
|
||||||
{ 0x0C, 0x1E, 0x3F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x00 }, // FONT_ICON_CAPSLOCK
|
// FONT_ICON_CAPSLOCK
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // unused trailing tile
|
{ 0x0C, 0x1E, 0x3F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x00 },
|
||||||
|
// unused trailing tile
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
};
|
};
|
||||||
|
|
||||||
errorret_t fontDefaultInit(void) {
|
errorret_t fontDefaultInit(void) {
|
||||||
@@ -155,7 +162,8 @@ errorret_t fontDefaultInit(void) {
|
|||||||
|
|
||||||
for(uint16_t i = 0; i < FONT_DEFAULT_TILE_COUNT; i++) {
|
for(uint16_t i = 0; i < FONT_DEFAULT_TILE_COUNT; i++) {
|
||||||
const uint16_t tileX = (i % FONT_DEFAULT_COLUMNS) * FONT_DEFAULT_TILE_WIDTH;
|
const uint16_t tileX = (i % FONT_DEFAULT_COLUMNS) * FONT_DEFAULT_TILE_WIDTH;
|
||||||
const uint16_t tileY = (i / FONT_DEFAULT_COLUMNS) * FONT_DEFAULT_TILE_HEIGHT;
|
const uint16_t tileY =
|
||||||
|
(i / FONT_DEFAULT_COLUMNS) * FONT_DEFAULT_TILE_HEIGHT;
|
||||||
|
|
||||||
for(uint8_t row = 0; row < FONT_DEFAULT_TILE_HEIGHT; row++) {
|
for(uint8_t row = 0; row < FONT_DEFAULT_TILE_HEIGHT; row++) {
|
||||||
const uint8_t bits = FONT_DEFAULT_GLYPHS[i][row];
|
const uint8_t bits = FONT_DEFAULT_GLYPHS[i][row];
|
||||||
@@ -172,8 +180,10 @@ errorret_t fontDefaultInit(void) {
|
|||||||
FONT_DEFAULT_TILESET.columns = FONT_DEFAULT_COLUMNS;
|
FONT_DEFAULT_TILESET.columns = FONT_DEFAULT_COLUMNS;
|
||||||
FONT_DEFAULT_TILESET.rows = FONT_DEFAULT_ROWS;
|
FONT_DEFAULT_TILESET.rows = FONT_DEFAULT_ROWS;
|
||||||
FONT_DEFAULT_TILESET.tileCount = FONT_DEFAULT_TILE_COUNT;
|
FONT_DEFAULT_TILESET.tileCount = FONT_DEFAULT_TILE_COUNT;
|
||||||
FONT_DEFAULT_TILESET.uv[0] = (float_t)FONT_DEFAULT_TILE_WIDTH / (float_t)width;
|
FONT_DEFAULT_TILESET.uv[0] =
|
||||||
FONT_DEFAULT_TILESET.uv[1] = (float_t)FONT_DEFAULT_TILE_HEIGHT / (float_t)height;
|
(float_t)FONT_DEFAULT_TILE_WIDTH / (float_t)width;
|
||||||
|
FONT_DEFAULT_TILESET.uv[1] =
|
||||||
|
(float_t)FONT_DEFAULT_TILE_HEIGHT / (float_t)height;
|
||||||
|
|
||||||
const texturedata_t data = { .rgbaColors = pixels };
|
const texturedata_t data = { .rgbaColors = pixels };
|
||||||
errorret_t textureResult = textureInit(
|
errorret_t textureResult = textureInit(
|
||||||
|
|||||||
@@ -214,7 +214,9 @@ void battleMoveTeamFirst(const battlefighterteam_t team) {
|
|||||||
sorted[count++] = BATTLE.executionOrder[i];
|
sorted[count++] = BATTLE.executionOrder[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
memoryCopy(BATTLE.executionOrder, sorted, sizeof(uint8_t) * BATTLE.executionCount);
|
memoryCopy(
|
||||||
|
BATTLE.executionOrder, sorted, sizeof(uint8_t) * BATTLE.executionCount
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
battlefighter_t *battleAIChooseTarget(const battlefighter_t *fighter) {
|
battlefighter_t *battleAIChooseTarget(const battlefighter_t *fighter) {
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ void cutsceneEntityAddStart(
|
|||||||
cutsceneitemdata_t *data
|
cutsceneitemdata_t *data
|
||||||
) {
|
) {
|
||||||
uint8_t entIndex = entityGetAvailable();
|
uint8_t entIndex = entityGetAvailable();
|
||||||
assertTrue(entIndex != 0xFF, "No available entity slots for CUTSCENE_ENTITY_ADD");
|
assertTrue(
|
||||||
|
entIndex != 0xFF, "No available entity slots for CUTSCENE_ENTITY_ADD"
|
||||||
|
);
|
||||||
|
|
||||||
entity_t *entity = &ENTITIES[entIndex];
|
entity_t *entity = &ENTITIES[entIndex];
|
||||||
entityInit(entity, item->entityAdd.entityType);
|
entityInit(entity, item->entityAdd.entityType);
|
||||||
|
|||||||
@@ -123,7 +123,9 @@ bool_t entityWalkCheckRampUp(
|
|||||||
abovePos.z += 1;
|
abovePos.z += 1;
|
||||||
tile_t tileAbove = mapGetTile(abovePos);
|
tile_t tileAbove = mapGetTile(abovePos);
|
||||||
|
|
||||||
if(tileAbove.shape != TILE_SHAPE_NULL && tileShapeIsWalkable(tileAbove.shape)) {
|
if(
|
||||||
|
tileAbove.shape != TILE_SHAPE_NULL && tileShapeIsWalkable(tileAbove.shape)
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +147,8 @@ bool_t entityWalkCheckFall(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
// This handles regular cardinal ramps
|
// This handles regular cardinal ramps
|
||||||
(entityDirGetOpposite(direction)+TILE_SHAPE_RAMP_NORTH) == tileBelow.shape ||
|
(entityDirGetOpposite(direction)+TILE_SHAPE_RAMP_NORTH) ==
|
||||||
|
tileBelow.shape ||
|
||||||
// This handles diagonal ramps. Inner ramps share the same
|
// This handles diagonal ramps. Inner ramps share the same
|
||||||
// allowed directions as their outer counterparts.
|
// allowed directions as their outer counterparts.
|
||||||
(
|
(
|
||||||
@@ -209,7 +212,8 @@ void entityWalk(entity_t *entity, const entitydir_t direction) {
|
|||||||
tile_t tileCurrent = mapGetTile(entity->position);
|
tile_t tileCurrent = mapGetTile(entity->position);
|
||||||
tile_t tileNew = mapGetTile(newPos);
|
tile_t tileNew = mapGetTile(newPos);
|
||||||
|
|
||||||
bool_t raise = entityWalkCheckRampUp(tileCurrent, direction, newPos, &tileNew);
|
bool_t raise =
|
||||||
|
entityWalkCheckRampUp(tileCurrent, direction, newPos, &tileNew);
|
||||||
bool_t fall = !raise && entityWalkCheckFall(tileNew, newPos, direction);
|
bool_t fall = !raise && entityWalkCheckFall(tileNew, newPos, direction);
|
||||||
|
|
||||||
// Can we walk here?
|
// Can we walk here?
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ typedef struct maparea_s maparea_t;
|
|||||||
#define MAP_TRIGGER_STEP (1 << 0)
|
#define MAP_TRIGGER_STEP (1 << 0)
|
||||||
#define MAP_TRIGGER_ENTER (1 << 1)
|
#define MAP_TRIGGER_ENTER (1 << 1)
|
||||||
#define MAP_TRIGGER_EXIT (1 << 2)
|
#define MAP_TRIGGER_EXIT (1 << 2)
|
||||||
#define MAP_TRIGGER_ALL (MAP_TRIGGER_STEP | MAP_TRIGGER_ENTER | MAP_TRIGGER_EXIT)
|
#define MAP_TRIGGER_ALL \
|
||||||
|
(MAP_TRIGGER_STEP | MAP_TRIGGER_ENTER | MAP_TRIGGER_EXIT)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback invoked for a map area.
|
* Callback invoked for a map area.
|
||||||
|
|||||||
@@ -155,7 +155,8 @@ bool_t saveDeviceRawIsValid(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t checksum = cryptCRC32(raw + sizeof(savedevicerawheader_t), compressedSize);
|
uint32_t checksum =
|
||||||
|
cryptCRC32(raw + sizeof(savedevicerawheader_t), compressedSize);
|
||||||
if(checksum != endianLittleToHost32(header->checksum)) return false;
|
if(checksum != endianLittleToHost32(header->checksum)) return false;
|
||||||
|
|
||||||
if(outGeneration != NULL) {
|
if(outGeneration != NULL) {
|
||||||
@@ -395,7 +396,8 @@ errorret_t saveDeviceRawStoreItem(
|
|||||||
header.version = endianLittleToHost32(SAVE_DEVICE_RAW_VERSION);
|
header.version = endianLittleToHost32(SAVE_DEVICE_RAW_VERSION);
|
||||||
header.uncompressedSize = endianLittleToHost32((uint32_t)logicalSize);
|
header.uncompressedSize = endianLittleToHost32((uint32_t)logicalSize);
|
||||||
header.compressedSize = endianLittleToHost32((uint32_t)compressedLen);
|
header.compressedSize = endianLittleToHost32((uint32_t)compressedLen);
|
||||||
header.checksum = endianLittleToHost32(cryptCRC32(compressedBuf, compressedLen));
|
header.checksum =
|
||||||
|
endianLittleToHost32(cryptCRC32(compressedBuf, compressedLen));
|
||||||
header.generation = endianLittleToHost32(haveOld ? oldGeneration + 1 : 1);
|
header.generation = endianLittleToHost32(haveOld ? oldGeneration + 1 : 1);
|
||||||
|
|
||||||
size_t finalSize = sizeof(header) + compressedLen;
|
size_t finalSize = sizeof(header) + compressedLen;
|
||||||
|
|||||||
@@ -282,7 +282,9 @@
|
|||||||
yyjson_mut_val *saveJsonArr = yyjson_mut_arr(doc); \
|
yyjson_mut_val *saveJsonArr = yyjson_mut_arr(doc); \
|
||||||
size_t saveJsonArrIdx = 0; \
|
size_t saveJsonArrIdx = 0; \
|
||||||
while(saveJsonArrIdx < (size_t)(count)) { \
|
while(saveJsonArrIdx < (size_t)(count)) { \
|
||||||
yyjson_mut_arr_add_real(doc, saveJsonArr, (double)(value)[saveJsonArrIdx]); \
|
yyjson_mut_arr_add_real( \
|
||||||
|
doc, saveJsonArr, (double)(value)[saveJsonArrIdx] \
|
||||||
|
); \
|
||||||
saveJsonArrIdx++; \
|
saveJsonArrIdx++; \
|
||||||
} \
|
} \
|
||||||
yyjson_mut_obj_add_val(doc, object, key, saveJsonArr); \
|
yyjson_mut_obj_add_val(doc, object, key, saveJsonArr); \
|
||||||
@@ -369,7 +371,9 @@
|
|||||||
key, (int)(maxLength) \
|
key, (int)(maxLength) \
|
||||||
); \
|
); \
|
||||||
} \
|
} \
|
||||||
stringCopy(saveJsonStringBuffer, yyjson_get_str(saveJsonStrVal), (maxLength)); \
|
stringCopy( \
|
||||||
|
saveJsonStringBuffer, yyjson_get_str(saveJsonStrVal), (maxLength) \
|
||||||
|
); \
|
||||||
} else { \
|
} else { \
|
||||||
stringCopy(saveJsonStringBuffer, (def), (maxLength)); \
|
stringCopy(saveJsonStringBuffer, (def), (maxLength)); \
|
||||||
} \
|
} \
|
||||||
@@ -402,7 +406,9 @@
|
|||||||
yyjson_mut_val *saveJsonTimeObj = yyjson_mut_obj_add_obj(doc, object, key); \
|
yyjson_mut_val *saveJsonTimeObj = yyjson_mut_obj_add_obj(doc, object, key); \
|
||||||
yyjson_mut_obj_add_real(doc, saveJsonTimeObj, "time", (value).time); \
|
yyjson_mut_obj_add_real(doc, saveJsonTimeObj, "time", (value).time); \
|
||||||
yyjson_mut_obj_add_real(doc, saveJsonTimeObj, "timeZone", (value).timeZone); \
|
yyjson_mut_obj_add_real(doc, saveJsonTimeObj, "timeZone", (value).timeZone); \
|
||||||
yyjson_mut_obj_add_real(doc, saveJsonTimeObj, "offsetTime", (value).offsetTime); \
|
yyjson_mut_obj_add_real( \
|
||||||
|
doc, saveJsonTimeObj, "offsetTime", (value).offsetTime \
|
||||||
|
); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -417,8 +423,11 @@
|
|||||||
if(saveJsonTimeObj == NULL) errorThrow("Save JSON missing '%s' key", key); \
|
if(saveJsonTimeObj == NULL) errorThrow("Save JSON missing '%s' key", key); \
|
||||||
yyjson_val *saveJsonTimeTime = yyjson_obj_get(saveJsonTimeObj, "time"); \
|
yyjson_val *saveJsonTimeTime = yyjson_obj_get(saveJsonTimeObj, "time"); \
|
||||||
yyjson_val *saveJsonTimeZone = yyjson_obj_get(saveJsonTimeObj, "timeZone"); \
|
yyjson_val *saveJsonTimeZone = yyjson_obj_get(saveJsonTimeObj, "timeZone"); \
|
||||||
yyjson_val *saveJsonTimeOffset = yyjson_obj_get(saveJsonTimeObj, "offsetTime"); \
|
yyjson_val *saveJsonTimeOffset = \
|
||||||
if(saveJsonTimeTime == NULL) errorThrow("Save JSON missing '%s.time' key", key); \
|
yyjson_obj_get(saveJsonTimeObj, "offsetTime"); \
|
||||||
|
if(saveJsonTimeTime == NULL) { \
|
||||||
|
errorThrow("Save JSON missing '%s.time' key", key); \
|
||||||
|
} \
|
||||||
if(saveJsonTimeZone == NULL) { \
|
if(saveJsonTimeZone == NULL) { \
|
||||||
errorThrow("Save JSON missing '%s.timeZone' key", key); \
|
errorThrow("Save JSON missing '%s.timeZone' key", key); \
|
||||||
} \
|
} \
|
||||||
|
|||||||
@@ -100,7 +100,9 @@ errorret_t sceneOverworldRender(scenedata_t *sceneData) {
|
|||||||
// shadermaterial_t skyboxMaterial = {
|
// shadermaterial_t skyboxMaterial = {
|
||||||
// .unlit = { .color = color(0xFF, 0x00, 0x00, 0xFF/2), .texture = NULL }
|
// .unlit = { .color = color(0xFF, 0x00, 0x00, 0xFF/2), .texture = NULL }
|
||||||
// };
|
// };
|
||||||
// errorChain(spriteBatchBuffer(&skyboxSprite, 1, &SHADER_UNLIT, skyboxMaterial));
|
// errorChain(
|
||||||
|
// spriteBatchBuffer(&skyboxSprite, 1, &SHADER_UNLIT, skyboxMaterial)
|
||||||
|
// );
|
||||||
// errorChain(spriteBatchFlush());
|
// errorChain(spriteBatchFlush());
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ errorret_t uiConsoleInit(void) {
|
|||||||
UICONSOLE.sprites[i], CONSOLE_LINE_MAX
|
UICONSOLE.sprites[i], CONSOLE_LINE_MAX
|
||||||
);
|
);
|
||||||
uiLabelSetX(&UICONSOLE.labels[i], (float_t)SCREEN.scanX);
|
uiLabelSetX(&UICONSOLE.labels[i], (float_t)SCREEN.scanX);
|
||||||
uiLabelSetY(&UICONSOLE.labels[i], (float_t)SCREEN.scanY + lineH * (float_t)i);
|
uiLabelSetY(
|
||||||
|
&UICONSOLE.labels[i], (float_t)SCREEN.scanY + lineH * (float_t)i
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
|
|||||||
@@ -381,7 +381,10 @@ void uiKeyboardMenuSelected(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(UI_KEYBOARD.onKeyPress != NULL && !UI_KEYBOARD.onKeyPress(c, UI_KEYBOARD.user)) {
|
if(
|
||||||
|
UI_KEYBOARD.onKeyPress != NULL &&
|
||||||
|
!UI_KEYBOARD.onKeyPress(c, UI_KEYBOARD.user)
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uiKeyboardAppendChar(c);
|
uiKeyboardAppendChar(c);
|
||||||
@@ -528,11 +531,15 @@ errorret_t uiKeyboardDraw(void) {
|
|||||||
uint8_t rows = (UI_KEYBOARD.menu.itemCount + columns - 1) / columns;
|
uint8_t rows = (UI_KEYBOARD.menu.itemCount + columns - 1) / columns;
|
||||||
|
|
||||||
float_t contentWidth = mathMax(
|
float_t contentWidth = mathMax(
|
||||||
mathMax((float_t)UI_KEYBOARD.titleLabel.width, (float_t)UI_KEYBOARD.textLabel.width),
|
mathMax(
|
||||||
|
(float_t)UI_KEYBOARD.titleLabel.width,
|
||||||
|
(float_t)UI_KEYBOARD.textLabel.width
|
||||||
|
),
|
||||||
(float_t)columns * UI_KEYBOARD_KEY_WIDTH
|
(float_t)columns * UI_KEYBOARD_KEY_WIDTH
|
||||||
);
|
);
|
||||||
float_t colStep = contentWidth / (float_t)columns;
|
float_t colStep = contentWidth / (float_t)columns;
|
||||||
float_t keyRowHeight = colStep * (UI_KEYBOARD_KEY_HEIGHT / UI_KEYBOARD_KEY_WIDTH);
|
float_t keyRowHeight =
|
||||||
|
colStep * (UI_KEYBOARD_KEY_HEIGHT / UI_KEYBOARD_KEY_WIDTH);
|
||||||
float_t contentHeight = rowHeight + UI_FRAME_PADDING_Y
|
float_t contentHeight = rowHeight + UI_FRAME_PADDING_Y
|
||||||
+ textHeight + UI_FRAME_PADDING_Y
|
+ textHeight + UI_FRAME_PADDING_Y
|
||||||
+ ((float_t)rows * keyRowHeight);
|
+ ((float_t)rows * keyRowHeight);
|
||||||
@@ -576,7 +583,9 @@ errorret_t uiKeyboardDraw(void) {
|
|||||||
&UI_KEYBOARD.cursorLabel,
|
&UI_KEYBOARD.cursorLabel,
|
||||||
contentX + (float_t)cursorCol * (float_t)FONT_DEFAULT_TILE_WIDTH
|
contentX + (float_t)cursorCol * (float_t)FONT_DEFAULT_TILE_WIDTH
|
||||||
);
|
);
|
||||||
uiLabelSetY(&UI_KEYBOARD.cursorLabel, textY + (float_t)cursorLine * rowHeight);
|
uiLabelSetY(
|
||||||
|
&UI_KEYBOARD.cursorLabel, textY + (float_t)cursorLine * rowHeight
|
||||||
|
);
|
||||||
errorChain(uiLabelRender(&UI_KEYBOARD.cursorLabel, COLOR_WHITE));
|
errorChain(uiLabelRender(&UI_KEYBOARD.cursorLabel, COLOR_WHITE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,9 @@ bool_t uiSaveSlotIsHighlighted(const uisaveslot_t *saveSlot) {
|
|||||||
return saveSlot->highlighted;
|
return saveSlot->highlighted;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiSaveSlotSetHighlighted(uisaveslot_t *saveSlot, const bool_t highlighted) {
|
void uiSaveSlotSetHighlighted(
|
||||||
|
uisaveslot_t *saveSlot, const bool_t highlighted
|
||||||
|
) {
|
||||||
assertNotNull(saveSlot, "Save slot cannot be NULL");
|
assertNotNull(saveSlot, "Save slot cannot be NULL");
|
||||||
saveSlot->highlighted = highlighted;
|
saveSlot->highlighted = highlighted;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,7 +157,8 @@ void uiSelectSaveSetActionLabel(const uiselectsavetype_t type) {
|
|||||||
);
|
);
|
||||||
if(errorIsNotOk(result)) errorCatch(result);
|
if(errorIsNotOk(result)) errorCatch(result);
|
||||||
|
|
||||||
UI_SELECT_SAVE.slotItems[UI_SELECT_SAVE_ACTION_INDEX].button.label.dirty = true;
|
UI_SELECT_SAVE.slotItems[UI_SELECT_SAVE_ACTION_INDEX].button.label.dirty =
|
||||||
|
true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiSelectSaveSwitchType(const uiselectsavetype_t type) {
|
void uiSelectSaveSwitchType(const uiselectsavetype_t type) {
|
||||||
@@ -346,7 +347,9 @@ void uiSelectSaveOpen(
|
|||||||
uiSelectSaveSetActionLabel(type);
|
uiSelectSaveSetActionLabel(type);
|
||||||
itemCount = UI_SELECT_SAVE_ITEM_CAPACITY;
|
itemCount = UI_SELECT_SAVE_ITEM_CAPACITY;
|
||||||
}
|
}
|
||||||
uiMenuSetItems(&UI_SELECT_SAVE.slotMenu, UI_SELECT_SAVE.slotItems, itemCount, 1);
|
uiMenuSetItems(
|
||||||
|
&UI_SELECT_SAVE.slotMenu, UI_SELECT_SAVE.slotItems, itemCount, 1
|
||||||
|
);
|
||||||
|
|
||||||
uiScrollingInit(&UI_SELECT_SAVE.scroll);
|
uiScrollingInit(&UI_SELECT_SAVE.scroll);
|
||||||
uiMenuOpen(&UI_SELECT_SAVE.slotMenu);
|
uiMenuOpen(&UI_SELECT_SAVE.slotMenu);
|
||||||
|
|||||||
@@ -97,7 +97,9 @@ errorret_t uiFatalErrorDraw(void) {
|
|||||||
|
|
||||||
const float_t menuY = contentY +
|
const float_t menuY = contentY +
|
||||||
(float_t)UI_FATAL_ERROR.messageLabel.height + UI_FRAME_PADDING_Y;
|
(float_t)UI_FATAL_ERROR.messageLabel.height + UI_FRAME_PADDING_Y;
|
||||||
errorChain(uiMenuDraw(&UI_FATAL_ERROR.menu, contentX, menuY, contentWidth, rowHeight));
|
errorChain(uiMenuDraw(
|
||||||
|
&UI_FATAL_ERROR.menu, contentX, menuY, contentWidth, rowHeight
|
||||||
|
));
|
||||||
|
|
||||||
errorChain(spriteBatchFlush());
|
errorChain(spriteBatchFlush());
|
||||||
errorOk();
|
errorOk();
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ bool_t uiCheckboxIsHighlighted(const uicheckbox_t *checkbox) {
|
|||||||
return checkbox->highlighted;
|
return checkbox->highlighted;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiCheckboxSetHighlighted(uicheckbox_t *checkbox, const bool_t highlighted) {
|
void uiCheckboxSetHighlighted(
|
||||||
|
uicheckbox_t *checkbox, const bool_t highlighted
|
||||||
|
) {
|
||||||
checkbox->highlighted = highlighted;
|
checkbox->highlighted = highlighted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -232,7 +232,10 @@ bool_t uiMenuFocusDirection(
|
|||||||
assertNotNull(focusItem->user, "Focus item user cannot be NULL");
|
assertNotNull(focusItem->user, "Focus item user cannot be NULL");
|
||||||
uimenu_t *menu = (uimenu_t *)focusItem->user;
|
uimenu_t *menu = (uimenu_t *)focusItem->user;
|
||||||
|
|
||||||
if(direction == UI_FOCUS_DIRECTION_LEFT || direction == UI_FOCUS_DIRECTION_RIGHT) {
|
if(
|
||||||
|
direction == UI_FOCUS_DIRECTION_LEFT ||
|
||||||
|
direction == UI_FOCUS_DIRECTION_RIGHT
|
||||||
|
) {
|
||||||
uint8_t slot = focusItem->y * menu->columns + focusItem->x;
|
uint8_t slot = focusItem->y * menu->columns + focusItem->x;
|
||||||
uint8_t index = uiMenuFocusSlotToIndex(menu, slot);
|
uint8_t index = uiMenuFocusSlotToIndex(menu, slot);
|
||||||
|
|
||||||
@@ -405,7 +408,9 @@ uint8_t uiMenuFocusableCount(const uimenu_t *menu) {
|
|||||||
uint8_t count = 0;
|
uint8_t count = 0;
|
||||||
for(uint8_t i = 0; i < menu->itemCount; i++) {
|
for(uint8_t i = 0; i < menu->itemCount; i++) {
|
||||||
uimenuwidgettype_t t = menu->items[i].type;
|
uimenuwidgettype_t t = menu->items[i].type;
|
||||||
if(t != UI_MENU_WIDGET_TYPE_LABEL && t != UI_MENU_WIDGET_TYPE_SPACER) count++;
|
if(t != UI_MENU_WIDGET_TYPE_LABEL && t != UI_MENU_WIDGET_TYPE_SPACER) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
@@ -415,7 +420,9 @@ uint8_t uiMenuFocusSlotToIndex(const uimenu_t *menu, const uint8_t slot) {
|
|||||||
uint8_t focusable = 0;
|
uint8_t focusable = 0;
|
||||||
for(uint8_t i = 0; i < menu->itemCount; i++) {
|
for(uint8_t i = 0; i < menu->itemCount; i++) {
|
||||||
uimenuwidgettype_t t = menu->items[i].type;
|
uimenuwidgettype_t t = menu->items[i].type;
|
||||||
if(t == UI_MENU_WIDGET_TYPE_LABEL || t == UI_MENU_WIDGET_TYPE_SPACER) continue;
|
if(t == UI_MENU_WIDGET_TYPE_LABEL || t == UI_MENU_WIDGET_TYPE_SPACER) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if(focusable == slot) return i;
|
if(focusable == slot) return i;
|
||||||
focusable++;
|
focusable++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -215,7 +215,8 @@ uint8_t uiMenuFocusSlotToIndex(const uimenu_t *menu, const uint8_t slot);
|
|||||||
void uiMenuItemSetHighlighted(uimenuitem_t *item, const bool_t highlighted);
|
void uiMenuItemSetHighlighted(uimenuitem_t *item, const bool_t highlighted);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal focus callback - forwards selection to the menu's selected handler.
|
* Internal focus callback - forwards selection to the menu's selected
|
||||||
|
* handler.
|
||||||
*
|
*
|
||||||
* @param focusItem The active focus item; user field must point to uimenu_t.
|
* @param focusItem The active focus item; user field must point to uimenu_t.
|
||||||
* @returns True.
|
* @returns True.
|
||||||
|
|||||||
@@ -166,7 +166,8 @@ void uiModalOpen(
|
|||||||
optionCount <= UI_MODAL_OPTIONS_MAX, "Too many options for modal"
|
optionCount <= UI_MODAL_OPTIONS_MAX, "Too many options for modal"
|
||||||
);
|
);
|
||||||
|
|
||||||
float_t maxContentWidth = ((float_t)SCREEN.scanWidth * UI_MODAL_MAX_WIDTH_RATIO)
|
float_t maxContentWidth =
|
||||||
|
((float_t)SCREEN.scanWidth * UI_MODAL_MAX_WIDTH_RATIO)
|
||||||
- (UI_FRAME_START_X * 2.0f);
|
- (UI_FRAME_START_X * 2.0f);
|
||||||
|
|
||||||
UI_MODAL.hasTitle = title != NULL;
|
UI_MODAL.hasTitle = title != NULL;
|
||||||
|
|||||||
@@ -159,7 +159,9 @@ errorret_t uiSliderDraw(
|
|||||||
|
|
||||||
spritebatchsprite_t trackSprite = {
|
spritebatchsprite_t trackSprite = {
|
||||||
.min = { trackX, trackY, 0.0f },
|
.min = { trackX, trackY, 0.0f },
|
||||||
.max = { trackX + UI_SLIDER_TRACK_WIDTH, trackY + UI_SLIDER_TRACK_HEIGHT, 0.0f },
|
.max = {
|
||||||
|
trackX + UI_SLIDER_TRACK_WIDTH, trackY + UI_SLIDER_TRACK_HEIGHT, 0.0f
|
||||||
|
},
|
||||||
.uvMin = { 0.0f, 0.0f },
|
.uvMin = { 0.0f, 0.0f },
|
||||||
.uvMax = { 1.0f, 1.0f }
|
.uvMax = { 1.0f, 1.0f }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -70,13 +70,16 @@ errorret_t audioStreamDolphinBuffer(audiostream_t *stream) {
|
|||||||
// end of the clip if not looping (or if startFrame already landed past
|
// end of the clip if not looping (or if startFrame already landed past
|
||||||
// the loop end, e.g. a seek into an outro). See
|
// the loop end, e.g. a seek into an outro). See
|
||||||
// audioStreamComputeEndFrame()'s own comment.
|
// audioStreamComputeEndFrame()'s own comment.
|
||||||
const size_t endFrame = audioStreamComputeEndFrame(stream, startFrame, totalFrames);
|
const size_t endFrame =
|
||||||
|
audioStreamComputeEndFrame(stream, startFrame, totalFrames);
|
||||||
|
|
||||||
float_t leftFactor, rightFactor;
|
float_t leftFactor, rightFactor;
|
||||||
audioStreamGetPanFactors(stream, &leftFactor, &rightFactor);
|
audioStreamGetPanFactors(stream, &leftFactor, &rightFactor);
|
||||||
const float_t baseVolume = stream->volume;
|
const float_t baseVolume = stream->volume;
|
||||||
stream->platform.volumeLeft = (s32) mathClamp(baseVolume * leftFactor * MAX_VOLUME, 0, MAX_VOLUME);
|
stream->platform.volumeLeft =
|
||||||
stream->platform.volumeRight = (s32) mathClamp(baseVolume * rightFactor * MAX_VOLUME, 0, MAX_VOLUME);
|
(s32) mathClamp(baseVolume * leftFactor * MAX_VOLUME, 0, MAX_VOLUME);
|
||||||
|
stream->platform.volumeRight =
|
||||||
|
(s32) mathClamp(baseVolume * rightFactor * MAX_VOLUME, 0, MAX_VOLUME);
|
||||||
|
|
||||||
// A fresh pass discards whatever windows were previously queued (both
|
// A fresh pass discards whatever windows were previously queued (both
|
||||||
// ASND buffer slots) rather than letting it play out - a natural loop
|
// ASND buffer slots) rather than letting it play out - a natural loop
|
||||||
@@ -140,13 +143,15 @@ errorret_t audioStreamDolphinFeed(audiostream_t *stream) {
|
|||||||
// silently skipping every ASND_AddVoice() call forever after the first
|
// silently skipping every ASND_AddVoice() call forever after the first
|
||||||
// window - confirmed the hard way (only ever heard a clip's first
|
// window - confirmed the hard way (only ever heard a clip's first
|
||||||
// buffered window, nothing ever played after it).
|
// buffered window, nothing ever played after it).
|
||||||
const bool_t ready = ASND_TestVoiceBufferReady(stream->platform.voiceId) == SND_OK;
|
const bool_t ready =
|
||||||
|
ASND_TestVoiceBufferReady(stream->platform.voiceId) == SND_OK;
|
||||||
if(stream->platform.primed && !ready) {
|
if(stream->platform.primed && !ready) {
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t frameSize = stream->channels * sizeof(int16_t);
|
const size_t frameSize = stream->channels * sizeof(int16_t);
|
||||||
const size_t framesRemaining = stream->platform.endFrame - stream->platform.position;
|
const size_t framesRemaining =
|
||||||
|
stream->platform.endFrame - stream->platform.position;
|
||||||
const size_t framesToRead = mathMin(
|
const size_t framesToRead = mathMin(
|
||||||
(size_t) AUDIO_DOLPHIN_WINDOW_FRAMES, framesRemaining
|
(size_t) AUDIO_DOLPHIN_WINDOW_FRAMES, framesRemaining
|
||||||
);
|
);
|
||||||
@@ -179,7 +184,8 @@ errorret_t audioStreamDolphinFeed(audiostream_t *stream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!stream->platform.primed) {
|
if(!stream->platform.primed) {
|
||||||
const s32 format = stream->channels == 1 ? VOICE_MONO_16BIT : VOICE_STEREO_16BIT;
|
const s32 format =
|
||||||
|
stream->channels == 1 ? VOICE_MONO_16BIT : VOICE_STEREO_16BIT;
|
||||||
const s32 pitch = (s32) stream->sampleRate;
|
const s32 pitch = (s32) stream->sampleRate;
|
||||||
const s32 result = ASND_SetVoice(
|
const s32 result = ASND_SetVoice(
|
||||||
stream->platform.voiceId, format, pitch, 0,
|
stream->platform.voiceId, format, pitch, 0,
|
||||||
|
|||||||
@@ -221,7 +221,9 @@ errorret_t saveDeviceDolphinCardDataWrite(
|
|||||||
int32_t writeResult = CARD_Write(&file, paddedBuffer, paddedSize, 0);
|
int32_t writeResult = CARD_Write(&file, paddedBuffer, paddedSize, 0);
|
||||||
CARD_Close(&file);
|
CARD_Close(&file);
|
||||||
memoryFree(paddedBuffer);
|
memoryFree(paddedBuffer);
|
||||||
if(writeResult < 0) errorThrow("Failed to write save data: %s", targetFilename);
|
if(writeResult < 0) {
|
||||||
|
errorThrow("Failed to write save data: %s", targetFilename);
|
||||||
|
}
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ systemdialogtype_t systemGetActiveDialogTypeDolphin(void);
|
|||||||
* ratio of the system. I do believe that Gamecube will only ever return 4:3.
|
* ratio of the system. I do believe that Gamecube will only ever return 4:3.
|
||||||
*
|
*
|
||||||
* Refer to;
|
* Refer to;
|
||||||
* https://github.com/devkitPro/libogc/blob/20d90e944b83c8991538e88b00b1e5f309428e85/gc/ogc/conf.h#L190
|
* https://github.com/devkitPro/libogc/blob/
|
||||||
|
* 20d90e944b83c8991538e88b00b1e5f309428e85/gc/ogc/conf.h#L190
|
||||||
*
|
*
|
||||||
* @return Aspect ratio of the system.
|
* @return Aspect ratio of the system.
|
||||||
*/
|
*/
|
||||||
@@ -38,7 +39,8 @@ int32_t systemGetAspectRatioDolphin(void);
|
|||||||
* locale management, to try to match the system language if possible.
|
* locale management, to try to match the system language if possible.
|
||||||
*
|
*
|
||||||
* Refer to;
|
* Refer to;
|
||||||
* https://github.com/devkitPro/libogc/blob/20d90e944b83c8991538e88b00b1e5f309428e85/gc/ogc/conf.h#L190
|
* https://github.com/devkitPro/libogc/blob/
|
||||||
|
* 20d90e944b83c8991538e88b00b1e5f309428e85/gc/ogc/conf.h#L190
|
||||||
*
|
*
|
||||||
* On gamecube, refer to;
|
* On gamecube, refer to;
|
||||||
* https://libogc.devkitpro.org/system_8h.html
|
* https://libogc.devkitpro.org/system_8h.html
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ errorret_t meshInitGL(
|
|||||||
mesh->vertices = vertices;
|
mesh->vertices = vertices;
|
||||||
|
|
||||||
#ifdef DUSK_OPENGL_LEGACY
|
#ifdef DUSK_OPENGL_LEGACY
|
||||||
// Nothing needed; client state is enabled once globally in displayOpenGLInit.
|
// Nothing needed; client state is enabled once globally in
|
||||||
|
// displayOpenGLInit.
|
||||||
#else
|
#else
|
||||||
// Generate Vertex Buffer Object
|
// Generate Vertex Buffer Object
|
||||||
glGenBuffers(1, &mesh->vboId);
|
glGenBuffers(1, &mesh->vboId);
|
||||||
|
|||||||
@@ -75,7 +75,8 @@ errorret_t audioStreamLinuxBuffer(audiostream_t *stream) {
|
|||||||
// end of the clip if not looping (or if startFrame already landed past
|
// end of the clip if not looping (or if startFrame already landed past
|
||||||
// the loop end, e.g. a seek into an outro). See
|
// the loop end, e.g. a seek into an outro). See
|
||||||
// audioStreamComputeEndFrame()'s own comment.
|
// audioStreamComputeEndFrame()'s own comment.
|
||||||
const size_t endFrame = audioStreamComputeEndFrame(stream, startFrame, totalFrames);
|
const size_t endFrame =
|
||||||
|
audioStreamComputeEndFrame(stream, startFrame, totalFrames);
|
||||||
|
|
||||||
// Only an explicit seek discards whatever's still queued and jumps -
|
// Only an explicit seek discards whatever's still queued and jumps -
|
||||||
// a natural loop restart deliberately leaves the previous pass's tail
|
// a natural loop restart deliberately leaves the previous pass's tail
|
||||||
|
|||||||
@@ -111,7 +111,8 @@ errorret_t audioStreamMp3DecoderRefill(audiostream_t *stream);
|
|||||||
* (minimad.c et al.), rounding to nearest and clamping to +/-1.0 rather
|
* (minimad.c et al.), rounding to nearest and clamping to +/-1.0 rather
|
||||||
* than wrapping on overflow.
|
* than wrapping on overflow.
|
||||||
*
|
*
|
||||||
* @param sample The fixed-point sample to convert (mad_fixed_t, Q1.MAD_F_FRACBITS).
|
* @param sample The fixed-point sample to convert (mad_fixed_t,
|
||||||
|
* Q1.MAD_F_FRACBITS).
|
||||||
* @return The converted 16-bit signed sample.
|
* @return The converted 16-bit signed sample.
|
||||||
*/
|
*/
|
||||||
int16_t audioStreamMp3DecoderScale(mad_fixed_t sample);
|
int16_t audioStreamMp3DecoderScale(mad_fixed_t sample);
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ errorret_t audioStreamMp3RingInit(audiostream_t *stream) {
|
|||||||
const size_t frameSize = stream->channels * sizeof(int16_t);
|
const size_t frameSize = stream->channels * sizeof(int16_t);
|
||||||
|
|
||||||
ring->data = (int16_t *) memoryAllocate(AUDIO_MP3_RING_FRAMES * frameSize);
|
ring->data = (int16_t *) memoryAllocate(AUDIO_MP3_RING_FRAMES * frameSize);
|
||||||
ring->scratch = (int16_t *) memoryAllocate(AUDIO_MP3_RING_STEP_FRAMES * frameSize);
|
ring->scratch =
|
||||||
|
(int16_t *) memoryAllocate(AUDIO_MP3_RING_STEP_FRAMES * frameSize);
|
||||||
ring->readPos = 0;
|
ring->readPos = 0;
|
||||||
ring->writePos = 0;
|
ring->writePos = 0;
|
||||||
ring->filled = 0;
|
ring->filled = 0;
|
||||||
@@ -127,8 +128,12 @@ size_t audioStreamMp3RingDrain(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const size_t toCopy = mathMin(available, maxFrames);
|
const size_t toCopy = mathMin(available, maxFrames);
|
||||||
const size_t firstPart = mathMin(toCopy, AUDIO_MP3_RING_FRAMES - ring->readPos);
|
const size_t firstPart =
|
||||||
memoryCopy(out, ring->data + ring->readPos * channels, firstPart * channels * sizeof(int16_t));
|
mathMin(toCopy, AUDIO_MP3_RING_FRAMES - ring->readPos);
|
||||||
|
memoryCopy(
|
||||||
|
out, ring->data + ring->readPos * channels,
|
||||||
|
firstPart * channels * sizeof(int16_t)
|
||||||
|
);
|
||||||
if(toCopy > firstPart) {
|
if(toCopy > firstPart) {
|
||||||
memoryCopy(
|
memoryCopy(
|
||||||
out + firstPart * channels, ring->data,
|
out + firstPart * channels, ring->data,
|
||||||
@@ -286,7 +291,8 @@ errorret_t audioStreamReadForPlayback(
|
|||||||
|
|
||||||
if(stream->type == AUDIO_STREAM_TYPE_MP3) {
|
if(stream->type == AUDIO_STREAM_TYPE_MP3) {
|
||||||
bool_t decodeDone = false;
|
bool_t decodeDone = false;
|
||||||
*outFramesRead = audioStreamMp3RingDrain(stream, out, maxFrames, &decodeDone);
|
*outFramesRead =
|
||||||
|
audioStreamMp3RingDrain(stream, out, maxFrames, &decodeDone);
|
||||||
if(*outFramesRead == 0 && !decodeDone) {
|
if(*outFramesRead == 0 && !decodeDone) {
|
||||||
*outNotReadyYet = true;
|
*outNotReadyYet = true;
|
||||||
errorOk();
|
errorOk();
|
||||||
|
|||||||
@@ -147,7 +147,8 @@ errorret_t audioStreamMp3RingStop(audiostream_t *stream);
|
|||||||
* it reaches endFrame, filling back up whenever audioStreamMp3RingDrain()
|
* it reaches endFrame, filling back up whenever audioStreamMp3RingDrain()
|
||||||
* makes room.
|
* makes room.
|
||||||
*
|
*
|
||||||
* @param stream The audio stream to start decoding. Must be AUDIO_STREAM_TYPE_MP3.
|
* @param stream The audio stream to start decoding. Must be
|
||||||
|
* AUDIO_STREAM_TYPE_MP3.
|
||||||
* @param startFrame This pass's starting frame offset.
|
* @param startFrame This pass's starting frame offset.
|
||||||
* @param endFrame This pass's stop frame offset.
|
* @param endFrame This pass's stop frame offset.
|
||||||
* @return Error state if any.
|
* @return Error state if any.
|
||||||
|
|||||||
@@ -194,7 +194,9 @@ errorret_t audioStreamMp3DecoderDecodeFrame(
|
|||||||
const size_t frameSize = stream->channels * sizeof(int16_t);
|
const size_t frameSize = stream->channels * sizeof(int16_t);
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if(sceMp3CheckStreamDataNeeded(decoder->handle) > 0 && !decoder->endOfFile) {
|
if(
|
||||||
|
sceMp3CheckStreamDataNeeded(decoder->handle) > 0 && !decoder->endOfFile
|
||||||
|
) {
|
||||||
errorChain(audioStreamMp3DecoderFillStream(stream));
|
errorChain(audioStreamMp3DecoderFillStream(stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,7 +212,8 @@ errorret_t audioStreamMp3DecoderDecodeFrame(
|
|||||||
// whatever followed stream->mp3.pending in memory, and only showed
|
// whatever followed stream->mp3.pending in memory, and only showed
|
||||||
// up as very intermittent audio clicking.
|
// up as very intermittent audio clicking.
|
||||||
assertTrue(
|
assertTrue(
|
||||||
(size_t) bytesDecoded <= AUDIO_MP3_MAX_SAMPLES_PER_FRAME * sizeof(int16_t),
|
(size_t) bytesDecoded <=
|
||||||
|
AUDIO_MP3_MAX_SAMPLES_PER_FRAME * sizeof(int16_t),
|
||||||
"sceMp3Decode returned more PCM than the destination buffer can hold."
|
"sceMp3Decode returned more PCM than the destination buffer can hold."
|
||||||
);
|
);
|
||||||
const size_t frames = (size_t) bytesDecoded / frameSize;
|
const size_t frames = (size_t) bytesDecoded / frameSize;
|
||||||
|
|||||||
@@ -48,8 +48,9 @@ typedef struct {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Feeds sceMp3 more compressed bytes if (and only as much as) it currently
|
* Feeds sceMp3 more compressed bytes if (and only as much as) it currently
|
||||||
* wants: asks it where in the stream and how much (sceMp3GetInfoToAddStreamData()),
|
* wants: asks it where in the stream and how much
|
||||||
* reads exactly that from stream->mp3.file, and hands it back
|
* (sceMp3GetInfoToAddStreamData()), reads exactly that from stream->mp3.file,
|
||||||
|
* and hands it back
|
||||||
* (sceMp3NotifyAddStreamData()). A no-op if sceMp3 doesn't currently want
|
* (sceMp3NotifyAddStreamData()). A no-op if sceMp3 doesn't currently want
|
||||||
* more. See this file's own top-of-file comment on why the source
|
* more. See this file's own top-of-file comment on why the source
|
||||||
* position sceMp3 requests is asserted rather than actually used to seek.
|
* position sceMp3 requests is asserted rather than actually used to seek.
|
||||||
|
|||||||
@@ -127,7 +127,8 @@ errorret_t audioStreamPSPBuffer(audiostream_t *stream) {
|
|||||||
stream->platform.loopEndFrame
|
stream->platform.loopEndFrame
|
||||||
);
|
);
|
||||||
|
|
||||||
const size_t startFrame = mathMin(stream->startFrame, stream->platform.totalFrames);
|
const size_t startFrame =
|
||||||
|
mathMin(stream->startFrame, stream->platform.totalFrames);
|
||||||
stream->startFrame = 0;
|
stream->startFrame = 0;
|
||||||
stream->seeking = false;
|
stream->seeking = false;
|
||||||
|
|
||||||
@@ -181,10 +182,12 @@ void audioStreamPSPTopUp(audiostream_t *stream) {
|
|||||||
const size_t room = mathMin(
|
const size_t room = mathMin(
|
||||||
AUDIO_PSP_RING_FRAMES - filled, (size_t) AUDIO_PSP_TOPUP_STEP_FRAMES
|
AUDIO_PSP_RING_FRAMES - filled, (size_t) AUDIO_PSP_TOPUP_STEP_FRAMES
|
||||||
);
|
);
|
||||||
const size_t currentEndFrame = stream->platform.readPosition < stream->platform.loopEndFrame
|
const size_t currentEndFrame =
|
||||||
|
stream->platform.readPosition < stream->platform.loopEndFrame
|
||||||
? stream->platform.loopEndFrame
|
? stream->platform.loopEndFrame
|
||||||
: stream->platform.totalFrames;
|
: stream->platform.totalFrames;
|
||||||
const size_t framesRemainingInSegment = currentEndFrame - stream->platform.readPosition;
|
const size_t framesRemainingInSegment =
|
||||||
|
currentEndFrame - stream->platform.readPosition;
|
||||||
const size_t framesToRead = mathMin(room, framesRemainingInSegment);
|
const size_t framesToRead = mathMin(room, framesRemainingInSegment);
|
||||||
|
|
||||||
if(framesToRead > 0) {
|
if(framesToRead > 0) {
|
||||||
@@ -201,7 +204,8 @@ void audioStreamPSPTopUp(audiostream_t *stream) {
|
|||||||
if(framesRead > 0) {
|
if(framesRead > 0) {
|
||||||
threadMutexLock(&stream->platform.ringLock);
|
threadMutexLock(&stream->platform.ringLock);
|
||||||
for(size_t i = 0; i < framesRead; i++) {
|
for(size_t i = 0; i < framesRead; i++) {
|
||||||
const size_t writeIndex = (stream->platform.ringWritePos + i) % AUDIO_PSP_RING_FRAMES;
|
const size_t writeIndex =
|
||||||
|
(stream->platform.ringWritePos + i) % AUDIO_PSP_RING_FRAMES;
|
||||||
memoryCopy(
|
memoryCopy(
|
||||||
stream->platform.ring + (writeIndex * channels),
|
stream->platform.ring + (writeIndex * channels),
|
||||||
scratch + (i * channels),
|
scratch + (i * channels),
|
||||||
@@ -239,7 +243,8 @@ void audioStreamPSPTopUp(audiostream_t *stream) {
|
|||||||
// still the right thing to compare against loopLimit.
|
// still the right thing to compare against loopLimit.
|
||||||
const bool_t loopLimitReached = stream->loopLimit > 0 &&
|
const bool_t loopLimitReached = stream->loopLimit > 0 &&
|
||||||
stream->loopRestartCount >= stream->loopLimit;
|
stream->loopRestartCount >= stream->loopLimit;
|
||||||
const bool_t reachesSegmentEnd = stream->platform.readPosition >= currentEndFrame;
|
const bool_t reachesSegmentEnd =
|
||||||
|
stream->platform.readPosition >= currentEndFrame;
|
||||||
const bool_t willLoop = reachesSegmentEnd &&
|
const bool_t willLoop = reachesSegmentEnd &&
|
||||||
(stream->state & AUDIO_STREAM_STATE_LOOPING) && !loopLimitReached;
|
(stream->state & AUDIO_STREAM_STATE_LOOPING) && !loopLimitReached;
|
||||||
|
|
||||||
@@ -257,7 +262,8 @@ void audioStreamPSPTopUp(audiostream_t *stream) {
|
|||||||
const size_t index = (
|
const size_t index = (
|
||||||
stream->platform.loopMarkerHead + stream->platform.loopMarkerCount
|
stream->platform.loopMarkerHead + stream->platform.loopMarkerCount
|
||||||
) % AUDIO_PSP_LOOP_MARKER_MAX;
|
) % AUDIO_PSP_LOOP_MARKER_MAX;
|
||||||
stream->platform.loopMarkerFrames[index] = stream->platform.framesEnqueued;
|
stream->platform.loopMarkerFrames[index] =
|
||||||
|
stream->platform.framesEnqueued;
|
||||||
stream->platform.loopMarkerCount++;
|
stream->platform.loopMarkerCount++;
|
||||||
}
|
}
|
||||||
threadMutexUnlock(&stream->platform.ringLock);
|
threadMutexUnlock(&stream->platform.ringLock);
|
||||||
@@ -282,7 +288,9 @@ bool_t audioStreamPSPIsFinished(audiostream_t *stream) {
|
|||||||
void audioStreamPSPThreadFeed(thread_t *thread) {
|
void audioStreamPSPThreadFeed(thread_t *thread) {
|
||||||
assertNotNull(thread, "Thread cannot be NULL.");
|
assertNotNull(thread, "Thread cannot be NULL.");
|
||||||
|
|
||||||
sceKernelChangeThreadPriority(sceKernelGetThreadId(), AUDIO_PSP_THREAD_PRIORITY);
|
sceKernelChangeThreadPriority(
|
||||||
|
sceKernelGetThreadId(), AUDIO_PSP_THREAD_PRIORITY
|
||||||
|
);
|
||||||
|
|
||||||
audiostream_t *stream = (audiostream_t *) thread->data;
|
audiostream_t *stream = (audiostream_t *) thread->data;
|
||||||
const size_t channels = stream->channels;
|
const size_t channels = stream->channels;
|
||||||
@@ -321,7 +329,9 @@ void audioStreamPSPThreadFeed(thread_t *thread) {
|
|||||||
threadMutexUnlock(&stream->platform.ringLock);
|
threadMutexUnlock(&stream->platform.ringLock);
|
||||||
|
|
||||||
if(available >= AUDIO_PSP_CHUNK_FRAMES) break;
|
if(available >= AUDIO_PSP_CHUNK_FRAMES) break;
|
||||||
if(stream->platform.readReachedEnd || stream->platform.readFailed) break;
|
if(
|
||||||
|
stream->platform.readReachedEnd || stream->platform.readFailed
|
||||||
|
) break;
|
||||||
if(threadShouldStop(thread)) {
|
if(threadShouldStop(thread)) {
|
||||||
stopRequested = true;
|
stopRequested = true;
|
||||||
break;
|
break;
|
||||||
@@ -358,7 +368,8 @@ void audioStreamPSPThreadFeed(thread_t *thread) {
|
|||||||
|
|
||||||
threadMutexLock(&stream->platform.ringLock);
|
threadMutexLock(&stream->platform.ringLock);
|
||||||
for(size_t i = 0; i < framesThisChunk; i++) {
|
for(size_t i = 0; i < framesThisChunk; i++) {
|
||||||
const size_t readIndex = (stream->platform.ringReadPos + i) % AUDIO_PSP_RING_FRAMES;
|
const size_t readIndex =
|
||||||
|
(stream->platform.ringReadPos + i) % AUDIO_PSP_RING_FRAMES;
|
||||||
memoryCopy(
|
memoryCopy(
|
||||||
chunk + (i * channels),
|
chunk + (i * channels),
|
||||||
stream->platform.ring + (readIndex * channels),
|
stream->platform.ring + (readIndex * channels),
|
||||||
@@ -366,7 +377,8 @@ void audioStreamPSPThreadFeed(thread_t *thread) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
stream->platform.ringReadPos =
|
stream->platform.ringReadPos =
|
||||||
(stream->platform.ringReadPos + framesThisChunk) % AUDIO_PSP_RING_FRAMES;
|
(stream->platform.ringReadPos + framesThisChunk) %
|
||||||
|
AUDIO_PSP_RING_FRAMES;
|
||||||
stream->platform.ringFilled -= framesThisChunk;
|
stream->platform.ringFilled -= framesThisChunk;
|
||||||
threadMutexUnlock(&stream->platform.ringLock);
|
threadMutexUnlock(&stream->platform.ringLock);
|
||||||
|
|
||||||
@@ -389,7 +401,8 @@ void audioStreamPSPThreadFeed(thread_t *thread) {
|
|||||||
: AUDIO_PSP_FADE_FRAMES;
|
: AUDIO_PSP_FADE_FRAMES;
|
||||||
for(size_t i = 0; i < fadeFrames; i++) {
|
for(size_t i = 0; i < fadeFrames; i++) {
|
||||||
const size_t frame = framesThisChunk - fadeFrames + i;
|
const size_t frame = framesThisChunk - fadeFrames + i;
|
||||||
const float_t factor = 1.0f - ((float_t) (i + 1) / (float_t) fadeFrames);
|
const float_t factor =
|
||||||
|
1.0f - ((float_t) (i + 1) / (float_t) fadeFrames);
|
||||||
for(size_t c = 0; c < channels; c++) {
|
for(size_t c = 0; c < channels; c++) {
|
||||||
int16_t *sample = &chunk[frame * channels + c];
|
int16_t *sample = &chunk[frame * channels + c];
|
||||||
*sample = (int16_t) ((float_t) *sample * factor);
|
*sample = (int16_t) ((float_t) *sample * factor);
|
||||||
|
|||||||
@@ -172,7 +172,8 @@ void networkPSPRequestConnection(
|
|||||||
|
|
||||||
|
|
||||||
// This is all related to getting the PSP online, refer to;
|
// This is all related to getting the PSP online, refer to;
|
||||||
// https://github.com/joel16/CMFileManager-PSP/blob/00dab16c64cd48bf6452fc274a3b898d77c39a8d/app/source/net.cpp#L97
|
// https://github.com/joel16/CMFileManager-PSP/blob/
|
||||||
|
// 00dab16c64cd48bf6452fc274a3b898d77c39a8d/app/source/net.cpp#L97
|
||||||
// since I follow this implementation closely.
|
// since I follow this implementation closely.
|
||||||
memoryZero(&NETWORK.platform.dialogData, sizeof(NETWORK.platform.dialogData));
|
memoryZero(&NETWORK.platform.dialogData, sizeof(NETWORK.platform.dialogData));
|
||||||
memoryZero(
|
memoryZero(
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ int_t systemPSPGetLanguage() {
|
|||||||
|
|
||||||
int_t systemPSPGetCrossButtonSetting() {
|
int_t systemPSPGetCrossButtonSetting() {
|
||||||
int_t ret;
|
int_t ret;
|
||||||
// See: https://pspdev.github.io/pspsdk/psputility__sysparam_8h.html#ab588fd5a14adc025f065e09325ffe729
|
// See: https://pspdev.github.io/pspsdk/psputility__sysparam_8h.html
|
||||||
|
// #ab588fd5a14adc025f065e09325ffe729
|
||||||
sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN, &ret);
|
sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN, &ret);
|
||||||
return (
|
return (
|
||||||
ret == 1 ? PSP_UTILITY_ACCEPT_CROSS : PSP_UTILITY_ACCEPT_CIRCLE
|
ret == 1 ? PSP_UTILITY_ACCEPT_CROSS : PSP_UTILITY_ACCEPT_CIRCLE
|
||||||
|
|||||||
@@ -84,7 +84,9 @@ static void test_animationInitMultiLayerDurationIsMax(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void test_animationInitNullAsserts(void **state) {
|
static void test_animationInitNullAsserts(void **state) {
|
||||||
keyframe_t keyframes[1] = { { .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR } };
|
keyframe_t keyframes[1] = {
|
||||||
|
{ .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR },
|
||||||
|
};
|
||||||
uint16_t keyframeCounts[1] = { 1 };
|
uint16_t keyframeCounts[1] = { 1 };
|
||||||
animation_t anim;
|
animation_t anim;
|
||||||
|
|
||||||
@@ -94,7 +96,9 @@ static void test_animationInitNullAsserts(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void test_animationInitZeroLayerCountAsserts(void **state) {
|
static void test_animationInitZeroLayerCountAsserts(void **state) {
|
||||||
keyframe_t keyframes[1] = { { .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR } };
|
keyframe_t keyframes[1] = {
|
||||||
|
{ .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR },
|
||||||
|
};
|
||||||
uint16_t keyframeCounts[1] = { 1 };
|
uint16_t keyframeCounts[1] = { 1 };
|
||||||
animation_t anim;
|
animation_t anim;
|
||||||
|
|
||||||
@@ -112,7 +116,9 @@ static void test_animationInitUnsortedKeyframesAsserts(void **state) {
|
|||||||
expect_assert_failure(animationInit(&anim, keyframes, keyframeCounts, 1));
|
expect_assert_failure(animationInit(&anim, keyframes, keyframeCounts, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_animationGetLayerValueSamplesEachLayerIndependently(void **state) {
|
static void test_animationGetLayerValueSamplesEachLayerIndependently(
|
||||||
|
void **state
|
||||||
|
) {
|
||||||
keyframe_t keyframes[4] = {
|
keyframe_t keyframes[4] = {
|
||||||
{ .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR },
|
{ .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR },
|
||||||
{ .time = 2.0f, .value = 20.0f, .easing = EASING_LINEAR },
|
{ .time = 2.0f, .value = 20.0f, .easing = EASING_LINEAR },
|
||||||
@@ -159,7 +165,9 @@ static void test_animationUpdateAdvancesTimeAndCallsOnUpdate(void **state) {
|
|||||||
assert_int_equal(cb.completeCount, 0);
|
assert_int_equal(cb.completeCount, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_animationUpdatePlainPlayStopsAtEndAndFiresOnceOnly(void **state) {
|
static void test_animationUpdatePlainPlayStopsAtEndAndFiresOnceOnly(
|
||||||
|
void **state
|
||||||
|
) {
|
||||||
keyframe_t keyframes[2] = {
|
keyframe_t keyframes[2] = {
|
||||||
{ .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR },
|
{ .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR },
|
||||||
{ .time = 2.0f, .value = 20.0f, .easing = EASING_LINEAR },
|
{ .time = 2.0f, .value = 20.0f, .easing = EASING_LINEAR },
|
||||||
@@ -219,7 +227,9 @@ static void test_animationUpdateLoopWrapsAndFiresOnLoop(void **state) {
|
|||||||
assert_int_equal(cb.completeCount, 0);
|
assert_int_equal(cb.completeCount, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_animationUpdateLoopStopEndCompletesInsteadOfWrapping(void **state) {
|
static void test_animationUpdateLoopStopEndCompletesInsteadOfWrapping(
|
||||||
|
void **state
|
||||||
|
) {
|
||||||
keyframe_t keyframes[2] = {
|
keyframe_t keyframes[2] = {
|
||||||
{ .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR },
|
{ .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR },
|
||||||
{ .time = 2.0f, .value = 20.0f, .easing = EASING_LINEAR },
|
{ .time = 2.0f, .value = 20.0f, .easing = EASING_LINEAR },
|
||||||
@@ -277,7 +287,9 @@ static void test_animationUpdateReverseStopsAtBeginning(void **state) {
|
|||||||
assert_int_equal(cb.completeCount, 1);
|
assert_int_equal(cb.completeCount, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_animationUpdatePingpongBouncesForeverWithoutStopFlags(void **state) {
|
static void test_animationUpdatePingpongBouncesForeverWithoutStopFlags(
|
||||||
|
void **state
|
||||||
|
) {
|
||||||
keyframe_t keyframes[2] = {
|
keyframe_t keyframes[2] = {
|
||||||
{ .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR },
|
{ .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR },
|
||||||
{ .time = 2.0f, .value = 20.0f, .easing = EASING_LINEAR },
|
{ .time = 2.0f, .value = 20.0f, .easing = EASING_LINEAR },
|
||||||
@@ -320,7 +332,9 @@ static void test_animationUpdatePingpongStopEndCompletesAtEnd(void **state) {
|
|||||||
assert_int_equal(cb.completeCount, 1);
|
assert_int_equal(cb.completeCount, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_animationUpdatePingpongStopBeginningCompletesAtStart(void **state) {
|
static void test_animationUpdatePingpongStopBeginningCompletesAtStart(
|
||||||
|
void **state
|
||||||
|
) {
|
||||||
keyframe_t keyframes[2] = {
|
keyframe_t keyframes[2] = {
|
||||||
{ .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR },
|
{ .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR },
|
||||||
{ .time = 2.0f, .value = 20.0f, .easing = EASING_LINEAR },
|
{ .time = 2.0f, .value = 20.0f, .easing = EASING_LINEAR },
|
||||||
@@ -376,7 +390,9 @@ static void test_animationUpdateNegativeDeltaTimeAsserts(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void test_animationInitZeroDurationAsserts(void **state) {
|
static void test_animationInitZeroDurationAsserts(void **state) {
|
||||||
keyframe_t keyframes[1] = { { .time = 0.0f, .value = 5.0f, .easing = EASING_LINEAR } };
|
keyframe_t keyframes[1] = {
|
||||||
|
{ .time = 0.0f, .value = 5.0f, .easing = EASING_LINEAR },
|
||||||
|
};
|
||||||
uint16_t keyframeCounts[1] = { 1 };
|
uint16_t keyframeCounts[1] = { 1 };
|
||||||
animation_t anim;
|
animation_t anim;
|
||||||
|
|
||||||
@@ -412,7 +428,9 @@ int main(int argc, char **argv) {
|
|||||||
cmocka_unit_test(test_animationUpdateLoopStopEndCompletesInsteadOfWrapping),
|
cmocka_unit_test(test_animationUpdateLoopStopEndCompletesInsteadOfWrapping),
|
||||||
cmocka_unit_test(test_animationUpdateReversePlaysBackward),
|
cmocka_unit_test(test_animationUpdateReversePlaysBackward),
|
||||||
cmocka_unit_test(test_animationUpdateReverseStopsAtBeginning),
|
cmocka_unit_test(test_animationUpdateReverseStopsAtBeginning),
|
||||||
cmocka_unit_test(test_animationUpdatePingpongBouncesForeverWithoutStopFlags),
|
cmocka_unit_test(
|
||||||
|
test_animationUpdatePingpongBouncesForeverWithoutStopFlags
|
||||||
|
),
|
||||||
cmocka_unit_test(test_animationUpdatePingpongStopEndCompletesAtEnd),
|
cmocka_unit_test(test_animationUpdatePingpongStopEndCompletesAtEnd),
|
||||||
cmocka_unit_test(test_animationUpdatePingpongStopBeginningCompletesAtStart),
|
cmocka_unit_test(test_animationUpdatePingpongStopBeginningCompletesAtStart),
|
||||||
cmocka_unit_test(test_animationUpdateMultiLayerCallsOnUpdatePerLayer),
|
cmocka_unit_test(test_animationUpdateMultiLayerCallsOnUpdatePerLayer),
|
||||||
|
|||||||
@@ -141,22 +141,61 @@ static void test_easingInOutBack(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void test_easingApplyDispatchesToEachType(void **state) {
|
static void test_easingApplyDispatchesToEachType(void **state) {
|
||||||
assert_float_equal(easingApply(EASING_LINEAR, 0.5f), easingLinear(0.5f), EASING_TOLERANCE);
|
assert_float_equal(
|
||||||
assert_float_equal(easingApply(EASING_IN_SINE, 0.5f), easingInSine(0.5f), EASING_TOLERANCE);
|
easingApply(EASING_LINEAR, 0.5f), easingLinear(0.5f), EASING_TOLERANCE
|
||||||
assert_float_equal(easingApply(EASING_OUT_SINE, 0.5f), easingOutSine(0.5f), EASING_TOLERANCE);
|
);
|
||||||
assert_float_equal(easingApply(EASING_IN_OUT_SINE, 0.5f), easingInOutSine(0.5f), EASING_TOLERANCE);
|
assert_float_equal(
|
||||||
assert_float_equal(easingApply(EASING_IN_QUAD, 0.5f), easingInQuad(0.5f), EASING_TOLERANCE);
|
easingApply(EASING_IN_SINE, 0.5f), easingInSine(0.5f), EASING_TOLERANCE
|
||||||
assert_float_equal(easingApply(EASING_OUT_QUAD, 0.5f), easingOutQuad(0.5f), EASING_TOLERANCE);
|
);
|
||||||
assert_float_equal(easingApply(EASING_IN_OUT_QUAD, 0.5f), easingInOutQuad(0.5f), EASING_TOLERANCE);
|
assert_float_equal(
|
||||||
assert_float_equal(easingApply(EASING_IN_CUBIC, 0.5f), easingInCubic(0.5f), EASING_TOLERANCE);
|
easingApply(EASING_OUT_SINE, 0.5f), easingOutSine(0.5f), EASING_TOLERANCE
|
||||||
assert_float_equal(easingApply(EASING_OUT_CUBIC, 0.5f), easingOutCubic(0.5f), EASING_TOLERANCE);
|
);
|
||||||
assert_float_equal(easingApply(EASING_IN_OUT_CUBIC, 0.5f), easingInOutCubic(0.5f), EASING_TOLERANCE);
|
assert_float_equal(
|
||||||
assert_float_equal(easingApply(EASING_IN_QUART, 0.5f), easingInQuart(0.5f), EASING_TOLERANCE);
|
easingApply(EASING_IN_OUT_SINE, 0.5f), easingInOutSine(0.5f),
|
||||||
assert_float_equal(easingApply(EASING_OUT_QUART, 0.5f), easingOutQuart(0.5f), EASING_TOLERANCE);
|
EASING_TOLERANCE
|
||||||
assert_float_equal(easingApply(EASING_IN_OUT_QUART, 0.5f), easingInOutQuart(0.5f), EASING_TOLERANCE);
|
);
|
||||||
assert_float_equal(easingApply(EASING_IN_BACK, 0.5f), easingInBack(0.5f), EASING_TOLERANCE);
|
assert_float_equal(
|
||||||
assert_float_equal(easingApply(EASING_OUT_BACK, 0.5f), easingOutBack(0.5f), EASING_TOLERANCE);
|
easingApply(EASING_IN_QUAD, 0.5f), easingInQuad(0.5f), EASING_TOLERANCE
|
||||||
assert_float_equal(easingApply(EASING_IN_OUT_BACK, 0.5f), easingInOutBack(0.5f), EASING_TOLERANCE);
|
);
|
||||||
|
assert_float_equal(
|
||||||
|
easingApply(EASING_OUT_QUAD, 0.5f), easingOutQuad(0.5f), EASING_TOLERANCE
|
||||||
|
);
|
||||||
|
assert_float_equal(
|
||||||
|
easingApply(EASING_IN_OUT_QUAD, 0.5f), easingInOutQuad(0.5f),
|
||||||
|
EASING_TOLERANCE
|
||||||
|
);
|
||||||
|
assert_float_equal(
|
||||||
|
easingApply(EASING_IN_CUBIC, 0.5f), easingInCubic(0.5f), EASING_TOLERANCE
|
||||||
|
);
|
||||||
|
assert_float_equal(
|
||||||
|
easingApply(EASING_OUT_CUBIC, 0.5f), easingOutCubic(0.5f),
|
||||||
|
EASING_TOLERANCE
|
||||||
|
);
|
||||||
|
assert_float_equal(
|
||||||
|
easingApply(EASING_IN_OUT_CUBIC, 0.5f), easingInOutCubic(0.5f),
|
||||||
|
EASING_TOLERANCE
|
||||||
|
);
|
||||||
|
assert_float_equal(
|
||||||
|
easingApply(EASING_IN_QUART, 0.5f), easingInQuart(0.5f), EASING_TOLERANCE
|
||||||
|
);
|
||||||
|
assert_float_equal(
|
||||||
|
easingApply(EASING_OUT_QUART, 0.5f), easingOutQuart(0.5f),
|
||||||
|
EASING_TOLERANCE
|
||||||
|
);
|
||||||
|
assert_float_equal(
|
||||||
|
easingApply(EASING_IN_OUT_QUART, 0.5f), easingInOutQuart(0.5f),
|
||||||
|
EASING_TOLERANCE
|
||||||
|
);
|
||||||
|
assert_float_equal(
|
||||||
|
easingApply(EASING_IN_BACK, 0.5f), easingInBack(0.5f), EASING_TOLERANCE
|
||||||
|
);
|
||||||
|
assert_float_equal(
|
||||||
|
easingApply(EASING_OUT_BACK, 0.5f), easingOutBack(0.5f), EASING_TOLERANCE
|
||||||
|
);
|
||||||
|
assert_float_equal(
|
||||||
|
easingApply(EASING_IN_OUT_BACK, 0.5f), easingInOutBack(0.5f),
|
||||||
|
EASING_TOLERANCE
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_easingApplyInvalidTypeAsserts(void **state) {
|
static void test_easingApplyInvalidTypeAsserts(void **state) {
|
||||||
|
|||||||
@@ -83,7 +83,9 @@ static void test_keyframeGetValueBeforeFirstKeyframeIsNaN(void **state) {
|
|||||||
assert_true(isnan(keyframeGetValue(keyframes, 2, 0.0f)));
|
assert_true(isnan(keyframeGetValue(keyframes, 2, 0.0f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_keyframeGetValueAtOrAfterLastKeyframeClampsToLastValue(void **state) {
|
static void test_keyframeGetValueAtOrAfterLastKeyframeClampsToLastValue(
|
||||||
|
void **state
|
||||||
|
) {
|
||||||
keyframe_t keyframes[2] = {
|
keyframe_t keyframes[2] = {
|
||||||
{ .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR },
|
{ .time = 0.0f, .value = 0.0f, .easing = EASING_LINEAR },
|
||||||
{ .time = 1.0f, .value = 10.0f, .easing = EASING_LINEAR },
|
{ .time = 1.0f, .value = 10.0f, .easing = EASING_LINEAR },
|
||||||
@@ -93,7 +95,9 @@ static void test_keyframeGetValueAtOrAfterLastKeyframeClampsToLastValue(void **s
|
|||||||
assert_float_equal(keyframeGetValue(keyframes, 2, 2.0f), 10.0f, 0.0001f);
|
assert_float_equal(keyframeGetValue(keyframes, 2, 2.0f), 10.0f, 0.0001f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_keyframeGetValueSingleKeyframeAtOrAfterClampsToValue(void **state) {
|
static void test_keyframeGetValueSingleKeyframeAtOrAfterClampsToValue(
|
||||||
|
void **state
|
||||||
|
) {
|
||||||
keyframe_t keyframes[1] = {
|
keyframe_t keyframes[1] = {
|
||||||
{ .time = 5.0f, .value = 42.0f, .easing = EASING_LINEAR },
|
{ .time = 5.0f, .value = 42.0f, .easing = EASING_LINEAR },
|
||||||
};
|
};
|
||||||
@@ -147,7 +151,9 @@ static void test_keyframeGetValueLaterKeyframeOutOfOrderAsserts(void **state) {
|
|||||||
expect_assert_failure(keyframeGetValue(keyframes, 3, 0.0f));
|
expect_assert_failure(keyframeGetValue(keyframes, 3, 0.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_keyframeGetValueEqualConsecutiveTimesDoesNotAssert(void **state) {
|
static void test_keyframeGetValueEqualConsecutiveTimesDoesNotAssert(
|
||||||
|
void **state
|
||||||
|
) {
|
||||||
// Equal (non-decreasing) times are allowed - only strictly decreasing
|
// Equal (non-decreasing) times are allowed - only strictly decreasing
|
||||||
// times should trigger the sorted check.
|
// times should trigger the sorted check.
|
||||||
keyframe_t keyframes[3] = {
|
keyframe_t keyframes[3] = {
|
||||||
@@ -167,7 +173,9 @@ int main(int argc, char **argv) {
|
|||||||
cmocka_unit_test(test_keyframeGetValueAppliesEasing),
|
cmocka_unit_test(test_keyframeGetValueAppliesEasing),
|
||||||
cmocka_unit_test(test_keyframeGetValueNonZeroStartTime),
|
cmocka_unit_test(test_keyframeGetValueNonZeroStartTime),
|
||||||
cmocka_unit_test(test_keyframeGetValueBeforeFirstKeyframeIsNaN),
|
cmocka_unit_test(test_keyframeGetValueBeforeFirstKeyframeIsNaN),
|
||||||
cmocka_unit_test(test_keyframeGetValueAtOrAfterLastKeyframeClampsToLastValue),
|
cmocka_unit_test(
|
||||||
|
test_keyframeGetValueAtOrAfterLastKeyframeClampsToLastValue
|
||||||
|
),
|
||||||
cmocka_unit_test(test_keyframeGetValueSingleKeyframeAtOrAfterClampsToValue),
|
cmocka_unit_test(test_keyframeGetValueSingleKeyframeAtOrAfterClampsToValue),
|
||||||
cmocka_unit_test(test_keyframeGetValueNullKeyframesAsserts),
|
cmocka_unit_test(test_keyframeGetValueNullKeyframesAsserts),
|
||||||
cmocka_unit_test(test_keyframeGetValueZeroCountAsserts),
|
cmocka_unit_test(test_keyframeGetValueZeroCountAsserts),
|
||||||
|
|||||||
@@ -108,7 +108,8 @@ static void test_assertStrLenMin(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void test_assertIsMainThread(void **state) {
|
static void test_assertIsMainThread(void **state) {
|
||||||
// The group setup recorded this thread as main - assertIsMainThread must pass.
|
// The group setup recorded this thread as main - assertIsMainThread
|
||||||
|
// must pass.
|
||||||
assertIsMainThread("test thread is main, should not assert");
|
assertIsMainThread("test thread is main, should not assert");
|
||||||
|
|
||||||
// assertNotMainThread must fail when called from the main thread.
|
// assertNotMainThread must fail when called from the main thread.
|
||||||
|
|||||||
+137
-55
@@ -90,7 +90,8 @@ static bool_t loading_slot_has_entry(const assetentry_t *entry) {
|
|||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static void test_getEntry_creates_new(void **state) {
|
static void test_getEntry_creates_new(void **state) {
|
||||||
assetentry_t *entry = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *entry =
|
||||||
|
assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
|
||||||
assert_non_null(entry);
|
assert_non_null(entry);
|
||||||
assert_int_equal(entry->state, ASSET_ENTRY_STATE_NOT_STARTED);
|
assert_int_equal(entry->state, ASSET_ENTRY_STATE_NOT_STARTED);
|
||||||
@@ -101,8 +102,10 @@ static void test_getEntry_creates_new(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void test_getEntry_dedup(void **state) {
|
static void test_getEntry_dedup(void **state) {
|
||||||
assetentry_t *a = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *a =
|
||||||
assetentry_t *b = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
assetentry_t *b =
|
||||||
|
assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
|
||||||
assert_ptr_equal(a, b);
|
assert_ptr_equal(a, b);
|
||||||
assert_int_equal(memoryGetAllocatedCount(), 0);
|
assert_int_equal(memoryGetAllocatedCount(), 0);
|
||||||
@@ -121,7 +124,8 @@ static void test_getEntry_distinct_names(void **state) {
|
|||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static void test_update_entry_reaches_loaded(void **state) {
|
static void test_update_entry_reaches_loaded(void **state) {
|
||||||
assetentry_t *entry = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *entry =
|
||||||
|
assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
assert_int_equal(entry->state, ASSET_ENTRY_STATE_NOT_STARTED);
|
assert_int_equal(entry->state, ASSET_ENTRY_STATE_NOT_STARTED);
|
||||||
|
|
||||||
assetEntryLock(entry);
|
assetEntryLock(entry);
|
||||||
@@ -134,7 +138,8 @@ static void test_update_entry_reaches_loaded(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void test_update_slot_cleared_after_first_update(void **state) {
|
static void test_update_slot_cleared_after_first_update(void **state) {
|
||||||
assetentry_t *entry = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *entry =
|
||||||
|
assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
|
||||||
assetEntryLock(entry);
|
assetEntryLock(entry);
|
||||||
assetUpdate();
|
assetUpdate();
|
||||||
@@ -149,7 +154,8 @@ static void test_update_slot_cleared_after_first_update(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void test_update_slot_stays_cleared_on_further_updates(void **state) {
|
static void test_update_slot_stays_cleared_on_further_updates(void **state) {
|
||||||
assetentry_t *entry = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *entry =
|
||||||
|
assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
|
||||||
assetEntryLock(entry);
|
assetEntryLock(entry);
|
||||||
assetUpdate();
|
assetUpdate();
|
||||||
@@ -186,10 +192,12 @@ static void test_update_four_slots_fill_independently(void **state) {
|
|||||||
static void test_update_error_state(void **state) {
|
static void test_update_error_state(void **state) {
|
||||||
ASSET_LOADER_CALLBACKS[ASSET_LOADER_TYPE_LOCALE].loadSync = stub_load_fail;
|
ASSET_LOADER_CALLBACKS[ASSET_LOADER_TYPE_LOCALE].loadSync = stub_load_fail;
|
||||||
|
|
||||||
assetentry_t *entry = assetGetEntry("fail.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *entry =
|
||||||
|
assetGetEntry("fail.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
|
||||||
// First update: dispatches and calls the failing stub.
|
// First update: dispatches and calls the failing stub.
|
||||||
// assetUpdate itself returns OK here; the error from loadSync is caught internally.
|
// assetUpdate itself returns OK here; the error from loadSync is
|
||||||
|
// caught internally.
|
||||||
errorret_t ret = assetUpdate();
|
errorret_t ret = assetUpdate();
|
||||||
assert_true(errorIsOk(ret));
|
assert_true(errorIsOk(ret));
|
||||||
assert_int_equal(entry->state, ASSET_ENTRY_STATE_ERROR);
|
assert_int_equal(entry->state, ASSET_ENTRY_STATE_ERROR);
|
||||||
@@ -209,7 +217,8 @@ static void test_update_noop_on_empty_table(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void test_update_loaded_entry_not_redispatched(void **state) {
|
static void test_update_loaded_entry_not_redispatched(void **state) {
|
||||||
assetentry_t *entry = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *entry =
|
||||||
|
assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
|
||||||
assetEntryLock(entry);
|
assetEntryLock(entry);
|
||||||
assetUpdate();
|
assetUpdate();
|
||||||
@@ -255,13 +264,17 @@ static void test_update_overflow_queues_entries(void **state) {
|
|||||||
for(int i = 0; i < ASSET_LOADING_COUNT_MAX; i++) {
|
for(int i = 0; i < ASSET_LOADING_COUNT_MAX; i++) {
|
||||||
assert_int_equal(entries[i]->state, ASSET_ENTRY_STATE_LOADED);
|
assert_int_equal(entries[i]->state, ASSET_ENTRY_STATE_LOADED);
|
||||||
}
|
}
|
||||||
assert_int_equal(entries[ASSET_LOADING_COUNT_MAX]->state, ASSET_ENTRY_STATE_NOT_STARTED);
|
assert_int_equal(
|
||||||
|
entries[ASSET_LOADING_COUNT_MAX]->state, ASSET_ENTRY_STATE_NOT_STARTED
|
||||||
|
);
|
||||||
|
|
||||||
// Update 2: the slots freed during update 1 are now available, so the
|
// Update 2: the slots freed during update 1 are now available, so the
|
||||||
// overflow entry is dispatched and loaded in this pass.
|
// overflow entry is dispatched and loaded in this pass.
|
||||||
ret = assetUpdate();
|
ret = assetUpdate();
|
||||||
assert_true(errorIsOk(ret));
|
assert_true(errorIsOk(ret));
|
||||||
assert_int_equal(entries[ASSET_LOADING_COUNT_MAX]->state, ASSET_ENTRY_STATE_LOADED);
|
assert_int_equal(
|
||||||
|
entries[ASSET_LOADING_COUNT_MAX]->state, ASSET_ENTRY_STATE_LOADED
|
||||||
|
);
|
||||||
|
|
||||||
for(int i = 0; i < TOTAL; i++) {
|
for(int i = 0; i < TOTAL; i++) {
|
||||||
assetEntryUnlock(entries[i]);
|
assetEntryUnlock(entries[i]);
|
||||||
@@ -273,12 +286,14 @@ static void test_update_overflow_queues_entries(void **state) {
|
|||||||
static void test_update_error_slot_stays_occupied(void **state) {
|
static void test_update_error_slot_stays_occupied(void **state) {
|
||||||
ASSET_LOADER_CALLBACKS[ASSET_LOADER_TYPE_LOCALE].loadSync = stub_load_fail;
|
ASSET_LOADER_CALLBACKS[ASSET_LOADER_TYPE_LOCALE].loadSync = stub_load_fail;
|
||||||
|
|
||||||
assetentry_t *entry = assetGetEntry("fail.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *entry =
|
||||||
|
assetGetEntry("fail.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
|
||||||
assetUpdate();
|
assetUpdate();
|
||||||
assert_int_equal(entry->state, ASSET_ENTRY_STATE_ERROR);
|
assert_int_equal(entry->state, ASSET_ENTRY_STATE_ERROR);
|
||||||
|
|
||||||
// Unlike LOADED, the ERROR case does NOT clear the slot - it throws instead.
|
// Unlike LOADED, the ERROR case does NOT clear the slot - it throws
|
||||||
|
// instead.
|
||||||
assert_true(loading_slot_has_entry(entry));
|
assert_true(loading_slot_has_entry(entry));
|
||||||
|
|
||||||
errorret_t ret = assetUpdate();
|
errorret_t ret = assetUpdate();
|
||||||
@@ -293,7 +308,8 @@ static void test_update_error_slot_stays_occupied(void **state) {
|
|||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static void test_getEntry_null_input_stays_null(void **state) {
|
static void test_getEntry_null_input_stays_null(void **state) {
|
||||||
assetentry_t *entry = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *entry =
|
||||||
|
assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
|
||||||
assert_null(entry->input);
|
assert_null(entry->input);
|
||||||
assert_int_equal(memoryGetAllocatedCount(), 0);
|
assert_int_equal(memoryGetAllocatedCount(), 0);
|
||||||
@@ -304,7 +320,8 @@ static void test_getEntry_input_copied_into_entry(void **state) {
|
|||||||
memoryZero(&input, sizeof(input));
|
memoryZero(&input, sizeof(input));
|
||||||
input.texture = (textureformat_t)42;
|
input.texture = (textureformat_t)42;
|
||||||
|
|
||||||
assetentry_t *entry = assetGetEntry("test.texture", ASSET_LOADER_TYPE_TEXTURE, &input);
|
assetentry_t *entry =
|
||||||
|
assetGetEntry("test.texture", ASSET_LOADER_TYPE_TEXTURE, &input);
|
||||||
|
|
||||||
// input must have been copied - entry->input must point inside the entry.
|
// input must have been copied - entry->input must point inside the entry.
|
||||||
assert_non_null(entry->input);
|
assert_non_null(entry->input);
|
||||||
@@ -338,10 +355,13 @@ static errorret_t reentrant_stub_load(assetloading_t *loading) {
|
|||||||
static void test_update_reentrant_sync_loader(void **state) {
|
static void test_update_reentrant_sync_loader(void **state) {
|
||||||
reentrant_inner_entry = NULL;
|
reentrant_inner_entry = NULL;
|
||||||
reentrant_inner_loaded = false;
|
reentrant_inner_loaded = false;
|
||||||
// LOCALE uses the re-entrant loader; JSON keeps the default stub_load_success.
|
// LOCALE uses the re-entrant loader; JSON keeps the default
|
||||||
ASSET_LOADER_CALLBACKS[ASSET_LOADER_TYPE_LOCALE].loadSync = reentrant_stub_load;
|
// stub_load_success.
|
||||||
|
ASSET_LOADER_CALLBACKS[ASSET_LOADER_TYPE_LOCALE].loadSync =
|
||||||
|
reentrant_stub_load;
|
||||||
|
|
||||||
assetentry_t *outer = assetGetEntry("outer.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *outer =
|
||||||
|
assetGetEntry("outer.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
|
||||||
errorret_t ret = assetRequireLoaded(outer);
|
errorret_t ret = assetRequireLoaded(outer);
|
||||||
assert_true(errorIsOk(ret));
|
assert_true(errorIsOk(ret));
|
||||||
@@ -360,7 +380,8 @@ static void test_update_reentrant_sync_loader(void **state) {
|
|||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static void test_getEntry_returns_loaded_entry(void **state) {
|
static void test_getEntry_returns_loaded_entry(void **state) {
|
||||||
assetentry_t *a = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *a =
|
||||||
|
assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
|
||||||
assetEntryLock(a);
|
assetEntryLock(a);
|
||||||
assetUpdate();
|
assetUpdate();
|
||||||
@@ -368,7 +389,8 @@ static void test_getEntry_returns_loaded_entry(void **state) {
|
|||||||
|
|
||||||
// A second request for the same name must return the same entry even though
|
// A second request for the same name must return the same entry even though
|
||||||
// it is already LOADED rather than NOT_STARTED.
|
// it is already LOADED rather than NOT_STARTED.
|
||||||
assetentry_t *b = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *b =
|
||||||
|
assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
assert_ptr_equal(a, b);
|
assert_ptr_equal(a, b);
|
||||||
assert_int_equal(b->state, ASSET_ENTRY_STATE_LOADED);
|
assert_int_equal(b->state, ASSET_ENTRY_STATE_LOADED);
|
||||||
assetEntryUnlock(a);
|
assetEntryUnlock(a);
|
||||||
@@ -381,7 +403,8 @@ static void test_getEntry_returns_loaded_entry(void **state) {
|
|||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static void test_entry_dispose_clears_entry(void **state) {
|
static void test_entry_dispose_clears_entry(void **state) {
|
||||||
assetentry_t *entry = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *entry =
|
||||||
|
assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
|
||||||
assetEntryLock(entry);
|
assetEntryLock(entry);
|
||||||
assetUpdate();
|
assetUpdate();
|
||||||
@@ -427,7 +450,8 @@ static void test_entry_dispose_slot_reusable(void **state) {
|
|||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static void test_requireLoaded_already_loaded(void **state) {
|
static void test_requireLoaded_already_loaded(void **state) {
|
||||||
assetentry_t *entry = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *entry =
|
||||||
|
assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
|
||||||
assetEntryLock(entry);
|
assetEntryLock(entry);
|
||||||
assetUpdate();
|
assetUpdate();
|
||||||
@@ -442,7 +466,8 @@ static void test_requireLoaded_already_loaded(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void test_requireLoaded_spins_to_loaded(void **state) {
|
static void test_requireLoaded_spins_to_loaded(void **state) {
|
||||||
assetentry_t *entry = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *entry =
|
||||||
|
assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
assert_int_equal(entry->state, ASSET_ENTRY_STATE_NOT_STARTED);
|
assert_int_equal(entry->state, ASSET_ENTRY_STATE_NOT_STARTED);
|
||||||
|
|
||||||
// requireLoaded calls assetUpdate internally until LOADED.
|
// requireLoaded calls assetUpdate internally until LOADED.
|
||||||
@@ -456,10 +481,12 @@ static void test_requireLoaded_spins_to_loaded(void **state) {
|
|||||||
static void test_requireLoaded_propagates_error(void **state) {
|
static void test_requireLoaded_propagates_error(void **state) {
|
||||||
ASSET_LOADER_CALLBACKS[ASSET_LOADER_TYPE_LOCALE].loadSync = stub_load_fail;
|
ASSET_LOADER_CALLBACKS[ASSET_LOADER_TYPE_LOCALE].loadSync = stub_load_fail;
|
||||||
|
|
||||||
assetentry_t *entry = assetGetEntry("fail.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *entry =
|
||||||
|
assetGetEntry("fail.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
|
||||||
// requireLoaded spins assetUpdate until LOADED - but the loader always fails,
|
// requireLoaded spins assetUpdate until LOADED - but the loader
|
||||||
// so the second assetUpdate sees ERROR and throws, which errorChain propagates.
|
// always fails, so the second assetUpdate sees ERROR and throws, which
|
||||||
|
// errorChain propagates.
|
||||||
errorret_t ret = assetRequireLoaded(entry);
|
errorret_t ret = assetRequireLoaded(entry);
|
||||||
assert_true(errorIsNotOk(ret));
|
assert_true(errorIsNotOk(ret));
|
||||||
errorCatch(ret);
|
errorCatch(ret);
|
||||||
@@ -473,7 +500,8 @@ static void test_requireLoaded_propagates_error(void **state) {
|
|||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static void test_update_does_not_reap_automatically(void **state) {
|
static void test_update_does_not_reap_automatically(void **state) {
|
||||||
assetentry_t *entry = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *entry =
|
||||||
|
assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
|
||||||
assetEntryLock(entry);
|
assetEntryLock(entry);
|
||||||
assetUpdate();
|
assetUpdate();
|
||||||
@@ -497,7 +525,8 @@ static void test_update_does_not_reap_automatically(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void test_reapUnused_disposes_zero_ref_loaded(void **state) {
|
static void test_reapUnused_disposes_zero_ref_loaded(void **state) {
|
||||||
assetentry_t *entry = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *entry =
|
||||||
|
assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
|
||||||
assetEntryLock(entry);
|
assetEntryLock(entry);
|
||||||
assetUpdate();
|
assetUpdate();
|
||||||
@@ -513,7 +542,8 @@ static void test_reapUnused_disposes_zero_ref_loaded(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void test_reapUnused_ignores_referenced_entries(void **state) {
|
static void test_reapUnused_ignores_referenced_entries(void **state) {
|
||||||
assetentry_t *entry = assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *entry =
|
||||||
|
assetGetEntry("test.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
|
|
||||||
assetEntryLock(entry);
|
assetEntryLock(entry);
|
||||||
assetUpdate();
|
assetUpdate();
|
||||||
@@ -548,7 +578,8 @@ static void test_getEntry_reaps_when_pool_full(void **state) {
|
|||||||
// The pool is now completely full of zero-ref LOADED entries with no
|
// The pool is now completely full of zero-ref LOADED entries with no
|
||||||
// ASSET_LOADER_TYPE_NULL slots left. Requesting one more must trigger an
|
// ASSET_LOADER_TYPE_NULL slots left. Requesting one more must trigger an
|
||||||
// implicit reap instead of asserting.
|
// implicit reap instead of asserting.
|
||||||
assetentry_t *fresh = assetGetEntry("fresh.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
assetentry_t *fresh =
|
||||||
|
assetGetEntry("fresh.locale", ASSET_LOADER_TYPE_LOCALE, NULL);
|
||||||
assert_non_null(fresh);
|
assert_non_null(fresh);
|
||||||
assert_int_equal(fresh->state, ASSET_ENTRY_STATE_NOT_STARTED);
|
assert_int_equal(fresh->state, ASSET_ENTRY_STATE_NOT_STARTED);
|
||||||
|
|
||||||
@@ -572,39 +603,90 @@ int main(void) {
|
|||||||
assertInit();
|
assertInit();
|
||||||
const struct CMUnitTest tests[] = {
|
const struct CMUnitTest tests[] = {
|
||||||
// getEntry
|
// getEntry
|
||||||
cmocka_unit_test_setup_teardown(test_getEntry_creates_new, asset_setup, asset_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
cmocka_unit_test_setup_teardown(test_getEntry_dedup, asset_setup, asset_teardown),
|
test_getEntry_creates_new, asset_setup, asset_teardown
|
||||||
cmocka_unit_test_setup_teardown(test_getEntry_distinct_names, asset_setup, asset_teardown),
|
),
|
||||||
cmocka_unit_test_setup_teardown(test_getEntry_returns_loaded_entry, asset_setup, asset_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
cmocka_unit_test_setup_teardown(test_getEntry_null_input_stays_null, asset_setup, asset_teardown),
|
test_getEntry_dedup, asset_setup, asset_teardown
|
||||||
cmocka_unit_test_setup_teardown(test_getEntry_input_copied_into_entry, asset_setup, asset_teardown),
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_getEntry_distinct_names, asset_setup, asset_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_getEntry_returns_loaded_entry, asset_setup, asset_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_getEntry_null_input_stays_null, asset_setup, asset_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_getEntry_input_copied_into_entry, asset_setup, asset_teardown
|
||||||
|
),
|
||||||
|
|
||||||
// assetUpdate - state machine
|
// assetUpdate - state machine
|
||||||
cmocka_unit_test_setup_teardown(test_update_noop_on_empty_table, asset_setup, asset_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
cmocka_unit_test_setup_teardown(test_update_entry_reaches_loaded, asset_setup, asset_teardown),
|
test_update_noop_on_empty_table, asset_setup, asset_teardown
|
||||||
cmocka_unit_test_setup_teardown(test_update_slot_cleared_after_first_update, asset_setup, asset_teardown),
|
),
|
||||||
cmocka_unit_test_setup_teardown(test_update_slot_stays_cleared_on_further_updates, asset_setup, asset_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
cmocka_unit_test_setup_teardown(test_update_four_slots_fill_independently, asset_setup, asset_teardown),
|
test_update_entry_reaches_loaded, asset_setup, asset_teardown
|
||||||
cmocka_unit_test_setup_teardown(test_update_loaded_entry_not_redispatched, asset_setup, asset_teardown),
|
),
|
||||||
cmocka_unit_test_setup_teardown(test_update_overflow_queues_entries, asset_setup, asset_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
cmocka_unit_test_setup_teardown(test_update_error_state, asset_setup, asset_teardown),
|
test_update_slot_cleared_after_first_update, asset_setup, asset_teardown
|
||||||
cmocka_unit_test_setup_teardown(test_update_error_slot_stays_occupied, asset_setup, asset_teardown),
|
),
|
||||||
cmocka_unit_test_setup_teardown(test_update_reentrant_sync_loader, asset_setup, asset_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_update_slot_stays_cleared_on_further_updates,
|
||||||
|
asset_setup, asset_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_update_four_slots_fill_independently, asset_setup, asset_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_update_loaded_entry_not_redispatched, asset_setup, asset_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_update_overflow_queues_entries, asset_setup, asset_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_update_error_state, asset_setup, asset_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_update_error_slot_stays_occupied, asset_setup, asset_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_update_reentrant_sync_loader, asset_setup, asset_teardown
|
||||||
|
),
|
||||||
|
|
||||||
// assetEntryDispose
|
// assetEntryDispose
|
||||||
cmocka_unit_test_setup_teardown(test_entry_dispose_clears_entry, asset_setup, asset_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
cmocka_unit_test_setup_teardown(test_entry_dispose_slot_reusable, asset_setup, asset_teardown),
|
test_entry_dispose_clears_entry, asset_setup, asset_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_entry_dispose_slot_reusable, asset_setup, asset_teardown
|
||||||
|
),
|
||||||
|
|
||||||
// assetRequireLoaded
|
// assetRequireLoaded
|
||||||
cmocka_unit_test_setup_teardown(test_requireLoaded_already_loaded, asset_setup, asset_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
cmocka_unit_test_setup_teardown(test_requireLoaded_spins_to_loaded, asset_setup, asset_teardown),
|
test_requireLoaded_already_loaded, asset_setup, asset_teardown
|
||||||
cmocka_unit_test_setup_teardown(test_requireLoaded_propagates_error, asset_setup, asset_teardown),
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_requireLoaded_spins_to_loaded, asset_setup, asset_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_requireLoaded_propagates_error, asset_setup, asset_teardown
|
||||||
|
),
|
||||||
|
|
||||||
// assetReapUnused
|
// assetReapUnused
|
||||||
cmocka_unit_test_setup_teardown(test_update_does_not_reap_automatically, asset_setup, asset_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
cmocka_unit_test_setup_teardown(test_reapUnused_disposes_zero_ref_loaded, asset_setup, asset_teardown),
|
test_update_does_not_reap_automatically, asset_setup, asset_teardown
|
||||||
cmocka_unit_test_setup_teardown(test_reapUnused_ignores_referenced_entries, asset_setup, asset_teardown),
|
),
|
||||||
cmocka_unit_test_setup_teardown(test_getEntry_reaps_when_pool_full, asset_setup, asset_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_reapUnused_disposes_zero_ref_loaded, asset_setup, asset_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_reapUnused_ignores_referenced_entries, asset_setup, asset_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_getEntry_reaps_when_pool_full, asset_setup, asset_teardown
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -240,10 +240,18 @@ static void test_json_buffer_cleared_after_load(void **state) {
|
|||||||
int main(void) {
|
int main(void) {
|
||||||
assertInit();
|
assertInit();
|
||||||
const struct CMUnitTest tests[] = {
|
const struct CMUnitTest tests[] = {
|
||||||
cmocka_unit_test_setup_teardown(test_json_valid_loads, zip_setup, zip_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
cmocka_unit_test_setup_teardown(test_json_parse_error, zip_setup, zip_teardown),
|
test_json_valid_loads, zip_setup, zip_teardown
|
||||||
cmocka_unit_test_setup_teardown(test_json_missing_file, zip_setup, zip_teardown),
|
),
|
||||||
cmocka_unit_test_setup_teardown(test_json_buffer_cleared_after_load, zip_setup, zip_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_json_parse_error, zip_setup, zip_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_json_missing_file, zip_setup, zip_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_json_buffer_cleared_after_load, zip_setup, zip_teardown
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,10 +104,14 @@ static int locale_setup(void **state) {
|
|||||||
|
|
||||||
char_t header[512];
|
char_t header[512];
|
||||||
ret = assetLocaleGetString(&g_locale, "", 0, header, sizeof(header));
|
ret = assetLocaleGetString(&g_locale, "", 0, header, sizeof(header));
|
||||||
if(errorIsNotOk(ret)) { errorCatch(ret); assetFileClose(&g_locale.file); goto fail; }
|
if(errorIsNotOk(ret)) {
|
||||||
|
errorCatch(ret); assetFileClose(&g_locale.file); goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
ret = assetLocaleParseHeader(&g_locale, header, sizeof(header));
|
ret = assetLocaleParseHeader(&g_locale, header, sizeof(header));
|
||||||
if(errorIsNotOk(ret)) { errorCatch(ret); assetFileClose(&g_locale.file); goto fail; }
|
if(errorIsNotOk(ret)) {
|
||||||
|
errorCatch(ret); assetFileClose(&g_locale.file); goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -309,7 +313,8 @@ static void test_evaluatePlural_less_than_boundary(void **state) {
|
|||||||
|
|
||||||
static void test_getString_simple(void **state) {
|
static void test_getString_simple(void **state) {
|
||||||
char_t result[256];
|
char_t result[256];
|
||||||
errorret_t ret = assetLocaleGetString(&g_locale, "greeting", 0, result, sizeof(result));
|
errorret_t ret =
|
||||||
|
assetLocaleGetString(&g_locale, "greeting", 0, result, sizeof(result));
|
||||||
|
|
||||||
assert_true(errorIsOk(ret));
|
assert_true(errorIsOk(ret));
|
||||||
assert_string_equal(result, "Hello, World!");
|
assert_string_equal(result, "Hello, World!");
|
||||||
@@ -321,7 +326,8 @@ static void test_getString_simple(void **state) {
|
|||||||
|
|
||||||
static void test_getString_plural_singular(void **state) {
|
static void test_getString_plural_singular(void **state) {
|
||||||
char_t result[256];
|
char_t result[256];
|
||||||
errorret_t ret = assetLocaleGetString(&g_locale, "item", 1, result, sizeof(result));
|
errorret_t ret =
|
||||||
|
assetLocaleGetString(&g_locale, "item", 1, result, sizeof(result));
|
||||||
|
|
||||||
assert_true(errorIsOk(ret));
|
assert_true(errorIsOk(ret));
|
||||||
assert_string_equal(result, "one item");
|
assert_string_equal(result, "one item");
|
||||||
@@ -330,7 +336,8 @@ static void test_getString_plural_singular(void **state) {
|
|||||||
|
|
||||||
static void test_getString_plural_many(void **state) {
|
static void test_getString_plural_many(void **state) {
|
||||||
char_t result[256];
|
char_t result[256];
|
||||||
errorret_t ret = assetLocaleGetString(&g_locale, "item", 5, result, sizeof(result));
|
errorret_t ret =
|
||||||
|
assetLocaleGetString(&g_locale, "item", 5, result, sizeof(result));
|
||||||
|
|
||||||
assert_true(errorIsOk(ret));
|
assert_true(errorIsOk(ret));
|
||||||
assert_string_equal(result, "many items");
|
assert_string_equal(result, "many items");
|
||||||
@@ -353,7 +360,8 @@ static void test_getString_multiple_calls(void **state) {
|
|||||||
|
|
||||||
static void test_getString_missing_id(void **state) {
|
static void test_getString_missing_id(void **state) {
|
||||||
char_t result[256];
|
char_t result[256];
|
||||||
errorret_t ret = assetLocaleGetString(&g_locale, "nonexistent", 0, result, sizeof(result));
|
errorret_t ret =
|
||||||
|
assetLocaleGetString(&g_locale, "nonexistent", 0, result, sizeof(result));
|
||||||
|
|
||||||
assert_true(errorIsNotOk(ret));
|
assert_true(errorIsNotOk(ret));
|
||||||
errorCatch(ret);
|
errorCatch(ret);
|
||||||
@@ -372,7 +380,8 @@ static void test_cache_findMiss_onEmptyCache(void **state) {
|
|||||||
|
|
||||||
char_t result[64];
|
char_t result[64];
|
||||||
bool_t hit = true;
|
bool_t hit = true;
|
||||||
errorret_t ret = assetLocaleCacheFind(&locale, "greeting", 0, result, sizeof(result), &hit);
|
errorret_t ret =
|
||||||
|
assetLocaleCacheFind(&locale, "greeting", 0, result, sizeof(result), &hit);
|
||||||
|
|
||||||
assert_true(errorIsOk(ret));
|
assert_true(errorIsOk(ret));
|
||||||
assert_false(hit);
|
assert_false(hit);
|
||||||
@@ -389,7 +398,8 @@ static void test_cache_insertThenFind_hits(void **state) {
|
|||||||
|
|
||||||
char_t result[64];
|
char_t result[64];
|
||||||
bool_t hit = false;
|
bool_t hit = false;
|
||||||
errorret_t ret = assetLocaleCacheFind(&locale, "greeting", 0, result, sizeof(result), &hit);
|
errorret_t ret =
|
||||||
|
assetLocaleCacheFind(&locale, "greeting", 0, result, sizeof(result), &hit);
|
||||||
|
|
||||||
assert_true(errorIsOk(ret));
|
assert_true(errorIsOk(ret));
|
||||||
assert_true(hit);
|
assert_true(hit);
|
||||||
@@ -409,7 +419,8 @@ static void test_cache_distinguishesByPluralCount(void **state) {
|
|||||||
char_t result[64];
|
char_t result[64];
|
||||||
bool_t hit = false;
|
bool_t hit = false;
|
||||||
|
|
||||||
errorret_t ret = assetLocaleCacheFind(&locale, "item", 1, result, sizeof(result), &hit);
|
errorret_t ret =
|
||||||
|
assetLocaleCacheFind(&locale, "item", 1, result, sizeof(result), &hit);
|
||||||
assert_true(errorIsOk(ret));
|
assert_true(errorIsOk(ret));
|
||||||
assert_true(hit);
|
assert_true(hit);
|
||||||
assert_string_equal(result, "one item");
|
assert_string_equal(result, "one item");
|
||||||
@@ -430,7 +441,8 @@ static void test_cache_find_missOnDifferentMessageId(void **state) {
|
|||||||
|
|
||||||
char_t result[64];
|
char_t result[64];
|
||||||
bool_t hit = true;
|
bool_t hit = true;
|
||||||
errorret_t ret = assetLocaleCacheFind(&locale, "farewell", 0, result, sizeof(result), &hit);
|
errorret_t ret =
|
||||||
|
assetLocaleCacheFind(&locale, "farewell", 0, result, sizeof(result), &hit);
|
||||||
|
|
||||||
assert_true(errorIsOk(ret));
|
assert_true(errorIsOk(ret));
|
||||||
assert_false(hit);
|
assert_false(hit);
|
||||||
@@ -446,7 +458,8 @@ static void test_cache_find_bufferTooSmall_errors(void **state) {
|
|||||||
|
|
||||||
char_t result[4];// too small for "Hello, World!"
|
char_t result[4];// too small for "Hello, World!"
|
||||||
bool_t hit = false;
|
bool_t hit = false;
|
||||||
errorret_t ret = assetLocaleCacheFind(&locale, "greeting", 0, result, sizeof(result), &hit);
|
errorret_t ret =
|
||||||
|
assetLocaleCacheFind(&locale, "greeting", 0, result, sizeof(result), &hit);
|
||||||
|
|
||||||
assert_true(errorIsNotOk(ret));
|
assert_true(errorIsNotOk(ret));
|
||||||
errorCatch(ret);
|
errorCatch(ret);
|
||||||
@@ -502,7 +515,8 @@ static void test_cache_insert_evictsLeastRecentlyUsed(void **state) {
|
|||||||
|
|
||||||
char_t result[32];
|
char_t result[32];
|
||||||
bool_t hit = true;
|
bool_t hit = true;
|
||||||
errorret_t ret = assetLocaleCacheFind(&locale, "id0", 0, result, sizeof(result), &hit);
|
errorret_t ret =
|
||||||
|
assetLocaleCacheFind(&locale, "id0", 0, result, sizeof(result), &hit);
|
||||||
assert_true(errorIsOk(ret));
|
assert_true(errorIsOk(ret));
|
||||||
assert_false(hit);
|
assert_false(hit);
|
||||||
|
|
||||||
@@ -530,7 +544,8 @@ static void test_cache_find_movesHitToFront(void **state) {
|
|||||||
|
|
||||||
char_t result[32];
|
char_t result[32];
|
||||||
bool_t hit = false;
|
bool_t hit = false;
|
||||||
errorret_t ret = assetLocaleCacheFind(&locale, "id0", 0, result, sizeof(result), &hit);
|
errorret_t ret =
|
||||||
|
assetLocaleCacheFind(&locale, "id0", 0, result, sizeof(result), &hit);
|
||||||
assert_true(errorIsOk(ret));
|
assert_true(errorIsOk(ret));
|
||||||
assert_true(hit);
|
assert_true(hit);
|
||||||
|
|
||||||
@@ -594,7 +609,8 @@ static void test_localeDispose_freesCache(void **state) {
|
|||||||
zip_source_free(write_src);
|
zip_source_free(write_src);
|
||||||
|
|
||||||
zip_error_init(&err);
|
zip_error_init(&err);
|
||||||
zip_source_t *read_src = zip_source_buffer_create(zipbuf, (zip_uint64_t)zs.size, 1, &err);
|
zip_source_t *read_src =
|
||||||
|
zip_source_buffer_create(zipbuf, (zip_uint64_t)zs.size, 1, &err);
|
||||||
assert_non_null(read_src);
|
assert_non_null(read_src);
|
||||||
zip_t *zip = zip_open_from_source(read_src, 0, &err);
|
zip_t *zip = zip_open_from_source(read_src, 0, &err);
|
||||||
assert_non_null(zip);
|
assert_non_null(zip);
|
||||||
@@ -604,7 +620,8 @@ static void test_localeDispose_freesCache(void **state) {
|
|||||||
memoryZero(&entry, sizeof(entry));
|
memoryZero(&entry, sizeof(entry));
|
||||||
entry.type = ASSET_LOADER_TYPE_LOCALE;
|
entry.type = ASSET_LOADER_TYPE_LOCALE;
|
||||||
|
|
||||||
errorret_t ret = assetFileInit(&entry.data.locale.file, "en.locale", NULL, NULL);
|
errorret_t ret =
|
||||||
|
assetFileInit(&entry.data.locale.file, "en.locale", NULL, NULL);
|
||||||
assert_true(errorIsOk(ret));
|
assert_true(errorIsOk(ret));
|
||||||
ret = assetFileOpen(&entry.data.locale.file);
|
ret = assetFileOpen(&entry.data.locale.file);
|
||||||
assert_true(errorIsOk(ret));
|
assert_true(errorIsOk(ret));
|
||||||
@@ -679,15 +696,29 @@ int main(void) {
|
|||||||
cmocka_unit_test(test_evaluatePlural_less_than_boundary),
|
cmocka_unit_test(test_evaluatePlural_less_than_boundary),
|
||||||
|
|
||||||
// getString - in-memory ZIP
|
// getString - in-memory ZIP
|
||||||
cmocka_unit_test_setup_teardown(test_getString_simple, locale_setup, locale_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
cmocka_unit_test_setup_teardown(test_getString_plural_singular, locale_setup, locale_teardown),
|
test_getString_simple, locale_setup, locale_teardown
|
||||||
cmocka_unit_test_setup_teardown(test_getString_plural_many, locale_setup, locale_teardown),
|
),
|
||||||
cmocka_unit_test_setup_teardown(test_getString_multiple_calls, locale_setup, locale_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
cmocka_unit_test_setup_teardown(test_getString_missing_id, locale_setup, locale_teardown),
|
test_getString_plural_singular, locale_setup, locale_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_getString_plural_many, locale_setup, locale_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_getString_multiple_calls, locale_setup, locale_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_getString_missing_id, locale_setup, locale_teardown
|
||||||
|
),
|
||||||
|
|
||||||
// getStringWithArgs - in-memory ZIP
|
// getStringWithArgs - in-memory ZIP
|
||||||
cmocka_unit_test_setup_teardown(test_getStringWithArgs_int, locale_setup, locale_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
cmocka_unit_test_setup_teardown(test_getStringWithArgs_string, locale_setup, locale_teardown),
|
test_getStringWithArgs_int, locale_setup, locale_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_getStringWithArgs_string, locale_setup, locale_teardown
|
||||||
|
),
|
||||||
|
|
||||||
// assetLocaleCacheFind / assetLocaleCacheInsert - pure
|
// assetLocaleCacheFind / assetLocaleCacheInsert - pure
|
||||||
cmocka_unit_test(test_cache_findMiss_onEmptyCache),
|
cmocka_unit_test(test_cache_findMiss_onEmptyCache),
|
||||||
|
|||||||
@@ -124,7 +124,9 @@ static bool_t run_tileset_async(assetloading_t *loading) {
|
|||||||
|
|
||||||
static zip_t *g_zip = NULL;
|
static zip_t *g_zip = NULL;
|
||||||
|
|
||||||
static int tileset_zip_add(zip_t *za, const char_t *name, const void *data, size_t len) {
|
static int tileset_zip_add(
|
||||||
|
zip_t *za, const char_t *name, const void *data, size_t len
|
||||||
|
) {
|
||||||
zip_source_t *s = zip_source_buffer(za, data, len, 0);
|
zip_source_t *s = zip_source_buffer(za, data, len, 0);
|
||||||
return (int)zip_file_add(za, name, s, ZIP_FL_OVERWRITE);
|
return (int)zip_file_add(za, name, s, ZIP_FL_OVERWRITE);
|
||||||
}
|
}
|
||||||
@@ -139,14 +141,30 @@ static int zip_setup(void **state) {
|
|||||||
zip_t *za = zip_open_from_source(write_src, ZIP_TRUNCATE, &err);
|
zip_t *za = zip_open_from_source(write_src, ZIP_TRUNCATE, &err);
|
||||||
if(!za) { zip_source_free(write_src); return -1; }
|
if(!za) { zip_source_free(write_src); return -1; }
|
||||||
|
|
||||||
if(tileset_zip_add(za, "valid.tileset", DTF_VALID, sizeof(DTF_VALID)) < 0 ||
|
if(
|
||||||
tileset_zip_add(za, "badmagic.tileset", DTF_BAD_MAGIC, sizeof(DTF_BAD_MAGIC)) < 0 ||
|
tileset_zip_add(za, "valid.tileset", DTF_VALID, sizeof(DTF_VALID)) < 0 ||
|
||||||
tileset_zip_add(za, "badversion.tileset", DTF_BAD_VERSION, sizeof(DTF_BAD_VERSION)) < 0 ||
|
tileset_zip_add(
|
||||||
tileset_zip_add(za, "zerowidth.tileset", DTF_ZERO_WIDTH, sizeof(DTF_ZERO_WIDTH)) < 0 ||
|
za, "badmagic.tileset", DTF_BAD_MAGIC, sizeof(DTF_BAD_MAGIC)
|
||||||
tileset_zip_add(za, "zeroheight.tileset", DTF_ZERO_HEIGHT, sizeof(DTF_ZERO_HEIGHT)) < 0 ||
|
) < 0 ||
|
||||||
tileset_zip_add(za, "zerocolumns.tileset", DTF_ZERO_COLUMNS, sizeof(DTF_ZERO_COLUMNS)) < 0 ||
|
tileset_zip_add(
|
||||||
tileset_zip_add(za, "zerorows.tileset", DTF_ZERO_ROWS, sizeof(DTF_ZERO_ROWS)) < 0 ||
|
za, "badversion.tileset", DTF_BAD_VERSION, sizeof(DTF_BAD_VERSION)
|
||||||
tileset_zip_add(za, "invaliduv.tileset", DTF_INVALID_UV, sizeof(DTF_INVALID_UV)) < 0) {
|
) < 0 ||
|
||||||
|
tileset_zip_add(
|
||||||
|
za, "zerowidth.tileset", DTF_ZERO_WIDTH, sizeof(DTF_ZERO_WIDTH)
|
||||||
|
) < 0 ||
|
||||||
|
tileset_zip_add(
|
||||||
|
za, "zeroheight.tileset", DTF_ZERO_HEIGHT, sizeof(DTF_ZERO_HEIGHT)
|
||||||
|
) < 0 ||
|
||||||
|
tileset_zip_add(
|
||||||
|
za, "zerocolumns.tileset", DTF_ZERO_COLUMNS, sizeof(DTF_ZERO_COLUMNS)
|
||||||
|
) < 0 ||
|
||||||
|
tileset_zip_add(
|
||||||
|
za, "zerorows.tileset", DTF_ZERO_ROWS, sizeof(DTF_ZERO_ROWS)
|
||||||
|
) < 0 ||
|
||||||
|
tileset_zip_add(
|
||||||
|
za, "invaliduv.tileset", DTF_INVALID_UV, sizeof(DTF_INVALID_UV)
|
||||||
|
) < 0
|
||||||
|
) {
|
||||||
zip_close(za); return -1;
|
zip_close(za); return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,16 +387,36 @@ static void test_tileset_missing_file(void **state) {
|
|||||||
int main(void) {
|
int main(void) {
|
||||||
assertInit();
|
assertInit();
|
||||||
const struct CMUnitTest tests[] = {
|
const struct CMUnitTest tests[] = {
|
||||||
cmocka_unit_test_setup_teardown(test_tileset_valid_loads, zip_setup, zip_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
cmocka_unit_test_setup_teardown(test_tileset_data_cleared_after_load, zip_setup, zip_teardown),
|
test_tileset_valid_loads, zip_setup, zip_teardown
|
||||||
cmocka_unit_test_setup_teardown(test_tileset_bad_magic, zip_setup, zip_teardown),
|
),
|
||||||
cmocka_unit_test_setup_teardown(test_tileset_bad_version, zip_setup, zip_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
cmocka_unit_test_setup_teardown(test_tileset_zero_tile_width, zip_setup, zip_teardown),
|
test_tileset_data_cleared_after_load, zip_setup, zip_teardown
|
||||||
cmocka_unit_test_setup_teardown(test_tileset_zero_tile_height, zip_setup, zip_teardown),
|
),
|
||||||
cmocka_unit_test_setup_teardown(test_tileset_zero_columns, zip_setup, zip_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
cmocka_unit_test_setup_teardown(test_tileset_zero_rows, zip_setup, zip_teardown),
|
test_tileset_bad_magic, zip_setup, zip_teardown
|
||||||
cmocka_unit_test_setup_teardown(test_tileset_invalid_uv, zip_setup, zip_teardown),
|
),
|
||||||
cmocka_unit_test_setup_teardown(test_tileset_missing_file, zip_setup, zip_teardown),
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_tileset_bad_version, zip_setup, zip_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_tileset_zero_tile_width, zip_setup, zip_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_tileset_zero_tile_height, zip_setup, zip_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_tileset_zero_columns, zip_setup, zip_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_tileset_zero_rows, zip_setup, zip_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_tileset_invalid_uv, zip_setup, zip_teardown
|
||||||
|
),
|
||||||
|
cmocka_unit_test_setup_teardown(
|
||||||
|
test_tileset_missing_file, zip_setup, zip_teardown
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ static const cutsceneitem_t CUTSCENE_TEST_SCRATCH_ITEMS[] = {
|
|||||||
// reach PRE_ROUND on its own to satisfy the wait.
|
// reach PRE_ROUND on its own to satisfy the wait.
|
||||||
CUTSCENE_BATTLE_WAIT_STATE(BATTLE_STATE_PRE_ROUND),
|
CUTSCENE_BATTLE_WAIT_STATE(BATTLE_STATE_PRE_ROUND),
|
||||||
CUTSCENE_SET_PAUSE(CUTSCENE_PAUSE_BATTLE),
|
CUTSCENE_SET_PAUSE(CUTSCENE_PAUSE_BATTLE),
|
||||||
CUTSCENE_BATTLE_FORCE_ACTION(2, 0),// enemy (slot 2) forced onto allyA (slot 0)
|
// enemy (slot 2) forced onto allyA (slot 0)
|
||||||
|
CUTSCENE_BATTLE_FORCE_ACTION(2, 0),
|
||||||
CUTSCENE_SET_PAUSE(CUTSCENE_PAUSE_NONE)
|
CUTSCENE_SET_PAUSE(CUTSCENE_PAUSE_NONE)
|
||||||
};
|
};
|
||||||
static const cutscene_t CUTSCENE_TEST_SCRATCH = {
|
static const cutscene_t CUTSCENE_TEST_SCRATCH = {
|
||||||
@@ -45,8 +46,12 @@ static void test_battleStartEntersOpeningThenPreRound(void **state) {
|
|||||||
|
|
||||||
|
|
||||||
battleInit();
|
battleInit();
|
||||||
addFighter(BATTLE_FIGHTER_TEAM_ALLY, BATTLE_FIGHTER_CONTROLLER_PLAYER, 10, 0, 10, 20);
|
addFighter(
|
||||||
addFighter(BATTLE_FIGHTER_TEAM_ENEMY, BATTLE_FIGHTER_CONTROLLER_AI, 10, 0, 5, 20);
|
BATTLE_FIGHTER_TEAM_ALLY, BATTLE_FIGHTER_CONTROLLER_PLAYER, 10, 0, 10, 20
|
||||||
|
);
|
||||||
|
addFighter(
|
||||||
|
BATTLE_FIGHTER_TEAM_ENEMY, BATTLE_FIGHTER_CONTROLLER_AI, 10, 0, 5, 20
|
||||||
|
);
|
||||||
|
|
||||||
battleStart(BATTLE_ENCOUNTER_REGULAR, true);
|
battleStart(BATTLE_ENCOUNTER_REGULAR, true);
|
||||||
assert_int_equal(BATTLE.state, BATTLE_STATE_OPENING);
|
assert_int_equal(BATTLE.state, BATTLE_STATE_OPENING);
|
||||||
@@ -231,8 +236,12 @@ static void test_battleFleeEndsInStateEndedImmediately(void **state) {
|
|||||||
|
|
||||||
|
|
||||||
battleInit();
|
battleInit();
|
||||||
addFighter(BATTLE_FIGHTER_TEAM_ALLY, BATTLE_FIGHTER_CONTROLLER_PLAYER, 5, 0, 10, 20);
|
addFighter(
|
||||||
addFighter(BATTLE_FIGHTER_TEAM_ENEMY, BATTLE_FIGHTER_CONTROLLER_AI, 5, 0, 5, 20);
|
BATTLE_FIGHTER_TEAM_ALLY, BATTLE_FIGHTER_CONTROLLER_PLAYER, 5, 0, 10, 20
|
||||||
|
);
|
||||||
|
addFighter(
|
||||||
|
BATTLE_FIGHTER_TEAM_ENEMY, BATTLE_FIGHTER_CONTROLLER_AI, 5, 0, 5, 20
|
||||||
|
);
|
||||||
|
|
||||||
battleStart(BATTLE_ENCOUNTER_REGULAR, true);
|
battleStart(BATTLE_ENCOUNTER_REGULAR, true);
|
||||||
battleUpdate();// OPENING -> PRE_ROUND
|
battleUpdate();// OPENING -> PRE_ROUND
|
||||||
@@ -247,8 +256,12 @@ static void test_battleFleeUnavailableIsIgnored(void **state) {
|
|||||||
|
|
||||||
|
|
||||||
battleInit();
|
battleInit();
|
||||||
addFighter(BATTLE_FIGHTER_TEAM_ALLY, BATTLE_FIGHTER_CONTROLLER_PLAYER, 5, 0, 10, 20);
|
addFighter(
|
||||||
addFighter(BATTLE_FIGHTER_TEAM_ENEMY, BATTLE_FIGHTER_CONTROLLER_AI, 5, 0, 5, 20);
|
BATTLE_FIGHTER_TEAM_ALLY, BATTLE_FIGHTER_CONTROLLER_PLAYER, 5, 0, 10, 20
|
||||||
|
);
|
||||||
|
addFighter(
|
||||||
|
BATTLE_FIGHTER_TEAM_ENEMY, BATTLE_FIGHTER_CONTROLLER_AI, 5, 0, 5, 20
|
||||||
|
);
|
||||||
|
|
||||||
battleStart(BATTLE_ENCOUNTER_REGULAR, false);
|
battleStart(BATTLE_ENCOUNTER_REGULAR, false);
|
||||||
battleUpdate();// OPENING -> PRE_ROUND
|
battleUpdate();// OPENING -> PRE_ROUND
|
||||||
@@ -279,7 +292,9 @@ static void test_battleOnStateChangedFiresAcrossFullRound(void **state) {
|
|||||||
stateChangedCount = 0;
|
stateChangedCount = 0;
|
||||||
BATTLE.onStateChanged = recordStateChanged;
|
BATTLE.onStateChanged = recordStateChanged;
|
||||||
|
|
||||||
addFighter(BATTLE_FIGHTER_TEAM_ALLY, BATTLE_FIGHTER_CONTROLLER_PLAYER, 1, 0, 10, 100);
|
addFighter(
|
||||||
|
BATTLE_FIGHTER_TEAM_ALLY, BATTLE_FIGHTER_CONTROLLER_PLAYER, 1, 0, 10, 100
|
||||||
|
);
|
||||||
battlefighter_t *enemy = addFighter(
|
battlefighter_t *enemy = addFighter(
|
||||||
BATTLE_FIGHTER_TEAM_ENEMY, BATTLE_FIGHTER_CONTROLLER_AI, 1, 0, 5, 100
|
BATTLE_FIGHTER_TEAM_ENEMY, BATTLE_FIGHTER_CONTROLLER_AI, 1, 0, 5, 100
|
||||||
);
|
);
|
||||||
@@ -410,10 +425,13 @@ static void test_battleCutsceneForceActionOverridesTarget(void **state) {
|
|||||||
battlePlayerAttack(enemy->id);// allyA -> AI_SELECTION would be next...
|
battlePlayerAttack(enemy->id);// allyA -> AI_SELECTION would be next...
|
||||||
assert_ptr_equal(battleGetCurrentFighter(), allyB);
|
assert_ptr_equal(battleGetCurrentFighter(), allyB);
|
||||||
battlePlayerAttack(enemy->id);// ...but AI_SELECTION must skip the enemy,
|
battlePlayerAttack(enemy->id);// ...but AI_SELECTION must skip the enemy,
|
||||||
assert_int_equal(BATTLE.state, BATTLE_STATE_AI_SELECTION);// since it's decided
|
// since it's decided
|
||||||
|
assert_int_equal(BATTLE.state, BATTLE_STATE_AI_SELECTION);
|
||||||
|
|
||||||
battleUpdate();// AI_SELECTION: enemy already decided, skipped -> MOVES_EXECUTING
|
// AI_SELECTION: enemy already decided, skipped -> MOVES_EXECUTING
|
||||||
assert_int_equal(BATTLE.actions[enemy->id].targetIndex, allyA->id);// untouched
|
battleUpdate();
|
||||||
|
// untouched
|
||||||
|
assert_int_equal(BATTLE.actions[enemy->id].targetIndex, allyA->id);
|
||||||
|
|
||||||
battleUpdate();// allyA attacks enemy
|
battleUpdate();// allyA attacks enemy
|
||||||
battleUpdate();// allyB attacks enemy
|
battleUpdate();// allyB attacks enemy
|
||||||
@@ -435,7 +453,9 @@ int main(int argc, char** argv) {
|
|||||||
cmocka_unit_test(test_battleFleeEndsInStateEndedImmediately),
|
cmocka_unit_test(test_battleFleeEndsInStateEndedImmediately),
|
||||||
cmocka_unit_test(test_battleFleeUnavailableIsIgnored),
|
cmocka_unit_test(test_battleFleeUnavailableIsIgnored),
|
||||||
cmocka_unit_test(test_battleOnStateChangedFiresAcrossFullRound),
|
cmocka_unit_test(test_battleOnStateChangedFiresAcrossFullRound),
|
||||||
cmocka_unit_test(test_battleOnActionDecidedFiresPerFighterRegardlessOfSource),
|
cmocka_unit_test(
|
||||||
|
test_battleOnActionDecidedFiresPerFighterRegardlessOfSource
|
||||||
|
),
|
||||||
cmocka_unit_test(test_battleCutsceneForceActionOverridesTarget),
|
cmocka_unit_test(test_battleCutsceneForceActionOverridesTarget),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ static void test_cutsceneCallbackFiresOnStartWithUserData(void **state) {
|
|||||||
static void test_cutsceneCallbackNullIsNoop(void **state) {
|
static void test_cutsceneCallbackNullIsNoop(void **state) {
|
||||||
|
|
||||||
callbackCallCount = 0;
|
callbackCallCount = 0;
|
||||||
cutsceneitem_t item = { .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = NULL };
|
cutsceneitem_t item =
|
||||||
|
{ .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = NULL };
|
||||||
cutsceneitemdata_t data;
|
cutsceneitemdata_t data;
|
||||||
|
|
||||||
cutsceneCallbackStart(&item, &data);// should not crash
|
cutsceneCallbackStart(&item, &data);// should not crash
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ static void test_cutsceneMapAreaRemoveResolvesLastCreatedSentinel(
|
|||||||
cutsceneMapAreaAddStart(&addItem, &data);
|
cutsceneMapAreaAddStart(&addItem, &data);
|
||||||
uint8_t id = CUTSCENE_SYSTEM.areaLastCreated;
|
uint8_t id = CUTSCENE_SYSTEM.areaLastCreated;
|
||||||
|
|
||||||
cutsceneitem_t removeItem = CUTSCENE_MAP_AREA_REMOVE(CUTSCENE_AREA_LAST_CREATED);
|
cutsceneitem_t removeItem =
|
||||||
|
CUTSCENE_MAP_AREA_REMOVE(CUTSCENE_AREA_LAST_CREATED);
|
||||||
cutsceneMapAreaRemoveStart(&removeItem, &data);
|
cutsceneMapAreaRemoveStart(&removeItem, &data);
|
||||||
assert_null(MAP_AREAS[id].callback);
|
assert_null(MAP_AREAS[id].callback);
|
||||||
}
|
}
|
||||||
@@ -135,7 +136,9 @@ int main(int argc, char** argv) {
|
|||||||
cmocka_unit_test(test_cutsceneMapAreaRemoveClearsSlot),
|
cmocka_unit_test(test_cutsceneMapAreaRemoveClearsSlot),
|
||||||
cmocka_unit_test(test_cutsceneMapAreaRemoveResolvesLastCreatedSentinel),
|
cmocka_unit_test(test_cutsceneMapAreaRemoveResolvesLastCreatedSentinel),
|
||||||
cmocka_unit_test(test_cutsceneMapAreaWaitCompletesWhenTriggerCountChanges),
|
cmocka_unit_test(test_cutsceneMapAreaWaitCompletesWhenTriggerCountChanges),
|
||||||
cmocka_unit_test(test_cutsceneMapAreaWaitCompletesWhenAnyWatchedAreaChanges),
|
cmocka_unit_test(
|
||||||
|
test_cutsceneMapAreaWaitCompletesWhenAnyWatchedAreaChanges
|
||||||
|
),
|
||||||
cmocka_unit_test(test_cutsceneMapAreaWaitResolvesLastCreatedSentinel),
|
cmocka_unit_test(test_cutsceneMapAreaWaitResolvesLastCreatedSentinel),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -126,7 +126,9 @@ static void test_cutsceneSystemGetEntityDirectIndexUpdatesLastRef(
|
|||||||
entity_t *resolved = cutsceneSystemGetEntity(2);
|
entity_t *resolved = cutsceneSystemGetEntity(2);
|
||||||
assert_ptr_equal(resolved, &ENTITIES[2]);
|
assert_ptr_equal(resolved, &ENTITIES[2]);
|
||||||
// Resolving by direct index also updates LAST_REF.
|
// Resolving by direct index also updates LAST_REF.
|
||||||
assert_ptr_equal(cutsceneSystemGetEntity(CUTSCENE_ENTITY_LAST_REF), &ENTITIES[2]);
|
assert_ptr_equal(
|
||||||
|
cutsceneSystemGetEntity(CUTSCENE_ENTITY_LAST_REF), &ENTITIES[2]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_cutsceneSystemGetAreaId(void **state) {
|
static void test_cutsceneSystemGetAreaId(void **state) {
|
||||||
|
|||||||
@@ -10,7 +10,9 @@
|
|||||||
#include "rpg/overworld/map.h"
|
#include "rpg/overworld/map.h"
|
||||||
#include "rpg/overworld/worldpos.h"
|
#include "rpg/overworld/worldpos.h"
|
||||||
|
|
||||||
static void setTile(const worldpos_t pos, const tileshape_t shape, const uint8_t z) {
|
static void setTile(
|
||||||
|
const worldpos_t pos, const tileshape_t shape, const uint8_t z
|
||||||
|
) {
|
||||||
chunktileindex_t index = worldPosToChunkTileIndex(&pos);
|
chunktileindex_t index = worldPosToChunkTileIndex(&pos);
|
||||||
MAP.chunks[0].tiles[index] = (tile_t){ .shape = shape, .z = z };
|
MAP.chunks[0].tiles[index] = (tile_t){ .shape = shape, .z = z };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,9 @@ static void test_entityInteractWithPrintTurnsNpcToFacePlayer(void **state) {
|
|||||||
entityInteractWith(player, target);
|
entityInteractWith(player, target);
|
||||||
|
|
||||||
assert_true(uiTextboxMainIsActive());
|
assert_true(uiTextboxMainIsActive());
|
||||||
assert_int_equal(target->data.npc.interactState, NPC_INTERACT_STATE_CONVERSING);
|
assert_int_equal(
|
||||||
|
target->data.npc.interactState, NPC_INTERACT_STATE_CONVERSING
|
||||||
|
);
|
||||||
// NPC turns to face the opposite of the player's facing direction.
|
// NPC turns to face the opposite of the player's facing direction.
|
||||||
assert_int_equal(target->direction, entityDirGetOpposite(player->direction));
|
assert_int_equal(target->direction, entityDirGetOpposite(player->direction));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,9 @@ static void test_mapAreaInit(void **state) {
|
|||||||
const worldpos_t max = { 0, 0, 0 };
|
const worldpos_t max = { 0, 0, 0 };
|
||||||
|
|
||||||
// min/max should be normalized regardless of argument order.
|
// min/max should be normalized regardless of argument order.
|
||||||
mapAreaInit(&area, min, max, recordCallback, MAP_AREA_NOTIFY_ALL, MAP_TRIGGER_ALL);
|
mapAreaInit(
|
||||||
|
&area, min, max, recordCallback, MAP_AREA_NOTIFY_ALL, MAP_TRIGGER_ALL
|
||||||
|
);
|
||||||
assert_int_equal(area.min.x, 0);
|
assert_int_equal(area.min.x, 0);
|
||||||
assert_int_equal(area.min.y, 0);
|
assert_int_equal(area.min.y, 0);
|
||||||
assert_int_equal(area.max.x, 5);
|
assert_int_equal(area.max.x, 5);
|
||||||
@@ -56,7 +58,9 @@ static void test_mapAreaIsInside(void **state) {
|
|||||||
|
|
||||||
assert_true(mapAreaIsInside(&area, (worldpos_t){ 5, 5, 0 }));
|
assert_true(mapAreaIsInside(&area, (worldpos_t){ 5, 5, 0 }));
|
||||||
assert_true(mapAreaIsInside(&area, (worldpos_t){ 0, 0, 0 }));// inclusive min
|
assert_true(mapAreaIsInside(&area, (worldpos_t){ 0, 0, 0 }));// inclusive min
|
||||||
assert_true(mapAreaIsInside(&area, (worldpos_t){ 10, 10, 0 }));// inclusive max
|
assert_true(
|
||||||
|
mapAreaIsInside(&area, (worldpos_t){ 10, 10, 0 })
|
||||||
|
);// inclusive max
|
||||||
assert_false(mapAreaIsInside(&area, (worldpos_t){ 11, 5, 0 }));
|
assert_false(mapAreaIsInside(&area, (worldpos_t){ 11, 5, 0 }));
|
||||||
assert_false(mapAreaIsInside(&area, (worldpos_t){ 5, 5, 1 }));
|
assert_false(mapAreaIsInside(&area, (worldpos_t){ 5, 5, 1 }));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ int saveTestFixtureSetup(void **state) {
|
|||||||
SAVE_TEST_FIXTURE_HAD_REAL_HOME = realHome != NULL;
|
SAVE_TEST_FIXTURE_HAD_REAL_HOME = realHome != NULL;
|
||||||
if(realHome != NULL) {
|
if(realHome != NULL) {
|
||||||
stringCopy(
|
stringCopy(
|
||||||
SAVE_TEST_FIXTURE_REAL_HOME, realHome, sizeof(SAVE_TEST_FIXTURE_REAL_HOME) - 1
|
SAVE_TEST_FIXTURE_REAL_HOME, realHome,
|
||||||
|
sizeof(SAVE_TEST_FIXTURE_REAL_HOME) - 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +56,10 @@ int saveTestFixtureSetup(void **state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int saveTestFixtureTeardown(void **state) {
|
int saveTestFixtureTeardown(void **state) {
|
||||||
nftw(SAVE_TEST_FIXTURE_HOME, saveTestFixtureRemoveEntry, 16, FTW_DEPTH | FTW_PHYS);
|
nftw(
|
||||||
|
SAVE_TEST_FIXTURE_HOME, saveTestFixtureRemoveEntry, 16,
|
||||||
|
FTW_DEPTH | FTW_PHYS
|
||||||
|
);
|
||||||
|
|
||||||
if(SAVE_TEST_FIXTURE_HAD_REAL_HOME) {
|
if(SAVE_TEST_FIXTURE_HAD_REAL_HOME) {
|
||||||
setenv("HOME", SAVE_TEST_FIXTURE_REAL_HOME, 1);
|
setenv("HOME", SAVE_TEST_FIXTURE_REAL_HOME, 1);
|
||||||
|
|||||||
+21
-9
@@ -299,7 +299,9 @@ static void test_saveSaveSlot_success(void **state) {
|
|||||||
makeDeviceAvailable();
|
makeDeviceAvailable();
|
||||||
SAVE.slotCurrent = 1;
|
SAVE.slotCurrent = 1;
|
||||||
saveSlotInit(&SAVE.slot);
|
saveSlotInit(&SAVE.slot);
|
||||||
stringCopy(SAVE.slot.cachedData.name, "Hero", sizeof(SAVE.slot.cachedData.name));
|
stringCopy(
|
||||||
|
SAVE.slot.cachedData.name, "Hero", sizeof(SAVE.slot.cachedData.name)
|
||||||
|
);
|
||||||
SAVE.slot.cachedData.playerLevel = 12;
|
SAVE.slot.cachedData.playerLevel = 12;
|
||||||
SAVE.slotDirty = true;
|
SAVE.slotDirty = true;
|
||||||
|
|
||||||
@@ -353,7 +355,9 @@ static void test_saveLoadSlot_deviceReadFails_cacheStaysStale(void **state) {
|
|||||||
makeDeviceAvailable();
|
makeDeviceAvailable();
|
||||||
|
|
||||||
char_t slotPath[512];
|
char_t slotPath[512];
|
||||||
errorret_t pathRet = saveDeviceLinuxGetSlotPath(slotPath, sizeof(slotPath), 0);
|
errorret_t pathRet = saveDeviceLinuxGetSlotPath(
|
||||||
|
slotPath, sizeof(slotPath), 0
|
||||||
|
);
|
||||||
assert_true(errorIsOk(pathRet));
|
assert_true(errorIsOk(pathRet));
|
||||||
FILE *file = fopen(slotPath, "w");
|
FILE *file = fopen(slotPath, "w");
|
||||||
assert_non_null(file);
|
assert_non_null(file);
|
||||||
@@ -428,7 +432,9 @@ static void test_saveLoadAllSlots_middleSlotCorrupt_stopsAtFailingIndex(
|
|||||||
assert_true(errorIsOk(saveRet));
|
assert_true(errorIsOk(saveRet));
|
||||||
|
|
||||||
char_t slotPath[512];
|
char_t slotPath[512];
|
||||||
errorret_t pathRet = saveDeviceLinuxGetSlotPath(slotPath, sizeof(slotPath), 1);
|
errorret_t pathRet = saveDeviceLinuxGetSlotPath(
|
||||||
|
slotPath, sizeof(slotPath), 1
|
||||||
|
);
|
||||||
assert_true(errorIsOk(pathRet));
|
assert_true(errorIsOk(pathRet));
|
||||||
FILE *file = fopen(slotPath, "w");
|
FILE *file = fopen(slotPath, "w");
|
||||||
assert_non_null(file);
|
assert_non_null(file);
|
||||||
@@ -487,7 +493,8 @@ int main(void) {
|
|||||||
),
|
),
|
||||||
|
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveUpdate_noopWhenNotFinding, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveUpdate_noopWhenNotFinding,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
|
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
@@ -537,7 +544,8 @@ int main(void) {
|
|||||||
saveTestFixtureSetup, saveTestFixtureTeardown
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveSaveSettings_notDirty_isNoop, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveSaveSettings_notDirty_isNoop,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveSaveSettings_dirtyForced_writesAndClearsFlag,
|
test_saveSaveSettings_dirtyForced_writesAndClearsFlag,
|
||||||
@@ -553,19 +561,23 @@ int main(void) {
|
|||||||
),
|
),
|
||||||
|
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveSaveSlot_noCurrentDeviceAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveSaveSlot_noCurrentDeviceAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveSaveSlot_invalidSlotIndexAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveSaveSlot_invalidSlotIndexAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveSaveSlot_success, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveSaveSlot_success, saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveLoadSlot_noCurrentDeviceAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveLoadSlot_noCurrentDeviceAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveLoadSlot_invalidSlotIndexAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveLoadSlot_invalidSlotIndexAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveLoadSlot_success, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveLoadSlot_success, saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
|
|||||||
+32
-16
@@ -258,30 +258,38 @@ int main(void) {
|
|||||||
assertInit();
|
assertInit();
|
||||||
const struct CMUnitTest tests[] = {
|
const struct CMUnitTest tests[] = {
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveDeviceInit_nullAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveDeviceInit_nullAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveDeviceInit_setsUnknownState, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveDeviceInit_setsUnknownState,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
|
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveDeviceUpdate_nullAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveDeviceUpdate_nullAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveDeviceUpdate_firesQueuedCallbackOnce, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveDeviceUpdate_firesQueuedCallbackOnce,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveDeviceFireCallback_nullAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveDeviceFireCallback_nullAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveDeviceFireCallback_setsFlag, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveDeviceFireCallback_setsFlag,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveDeviceFireCallback_assertsIfAlreadyQueued, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveDeviceFireCallback_assertsIfAlreadyQueued,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
|
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveDeviceCheckAvailability_nullAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveDeviceCheckAvailability_nullAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveDeviceCheckAvailability_assertsWhileAlreadyChecking,
|
test_saveDeviceCheckAvailability_assertsWhileAlreadyChecking,
|
||||||
@@ -293,29 +301,37 @@ int main(void) {
|
|||||||
),
|
),
|
||||||
|
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveDeviceSlotWrite_nullAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveDeviceSlotWrite_nullAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveDeviceSlotRead_nullAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveDeviceSlotRead_nullAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveDeviceSettingsWrite_nullAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveDeviceSettingsWrite_nullAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveDeviceSettingsRead_nullAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveDeviceSettingsRead_nullAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveDeviceSlot_dispatchesToPlatform, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveDeviceSlot_dispatchesToPlatform,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveDeviceSettings_dispatchesToPlatform, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveDeviceSettings_dispatchesToPlatform,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
|
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveDeviceDispose_nullAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveDeviceDispose_nullAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_saveDeviceDispose_succeeds, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_saveDeviceDispose_succeeds,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -250,7 +250,8 @@ static void test_slotRead_corruptFile_errors(void **state) {
|
|||||||
assert_int_equal(tmpDevice.state, SAVE_DEVICE_STATE_AVAILABLE);
|
assert_int_equal(tmpDevice.state, SAVE_DEVICE_STATE_AVAILABLE);
|
||||||
|
|
||||||
char_t slotPath[512];
|
char_t slotPath[512];
|
||||||
errorret_t pathRet = saveDeviceLinuxGetSlotPath(slotPath, sizeof(slotPath), 0);
|
errorret_t pathRet =
|
||||||
|
saveDeviceLinuxGetSlotPath(slotPath, sizeof(slotPath), 0);
|
||||||
assert_true(errorIsOk(pathRet));
|
assert_true(errorIsOk(pathRet));
|
||||||
|
|
||||||
FILE *file = fopen(slotPath, "w");
|
FILE *file = fopen(slotPath, "w");
|
||||||
@@ -334,7 +335,8 @@ static void test_settingsRead_corruptFile_errors(void **state) {
|
|||||||
assert_int_equal(tmpDevice.state, SAVE_DEVICE_STATE_AVAILABLE);
|
assert_int_equal(tmpDevice.state, SAVE_DEVICE_STATE_AVAILABLE);
|
||||||
|
|
||||||
char_t settingsPath[512];
|
char_t settingsPath[512];
|
||||||
errorret_t pathRet = saveDeviceLinuxGetSettingsPath(settingsPath, sizeof(settingsPath));
|
errorret_t pathRet =
|
||||||
|
saveDeviceLinuxGetSettingsPath(settingsPath, sizeof(settingsPath));
|
||||||
assert_true(errorIsOk(pathRet));
|
assert_true(errorIsOk(pathRet));
|
||||||
|
|
||||||
FILE *file = fopen(settingsPath, "w");
|
FILE *file = fopen(settingsPath, "w");
|
||||||
@@ -357,38 +359,48 @@ int main(void) {
|
|||||||
test_getDirectory_success, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_getDirectory_success, saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_getDirectory_homeUnset_errors, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_getDirectory_homeUnset_errors,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_getDirectory_nullAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_getDirectory_nullAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_getSettingsPath_success, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_getSettingsPath_success,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_getSettingsPath_homeUnset_errors, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_getSettingsPath_homeUnset_errors,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_getSlotPath_success, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_getSlotPath_success, saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_getSlotPath_homeUnset_errors, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_getSlotPath_homeUnset_errors,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
|
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_checkAvailability_wrongStateAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_checkAvailability_wrongStateAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_checkAvailability_nullAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_checkAvailability_nullAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_checkAvailability_success, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_checkAvailability_success,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_checkAvailability_homeUnset, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_checkAvailability_homeUnset,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_checkAvailability_mkdirpFails, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_checkAvailability_mkdirpFails,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
|
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
@@ -398,29 +410,37 @@ int main(void) {
|
|||||||
test_slotRead_nullAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_slotRead_nullAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_slotWriteRead_roundTrip, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_slotWriteRead_roundTrip,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_slotRead_noFileYet_leavesSlotUntouched, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_slotRead_noFileYet_leavesSlotUntouched,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_slotRead_corruptFile_errors, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_slotRead_corruptFile_errors,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
|
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_settingsWrite_nullAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_settingsWrite_nullAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_settingsRead_nullAsserts, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_settingsRead_nullAsserts,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_settingsWriteRead_roundTrip, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_settingsWriteRead_roundTrip,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_settingsRead_noFileYet_leavesUntouched, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_settingsRead_noFileYet_leavesUntouched,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
cmocka_unit_test_setup_teardown(
|
cmocka_unit_test_setup_teardown(
|
||||||
test_settingsRead_corruptFile_errors, saveTestFixtureSetup, saveTestFixtureTeardown
|
test_settingsRead_corruptFile_errors,
|
||||||
|
saveTestFixtureSetup, saveTestFixtureTeardown
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,9 @@ static errorret_t settingsToJSON(
|
|||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
static errorret_t settingsFromJSON(savesettings_t *settings, const char_t *json) {
|
static errorret_t settingsFromJSON(
|
||||||
|
savesettings_t *settings, const char_t *json
|
||||||
|
) {
|
||||||
readInit(json, strlen(json));
|
readInit(json, strlen(json));
|
||||||
errorret_t readResult = saveSettingsReadJSON(settings, object);
|
errorret_t readResult = saveSettingsReadJSON(settings, object);
|
||||||
yyjson_doc_free(jsonDoc);
|
yyjson_doc_free(jsonDoc);
|
||||||
|
|||||||
@@ -18,7 +18,9 @@
|
|||||||
// inside a function returning errorret_t) so tests can call them plainly.
|
// inside a function returning errorret_t) so tests can call them plainly.
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static errorret_t slotToJSON(saveslot_t *slot, char_t **outJson, size_t *outLen) {
|
static errorret_t slotToJSON(
|
||||||
|
saveslot_t *slot, char_t **outJson, size_t *outLen
|
||||||
|
) {
|
||||||
writeInit();
|
writeInit();
|
||||||
|
|
||||||
errorret_t writeResult = saveSlotWriteJSON(slot, doc, object);
|
errorret_t writeResult = saveSlotWriteJSON(slot, doc, object);
|
||||||
|
|||||||
+26
-12
@@ -100,8 +100,12 @@ static void test_memoryCopy(void **state) {
|
|||||||
|
|
||||||
// Overlapping regions (should assert)
|
// Overlapping regions (should assert)
|
||||||
void *overlap = memoryAllocate(size * 2);
|
void *overlap = memoryAllocate(size * 2);
|
||||||
expect_assert_failure(memoryCopy((uint8_t*)overlap, (uint8_t*)overlap + 8, size));
|
expect_assert_failure(
|
||||||
expect_assert_failure(memoryCopy((uint8_t*)overlap + 8, (uint8_t*)overlap, size));
|
memoryCopy((uint8_t*)overlap, (uint8_t*)overlap + 8, size)
|
||||||
|
);
|
||||||
|
expect_assert_failure(
|
||||||
|
memoryCopy((uint8_t*)overlap + 8, (uint8_t*)overlap, size)
|
||||||
|
);
|
||||||
memoryFree(overlap);
|
memoryFree(overlap);
|
||||||
|
|
||||||
memoryFree(src);
|
memoryFree(src);
|
||||||
@@ -198,22 +202,32 @@ static void test_memoryCopyRangeSafe(void **state) {
|
|||||||
assert_memory_equal(dest, src, size);
|
assert_memory_equal(dest, src, size);
|
||||||
|
|
||||||
// Cannot copy to NULL destination
|
// Cannot copy to NULL destination
|
||||||
expect_assert_failure(memoryCopyRangeSafe(NULL, src, (uint8_t*)src + 5, size));
|
expect_assert_failure(
|
||||||
|
memoryCopyRangeSafe(NULL, src, (uint8_t*)src + 5, size)
|
||||||
|
);
|
||||||
|
|
||||||
// Cannot copy from NULL start
|
// Cannot copy from NULL start
|
||||||
expect_assert_failure(memoryCopyRangeSafe(dest, NULL, (uint8_t*)src + 5, size));
|
expect_assert_failure(
|
||||||
|
memoryCopyRangeSafe(dest, NULL, (uint8_t*)src + 5, size)
|
||||||
|
);
|
||||||
|
|
||||||
// Cannot copy from NULL end
|
// Cannot copy from NULL end
|
||||||
expect_assert_failure(memoryCopyRangeSafe(dest, (uint8_t*)src, NULL, size));
|
expect_assert_failure(memoryCopyRangeSafe(dest, (uint8_t*)src, NULL, size));
|
||||||
|
|
||||||
// Start and end are the same
|
// Start and end are the same
|
||||||
expect_assert_failure(memoryCopyRangeSafe(dest, (uint8_t*)src, (uint8_t*)src, size));
|
expect_assert_failure(
|
||||||
|
memoryCopyRangeSafe(dest, (uint8_t*)src, (uint8_t*)src, size)
|
||||||
|
);
|
||||||
|
|
||||||
// End is before start
|
// End is before start
|
||||||
expect_assert_failure(memoryCopyRangeSafe(dest, (uint8_t*)src + 5, (uint8_t*)src + 2, size));
|
expect_assert_failure(
|
||||||
|
memoryCopyRangeSafe(dest, (uint8_t*)src + 5, (uint8_t*)src + 2, size)
|
||||||
|
);
|
||||||
|
|
||||||
// Size to copy exceeds maximum
|
// Size to copy exceeds maximum
|
||||||
expect_assert_failure(memoryCopyRangeSafe(dest, (uint8_t*)src, (uint8_t*)src + 10, 5));
|
expect_assert_failure(
|
||||||
|
memoryCopyRangeSafe(dest, (uint8_t*)src, (uint8_t*)src + 10, 5)
|
||||||
|
);
|
||||||
|
|
||||||
memoryFree(src);
|
memoryFree(src);
|
||||||
memoryFree(dest);
|
memoryFree(dest);
|
||||||
|
|||||||
@@ -77,7 +77,8 @@ void testSortMethod(
|
|||||||
int_t compareStructsValues(const void *a, const void *b) {
|
int_t compareStructsValues(const void *a, const void *b) {
|
||||||
const teststruct_t *structA = (const teststruct_t*)a;
|
const teststruct_t *structA = (const teststruct_t*)a;
|
||||||
const teststruct_t *structB = (const teststruct_t*)b;
|
const teststruct_t *structB = (const teststruct_t*)b;
|
||||||
return (structA->value > structB->value) - (structA->value < structB->value);
|
return
|
||||||
|
(structA->value > structB->value) - (structA->value < structB->value);
|
||||||
}
|
}
|
||||||
sortMethod(structArray, 4, sizeof(teststruct_t), compareStructsValues);
|
sortMethod(structArray, 4, sizeof(teststruct_t), compareStructsValues);
|
||||||
char expectedValues[4] = {'a', 'b', 'c', 'd'};
|
char expectedValues[4] = {'a', 'b', 'c', 'd'};
|
||||||
|
|||||||
@@ -207,7 +207,11 @@ static void test_stringFormat(void **state) {
|
|||||||
|
|
||||||
// Test buffer too small
|
// Test buffer too small
|
||||||
expect_assert_failure(stringFormat(buffer, 5, "This is too long"));
|
expect_assert_failure(stringFormat(buffer, 5, "This is too long"));
|
||||||
expect_assert_failure(stringFormat(buffer, sizeof(buffer), "Hello %s", "This string is way too long to fit within the buffer that we have allocated"));
|
expect_assert_failure(stringFormat(
|
||||||
|
buffer, sizeof(buffer), "Hello %s",
|
||||||
|
"This string is way too long to fit within the buffer that we have "
|
||||||
|
"allocated"
|
||||||
|
));
|
||||||
|
|
||||||
// Test NULL destination, simply returns required length
|
// Test NULL destination, simply returns required length
|
||||||
len = stringFormat(NULL, 0, "Hello %s!", "World");
|
len = stringFormat(NULL, 0, "Hello %s!", "World");
|
||||||
|
|||||||
Reference in New Issue
Block a user