Commit 2d86d0c3 authored by mercury233's avatar mercury233

Merge branch 'fh' into patch-build-all

parents b1cc8798 e677985c
......@@ -32,7 +32,7 @@ public:
* @brief Copy a C-style string to another C-style string.
* @param src The source wide string
* @param pstr The destination char string
* @param bufsize The size of the destination buffer
* @param bufsize The length of the destination buffer
* @return The length of the copied string
*/
template<typename T1, typename T2>
......@@ -62,13 +62,13 @@ public:
}
template<size_t N>
static void CopyString(const char* src, char(&dst)[N]) {
dst[0] = 0;
std::strncat(dst, src, N - 1);
std::strncpy(dst, src, N - 1);
dst[N - 1] = 0;
}
template<size_t N>
static void CopyWideString(const wchar_t* src, wchar_t(&dst)[N]) {
dst[0] = 0;
std::wcsncat(dst, src, N - 1);
std::wcsncpy(dst, src, N - 1);
dst[N - 1] = 0;
}
template<typename T>
static bool CheckUTF8Byte(const T* str, int len) {
......
......@@ -1262,7 +1262,12 @@ void Game::DrawDeckBd() {
driver->draw2DRectangle(Resize(805, 160, 1020, 630), 0x400000ff, 0x400000ff, 0x40000000, 0x40000000);
driver->draw2DRectangleOutline(Resize(804, 159, 1020, 630));
}
for(int i = 0; i < 9 && i + scrFilter->getPos() < (int)deckBuilder.results.size(); ++i) {
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
constexpr int MAX_RESULT = 9;
#else
constexpr int MAX_RESULT = 7;
#endif
for(int i = 0; i < MAX_RESULT && i + scrFilter->getPos() < (int)deckBuilder.results.size(); ++i) {
code_pointer ptr = deckBuilder.results[i + scrFilter->getPos()];
if(i >= 7)
{
......
......@@ -33,11 +33,17 @@ int main(int argc, char* argv[]) {
#ifdef __APPLE__
CFURLRef bundle_url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
CFURLRef bundle_base_url = CFURLCreateCopyDeletingLastPathComponent(nullptr, bundle_url);
CFStringRef bundle_ext = CFURLCopyPathExtension(bundle_url);
if (bundle_ext) {
char path[PATH_MAX];
if (CFStringCompare(bundle_ext, CFSTR("app"), kCFCompareCaseInsensitive) == kCFCompareEqualTo
&& CFURLGetFileSystemRepresentation(bundle_base_url, true, (UInt8*)path, PATH_MAX)) {
chdir(path);
}
CFRelease(bundle_ext);
}
CFRelease(bundle_url);
CFStringRef path = CFURLCopyFileSystemPath(bundle_base_url, kCFURLPOSIXPathStyle);
CFRelease(bundle_base_url);
chdir(CFStringGetCStringPtr(path, kCFStringEncodingUTF8));
CFRelease(path);
#endif //__APPLE__
#ifdef _WIN32
if (argc == 2 && (ygo::IsExtension(argv[1], ".ydk") || ygo::IsExtension(argv[1], ".yrp"))) { // open file from explorer
......
#include "image_manager.h"
#include "game.h"
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
#include <thread>
#endif
#ifdef _OPENMP
#include <omp.h>
#endif
namespace ygo {
......@@ -17,8 +22,10 @@ bool ImageManager::Initial() {
tUnknownFit = nullptr;
tUnknownThumb = nullptr;
tBigPicture = nullptr;
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
tLoading = nullptr;
tThumbLoadingThreadRunning = false;
#endif
tAct = driver->getTexture("textures/act.png");
tAttack = driver->getTexture("textures/attack.png");
tChain = driver->getTexture("textures/chain.png");
......@@ -59,7 +66,11 @@ void ImageManager::ClearTexture() {
driver->removeTexture(tit->second);
}
for(auto tit = tThumb.begin(); tit != tThumb.end(); ++tit) {
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
if(tit->second && tit->second != tLoading)
#else
if(tit->second)
#endif
driver->removeTexture(tit->second);
}
if(tBigPicture != nullptr) {
......@@ -69,12 +80,14 @@ void ImageManager::ClearTexture() {
tMap[0].clear();
tMap[1].clear();
tThumb.clear();
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
tThumbLoadingMutex.lock();
tThumbLoading.clear();
while(!tThumbLoadingCodes.empty())
tThumbLoadingCodes.pop();
tThumbLoadingThreadRunning = false;
tThumbLoadingMutex.unlock();
#endif
tFields.clear();
}
void ImageManager::RemoveTexture(int code) {
......@@ -110,11 +123,13 @@ void ImageManager::ResizeTexture() {
driver->removeTexture(tUnknown);
driver->removeTexture(tUnknownFit);
driver->removeTexture(tUnknownThumb);
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
driver->removeTexture(tLoading);
tLoading = GetTextureFromFile("textures/cover.jpg", imgWidthThumb, imgHeightThumb);
#endif
tUnknown = GetTextureFromFile("textures/unknown.jpg", CARD_IMG_WIDTH, CARD_IMG_HEIGHT);
tUnknownFit = GetTextureFromFile("textures/unknown.jpg", imgWidthFit, imgHeightFit);
tUnknownThumb = GetTextureFromFile("textures/unknown.jpg", imgWidthThumb, imgHeightThumb);
tLoading = GetTextureFromFile("textures/cover.jpg", imgWidthThumb, imgHeightThumb);
driver->removeTexture(tBackGround);
tBackGround = GetTextureFromFile("textures/bg.jpg", bgWidth, bgHeight);
driver->removeTexture(tBackGround_menu);
......@@ -128,25 +143,27 @@ void ImageManager::ResizeTexture() {
}
// function by Warr1024, from https://github.com/minetest/minetest/issues/2419 , modified
void imageScaleNNAA(irr::video::IImage *src, irr::video::IImage *dest) {
double sx, sy, minsx, maxsx, minsy, maxsy, area, ra, ga, ba, aa, pw, ph, pa;
irr::u32 dy, dx;
irr::video::SColor pxl;
const irr::core::dimension2d<irr::u32> srcDim = src->getDimension();
const irr::core::dimension2d<irr::u32> destDim = dest->getDimension();
// Cache rectsngle boundaries.
double sw = src->getDimension().Width * 1.0;
double sh = src->getDimension().Height * 1.0;
// Cache scale ratios.
const double rx = (double)srcDim.Width / destDim.Width;
const double ry = (double)srcDim.Height / destDim.Height;
// Walk each destination image pixel.
// Note: loop y around x for better cache locality.
irr::core::dimension2d<irr::u32> dim = dest->getDimension();
for(dy = 0; dy < dim.Height; dy++)
for(dx = 0; dx < dim.Width; dx++) {
#pragma omp parallel
{
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 < destDim.Height; dy++) {
for(irr::s32 dx = 0; dx < destDim.Width; dx++) {
// Calculate floating-point source rectangle bounds.
minsx = dx * sw / dim.Width;
maxsx = minsx + sw / dim.Width;
minsy = dy * sh / dim.Height;
maxsy = minsy + sh / dim.Height;
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.
......@@ -157,9 +174,8 @@ void imageScaleNNAA(irr::video::IImage *src, irr::video::IImage *dest) {
aa = 0;
// Loop over the integral pixel positions described by those bounds.
for(sy = floor(minsy); sy < maxsy; sy++)
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;
......@@ -183,21 +199,20 @@ void imageScaleNNAA(irr::video::IImage *src, irr::video::IImage *dest) {
ba += pa * pxl.getBlue();
aa += pa * pxl.getAlpha();
}
}
// Set the destination image pixel to the average color.
if(area > 0) {
pxl.setRed(ra / area + 0.5);
pxl.setGreen(ga / area + 0.5);
pxl.setBlue(ba / area + 0.5);
pxl.setAlpha(aa / area + 0.5);
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 {
pxl.setRed(0);
pxl.setGreen(0);
pxl.setBlue(0);
pxl.setAlpha(0);
npxl.set(0);
}
dest->setPixel(dx, dy, pxl);
dest->setPixel(dx, dy, npxl);
}
}
} // end of parallel region
}
irr::video::ITexture* ImageManager::GetTextureFromFile(const char* file, irr::s32 width, irr::s32 height) {
if(mainGame->gameConf.use_image_scale) {
......@@ -283,6 +298,7 @@ irr::video::ITexture* ImageManager::GetBigPicture(int code, float zoom) {
tBigPicture = texture;
return texture;
}
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
int ImageManager::LoadThumbThread() {
while(true) {
imageManager.tThumbLoadingMutex.lock();
......@@ -338,9 +354,34 @@ int ImageManager::LoadThumbThread() {
imageManager.tThumbLoadingMutex.unlock();
return 0;
}
#endif // YGOPRO_USE_THUMB_LOAD_THREAD
irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
if(code == 0)
return tUnknownThumb;
#ifndef YGOPRO_USE_THUMB_LOAD_THREAD
auto tit = tThumb.find(code);
if(tit == tThumb.end()) {
char file[256];
std::snprintf(file, sizeof file, "expansions/pics/thumbnail/%d.jpg", code);
int width = CARD_THUMB_WIDTH * mainGame->xScale;
int height = CARD_THUMB_HEIGHT * mainGame->yScale;
irr::video::ITexture* img = GetTextureFromFile(file, width, height);
if(img == NULL) {
std::snprintf(file, sizeof file, "pics/thumbnail/%d.jpg", code);
img = GetTextureFromFile(file, width, height);
}
if(img == NULL && mainGame->gameConf.use_image_scale) {
std::snprintf(file, sizeof file, "expansions/pics/%d.jpg", code);
img = GetTextureFromFile(file, width, height);
if(img == NULL) {
std::snprintf(file, sizeof file, "pics/%d.jpg", code);
img = GetTextureFromFile(file, width, height);
}
}
tThumb[code] = img;
return (img == NULL) ? tUnknownThumb : img;
}
#else // YGOPRO_USE_THUMB_LOAD_THREAD
imageManager.tThumbLoadingMutex.lock();
auto lit = tThumbLoading.find(code);
if(lit != tThumbLoading.end()) {
......@@ -368,6 +409,7 @@ irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
imageManager.tThumbLoadingMutex.unlock();
return tLoading;
}
#endif // YGOPRO_USE_THUMB_LOAD_THREAD
if(tit->second)
return tit->second;
else
......
#ifndef IMAGEMANAGER_H
#define IMAGEMANAGER_H
#ifndef _OPENMP
#define YGOPRO_USE_THUMB_LOAD_THREAD
#endif
#include "config.h"
#include "data_manager.h"
#include <unordered_map>
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
#include <queue>
#include <mutex>
#endif
namespace ygo {
......@@ -21,15 +27,19 @@ public:
irr::video::ITexture* GetBigPicture(int code, float zoom);
irr::video::ITexture* GetTextureThumb(int code);
irr::video::ITexture* GetTextureField(int code);
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
static int LoadThumbThread();
#endif
std::unordered_map<int, irr::video::ITexture*> tMap[2];
std::unordered_map<int, irr::video::ITexture*> tThumb;
std::unordered_map<int, irr::video::ITexture*> tFields;
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
std::unordered_map<int, irr::video::IImage*> tThumbLoading;
std::queue<int> tThumbLoadingCodes;
std::mutex tThumbLoadingMutex;
bool tThumbLoadingThreadRunning;
#endif
irr::IrrlichtDevice* device;
irr::video::IVideoDriver* driver;
irr::video::ITexture* tCover[4];
......@@ -37,7 +47,9 @@ public:
irr::video::ITexture* tUnknownFit;
irr::video::ITexture* tUnknownThumb;
irr::video::ITexture* tBigPicture;
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
irr::video::ITexture* tLoading;
#endif
irr::video::ITexture* tAct;
irr::video::ITexture* tAttack;
irr::video::ITexture* tNegated;
......
......@@ -5,6 +5,7 @@ project "YGOPro"
kind "WindowedApp"
cppdialect "C++14"
rtti "Off"
openmp "On"
files { "*.cpp", "*.h" }
includedirs { "../ocgcore" }
......@@ -84,6 +85,7 @@ project "YGOPro"
filter "not system:windows"
links { "dl", "pthread" }
filter "system:macosx"
openmp "Off"
links { "z" }
defines { "GL_SILENCE_DEPRECATION" }
if MAC_ARM then
......@@ -97,6 +99,7 @@ project "YGOPro"
end
filter "system:linux"
links { "GL", "X11", "Xxf86vm" }
linkoptions { "-fopenmp" }
if USE_AUDIO and AUDIO_LIB == "irrklang" then
links { "IrrKlang" }
linkoptions{ IRRKLANG_LINK_RPATH }
......
......@@ -159,7 +159,7 @@ bool ReplayMode::StartDuel() {
unsigned int seed = rh.seed;
std::mt19937 rnd(seed);
cur_replay.SkipInfo();
if(mainGame->dInfo.isTag) {
if(rh.flag & REPLAY_TAG) {
BufferIO::CopyWideString(cur_replay.players[0].c_str(), mainGame->dInfo.hostname);
BufferIO::CopyWideString(cur_replay.players[1].c_str(), mainGame->dInfo.hostname_tag);
BufferIO::CopyWideString(cur_replay.players[2].c_str(), mainGame->dInfo.clientname_tag);
......@@ -824,12 +824,12 @@ bool ReplayMode::ReplayAnalyze(unsigned char* msg, unsigned int len) {
break;
}
case MSG_AI_NAME: {
int len = BufferIO::ReadInt16(pbuf);
int len = buffer_read<uint16_t>(pbuf);
pbuf += len + 1;
break;
}
case MSG_SHOW_HINT: {
int len = BufferIO::ReadInt16(pbuf);
int len = buffer_read<uint16_t>(pbuf);
pbuf += len + 1;
break;
}
......
......@@ -749,21 +749,25 @@ bool SingleMode::SinglePlayAnalyze(unsigned char* msg, unsigned int len) {
case MSG_AI_NAME: {
char namebuf[128]{};
wchar_t wname[20]{};
int len = BufferIO::ReadInt16(pbuf);
auto begin = pbuf;
pbuf += len + 1;
std::memcpy(namebuf, begin, len + 1);
int name_len = buffer_read<uint16_t>(pbuf);
if (name_len + 1 <= (int)sizeof namebuf) {
std::memcpy(namebuf, pbuf, name_len);
namebuf[name_len] = 0;
}
pbuf += name_len + 1;
BufferIO::DecodeUTF8(namebuf, wname);
BufferIO::CopyCharArray(wname, mainGame->dInfo.clientname);
break;
}
case MSG_SHOW_HINT: {
char msgbuf[1024];
wchar_t msg[1024];
int len = BufferIO::ReadInt16(pbuf);
auto begin = pbuf;
pbuf += len + 1;
std::memcpy(msgbuf, begin, len + 1);
char msgbuf[1024]{};
wchar_t msg[1024]{};
int msg_len = buffer_read<uint16_t>(pbuf);
if (msg_len + 1 <= (int)sizeof msgbuf) {
std::memcpy(msgbuf, pbuf, msg_len);
msgbuf[msg_len] = 0;
}
pbuf += msg_len + 1;
BufferIO::DecodeUTF8(msgbuf, msg);
mainGame->gMutex.lock();
mainGame->SetStaticText(mainGame->stMessage, 310, mainGame->guiFont, msg);
......
......@@ -16,6 +16,7 @@ project "irrlicht"
"_IRR_STATIC_LIB_",
"NO_IRR_USE_NON_SYSTEM_BZLIB_",
"NO_IRR_COMPILE_WITH_BZIP2_",
"NO_IRR_COMPILE_WITH_LZMA_",
"NO_IRR_COMPILE_WITH_CONSOLE_DEVICE_",
"NO_IRR_COMPILE_WITH_DIRECT3D_8_",
"NO_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_",
......
......@@ -87,6 +87,14 @@ function GetParam(param)
return _OPTIONS[param] or os.getenv(string.upper(string.gsub(param,"-","_")))
end
function FindHeaderWithSubDir(header, subdir)
local result = os.findheader(header)
if result and subdir then
result = path.join(result, subdir)
end
return result
end
if GetParam("build-lua") then
BUILD_LUA = true
elseif GetParam("no-build-lua") then
......@@ -116,7 +124,7 @@ elseif GetParam("no-build-freetype") then
BUILD_FREETYPE = false
end
if not BUILD_FREETYPE then
FREETYPE_INCLUDE_DIR = GetParam("freetype-include-dir") or os.findheader("freetype2/ft2build.h") .. "/freetype2"
FREETYPE_INCLUDE_DIR = GetParam("freetype-include-dir") or FindHeaderWithSubDir("freetype2/ft2build.h", "freetype2")
FREETYPE_LIB_DIR = GetParam("freetype-lib-dir") or os.findlib("freetype")
end
......@@ -173,9 +181,9 @@ if USE_AUDIO then
MINIAUDIO_BUILD_OPUS_VORBIS = true
end
if not MINIAUDIO_BUILD_OPUS_VORBIS then
OPUS_INCLUDE_DIR = GetParam("opus-include-dir") or os.findheader("opus/opus.h") .. "/opus"
OPUS_INCLUDE_DIR = GetParam("opus-include-dir") or FindHeaderWithSubDir("opus/opus.h", "opus")
OPUS_LIB_DIR = GetParam("opus-lib-dir") or os.findlib("opus")
OPUSFILE_INCLUDE_DIR = GetParam("opusfile-include-dir") or os.findheader("opus/opusfile.h") .. "/opus"
OPUSFILE_INCLUDE_DIR = GetParam("opusfile-include-dir") or FindHeaderWithSubDir("opus/opusfile.h", "opus")
OPUSFILE_LIB_DIR = GetParam("opusfile-lib-dir") or os.findlib("opusfile")
VORBIS_INCLUDE_DIR = GetParam("vorbis-include-dir") or os.findheader("vorbis/vorbisfile.h")
VORBIS_LIB_DIR = GetParam("vorbis-lib-dir") or os.findlib("vorbis")
......
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