diff --git a/Changelog.md b/Changelog.md index 70ce1a9c..12cec371 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,7 @@ - External movies: Always enable external_movies by default ( https://github.com/julianxhokaxhiu/FFNx/pull/854 ) - External music: Fix music stopping too soon if the music is not looped ( https://github.com/julianxhokaxhiu/FFNx/pull/889 ) +- External textures: Convert RGB png to RGBA and RGBA64 to RGBA32 ( https://github.com/julianxhokaxhiu/FFNx/pull/896 ) - Renderer: Skip rendering frame if no draw commands have been submitted previously ## FF7 @@ -17,7 +18,7 @@ ## FF8 -- Core: Fix crashes happening in Non-US versions ( https://github.com/julianxhokaxhiu/FFNx/pull/848 ) +- Core: Fix crashes happening in Non-US versions ( https://github.com/julianxhokaxhiu/FFNx/pull/848 https://github.com/julianxhokaxhiu/FFNx/pull/896 ) - Core: Fix the game engine to show up to 16 high res field models without crashes or texture glitches ( https://github.com/julianxhokaxhiu/FFNx/pull/860 ) - Core: Fix sudden black frame between New Game movie and Infirmary intro scene - Core: Fix missing polygons on field 3D models ( https://github.com/julianxhokaxhiu/FFNx/pull/868 ) diff --git a/src/audio.cpp b/src/audio.cpp index 0159d700..43992074 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -75,8 +75,15 @@ void NxAudioEngine::loadConfig() } catch (const toml::parse_error &err) { - ffnx_warning("Parse error while opening the file %s. Will continue with the default settings.\n", _fullpath); - ffnx_warning("%s (Line %u Column %u)\n", err.what(), err.source().begin.line, err.source().begin.column); + if (!fileExists(_fullpath)) + { + ffnx_warning("File %s not found. Will continue with the default settings.\n", _fullpath); + } + else + { + ffnx_warning("Parse error while opening the file %s. Will continue with the default settings.\n", _fullpath); + ffnx_warning("%s (Line %u Column %u)\n", err.what(), err.source().begin.line, err.source().begin.column); + } nxAudioEngineConfig[type] = toml::parse(""); } @@ -565,19 +572,18 @@ void NxAudioEngine::cleanOldAudioSources() if (trace_all || trace_music) ffnx_trace("NxAudioEngine::%s: %d elements in the list after cleaning\n", __func__, _audioSourcesToDeleteLater.size()); } -SoLoud::AudioSource* NxAudioEngine::loadMusic(const char* name, bool isFullPath, const char* format, bool suppressOpeningSilence) +SoLoud::AudioSource* NxAudioEngine::loadMusic(const char* name, bool useNameAsFullPath, const char* format, bool suppressOpeningSilence) { SoLoud::AudioSource* music = nullptr; char filename[MAX_PATH]; bool exists = false; - if (isFullPath) + if (useNameAsFullPath) { - exists = fileExists(name); + exists = true; strcpy(filename, name); } - - if (!exists) + else { exists = getFilenameFullPath(filename, name, NxAudioEngineLayer::NXAUDIOENGINE_MUSIC); } diff --git a/src/audio.h b/src/audio.h index adbb7ca6..05d91648 100644 --- a/src/audio.h +++ b/src/audio.h @@ -190,7 +190,7 @@ class NxAudioEngine SoLoud::time _lastVolumeFadeEndTime = 0.0; void cleanOldAudioSources(); - SoLoud::AudioSource* loadMusic(const char* name, bool isFullPath = false, const char* format = nullptr, bool suppressOpeningSilence = false); + SoLoud::AudioSource* loadMusic(const char* name, bool useNameAsFullPath = false, const char* format = nullptr, bool suppressOpeningSilence = false); void overloadPlayArgumentsFromConfig(char* name, uint32_t *id, MusicOptions *MusicOptions); void backupMusic(int channelSource); void restoreMusic(int channelDest, double stopTime = 0); diff --git a/src/common.cpp b/src/common.cpp index 1676ed63..7e9ba6c9 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -2988,7 +2988,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) return FALSE; } - bool is_genuine_steam_api = isFileSigned(L"steam_api.dll"); + bool is_genuine_steam_api = isFileSigned("steam_api.dll"); if (!is_genuine_steam_api) is_genuine_steam_api = sha1_file("steam_api.dll") == "03bd9f3e352553a0af41f5fe006f6249a168c243"; if (!is_genuine_steam_api) { diff --git a/src/ff8.h b/src/ff8.h index b4ae06b1..25ebb1cb 100644 --- a/src/ff8.h +++ b/src/ff8.h @@ -1008,7 +1008,7 @@ struct ff8_gfx_driver struct ff8_field_state_common { uint8_t stack_data[0x140]; - uint32_t field_140; + uint32_t return_value; uint32_t field_144; uint32_t field_148; uint32_t field_14c; @@ -1066,6 +1066,30 @@ struct ff8_field_state_background { uint8_t field_1b3; }; +struct ff8_field_state_other { + ff8_field_state_common common; + uint8_t gap1[114]; + uint16_t current_triangle_id; + uint8_t gap1b[28]; + int16_t model_id; + uint8_t gap2[47]; + uint8_t pushonoff; + uint8_t gap3; + uint8_t talkonoff; + uint8_t throughonoff; + uint8_t gap4[2]; + uint8_t baseanim1; + uint8_t baseanim2; + uint8_t baseanim3; + uint8_t ladderanim1; + uint8_t ladderanim2; + uint8_t ladderanim3; + uint8_t setpc; + uint8_t gap5; + uint8_t setgeta; + uint8_t gap6[12]; +}; + struct ff8_char_computed_stats { uint8_t unk1[370]; uint16_t curr_hp; @@ -1276,6 +1300,8 @@ struct ff8_externals int (*field_scripts_init)(int, int, int, int); uint8_t *field_state_background_count; ff8_field_state_background **field_state_backgrounds; + uint8_t *field_state_other_count; + ff8_field_state_other **field_state_others; uint32_t load_field_models; uint32_t chara_one_read_file; uint32_t chara_one_seek_file; @@ -1691,7 +1717,6 @@ struct ff8_externals uint32_t scan_text_positions; uint32_t fps_limiter; double *time_volume_change_related_1A78BE0; - uint32_t* game_mode_obj_1D9CF88; uint32_t field_vars_stack_1CFE9B8; uint32_t get_card_name; uint32_t card_name_positions; diff --git a/src/ff8/mod.cpp b/src/ff8/mod.cpp index 354b787e..064e354c 100644 --- a/src/ff8/mod.cpp +++ b/src/ff8/mod.cpp @@ -48,14 +48,8 @@ bool TextureImage::createImage(const char *filename, int originalTexturePixelWid const char *extension = strrchr(filename, '.'); if (extension != nullptr && stricmp(extension + 1, "png") == 0) { // Load PNG using libPNG - bimg::ImageMip mip; - if (loadPng(filename, mip, targetFormat) && Renderer::doesItFitInMemory(mip.m_size + 1)) - { - _image = bimg::imageAlloc(&defaultAllocator, mip.m_format, mip.m_width, mip.m_height, mip.m_depth, 1, false, false, mip.m_data); - setLod(0); - - driver_free((void *)mip.m_data); - } + _image = loadPng(&defaultAllocator, filename, targetFormat); + setLod(0); } else if (extension != nullptr && stricmp(extension + 1, "dds") == 0) { // Load DDS using DirectXTex DirectX::TexMetadata metadata; @@ -68,7 +62,7 @@ bool TextureImage::createImage(const char *filename, int originalTexturePixelWid setLod(0); } } else { - _image = loadImageContainer(&defaultAllocator, filename, bimg::TextureFormat::BGRA8); + _image = loadImageContainer(&defaultAllocator, filename, targetFormat); if (_image != nullptr) { @@ -541,7 +535,7 @@ TexturePacker::TextureTypes TextureBackground::drawToImage( const bimg::ImageMip &mip = _texture.mip(); const uint32_t *imgData = reinterpret_cast(mip.m_data); const uint8_t imgScale = _texture.scale(); - const uint32_t imgWidth = mip.m_width / imgScale, imgHeight = mip.m_height / imgScale; + const uint32_t imgWidth = mip.m_width / imgScale; const uint8_t cols = targetW / TILE_SIZE, rows = targetH / TILE_SIZE; const uint8_t colsBpp = TILE_SIZE / (1 << uint16_t(targetBpp)); diff --git a/src/ff8_data.cpp b/src/ff8_data.cpp index d9ec5fb4..80255e0a 100644 --- a/src/ff8_data.cpp +++ b/src/ff8_data.cpp @@ -530,6 +530,8 @@ void ff8_find_externals() ff8_externals.field_scripts_init = (int(*)(int,int,int,int))(get_relative_call(ff8_externals.read_field_data, JP_VERSION ? 0xEDC : 0xE49)); ff8_externals.field_state_background_count = (uint8_t *)get_absolute_value(uint32_t(ff8_externals.field_scripts_init), 0x2CD + 0x1); ff8_externals.field_state_backgrounds = (ff8_field_state_background **)get_absolute_value(uint32_t(ff8_externals.field_scripts_init), 0x50B + 0x2); + ff8_externals.field_state_other_count = (uint8_t *)get_absolute_value(uint32_t(ff8_externals.field_scripts_init), 0x2C3 + 0x1); + ff8_externals.field_state_others = (ff8_field_state_other **)get_absolute_value(uint32_t(ff8_externals.field_scripts_init), 0x62C + 0x2); ff8_externals.load_field_models = get_relative_call(ff8_externals.read_field_data, JP_VERSION ? 0xFA2 : 0xF0F); ff8_externals.chara_one_read_file = get_relative_call(ff8_externals.load_field_models, 0x15F); ff8_externals.chara_one_seek_file = get_relative_call(ff8_externals.load_field_models, 0x582); @@ -813,7 +815,7 @@ void ff8_find_externals() ff8_externals.sub_54A230 = get_relative_call(ff8_externals.worldmap_with_fog_sub_53FAC0, 0x5D1); ff8_externals.sub_543CB0 = get_relative_call(ff8_externals.worldmap_with_fog_sub_53FAC0, JP_VERSION ? 0xA3C : 0xA47); ff8_externals.worldmap_update_steps_sub_6519D0 = get_relative_call(ff8_externals.worldmap_with_fog_sub_53FAC0, JP_VERSION ? 0x8C4 : 0x8CD); - ff8_externals.set_drawpoint_state_521D90 = (void(*)(uint8_t, char))get_relative_call(ff8_externals.sub_54E9B0, 0x85F); + ff8_externals.set_drawpoint_state_521D90 = (void(*)(uint8_t, char))get_relative_call(ff8_externals.sub_54E9B0, FF8_SP_VERSION ? 0x89A : 0x85F); ff8_externals.set_render_to_vram_current_screen_flag_before_battle = get_relative_call(ff8_externals.worldmap_with_fog_sub_53FAC0, JP_VERSION ? 0xB24 : 0xB2F); ff8_externals.sub_545F10 = get_relative_call(ff8_externals.sub_545EA0, 0x1C); @@ -875,7 +877,7 @@ void ff8_find_externals() ff8_externals.battle_sub_4877F0 = get_relative_call(ff8_externals.sub_485610, 0x6F); ff8_externals.battle_sub_48D200 = get_relative_call(ff8_externals.sub_485610, 0x323); ff8_externals.battle_ai_opcode_sub_487DF0 = get_relative_call(ff8_externals.battle_sub_4877F0, 0x82); - ff8_externals.update_tutorial_info_4AD170 = (void(*)(int))get_relative_call(ff8_externals.battle_ai_opcode_sub_487DF0, FF8_US_VERSION ? 0x216C : (JP_VERSION ? 0x2148 : 0x2176)); + ff8_externals.update_tutorial_info_4AD170 = (void(*)(int))get_relative_call(ff8_externals.battle_ai_opcode_sub_487DF0, FF8_US_VERSION ? 0x216C : (JP_VERSION ? 0x2148 : (FF8_SP_VERSION ? 0x21A0 : 0x2176))); ff8_externals.battle_get_draw_magic_amount_48FD20 = (int(*)(int, int, int))get_relative_call(ff8_externals.battle_sub_48D200, FF8_US_VERSION ? 0x354 : (JP_VERSION ? 0x36F : 0x355)); ff8_externals.sub_48B7E0 = get_relative_call(ff8_externals.sub_47CCB0, 0x8F0); ff8_externals.compute_char_stats_sub_495960 = get_relative_call(ff8_externals.sub_48B7E0, 0xA3); @@ -963,7 +965,7 @@ void ff8_find_externals() ff8_externals.character_data_1CFE74C = (byte*)get_absolute_value((uint32_t)ff8_externals.battle_menu_add_exp_and_stat_bonus_496CB0, 0xD); ff8_externals.battle_sub_485160 = get_relative_call(ff8_externals.sub_47CCB0, 0xB18); ff8_externals.battle_sub_48FE20 = get_relative_call(ff8_externals.battle_sub_485160, 0x91); - ff8_externals.battle_sub_494410 = get_relative_call(ff8_externals.battle_sub_48FE20, FF8_US_VERSION ? 0x139C : (JP_VERSION ? 0x1300 : 0x1301)); + ff8_externals.battle_sub_494410 = get_relative_call(ff8_externals.battle_sub_48FE20, FF8_US_VERSION ? 0x139C : (JP_VERSION ? 0x1300 : (FF8_SP_VERSION ? 0x130B : 0x1301))); ff8_externals.battle_sub_494AF0 = (void(*)(int, int, int, int))get_relative_call(ff8_externals.battle_sub_494410, 0x525); ff8_externals.fps_limiter = get_relative_call(ff8_externals.field_main_loop, 0x261); @@ -973,7 +975,6 @@ void ff8_find_externals() } ff8_externals.time_volume_change_related_1A78BE0 = (double *)get_absolute_value(ff8_externals.fps_limiter, 0x3F); - ff8_externals.game_mode_obj_1D9CF88 = (uint32_t*)get_absolute_value(uint32_t(ff8_externals.sub_47CA90), 0xCD); ff8_externals.field_vars_stack_1CFE9B8 = get_absolute_value(ff8_externals.opcode_pshm_w, 0x1E); common_externals.current_triangle_id = 0x0; diff --git a/src/ff8_opengl.cpp b/src/ff8_opengl.cpp index eaa27b40..e8250a17 100644 --- a/src/ff8_opengl.cpp +++ b/src/ff8_opengl.cpp @@ -1837,7 +1837,7 @@ void ff8_init_hooks(struct game_obj *_game_object) // draw magic from draw points replace_call(ff8_externals.opcode_drawpoint + 0x6B7, (void*)ff8_opcode_drawpoint_sub_4A0850); - replace_call(ff8_externals.sub_54E9B0 + (FF8_US_VERSION ? 0x845 : 0x85F), (void*)ff8_set_drawpoint_state_52D190); + replace_call(ff8_externals.sub_54E9B0 + (FF8_US_VERSION ? 0x845 : (FF8_SP_VERSION ? 0x89A : 0x85F)), (void*)ff8_set_drawpoint_state_52D190); // draw magic via stock in battle replace_call(ff8_externals.battle_sub_48D200 + (FF8_US_VERSION ? 0x354 : (JP_VERSION ? 0x36F : 0x355)), (void*)ff8_battle_get_magic_draw_amount_48FD20); @@ -1854,7 +1854,7 @@ void ff8_init_hooks(struct game_obj *_game_object) replace_call(ff8_externals.worldmap_update_steps_sub_6519D0 + 0x225, (void*)ff8_play_sfx_at_unlock_rinoa_limit_break); // omega destroyed - replace_call(ff8_externals.battle_ai_opcode_sub_487DF0 + (FF8_US_VERSION ? 0x216C : (JP_VERSION ? 0x2148 : 0x2176)), (void*)ff8_obtain_proof_of_omega); + replace_call(ff8_externals.battle_ai_opcode_sub_487DF0 + (FF8_US_VERSION ? 0x216C : (JP_VERSION ? 0x2148 : (FF8_SP_VERSION ? 0x21A0 : 0x2176))), (void*)ff8_obtain_proof_of_omega); // pupu side quest replace_call(ff8_externals.battle_check_won_sub_486500 + 0x66, (void*)ff8_battle_after_set_result_to_won_sub_494D40); diff --git a/src/field.cpp b/src/field.cpp index 690e51cd..2f61ce0a 100644 --- a/src/field.cpp +++ b/src/field.cpp @@ -249,7 +249,7 @@ int ff8_field_init_from_file(int unk1, int unk2, int unk3, int unk4) // Loop through objects until we find the one that has a valid triangle ID for(int i = 0; i < MAXBYTE; i++) { - common_externals.current_triangle_id = (int16_t*)(*ff8_externals.game_mode_obj_1D9CF88 + 0x264 * i + 0x1FA); + common_externals.current_triangle_id = (int16_t*)(*(uint32_t *)ff8_externals.field_state_others + 0x264 * i + 0x1FA); if (*common_externals.current_triangle_id != 0) break; } diff --git a/src/image/image.cpp b/src/image/image.cpp index 21a0d09b..d1d11094 100644 --- a/src/image/image.cpp +++ b/src/image/image.cpp @@ -38,15 +38,39 @@ static void LibPngWarningCb(png_structp png_ptr, const char* warning) ffnx_info("libpng warning: %s\n", warning); } -bool loadPng(const char *filename, bimg::ImageMip &mip, bimg::TextureFormat::Enum targetFormat) +void read_png_file(png_structp png_ptr, png_bytep data, size_t size) { - FILE* file = fopen(filename, "rb"); + bx::ReaderI *reader = (bx::ReaderI *)png_get_io_ptr(png_ptr); + bx::Error err; - if (!file) - { - return false; + int32_t r = bx::read(reader, data, size, &err); + + if (!err.isOk() || r != size) { + png_error(png_ptr, "Cannot read data"); + } +} + +bimg::ImageContainer *loadPng(bx::AllocatorI *allocator, const char *filename, bimg::TextureFormat::Enum targetFormat) +{ + bimg::ImageContainer *ret; + bx::FileReader reader; + bx::Error err; + + if (!bx::open(&reader, filename, &err) || !err.isOk()) { + return nullptr; } + if (trace_all || trace_loaders) ffnx_trace("%s: %s\n", __func__, filename); + + ret = loadPng(allocator, &reader, targetFormat); + + bx::close(&reader); + + return ret; +} + +bimg::ImageContainer *loadPng(bx::AllocatorI *allocator, bx::ReaderI *reader, bimg::TextureFormat::Enum targetFormat) +{ png_infop info_ptr = nullptr; png_structp png_ptr = nullptr; @@ -59,17 +83,11 @@ bool loadPng(const char *filename, bimg::ImageMip &mip, bimg::TextureFormat::Enu uint8_t* data = nullptr; size_t datasize = 0; - fseek(file, 0, SEEK_END); - datasize = ftell(file); - fseek(file, 0, SEEK_SET); - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)0, LibPngErrorCb, LibPngWarningCb); if (!png_ptr) { - fclose(file); - - return false; + return nullptr; } info_ptr = png_create_info_struct(png_ptr); @@ -78,147 +96,87 @@ bool loadPng(const char *filename, bimg::ImageMip &mip, bimg::TextureFormat::Enu { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); - fclose(file); - - return false; + return nullptr; } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - fclose(file); - - return false; + return nullptr; } - png_init_io(png_ptr, file); + png_set_read_fn(png_ptr, reader, read_png_file); png_set_filter(png_ptr, 0, PNG_FILTER_NONE); - if (!Renderer::doesItFitInMemory(datasize)) - { - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + png_read_info(png_ptr, info_ptr); - fclose(file); + // Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. + png_set_expand(png_ptr); + png_set_add_alpha(png_ptr, 0xFF, PNG_FILLER_AFTER); + // Use 1 byte per pixel in 1, 2, or 4-bit depth files. + png_set_packing(png_ptr); + // Expand the grayscale to 24-bit RGB if necessary. + png_set_gray_to_rgb(png_ptr); + // Scale a 16-bit depth file down to 8-bit, accurately. + png_set_scale_16(png_ptr); - return false; + if (targetFormat == bimg::TextureFormat::BGRA8) { + png_set_bgr(png_ptr); } - int transforms = PNG_TRANSFORM_EXPAND; - - if (targetFormat == bimg::TextureFormat::BGRA8) { - transforms |= PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_GRAY_TO_RGB | PNG_TRANSFORM_BGR; - } else if (targetFormat == bimg::TextureFormat::RGBA8) { - transforms |= PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_GRAY_TO_RGB; + if ((trace_all || trace_loaders) && (png_get_bit_depth(png_ptr, info_ptr) != 8 || png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_RGBA)) { + ffnx_warning("%s: PNG format is not RGBA32, it will be converted automatically (bit_depth=%d color_type=%X)\n", __func__, png_get_bit_depth(png_ptr, info_ptr), png_get_color_type(png_ptr, info_ptr)); } - png_read_png(png_ptr, info_ptr, transforms, NULL); + int number_passes = png_set_interlace_handling(png_ptr); + + png_read_update_info(png_ptr, info_ptr); color_type = png_get_color_type(png_ptr, info_ptr); bit_depth = png_get_bit_depth(png_ptr, info_ptr); _width = png_get_image_width(png_ptr, info_ptr); _height = png_get_image_height(png_ptr, info_ptr); - if (color_type == PNG_COLOR_TYPE_RGB && (targetFormat == bimg::TextureFormat::BGRA8 || targetFormat == bimg::TextureFormat::RGBA8)) { - ffnx_warning("%s: PNG files without alpha is not supported, please convert it to RGBA for improved performance\n", __func__); - - return false; - } - - rowptrs = png_get_rows(png_ptr, info_ptr); rowbytes = png_get_rowbytes(png_ptr, info_ptr); datasize = rowbytes * _height; if (trace_all || trace_loaders) ffnx_trace("%s: data_size=%d width=%d height=%d bit_depth=%d color_type=%X\n", __func__, datasize, _width, _height, bit_depth, color_type); - if (!Renderer::doesItFitInMemory(datasize)) + if (color_type != PNG_COLOR_TYPE_RGBA || bit_depth != 8) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - fclose(file); + ffnx_error("%s: Cannot convert PNG to RGBA32\n", __func__); - return false; + return nullptr; } - data = (uint8_t*)driver_calloc(datasize, sizeof(uint8_t)); - - for (png_uint_32 y = 0; y < _height; y++) memcpy(data + (rowbytes * y), rowptrs[y], rowbytes); - - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - - fclose(file); - - // ------------------------------------------------------------ + bimg::ImageContainer *image = bimg::imageAlloc(allocator, targetFormat == bimg::TextureFormat::Count ? bimg::TextureFormat::RGBA8 : targetFormat, _width, _height, 0, 1, false, false); - bimg::TextureFormat::Enum texFmt = bimg::TextureFormat::Unknown; + if (image == nullptr) { + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - switch (bit_depth) - { - case 8: - { - switch (color_type) - { - case PNG_COLOR_TYPE_GRAY: - texFmt = bimg::TextureFormat::R8; - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - texFmt = bimg::TextureFormat::RG8; - break; - case PNG_COLOR_TYPE_RGB: - texFmt = bimg::TextureFormat::RGB8; - break; - case PNG_COLOR_TYPE_RGBA: - case PNG_COLOR_TYPE_PALETTE: - texFmt = bimg::TextureFormat::RGBA8; - break; - } - break; + return nullptr; } - case 16: + + for (int pass = 0; pass < number_passes; pass++) { - switch (color_type) + data = (uint8_t *)image->m_data; + for (int y = 0; y < _height; y++) { - case PNG_COLOR_TYPE_GRAY: - texFmt = bimg::TextureFormat::R16; - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - texFmt = bimg::TextureFormat::RG16; - break; - case PNG_COLOR_TYPE_RGB: - case PNG_COLOR_TYPE_RGBA: - texFmt = bimg::TextureFormat::RGBA16; - break; - case PNG_COLOR_TYPE_PALETTE: - break; + png_read_row(png_ptr, data, NULL); + data += rowbytes; } - break; - } - default: - break; } - if (texFmt != bimg::TextureFormat::Unknown) - { - mip.m_blockSize = 0; - mip.m_bpp = 0; - mip.m_data = data; - mip.m_depth = 0; - mip.m_format = texFmt; - mip.m_hasAlpha = true; - mip.m_size = datasize; - mip.m_width = _width; - mip.m_height = _height; - - return true; - } - else - { - driver_free(data); - } + png_read_end(png_ptr, info_ptr); + + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - return false; + return image; } bool parseDds(const char *filename, DirectX::ScratchImage &image, DirectX::TexMetadata &metadata) diff --git a/src/image/image.h b/src/image/image.h index c02a0bb2..952f6329 100644 --- a/src/image/image.h +++ b/src/image/image.h @@ -25,10 +25,12 @@ #include #include #include +#include bimg::ImageContainer *loadImageContainer(bx::AllocatorI *allocator, const char *filename, bimg::TextureFormat::Enum targetFormat = bimg::TextureFormat::Count); -// Fast PNG opening, you need to deallocate mip.m_data yourself -bool loadPng(const char *filename, bimg::ImageMip &mip, bimg::TextureFormat::Enum targetFormat = bimg::TextureFormat::Count); +// Fast PNG opening +bimg::ImageContainer *loadPng(bx::AllocatorI *allocator, const char *filename, bimg::TextureFormat::Enum targetFormat = bimg::TextureFormat::Count); +bimg::ImageContainer *loadPng(bx::AllocatorI *allocator, bx::ReaderI *reader, bimg::TextureFormat::Enum targetFormat = bimg::TextureFormat::Count); // Fast DDS opening bool parseDds(const char *filename, DirectX::ScratchImage &image, DirectX::TexMetadata &metadata); bimg::ImageContainer *convertDds(bx::AllocatorI *allocator, DirectX::ScratchImage &image, const DirectX::TexMetadata &metadata, bimg::TextureFormat::Enum targetFormat, int lod); diff --git a/src/movies.cpp b/src/movies.cpp index 449af5d4..4f67f4d0 100644 --- a/src/movies.cpp +++ b/src/movies.cpp @@ -197,7 +197,6 @@ uint32_t ff8_movie_frames; void ff8_prepare_movie(uint8_t disc, uint32_t movie) { char fmvName[MAX_PATH], camName[MAX_PATH], newFmvName[MAX_PATH], newCamName[MAX_PATH]; - uint32_t camOffset = 0; _snprintf(fmvName, sizeof(fmvName), "data/movies/disc%02i_%02ih.%s", disc, movie, ffmpeg_video_ext.c_str()); diff --git a/src/music.cpp b/src/music.cpp index 75e4d224..96de3915 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -218,7 +218,7 @@ uint32_t ff7_use_midi(uint32_t midi) return strcmp(name, "HEART") != 0 && strcmp(name, "SATO") != 0 && strcmp(name, "SENSUI") != 0 && strcmp(name, "WIND") != 0; } -bool play_music(const char* music_name, uint32_t music_id, int channel, NxAudioEngine::MusicOptions options = NxAudioEngine::MusicOptions(), char* fullpath = nullptr) +bool play_music(const char* music_name, uint32_t music_id, int channel, NxAudioEngine::MusicOptions options = NxAudioEngine::MusicOptions(), char* wav_fullpath = nullptr) { const struct game_mode* mode; bool playing = false; @@ -282,19 +282,18 @@ bool play_music(const char* music_name, uint32_t music_id, int channel, NxAudioE playing = nxAudioEngine.playMusic(new_music_name, music_id, channel, options); } - if (!playing) { - if (fullpath == nullptr || nxAudioEngine.canPlayMusic(music_name)) - { - playing = nxAudioEngine.playMusic(music_name, music_id, channel, options); - } - else if (fullpath != nullptr) - { - if (trace_all || trace_music) ffnx_info("%s: back to wav %s\n", __func__, fullpath); + if (!playing) + { + playing = nxAudioEngine.playMusic(music_name, music_id, channel, options); + } - options.useNameAsFullPath = true; - strcpy(options.format, "wav"); - playing = nxAudioEngine.playMusic(fullpath, music_id, channel, options); - } + if (!playing && wav_fullpath != nullptr) + { + if (trace_all || trace_music) ffnx_info("%s: back to wav %s\n", __func__, wav_fullpath); + + options.useNameAsFullPath = true; + strcpy(options.format, "wav"); + playing = nxAudioEngine.playMusic(wav_fullpath, music_id, channel, options); } } else diff --git a/src/renderer.cpp b/src/renderer.cpp index 3d2985f9..811e7a99 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -2050,13 +2050,13 @@ bgfx::TextureHandle Renderer::createTextureHandle(cmrc::file* file, char* filena uint32_t Renderer::createTextureLibPng(char* filename, uint32_t* width, uint32_t* height, bool isSrgb) { bgfx::TextureHandle ret = FFNX_RENDERER_INVALID_HANDLE; - bimg::ImageMip mip; + bimg::ImageContainer* img = loadPng(&defaultAllocator, filename); - if (!loadPng(filename, mip)) { + if (img == nullptr) { return ret.idx; } - const bgfx::Memory* mem = bgfx::makeRef(mip.m_data, mip.m_size, RendererReleaseData, (void *)mip.m_data); + const bgfx::Memory* mem = bgfx::makeRef(img->m_data, img->m_size, RendererReleaseImageContainer, img); uint64_t flags = BGFX_SAMPLER_NONE; @@ -2064,17 +2064,17 @@ uint32_t Renderer::createTextureLibPng(char* filename, uint32_t* width, uint32_t else flags |= BGFX_TEXTURE_NONE; ret = bgfx::createTexture2D( - mip.m_width, - mip.m_height, + img->m_width, + img->m_height, false, 1, - bgfx::TextureFormat::Enum(mip.m_format), + bgfx::TextureFormat::Enum(img->m_format), flags, mem ); - *width = mip.m_width; - *height = mip.m_height; + *width = img->m_width; + *height = img->m_height; if (trace_all || trace_renderer) ffnx_trace("Renderer::%s: %u => %ux%u from filename %s\n", __func__, ret.idx, *width, *height, filename); diff --git a/src/saveload.cpp b/src/saveload.cpp index 3278024d..69fb78aa 100644 --- a/src/saveload.cpp +++ b/src/saveload.cpp @@ -129,7 +129,7 @@ uint32_t load_texture_helper(char* name, uint32_t* width, uint32_t* height, bool if (ret) { - if (trace_all || trace_loaders) ffnx_trace("Using texture: %s\n", name); + if (trace_all || trace_loaders) ffnx_trace("Using texture: %s (textureId=%d)\n", name, ret); } return ret; diff --git a/src/utils.cpp b/src/utils.cpp index cb9addba..13f40d7c 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -103,7 +103,7 @@ std::wstring GetErrorMessage(unsigned long errorCode) return message; } -bool isFileSigned(const wchar_t* dllPath) +bool isFileSigned(const char* dllPath) { WINTRUST_FILE_INFO fileInfo = {}; WINTRUST_DATA trustData = {}; @@ -112,7 +112,7 @@ bool isFileSigned(const wchar_t* dllPath) // Open the file with proper sharing flags fileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO); fileInfo.pcwszFilePath = NULL; - fileInfo.hFile = CreateFileW(dllPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);; + fileInfo.hFile = CreateFileA(dllPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); fileInfo.pgKnownSubject = NULL; GUID actionID = WINTRUST_ACTION_GENERIC_VERIFY_V2; @@ -137,12 +137,12 @@ bool isFileSigned(const wchar_t* dllPath) return status == ERROR_SUCCESS; } -std::string sha1_file(const std::string& filename) +std::string sha1_file(const char *filename) { CryptoPP::SHA1 hash; std::string digest; - CryptoPP::FileSource(filename.c_str(), true, + CryptoPP::FileSource(filename, true, new CryptoPP::HashFilter(hash, new CryptoPP::HexEncoder( new CryptoPP::StringSink(digest), false))); diff --git a/src/utils.h b/src/utils.h index f3289018..5051cf77 100644 --- a/src/utils.h +++ b/src/utils.h @@ -141,6 +141,6 @@ bool fileExists(const char *filename); bool dirExists(const char *dirname); std::string getCopyrightInfoFromExe(const std::string& filePath); std::wstring GetErrorMessage(unsigned long errorCode); -bool isFileSigned(const wchar_t* dllPath); -std::string sha1_file(const std::string& filename); +bool isFileSigned(const char* dllPath); +std::string sha1_file(const char* filename); std::string md5_hash(const unsigned char* data, size_t length);