Commit 38e58ef6 authored by nanahira's avatar nanahira

Merge branch 'fh-20250210' into develop

# Conflicts:
#	gframe/data_manager.h
#	gframe/image_manager.cpp
#	gframe/image_manager.h
#	gframe/sound_manager.cpp
parents 8cc33752 7887bc71
...@@ -388,32 +388,26 @@ const wchar_t* DataManager::GetDesc(uint32_t strCode) const { ...@@ -388,32 +388,26 @@ const wchar_t* DataManager::GetDesc(uint32_t strCode) const {
return csit->second.desc[offset].c_str(); return csit->second.desc[offset].c_str();
return unknown_string; return unknown_string;
} }
const wchar_t* DataManager::GetSysString(int code) const { const wchar_t* DataManager::GetMapString(const wstring_map& table, uint32_t code) const {
auto csit = _sysStrings.find(code); auto csit = table.find(code);
if(csit == _sysStrings.end()) if (csit == table.end())
return unknown_string; return unknown_string;
return csit->second.c_str(); return csit->second.c_str();
} }
const wchar_t* DataManager::GetVictoryString(int code) const { const wchar_t* DataManager::GetSysString(uint32_t code) const {
auto csit = _victoryStrings.find(code); return GetMapString(_sysStrings, code);
if(csit == _victoryStrings.end())
return unknown_string;
return csit->second.c_str();
} }
const wchar_t* DataManager::GetCounterName(int code) const { const wchar_t* DataManager::GetVictoryString(uint32_t code) const {
auto csit = _counterStrings.find(code); return GetMapString(_victoryStrings, code);
if(csit == _counterStrings.end())
return unknown_string;
return csit->second.c_str();
} }
const wchar_t* DataManager::GetSetName(int code) const { const wchar_t* DataManager::GetCounterName(uint32_t code) const {
auto csit = _setnameStrings.find(code); return GetMapString(_counterStrings, code);
if(csit == _setnameStrings.end()) }
return unknown_string; const wchar_t* DataManager::GetSetName(uint32_t code) const {
return csit->second.c_str(); return GetMapString(_setnameStrings, code);
} }
std::vector<unsigned int> DataManager::GetSetCodes(std::wstring setname) const { std::vector<uint32_t> DataManager::GetSetCodes(std::wstring setname) const {
std::vector<unsigned int> matchingCodes; std::vector<uint32_t> matchingCodes;
for(auto csit = _setnameStrings.begin(); csit != _setnameStrings.end(); ++csit) { for(auto csit = _setnameStrings.begin(); csit != _setnameStrings.end(); ++csit) {
auto xpos = csit->second.find_first_of(L'|');//setname|another setname or extra info auto xpos = csit->second.find_first_of(L'|');//setname|another setname or extra info
if (mainGame->CheckRegEx(csit->second, setname, true)) { if (mainGame->CheckRegEx(csit->second, setname, true)) {
......
...@@ -57,6 +57,7 @@ struct CardString { ...@@ -57,6 +57,7 @@ struct CardString {
}; };
using code_pointer = std::unordered_map<uint32_t, CardDataC>::const_iterator; using code_pointer = std::unordered_map<uint32_t, CardDataC>::const_iterator;
using string_pointer = std::unordered_map<uint32_t, CardString>::const_iterator; using string_pointer = std::unordered_map<uint32_t, CardString>::const_iterator;
using wstring_map = std::unordered_map<uint32_t, std::wstring>;
class ClientCard; class ClientCard;
...@@ -95,11 +96,11 @@ public: ...@@ -95,11 +96,11 @@ public:
const wchar_t* GetName(uint32_t code) const; const wchar_t* GetName(uint32_t code) const;
const wchar_t* GetText(uint32_t code) const; const wchar_t* GetText(uint32_t code) const;
const wchar_t* GetDesc(uint32_t strCode) const; const wchar_t* GetDesc(uint32_t strCode) const;
const wchar_t* GetSysString(int code) const; const wchar_t* GetSysString(uint32_t code) const;
const wchar_t* GetVictoryString(int code) const; const wchar_t* GetVictoryString(uint32_t code) const;
const wchar_t* GetCounterName(int code) const; const wchar_t* GetCounterName(uint32_t code) const;
const wchar_t* GetSetName(int code) const; const wchar_t* GetSetName(uint32_t code) const;
std::vector<unsigned int> GetSetCodes(std::wstring setname) const; std::vector<uint32_t> GetSetCodes(std::wstring setname) const;
std::wstring GetNumString(int num, bool bracket = false) const; std::wstring GetNumString(int num, bool bracket = false) const;
const wchar_t* FormatLocation(int location, int sequence) const; const wchar_t* FormatLocation(int location, int sequence) const;
const wchar_t* FormatLocation(ClientCard* card) const; const wchar_t* FormatLocation(ClientCard* card) const;
...@@ -109,19 +110,19 @@ public: ...@@ -109,19 +110,19 @@ public:
std::wstring FormatSetName(const uint16_t setcode[]) const; std::wstring FormatSetName(const uint16_t setcode[]) const;
std::wstring FormatLinkMarker(unsigned int link_marker) const; std::wstring FormatLinkMarker(unsigned int link_marker) const;
std::unordered_map<unsigned int, std::wstring> _counterStrings; wstring_map _counterStrings;
std::unordered_map<unsigned int, std::wstring> _victoryStrings; wstring_map _victoryStrings;
std::unordered_map<unsigned int, std::wstring> _setnameStrings; wstring_map _setnameStrings;
std::unordered_map<unsigned int, std::wstring> _sysStrings; wstring_map _sysStrings;
std::vector<std::pair<std::wstring, std::wstring>> _serverStrings; std::vector<std::pair<std::wstring, std::wstring>> _serverStrings;
char errmsg[512]{}; char errmsg[512]{};
const wchar_t* unknown_string{ L"???" }; const wchar_t* unknown_string{ L"???" };
irr::io::IFileSystem* FileSystem{}; irr::io::IFileSystem* FileSystem{};
static constexpr int STRING_ID_LOCATION = 1000; static constexpr uint32_t STRING_ID_LOCATION = 1000;
static constexpr int STRING_ID_ATTRIBUTE = 1010; static constexpr uint32_t STRING_ID_ATTRIBUTE = 1010;
static constexpr int STRING_ID_RACE = 1020; static constexpr uint32_t STRING_ID_RACE = 1020;
static constexpr int STRING_ID_TYPE = 1050; static constexpr uint32_t STRING_ID_TYPE = 1050;
static constexpr int TYPES_COUNT = 27; static constexpr int TYPES_COUNT = 27;
static unsigned char scriptBuffer[0x100000]; static unsigned char scriptBuffer[0x100000];
...@@ -141,6 +142,7 @@ public: ...@@ -141,6 +142,7 @@ public:
static bool deck_sort_name(code_pointer l1, code_pointer l2); static bool deck_sort_name(code_pointer l1, code_pointer l2);
private: private:
const wchar_t* GetMapString(const wstring_map& table, uint32_t code) const;
std::unordered_map<uint32_t, CardDataC> _datas; std::unordered_map<uint32_t, CardDataC> _datas;
std::unordered_map<uint32_t, CardString> _strings; std::unordered_map<uint32_t, CardString> _strings;
std::unordered_map<uint32_t, std::vector<uint16_t>> extra_setcode; std::unordered_map<uint32_t, std::vector<uint16_t>> extra_setcode;
......
...@@ -1440,7 +1440,7 @@ void DeckBuilder::FilterCards() { ...@@ -1440,7 +1440,7 @@ void DeckBuilder::FilterCards() {
results.clear(); results.clear();
struct element_t { struct element_t {
std::wstring keyword; std::wstring keyword;
std::vector<unsigned int> setcodes; std::vector<uint32_t> setcodes;
enum class type_t { enum class type_t {
all, all,
name, name,
......
#include "image_manager.h" #include "image_manager.h"
#include "image_resizer.h"
#include "game.h" #include "game.h"
#include "myfilesystem.h" #include "myfilesystem.h"
#include <thread> #include <thread>
#ifdef _OPENMP
#include <omp.h>
#endif
namespace ygo { namespace ygo {
...@@ -213,84 +211,15 @@ void ImageManager::ResizeTexture() { ...@@ -213,84 +211,15 @@ void ImageManager::ResizeTexture() {
if(!tBackGround_deck) if(!tBackGround_deck)
tBackGround_deck = tBackGround; tBackGround_deck = tBackGround;
} }
/** Scale image using nearest neighbor anti-aliasing. void ImageManager::resizeImage(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading) {
* Function by Warr1024, from https://github.com/minetest/minetest/issues/2419, modified. */ imageResizer.resize(src, dest, use_threading);
void imageScaleNNAA(irr::video::IImage *src, irr::video::IImage *dest) {
const auto& srcDim = src->getDimension();
const auto& destDim = dest->getDimension();
// Cache scale ratios.
const double rx = (double)srcDim.Width / destDim.Width;
const double ry = (double)srcDim.Height / destDim.Height;
#pragma omp parallel if(mainGame->gameConf.use_image_scale_multi_thread)
{
double sx, sy, minsx, maxsx, minsy, maxsy, area, ra, ga, ba, aa, pw, ph, pa;
irr::video::SColor pxl, npxl;
// Walk each destination image pixel.
#pragma omp for schedule(dynamic)
for(irr::s32 dy = 0; dy < (irr::s32)destDim.Height; dy++) {
for(irr::s32 dx = 0; dx < (irr::s32)destDim.Width; dx++) {
// Calculate floating-point source rectangle bounds.
minsx = dx * rx;
maxsx = minsx + rx;
minsy = dy * ry;
maxsy = minsy + ry;
// Total area, and integral of r, g, b values over that area,
// initialized to zero, to be summed up in next loops.
area = 0;
ra = 0;
ga = 0;
ba = 0;
aa = 0;
// Loop over the integral pixel positions described by those bounds.
for(sy = floor(minsy); sy < maxsy; sy++) {
for(sx = floor(minsx); sx < maxsx; sx++) {
// Calculate width, height, then area of dest pixel
// that's covered by this source pixel.
pw = 1;
if(minsx > sx)
pw += sx - minsx;
if(maxsx < (sx + 1))
pw += maxsx - sx - 1;
ph = 1;
if(minsy > sy)
ph += sy - minsy;
if(maxsy < (sy + 1))
ph += maxsy - sy - 1;
pa = pw * ph;
// Get source pixel and add it to totals, weighted
// by covered area and alpha.
pxl = src->getPixel((irr::u32)sx, (irr::u32)sy);
area += pa;
ra += pa * pxl.getRed();
ga += pa * pxl.getGreen();
ba += pa * pxl.getBlue();
aa += pa * pxl.getAlpha();
}
}
// Set the destination image pixel to the average color.
if(area > 0) {
npxl.set((irr::u32)(aa / area + 0.5),
(irr::u32)(ra / area + 0.5),
(irr::u32)(ga / area + 0.5),
(irr::u32)(ba / area + 0.5));
} else {
npxl.set(0);
}
dest->setPixel(dx, dy, npxl);
}
}
} // end of parallel region
} }
/** Convert image to texture, resizing if needed. /**
* Convert image to texture, resizing if needed.
* @param name Texture name (Irrlicht texture key). * @param name Texture name (Irrlicht texture key).
* @param srcimg Source image; will be dropped by this function. * @param srcimg Source image; will be dropped by this function.
* @return Texture pointer. Remove via `driver->removeTexture` (do not `drop`). */ * @return Texture pointer. Remove via `driver->removeTexture` (do not `drop`).
*/
irr::video::ITexture* ImageManager::addTexture(const char* name, irr::video::IImage* srcimg, irr::s32 width, irr::s32 height) { irr::video::ITexture* ImageManager::addTexture(const char* name, irr::video::IImage* srcimg, irr::s32 width, irr::s32 height) {
if(srcimg == nullptr) if(srcimg == nullptr)
return nullptr; return nullptr;
...@@ -299,7 +228,7 @@ irr::video::ITexture* ImageManager::addTexture(const char* name, irr::video::IIm ...@@ -299,7 +228,7 @@ irr::video::ITexture* ImageManager::addTexture(const char* name, irr::video::IIm
texture = driver->addTexture(name, srcimg); texture = driver->addTexture(name, srcimg);
} else { } else {
irr::video::IImage* destimg = driver->createImage(srcimg->getColorFormat(), irr::core::dimension2d<irr::u32>(width, height)); irr::video::IImage* destimg = driver->createImage(srcimg->getColorFormat(), irr::core::dimension2d<irr::u32>(width, height));
imageScaleNNAA(srcimg, destimg); resizeImage(srcimg, destimg, mainGame->gameConf.use_image_scale_multi_thread);
texture = driver->addTexture(name, destimg); texture = driver->addTexture(name, destimg);
destimg->drop(); destimg->drop();
} }
...@@ -388,14 +317,14 @@ irr::video::ITexture* ImageManager::GetTexture(int code, bool fit) { ...@@ -388,14 +317,14 @@ irr::video::ITexture* ImageManager::GetTexture(int code, bool fit) {
* @return Texture pointer. Should NOT be removed nor dropped. */ * @return Texture pointer. Should NOT be removed nor dropped. */
irr::video::ITexture* ImageManager::GetBigPicture(int code, float zoom) { irr::video::ITexture* ImageManager::GetBigPicture(int code, float zoom) {
if(code == 0) if(code == 0)
return tUnknown; return tUnknownFit;
if(tBigPicture != nullptr) { if(tBigPicture != nullptr) {
driver->removeTexture(tBigPicture); driver->removeTexture(tBigPicture);
tBigPicture = nullptr; tBigPicture = nullptr;
} }
irr::video::IImage* img = GetImage(code); irr::video::IImage* img = GetImage(code);
if(img == nullptr) { if(img == nullptr) {
return tUnknown; return tUnknownFit;
} }
char name[256]; char name[256];
mysnprintf(name, "pics/%d/big", code); mysnprintf(name, "pics/%d/big", code);
...@@ -427,7 +356,7 @@ int ImageManager::LoadThumbThread() { ...@@ -427,7 +356,7 @@ int ImageManager::LoadThumbThread() {
imageManager.tThumbLoadingMutex.unlock(); imageManager.tThumbLoadingMutex.unlock();
} else { } else {
irr::video::IImage *destimg = imageManager.driver->createImage(img->getColorFormat(), irr::core::dimension2d<irr::u32>(width, height)); irr::video::IImage *destimg = imageManager.driver->createImage(img->getColorFormat(), irr::core::dimension2d<irr::u32>(width, height));
imageScaleNNAA(img, destimg); imageManager.resizeImage(img, destimg, mainGame->gameConf.use_image_scale_multi_thread);
img->drop(); img->drop();
imageManager.tThumbLoadingMutex.lock(); imageManager.tThumbLoadingMutex.lock();
if(imageManager.tThumbLoadingThreadRunning) if(imageManager.tThumbLoadingThreadRunning)
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "config.h" #include "config.h"
#include "data_manager.h" #include "data_manager.h"
#include <unordered_map> #include <unordered_map>
#include <vector>
#include <string>
#include <queue> #include <queue>
#include <mutex> #include <mutex>
...@@ -11,6 +13,7 @@ namespace ygo { ...@@ -11,6 +13,7 @@ namespace ygo {
class ImageManager { class ImageManager {
private: private:
void resizeImage(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading);
irr::video::ITexture* addTexture(const char* name, irr::video::IImage* srcimg, irr::s32 width, irr::s32 height); irr::video::ITexture* addTexture(const char* name, irr::video::IImage* srcimg, irr::s32 width, irr::s32 height);
// Internal implementation using void* for type erasure // Internal implementation using void* for type erasure
...@@ -26,7 +29,6 @@ private: ...@@ -26,7 +29,6 @@ private:
}; };
return static_cast<RetType>(LoadFromSearchPathsImpl(code, subpath, extensions, wrapper, &callback)); return static_cast<RetType>(LoadFromSearchPathsImpl(code, subpath, extensions, wrapper, &callback));
} }
public: public:
std::vector<std::wstring> ImageList[7]; std::vector<std::wstring> ImageList[7];
int saved_image_id[7]; int saved_image_id[7];
......
#include "image_resizer.h"
#include <cmath>
#ifdef _OPENMP
#include <omp.h>
#endif
#define STB_IMAGE_RESIZE2_IMPLEMENTATION
#include "stb_image_resize2.h"
namespace ygo {
ImageResizer imageResizer;
struct StbSamplerCache {
STBIR_RESIZE resize{};
int in_w = 0;
int in_h = 0;
int out_w = 0;
int out_h = 0;
stbir_pixel_layout layout = STBIR_BGRA;
bool samplers_built = false;
~StbSamplerCache() {
if(samplers_built) {
stbir_free_samplers(&resize);
samplers_built = false;
}
}
void reset_if_needed(int new_in_w, int new_in_h, int new_out_w, int new_out_h, stbir_pixel_layout new_layout) {
if(new_in_w == in_w && new_in_h == in_h && new_out_w == out_w && new_out_h == out_h && new_layout == layout)
return;
if(samplers_built) {
stbir_free_samplers(&resize);
samplers_built = false;
}
in_w = new_in_w;
in_h = new_in_h;
out_w = new_out_w;
out_h = new_out_h;
layout = new_layout;
resize = STBIR_RESIZE{};
}
};
/**
* Scale image using stb_image_resize2.
* Returns true on success, false on failure or unsupported format.
*/
bool ImageResizer::imageScaleSTB(irr::video::IImage* src, irr::video::IImage* dest) {
if(!src || !dest)
return false;
const auto srcDim = src->getDimension();
const auto destDim = dest->getDimension();
if(srcDim.Width == 0 || srcDim.Height == 0 || destDim.Width == 0 || destDim.Height == 0)
return false;
if(src->getColorFormat() != dest->getColorFormat())
return false;
stbir_pixel_layout layout = STBIR_BGRA;
// Fast-paths (8-bit per channel only):
// - ECF_A8R8G8B8: Irrlicht stores as BGRA in memory on little-endian.
// - ECF_R8G8B8: common for JPEGs (3 channels).
switch(src->getColorFormat()) {
case irr::video::ECF_A8R8G8B8:
layout = STBIR_BGRA;
break;
case irr::video::ECF_R8G8B8:
layout = STBIR_RGB;
break;
default:
return false;
}
void* srcPtr = src->lock();
if(!srcPtr)
return false;
void* destPtr = dest->lock();
if(!destPtr) {
src->unlock();
return false;
}
const int srcStride = (int)src->getPitch();
const int destStride = (int)dest->getPitch();
thread_local StbSamplerCache cache;
cache.reset_if_needed((int)srcDim.Width, (int)srcDim.Height, (int)destDim.Width, (int)destDim.Height, layout);
if(!cache.samplers_built) {
stbir_resize_init(&cache.resize,
srcPtr, (int)srcDim.Width, (int)srcDim.Height, srcStride,
destPtr, (int)destDim.Width, (int)destDim.Height, destStride,
layout, STBIR_TYPE_UINT8);
stbir_set_edgemodes(&cache.resize, STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP);
// Use box filters to reduce aliasing when downscaling.
stbir_set_filters(&cache.resize, STBIR_FILTER_BOX, STBIR_FILTER_BOX);
cache.samplers_built = (stbir_build_samplers(&cache.resize) != 0);
if(!cache.samplers_built) {
dest->unlock();
src->unlock();
return false;
}
} else {
// Reuse samplers but update buffer pointers for the current images
stbir_set_buffer_ptrs(&cache.resize, srcPtr, srcStride, destPtr, destStride);
}
const int ok = stbir_resize_extended(&cache.resize);
dest->unlock();
src->unlock();
return ok != 0;
}
/**
* Scale image using nearest neighbor anti-aliasing.
* Function by Warr1024, from https://github.com/minetest/minetest/issues/2419, modified.
*/
void ImageResizer::imageScaleNNAA(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading) {
const auto& srcDim = src->getDimension();
const auto& destDim = dest->getDimension();
if (destDim.Width == 0 || destDim.Height == 0)
return;
// Cache scale ratios.
const double rx = (double)srcDim.Width / destDim.Width;
const double ry = (double)srcDim.Height / destDim.Height;
#pragma omp parallel if(use_threading)
{
// Walk each destination image pixel.
#pragma omp for schedule(dynamic)
for(irr::s32 dy = 0; dy < (irr::s32)destDim.Height; dy++) {
for(irr::s32 dx = 0; dx < (irr::s32)destDim.Width; dx++) {
// Calculate floating-point source rectangle bounds.
double minsx = dx * rx;
double maxsx = minsx + rx;
double minsy = dy * ry;
double maxsy = minsy + ry;
irr::u32 sx_begin = (irr::u32)std::floor(minsx);
irr::u32 sx_end = (irr::u32)std::ceil(maxsx);
if (sx_end > srcDim.Width)
sx_end = srcDim.Width;
irr::u32 sy_begin = (irr::u32)std::floor(minsy);
irr::u32 sy_end = (irr::u32)std::ceil(maxsy);
if (sy_end > srcDim.Height)
sy_end = srcDim.Height;
// Total area, and integral of r, g, b values over that area,
// initialized to zero, to be summed up in next loops.
double area = 0, ra = 0, ga = 0, ba = 0, aa = 0;
irr::video::SColor pxl, npxl;
// Loop over the integral pixel positions described by those bounds.
for(irr::u32 sy = sy_begin; sy < sy_end; sy++) {
for(irr::u32 sx = sx_begin; sx < sx_end; sx++) {
// Calculate width, height, then area of dest pixel
// that's covered by this source pixel.
double pw = 1;
if(minsx > sx)
pw += sx - minsx;
if(maxsx < (sx + 1))
pw += maxsx - sx - 1;
double ph = 1;
if(minsy > sy)
ph += sy - minsy;
if(maxsy < (sy + 1))
ph += maxsy - sy - 1;
double pa = pw * ph;
// Get source pixel and add it to totals, weighted
// by covered area and alpha.
pxl = src->getPixel(sx, sy);
area += pa;
ra += pa * pxl.getRed();
ga += pa * pxl.getGreen();
ba += pa * pxl.getBlue();
aa += pa * pxl.getAlpha();
}
}
// Set the destination image pixel to the average color.
if(area > 0) {
npxl.set((irr::u32)(aa / area + 0.5),
(irr::u32)(ra / area + 0.5),
(irr::u32)(ga / area + 0.5),
(irr::u32)(ba / area + 0.5));
} else {
npxl.set(0);
}
dest->setPixel(dx, dy, npxl);
}
}
} // end of parallel region
}
void ImageResizer::resize(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading) {
if(imageScaleSTB(src, dest))
return;
imageScaleNNAA(src, dest, use_threading);
}
} // namespace ygo
#ifndef IMAGE_RESIZER_H
#define IMAGE_RESIZER_H
#include <irrlicht.h>
namespace ygo {
class ImageResizer {
private:
bool imageScaleSTB(irr::video::IImage* src, irr::video::IImage* dest);
void imageScaleNNAA(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading);
public:
void resize(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading);
};
extern ImageResizer imageResizer;
} // namespace ygo
#endif // IMAGE_RESIZER_H
...@@ -8,8 +8,10 @@ ...@@ -8,8 +8,10 @@
#ifndef _WIN32 #ifndef _WIN32
#include <dirent.h> #include <dirent.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <string>
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
...@@ -182,7 +184,7 @@ public: ...@@ -182,7 +184,7 @@ public:
bool success = true; bool success = true;
TraversalDir(dir, [dir, &success](const char *name, bool isdir) { TraversalDir(dir, [dir, &success](const char *name, bool isdir) {
char full_path[1024]; char full_path[1024];
int len = mysnprintf(full_path, "%s/%s", dir, name); int len = std::snprintf(full_path, sizeof(full_path), "%s/%s", dir, name);
if (len < 0 || len >= (int)(sizeof full_path)) { if (len < 0 || len >= (int)(sizeof full_path)) {
success = false; success = false;
return; return;
...@@ -228,7 +230,7 @@ public: ...@@ -228,7 +230,7 @@ public:
while((dirp = readdir(dir)) != nullptr) { while((dirp = readdir(dir)) != nullptr) {
file_unit funit; file_unit funit;
char fname[1024]; char fname[1024];
int len = mysnprintf(fname, "%s/%s", path, dirp->d_name); int len = std::snprintf(fname, sizeof(fname), "%s/%s", path, dirp->d_name);
if (len < 0 || len >= (int)(sizeof fname)) if (len < 0 || len >= (int)(sizeof fname))
continue; continue;
stat(fname, &fileStat); stat(fname, &fileStat);
......
...@@ -124,134 +124,134 @@ void SoundManager::PlaySoundEffect(int sound) { ...@@ -124,134 +124,134 @@ void SoundManager::PlaySoundEffect(int sound) {
#ifdef YGOPRO_USE_AUDIO #ifdef YGOPRO_USE_AUDIO
if(!mainGame->chkEnableSound->isChecked()) if(!mainGame->chkEnableSound->isChecked())
return; return;
char soundName[32]; std::string soundName;
switch(sound) { switch(sound) {
case SOUND_SUMMON: { case SOUND_SUMMON: {
strcpy(soundName, "summon"); soundName = "summon";
break; break;
} }
case SOUND_SPECIAL_SUMMON: { case SOUND_SPECIAL_SUMMON: {
strcpy(soundName, "specialsummon"); soundName = "specialsummon";
break; break;
} }
case SOUND_ACTIVATE: { case SOUND_ACTIVATE: {
strcpy(soundName, "activate"); soundName = "activate";
break; break;
} }
case SOUND_SET: { case SOUND_SET: {
strcpy(soundName, "set"); soundName = "set";
break; break;
} }
case SOUND_FLIP: { case SOUND_FLIP: {
strcpy(soundName, "flip"); soundName = "flip";
break; break;
} }
case SOUND_REVEAL: { case SOUND_REVEAL: {
strcpy(soundName, "reveal"); soundName = "reveal";
break; break;
} }
case SOUND_EQUIP: { case SOUND_EQUIP: {
strcpy(soundName, "equip"); soundName = "equip";
break; break;
} }
case SOUND_DESTROYED: { case SOUND_DESTROYED: {
strcpy(soundName, "destroyed"); soundName = "destroyed";
break; break;
} }
case SOUND_BANISHED: { case SOUND_BANISHED: {
strcpy(soundName, "banished"); soundName = "banished";
break; break;
} }
case SOUND_TOKEN: { case SOUND_TOKEN: {
strcpy(soundName, "token"); soundName = "token";
break; break;
} }
case SOUND_NEGATE: { case SOUND_NEGATE: {
strcpy(soundName, "negate"); soundName = "negate";
break; break;
} }
case SOUND_ATTACK: { case SOUND_ATTACK: {
strcpy(soundName, "attack"); soundName = "attack";
break; break;
} }
case SOUND_DIRECT_ATTACK: { case SOUND_DIRECT_ATTACK: {
strcpy(soundName, "directattack"); soundName = "directattack";
break; break;
} }
case SOUND_DRAW: { case SOUND_DRAW: {
strcpy(soundName, "draw"); soundName = "draw";
break; break;
} }
case SOUND_SHUFFLE: { case SOUND_SHUFFLE: {
strcpy(soundName, "shuffle"); soundName = "shuffle";
break; break;
} }
case SOUND_DAMAGE: { case SOUND_DAMAGE: {
strcpy(soundName, "damage"); soundName = "damage";
break; break;
} }
case SOUND_RECOVER: { case SOUND_RECOVER: {
strcpy(soundName, "gainlp"); soundName = "gainlp";
break; break;
} }
case SOUND_COUNTER_ADD: { case SOUND_COUNTER_ADD: {
strcpy(soundName, "addcounter"); soundName = "addcounter";
break; break;
} }
case SOUND_COUNTER_REMOVE: { case SOUND_COUNTER_REMOVE: {
strcpy(soundName, "removecounter"); soundName = "removecounter";
break; break;
} }
case SOUND_COIN: { case SOUND_COIN: {
strcpy(soundName, "coinflip"); soundName = "coinflip";
break; break;
} }
case SOUND_DICE: { case SOUND_DICE: {
strcpy(soundName, "diceroll"); soundName = "diceroll";
break; break;
} }
case SOUND_NEXT_TURN: { case SOUND_NEXT_TURN: {
strcpy(soundName, "nextturn"); soundName = "nextturn";
break; break;
} }
case SOUND_PHASE: { case SOUND_PHASE: {
strcpy(soundName, "phase"); soundName = "phase";
break; break;
} }
case SOUND_MENU: { case SOUND_MENU: {
strcpy(soundName, "menu"); soundName = "menu";
break; break;
} }
case SOUND_BUTTON: { case SOUND_BUTTON: {
strcpy(soundName, "button"); soundName = "button";
break; break;
} }
case SOUND_INFO: { case SOUND_INFO: {
strcpy(soundName, "info"); soundName = "info";
break; break;
} }
case SOUND_QUESTION: { case SOUND_QUESTION: {
strcpy(soundName, "question"); soundName = "question";
break; break;
} }
case SOUND_CARD_PICK: { case SOUND_CARD_PICK: {
strcpy(soundName, "cardpick"); soundName = "cardpick";
break; break;
} }
case SOUND_CARD_DROP: { case SOUND_CARD_DROP: {
strcpy(soundName, "carddrop"); soundName = "carddrop";
break; break;
} }
case SOUND_PLAYER_ENTER: { case SOUND_PLAYER_ENTER: {
strcpy(soundName, "playerenter"); soundName = "playerenter";
break; break;
} }
case SOUND_CHAT: { case SOUND_CHAT: {
strcpy(soundName, "chatmessage"); soundName = "chatmessage";
break; break;
} }
default: default:
break; return;
} }
wchar_t soundNameW[32]; wchar_t soundNameW[32];
BufferIO::DecodeUTF8(soundName, soundNameW); BufferIO::DecodeUTF8(soundName, soundNameW);
......
This diff is collapsed.
...@@ -680,6 +680,7 @@ ...@@ -680,6 +680,7 @@
!counter 0x70 盘子指示物 !counter 0x70 盘子指示物
!counter 0x71 纠罪指示物 !counter 0x71 纠罪指示物
!counter 0x1072 少女指示物 !counter 0x1072 少女指示物
!counter 0x73 T指示物
#setnames, using tab for comment #setnames, using tab for comment
!setname 0x1 正义盟军 AOJ !setname 0x1 正义盟军 AOJ
!setname 0x2 次世代 ジェネクス !setname 0x2 次世代 ジェネクス
...@@ -841,7 +842,7 @@ ...@@ -841,7 +842,7 @@
!setname 0x106e 魔导书 魔導書 !setname 0x106e 魔导书 魔導書
!setname 0x6f 英豪 ヒロイック !setname 0x6f 英豪 ヒロイック
!setname 0x106f 英豪挑战者 HC !setname 0x106f 英豪挑战者 HC
#setname 0x206f 英豪冠军 H-C !setname 0x206f 英豪冠军 HC
!setname 0x70 先史遗产 先史遺産 !setname 0x70 先史遗产 先史遺産
!setname 0x71 魔偶甜点 マドルチェ !setname 0x71 魔偶甜点 マドルチェ
!setname 0x72 齿轮齿轮 ギアギア !setname 0x72 齿轮齿轮 ギアギア
...@@ -1287,3 +1288,6 @@ ...@@ -1287,3 +1288,6 @@
!setname 0x1d8 耀圣 エルフェンノーツ !setname 0x1d8 耀圣 エルフェンノーツ
!setname 0x1d9 磁力 マグネット !setname 0x1d9 磁力 マグネット
!setname 0x1da 世界末日 エンド・オブ・ザ・ワールド !setname 0x1da 世界末日 エンド・オブ・ザ・ワールド
!setname 0x1db 妖精传姬 妖精伝姫
!setname 0x1dc 道化一座 道化の一座
!setname 0x1dd GMX
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment