Commit a18e1436 authored by wind2009's avatar wind2009

Merge branch 'server' into server-develop

parents 5ed73cba f49949d1
...@@ -12,6 +12,7 @@ jobs: ...@@ -12,6 +12,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
os: [windows-2019, windows-2022] os: [windows-2019, windows-2022]
audiolib: [miniaudio, irrklang]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
...@@ -90,13 +91,75 @@ jobs: ...@@ -90,13 +91,75 @@ jobs:
7z x ${{ steps.sqlite.outputs.filepath }} 7z x ${{ steps.sqlite.outputs.filepath }}
move sqlite-amalgamation-3490100 sqlite3 move sqlite-amalgamation-3490100 sqlite3
- name: Download miniaudio
if: matrix.audiolib == 'miniaudio'
run: |
git clone --depth=1 --branch 0.11.22 https://github.com/mackron/miniaudio
cd miniaudio
xcopy /Y extras\miniaudio_split\miniaudio.* .
cd ..
- name: Download ogg
if: matrix.audiolib == 'miniaudio'
id: ogg
uses: mercury233/action-cache-download-file@v1.0.0
with:
url: https://github.com/xiph/ogg/releases/download/v1.3.5/libogg-1.3.5.tar.gz
- name: Extract ogg
if: matrix.audiolib == 'miniaudio'
run: |
tar xf ${{ steps.ogg.outputs.filepath }}
move libogg-1.3.5 miniaudio/external/ogg
- name: Download opus
if: matrix.audiolib == 'miniaudio'
id: opus
uses: mercury233/action-cache-download-file@v1.0.0
with:
url: https://github.com/xiph/opus/releases/download/v1.5.2/opus-1.5.2.tar.gz
- name: Extract opus
if: matrix.audiolib == 'miniaudio'
run: |
tar xf ${{ steps.opus.outputs.filepath }}
move opus-1.5.2 miniaudio/external/opus
- name: Download opusfile
if: matrix.audiolib == 'miniaudio'
id: opusfile
uses: mercury233/action-cache-download-file@v1.0.0
with:
url: https://github.com/xiph/opusfile/releases/download/v0.12/opusfile-0.12.tar.gz
- name: Extract opusfile
if: matrix.audiolib == 'miniaudio'
run: |
tar xf ${{ steps.opusfile.outputs.filepath }}
move opusfile-0.12 miniaudio/external/opusfile
- name: Download vorbis
if: matrix.audiolib == 'miniaudio'
id: vorbis
uses: mercury233/action-cache-download-file@v1.0.0
with:
url: https://github.com/xiph/vorbis/releases/download/v1.3.7/libvorbis-1.3.7.tar.gz
- name: Extract vorbis
if: matrix.audiolib == 'miniaudio'
run: |
tar xf ${{ steps.vorbis.outputs.filepath }}
move libvorbis-1.3.7 miniaudio/external/vorbis
- name: Download irrKlang - name: Download irrKlang
if: matrix.audiolib == 'irrklang'
id: irrKlang id: irrKlang
uses: mercury233/action-cache-download-file@v1.0.0 uses: mercury233/action-cache-download-file@v1.0.0
with: with:
url: https://www.ambiera.at/downloads/irrKlang-32bit-1.6.0.zip url: https://www.ambiera.at/downloads/irrKlang-32bit-1.6.0.zip
- name: Extract irrKlang - name: Extract irrKlang
if: matrix.audiolib == 'irrklang'
run: | run: |
7z x ${{ steps.irrKlang.outputs.filepath }} 7z x ${{ steps.irrKlang.outputs.filepath }}
move irrKlang-1.6.0 irrKlang move irrKlang-1.6.0 irrKlang
...@@ -134,16 +197,26 @@ jobs: ...@@ -134,16 +197,26 @@ jobs:
xcopy /E premake\* . xcopy /E premake\* .
xcopy /E resource\* . xcopy /E resource\* .
- name: Use premake to generate Visual Studio solution (2019) - name: Use premake to generate Visual Studio solution (2019, miniaudio)
if: matrix.os == 'windows-2019' if: matrix.os == 'windows-2019' && matrix.audiolib == 'miniaudio'
run: | run: |
.\premake5.exe vs2019 --winxp-support .\premake5.exe vs2019 --winxp-support
- name: Use premake to generate Visual Studio solution (2022) - name: Use premake to generate Visual Studio solution (2022, miniaudio)
if: matrix.os == 'windows-2022' if: matrix.os == 'windows-2022' && matrix.audiolib == 'miniaudio'
run: | run: |
.\premake5.exe vs2022 .\premake5.exe vs2022
- name: Use premake to generate Visual Studio solution (2019, irrKlang)
if: matrix.os == 'windows-2019' && matrix.audiolib == 'irrklang'
run: |
.\premake5.exe vs2019 --winxp-support --audio-lib=irrklang
- name: Use premake to generate Visual Studio solution (2022, irrKlang)
if: matrix.os == 'windows-2022' && matrix.audiolib == 'irrklang'
run: |
.\premake5.exe vs2022 --audio-lib=irrklang
- name: Add msbuild to PATH - name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v2 uses: microsoft/setup-msbuild@v2
...@@ -154,7 +227,7 @@ jobs: ...@@ -154,7 +227,7 @@ jobs:
- name: Upload build artifacts - name: Upload build artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: YGOPro-${{ matrix.os }} name: YGOPro-${{ matrix.os }}-${{ matrix.audiolib }}
path: | path: |
bin/release/YGOPro.exe bin/release/YGOPro.exe
...@@ -197,7 +270,7 @@ jobs: ...@@ -197,7 +270,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y libevent-dev libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev libsqlite3-dev libxxf86vm-dev sudo apt-get install -y libevent-dev libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev libsqlite3-dev libxxf86vm-dev libopusfile-dev libvorbis-dev
- name: Download premake - name: Download premake
id: premake id: premake
...@@ -222,6 +295,13 @@ jobs: ...@@ -222,6 +295,13 @@ jobs:
tar xf ${{ steps.lua.outputs.filepath }} tar xf ${{ steps.lua.outputs.filepath }}
mv lua-5.4.7 lua mv lua-5.4.7 lua
- name: Download miniaudio
run: |
git clone --depth=1 --branch 0.11.22 https://github.com/mackron/miniaudio
cd miniaudio
cp extras/miniaudio_split/miniaudio.* .
cd ..
- name: Download irrlicht - name: Download irrlicht
run: | run: |
git clone --depth=1 https://github.com/mercury233/irrlicht git clone --depth=1 https://github.com/mercury233/irrlicht
...@@ -234,8 +314,8 @@ jobs: ...@@ -234,8 +314,8 @@ jobs:
- name: Use premake to generate make files - name: Use premake to generate make files
run: | run: |
./premake5 gmake \ ./premake5 gmake \
--no-use-irrklang \ --freetype-include-dir="/usr/include/freetype2" \
--freetype-include-dir="/usr/include/freetype2" --opus-include-dir="/usr/include/opus"
- name: Make - name: Make
run: | run: |
...@@ -283,9 +363,9 @@ jobs: ...@@ -283,9 +363,9 @@ jobs:
# git pull origin master # git pull origin master
# cd .. # cd ..
# - name: Install dependencies - name: Install dependencies
# run: | run: |
# brew install freetype libevent libx11 sqlite zlib brew install freetype libevent libx11 sqlite opus opusfile libvorbis
- name: Download premake - name: Download premake
id: premake id: premake
...@@ -310,15 +390,16 @@ jobs: ...@@ -310,15 +390,16 @@ jobs:
tar xf ${{ steps.lua.outputs.filepath }} tar xf ${{ steps.lua.outputs.filepath }}
mv lua-5.4.7 lua mv lua-5.4.7 lua
- name: Download irrlicht - name: Download miniaudio
run: | run: |
git clone --depth=1 https://github.com/mercury233/irrlicht git clone --depth=1 --branch 0.11.22 https://github.com/mackron/miniaudio
cd miniaudio
cp extras/miniaudio_split/miniaudio.* .
cd ..
- name: Build irrlicht - name: Download irrlicht
run: | run: |
cd irrlicht/source/Irrlicht/MacOSX git clone --depth=1 https://github.com/mercury233/irrlicht
xcodebuild -project MacOSX.xcodeproj
cd ../../../..
- name: Copy premake files - name: Copy premake files
run: | run: |
...@@ -330,25 +411,26 @@ jobs: ...@@ -330,25 +411,26 @@ jobs:
run: | run: |
./premake5 gmake \ ./premake5 gmake \
--cc=clang \ --cc=clang \
--no-use-irrklang \
--freetype-include-dir="/usr/local/include/freetype2" \ --freetype-include-dir="/usr/local/include/freetype2" \
--irrlicht-include-dir="../irrlicht/include" \ --opus-include-dir="/usr/local/include/opus"
--irrlicht-lib-dir="../irrlicht/source/Irrlicht/MacOSX/build/Release"
- name: Use premake to generate make files (ARM64) - name: Use premake to generate make files (ARM64)
if: runner.arch == 'ARM64' if: runner.arch == 'ARM64'
run: | run: |
./premake5 gmake \ ./premake5 gmake \
--cc=clang \ --cc=clang \
--no-use-irrklang \
--event-include-dir="/opt/homebrew/include" \ --event-include-dir="/opt/homebrew/include" \
--event-lib-dir="/opt/homebrew/lib" \ --event-lib-dir="/opt/homebrew/lib" \
--freetype-include-dir="/opt/homebrew/include/freetype2" \ --freetype-include-dir="/opt/homebrew/include/freetype2" \
--freetype-lib-dir="/opt/homebrew/lib" \ --freetype-lib-dir="/opt/homebrew/lib" \
--sqlite-include-dir="/opt/homebrew/opt/sqlite/include" \ --sqlite-include-dir="/opt/homebrew/opt/sqlite/include" \
--sqlite-lib-dir="/opt/homebrew/opt/sqlite/lib" \ --sqlite-lib-dir="/opt/homebrew/opt/sqlite/lib" \
--irrlicht-include-dir="../irrlicht/include" \ --miniaudio-include-dir="/opt/homebrew/include" \
--irrlicht-lib-dir="../irrlicht/source/Irrlicht/MacOSX/build/Release" --miniaudio-lib-dir="/opt/homebrew/lib" \
--opus-include-dir="/opt/homebrew/include/opus" \
--opus-lib-dir="/opt/homebrew/lib" \
--vorbis-include-dir="/opt/homebrew/include" \
--vorbis-lib-dir="/opt/homebrew/lib"
- name: Make - name: Make
run: | run: |
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
/pics /pics
/replay /replay
/single /single
/sound
!/sound/files.txt
/WindBot /WindBot
/cards.cdb /cards.cdb
/error.log /error.log
...@@ -32,6 +34,7 @@ ...@@ -32,6 +34,7 @@
/irrklang /irrklang
/ikpmp3 /ikpmp3
/lua /lua
/miniaudio
/sqlite3 /sqlite3
/gframe/*.ico /gframe/*.ico
/gframe/ygopro.rc /gframe/ygopro.rc
......
...@@ -99,7 +99,7 @@ exec_windows: ...@@ -99,7 +99,7 @@ exec_windows:
- mat_windows - mat_windows
- mat_submodules - mat_submodules
script: script:
- bash -c 'cp -rf premake/* .' - bash -c 'cp -rf premake/* . ; cp -rf resource/* .'
- '.\premake5.exe vs2019' - '.\premake5.exe vs2019'
- cmd /c '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\msbuild.exe" build\YGOPro.sln /m /p:Configuration=Release' - cmd /c '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\msbuild.exe" build\YGOPro.sln /m /p:Configuration=Release'
- copy bin\release\ygopro.exe . - copy bin\release\ygopro.exe .
......
...@@ -27,6 +27,7 @@ install: ...@@ -27,6 +27,7 @@ install:
before_build: before_build:
- xcopy /E premake\* . - xcopy /E premake\* .
- xcopy /E resource\* .
- premake5 vs2022 - premake5 vs2022
configuration: Release configuration: Release
...@@ -49,6 +50,7 @@ for: ...@@ -49,6 +50,7 @@ for:
- move irrlicht-1.8.5 irrlicht - move irrlicht-1.8.5 irrlicht
- xcopy /E premake\* . - xcopy /E premake\* .
- xcopy /E resource\* .
- cd irrlicht - cd irrlicht
- patch -p1 < irrlicht.patch - patch -p1 < irrlicht.patch
......
...@@ -72,6 +72,21 @@ inline FILE* mywfopen(const wchar_t* filename, const char* mode) { ...@@ -72,6 +72,21 @@ inline FILE* mywfopen(const wchar_t* filename, const char* mode) {
return fp; return fp;
} }
#if !defined(_WIN32)
#define myfopen std::fopen
#elif defined(WDK_NTDDI_VERSION) && (WDK_NTDDI_VERSION >= 0x0A000005) // Redstone 4, Version 1803, Build 17134.
#define FOPEN_WINDOWS_SUPPORT_UTF8
#define myfopen std::fopen
#else
inline FILE* myfopen(const char* filename, const char* mode) {
wchar_t wfilename[256]{};
BufferIO::DecodeUTF8(filename, wfilename);
wchar_t wmode[20]{};
BufferIO::CopyCharArray(mode, wmode);
return _wfopen(wfilename, wmode);
}
#endif
#if !defined(YGOPRO_SERVER_MODE) || defined(SERVER_ZIP_SUPPORT) #if !defined(YGOPRO_SERVER_MODE) || defined(SERVER_ZIP_SUPPORT)
#include <irrlicht.h> #include <irrlicht.h>
#endif #endif
......
...@@ -131,7 +131,7 @@ bool DataManager::LoadDB(const wchar_t* wfile) { ...@@ -131,7 +131,7 @@ bool DataManager::LoadDB(const wchar_t* wfile) {
} }
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
bool DataManager::LoadStrings(const char* file) { bool DataManager::LoadStrings(const char* file) {
FILE* fp = std::fopen(file, "r"); FILE* fp = myfopen(file, "r");
if(!fp) if(!fp)
return false; return false;
char linebuf[TEXT_LINE_SIZE]{}; char linebuf[TEXT_LINE_SIZE]{};
...@@ -475,9 +475,7 @@ unsigned char* DataManager::ReadScriptFromIrrFS(const char* script_name, int* sl ...@@ -475,9 +475,7 @@ unsigned char* DataManager::ReadScriptFromIrrFS(const char* script_name, int* sl
} }
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
unsigned char* DataManager::ReadScriptFromFile(const char* script_name, int* slen) { unsigned char* DataManager::ReadScriptFromFile(const char* script_name, int* slen) {
wchar_t fname[256]{}; FILE* fp = myfopen(script_name, "rb");
BufferIO::DecodeUTF8(script_name, fname);
FILE* fp = mywfopen(fname, "rb");
if (!fp) if (!fp)
return nullptr; return nullptr;
size_t len = std::fread(scriptBuffer, 1, sizeof scriptBuffer, fp); size_t len = std::fread(scriptBuffer, 1, sizeof scriptBuffer, fp);
......
...@@ -12,7 +12,7 @@ DeckManager deckManager; ...@@ -12,7 +12,7 @@ DeckManager deckManager;
void DeckManager::LoadLFListSingle(const char* path) { void DeckManager::LoadLFListSingle(const char* path) {
auto cur = _lfList.rend(); auto cur = _lfList.rend();
FILE* fp = std::fopen(path, "r"); FILE* fp = myfopen(path, "r");
char linebuf[256]{}; char linebuf[256]{};
wchar_t strBuffer[256]{}; wchar_t strBuffer[256]{};
char str1[16]{}; char str1[16]{};
...@@ -321,7 +321,7 @@ bool DeckManager::LoadCurrentDeck(int category_index, const wchar_t* category_na ...@@ -321,7 +321,7 @@ bool DeckManager::LoadCurrentDeck(int category_index, const wchar_t* category_na
mainGame->deckBuilder.RefreshPackListScroll(); mainGame->deckBuilder.RefreshPackListScroll();
return res; return res;
} }
bool DeckManager::SaveDeck(Deck& deck, const wchar_t* file) { bool DeckManager::SaveDeck(const Deck& deck, const wchar_t* file) {
if(!FileSystem::IsDirExists(L"./deck") && !FileSystem::MakeDir(L"./deck")) if(!FileSystem::IsDirExists(L"./deck") && !FileSystem::MakeDir(L"./deck"))
return false; return false;
FILE* fp = OpenDeckFile(file, "w"); FILE* fp = OpenDeckFile(file, "w");
...@@ -329,26 +329,18 @@ bool DeckManager::SaveDeck(Deck& deck, const wchar_t* file) { ...@@ -329,26 +329,18 @@ bool DeckManager::SaveDeck(Deck& deck, const wchar_t* file) {
return false; return false;
std::fprintf(fp, "#created by ...\n#main\n"); std::fprintf(fp, "#created by ...\n#main\n");
for(size_t i = 0; i < deck.main.size(); ++i) for(size_t i = 0; i < deck.main.size(); ++i)
std::fprintf(fp, "%d\n", deck.main[i]->first); std::fprintf(fp, "%u\n", deck.main[i]->first);
std::fprintf(fp, "#extra\n"); std::fprintf(fp, "#extra\n");
for(size_t i = 0; i < deck.extra.size(); ++i) for(size_t i = 0; i < deck.extra.size(); ++i)
std::fprintf(fp, "%d\n", deck.extra[i]->first); std::fprintf(fp, "%u\n", deck.extra[i]->first);
std::fprintf(fp, "!side\n"); std::fprintf(fp, "!side\n");
for(size_t i = 0; i < deck.side.size(); ++i) for(size_t i = 0; i < deck.side.size(); ++i)
std::fprintf(fp, "%d\n", deck.side[i]->first); std::fprintf(fp, "%u\n", deck.side[i]->first);
std::fclose(fp); std::fclose(fp);
return true; return true;
} }
bool DeckManager::DeleteDeck(const wchar_t* file) { bool DeckManager::DeleteDeck(const wchar_t* file) {
#ifdef _WIN32 return FileSystem::RemoveFile(file);
BOOL result = DeleteFileW(file);
return !!result;
#else
char filefn[256];
BufferIO::EncodeUTF8(file, filefn);
int result = unlink(filefn);
return result == 0;
#endif
} }
bool DeckManager::CreateCategory(const wchar_t* name) { bool DeckManager::CreateCategory(const wchar_t* name) {
if(!FileSystem::IsDirExists(L"./deck") && !FileSystem::MakeDir(L"./deck")) if(!FileSystem::IsDirExists(L"./deck") && !FileSystem::MakeDir(L"./deck"))
...@@ -377,34 +369,21 @@ bool DeckManager::DeleteCategory(const wchar_t* name) { ...@@ -377,34 +369,21 @@ bool DeckManager::DeleteCategory(const wchar_t* name) {
return false; return false;
return FileSystem::DeleteDir(localname); return FileSystem::DeleteDir(localname);
} }
bool DeckManager::SaveDeckBuffer(const int deckbuf[], const wchar_t* name) { bool DeckManager::SaveDeckArray(const DeckArray& deck, const wchar_t* name) {
if (!FileSystem::IsDirExists(L"./deck") && !FileSystem::MakeDir(L"./deck")) if (!FileSystem::IsDirExists(L"./deck") && !FileSystem::MakeDir(L"./deck"))
return false; return false;
FILE* fp = OpenDeckFile(name, "w"); FILE* fp = OpenDeckFile(name, "w");
if (!fp) if (!fp)
return false; return false;
int it = 0;
const int mainc = deckbuf[it];
++it;
std::fprintf(fp, "#created by ...\n#main\n"); std::fprintf(fp, "#created by ...\n#main\n");
for (int i = 0; i < mainc; ++i) { for (const auto& code : deck.main)
std::fprintf(fp, "%d\n", deckbuf[it]); std::fprintf(fp, "%u\n", code);
++it;
}
const int extrac = deckbuf[it];
++it;
std::fprintf(fp, "#extra\n"); std::fprintf(fp, "#extra\n");
for (int i = 0; i < extrac; ++i) { for (const auto& code : deck.extra)
std::fprintf(fp, "%d\n", deckbuf[it]); std::fprintf(fp, "%u\n", code);
++it;
}
const int sidec = deckbuf[it];
++it;
std::fprintf(fp, "!side\n"); std::fprintf(fp, "!side\n");
for (int i = 0; i < sidec; ++i) { for (const auto& code : deck.side)
std::fprintf(fp, "%d\n", deckbuf[it]); std::fprintf(fp, "%u\n", code);
++it;
}
std::fclose(fp); std::fclose(fp);
return true; return true;
} }
......
...@@ -51,6 +51,12 @@ struct Deck { ...@@ -51,6 +51,12 @@ struct Deck {
} }
}; };
struct DeckArray {
std::vector<uint32_t> main;
std::vector<uint32_t> extra;
std::vector<uint32_t> side;
};
class DeckManager { class DeckManager {
public: public:
Deck current_deck; Deck current_deck;
...@@ -68,7 +74,6 @@ public: ...@@ -68,7 +74,6 @@ public:
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
bool LoadCurrentDeck(const wchar_t* file, bool is_packlist = false); bool LoadCurrentDeck(const wchar_t* file, bool is_packlist = false);
bool LoadCurrentDeck(int category_index, const wchar_t* category_name, const wchar_t* deckname); bool LoadCurrentDeck(int category_index, const wchar_t* category_name, const wchar_t* deckname);
bool SaveDeckBuffer(const int deckbuf[], const wchar_t* name);
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
static uint32_t LoadDeck(Deck& deck, uint32_t dbuf[], int mainc, int sidec, bool is_packlist = false); static uint32_t LoadDeck(Deck& deck, uint32_t dbuf[], int mainc, int sidec, bool is_packlist = false);
...@@ -79,11 +84,12 @@ public: ...@@ -79,11 +84,12 @@ public:
static void GetDeckFile(wchar_t* ret, int category_index, const wchar_t* category_name, const wchar_t* deckname); static void GetDeckFile(wchar_t* ret, int category_index, const wchar_t* category_name, const wchar_t* deckname);
static FILE* OpenDeckFile(const wchar_t* file, const char* mode); static FILE* OpenDeckFile(const wchar_t* file, const char* mode);
static irr::io::IReadFile* OpenDeckReader(const wchar_t* file); static irr::io::IReadFile* OpenDeckReader(const wchar_t* file);
static bool SaveDeck(Deck& deck, const wchar_t* file); static bool SaveDeck(const Deck& deck, const wchar_t* file);
static bool DeleteDeck(const wchar_t* file); static bool DeleteDeck(const wchar_t* file);
static bool CreateCategory(const wchar_t* name); static bool CreateCategory(const wchar_t* name);
static bool RenameCategory(const wchar_t* oldname, const wchar_t* newname); static bool RenameCategory(const wchar_t* oldname, const wchar_t* newname);
static bool DeleteCategory(const wchar_t* name); static bool DeleteCategory(const wchar_t* name);
static bool SaveDeckArray(const DeckArray& deck, const wchar_t* name);
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
}; };
......
...@@ -3034,6 +3034,7 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) { ...@@ -3034,6 +3034,7 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
case MSG_CHAIN_DISABLED: { case MSG_CHAIN_DISABLED: {
int ct = BufferIO::ReadUInt8(pbuf); int ct = BufferIO::ReadUInt8(pbuf);
if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping) { if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping) {
soundManager.PlaySoundEffect(SOUND_NEGATE);
mainGame->showcardcode = mainGame->dField.chains[ct - 1].code; mainGame->showcardcode = mainGame->dField.chains[ct - 1].code;
mainGame->showcarddif = 0; mainGame->showcarddif = 0;
mainGame->showcard = 3; mainGame->showcard = 3;
...@@ -3868,7 +3869,9 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) { ...@@ -3868,7 +3869,9 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
break; break;
} }
case MSG_RELOAD_FIELD: { case MSG_RELOAD_FIELD: {
mainGame->gMutex.lock(); if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping) {
mainGame->gMutex.lock();
}
mainGame->dField.Clear(); mainGame->dField.Clear();
mainGame->dInfo.duel_rule = BufferIO::ReadUInt8(pbuf); mainGame->dInfo.duel_rule = BufferIO::ReadUInt8(pbuf);
int val = 0; int val = 0;
...@@ -3974,7 +3977,9 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) { ...@@ -3974,7 +3977,9 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
myswprintf(event_string, dataManager.GetSysString(1609), dataManager.GetName(mainGame->dField.current_chain.code)); myswprintf(event_string, dataManager.GetSysString(1609), dataManager.GetName(mainGame->dField.current_chain.code));
mainGame->dField.last_chain = true; mainGame->dField.last_chain = true;
} }
mainGame->gMutex.unlock(); if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping) {
mainGame->gMutex.unlock();
}
break; break;
} }
} }
......
...@@ -151,6 +151,9 @@ bool Game::Initialize() { ...@@ -151,6 +151,9 @@ bool Game::Initialize() {
numFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 16); numFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 16);
if(!numFont) { if(!numFont) {
const wchar_t* numFontPaths[] = { const wchar_t* numFontPaths[] = {
L"./fonts/numFont.ttf",
L"./fonts/numFont.ttc",
L"./fonts/numFont.otf",
L"C:/Windows/Fonts/arialbd.ttf", L"C:/Windows/Fonts/arialbd.ttf",
L"/usr/share/fonts/truetype/DroidSansFallbackFull.ttf", L"/usr/share/fonts/truetype/DroidSansFallbackFull.ttf",
L"/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc", L"/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc",
...@@ -158,9 +161,6 @@ bool Game::Initialize() { ...@@ -158,9 +161,6 @@ bool Game::Initialize() {
L"/usr/share/fonts/noto-cjk/NotoSansCJK-Bold.ttc", L"/usr/share/fonts/noto-cjk/NotoSansCJK-Bold.ttc",
L"/System/Library/Fonts/SFNSTextCondensed-Bold.otf", L"/System/Library/Fonts/SFNSTextCondensed-Bold.otf",
L"/System/Library/Fonts/SFNS.ttf", L"/System/Library/Fonts/SFNS.ttf",
L"./fonts/numFont.ttf",
L"./fonts/numFont.ttc",
L"./fonts/numFont.otf"
}; };
for(const wchar_t* path : numFontPaths) { for(const wchar_t* path : numFontPaths) {
BufferIO::CopyWideString(path, gameConf.numfont); BufferIO::CopyWideString(path, gameConf.numfont);
...@@ -172,6 +172,9 @@ bool Game::Initialize() { ...@@ -172,6 +172,9 @@ bool Game::Initialize() {
textFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize); textFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize);
if(!textFont) { if(!textFont) {
const wchar_t* textFontPaths[] = { const wchar_t* textFontPaths[] = {
L"./fonts/textFont.ttf",
L"./fonts/textFont.ttc",
L"./fonts/textFont.otf",
L"C:/Windows/Fonts/msyh.ttc", L"C:/Windows/Fonts/msyh.ttc",
L"C:/Windows/Fonts/msyh.ttf", L"C:/Windows/Fonts/msyh.ttf",
L"C:/Windows/Fonts/simsun.ttc", L"C:/Windows/Fonts/simsun.ttc",
...@@ -183,9 +186,7 @@ bool Game::Initialize() { ...@@ -183,9 +186,7 @@ bool Game::Initialize() {
L"/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc", L"/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc",
L"/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc", L"/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc",
L"/System/Library/Fonts/PingFang.ttc", L"/System/Library/Fonts/PingFang.ttc",
L"./fonts/textFont.ttf", L"/System/Library/Fonts/STHeiti Medium.ttc",
L"./fonts/textFont.ttc",
L"./fonts/textFont.otf"
}; };
for(const wchar_t* path : textFontPaths) { for(const wchar_t* path : textFontPaths) {
BufferIO::CopyWideString(path, gameConf.textfont); BufferIO::CopyWideString(path, gameConf.textfont);
...@@ -203,7 +204,7 @@ bool Game::Initialize() { ...@@ -203,7 +204,7 @@ bool Game::Initialize() {
} }
}); });
if(fpath[0] == 0) { if(fpath[0] == 0) {
ErrorLog("Failed to load font(s)!"); ErrorLog("No fonts found! Please place appropriate font file in the fonts directory, or edit system.conf manually.");
return false; return false;
} }
if(!numFont) { if(!numFont) {
...@@ -215,6 +216,10 @@ bool Game::Initialize() { ...@@ -215,6 +216,10 @@ bool Game::Initialize() {
textFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize); textFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize);
} }
} }
if(!numFont || !textFont) {
ErrorLog("Failed to load font(s)!");
return false;
}
adFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 12); adFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 12);
lpcFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 48); lpcFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 48);
guiFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize); guiFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize);
...@@ -1354,7 +1359,7 @@ void Game::RefreshBot() { ...@@ -1354,7 +1359,7 @@ void Game::RefreshBot() {
if(!gameConf.enable_bot_mode) if(!gameConf.enable_bot_mode)
return; return;
botInfo.clear(); botInfo.clear();
FILE* fp = std::fopen("bot.conf", "r"); FILE* fp = myfopen("bot.conf", "r");
char linebuf[256]{}; char linebuf[256]{};
char strbuf[256]{}; char strbuf[256]{};
if(fp) { if(fp) {
...@@ -1407,7 +1412,7 @@ void Game::RefreshBot() { ...@@ -1407,7 +1412,7 @@ void Game::RefreshBot() {
} }
} }
void Game::LoadConfig() { void Game::LoadConfig() {
FILE* fp = std::fopen("system.conf", "r"); FILE* fp = myfopen("system.conf", "r");
if(!fp) if(!fp)
return; return;
char linebuf[CONFIG_LINE_SIZE]{}; char linebuf[CONFIG_LINE_SIZE]{};
...@@ -1425,14 +1430,6 @@ void Game::LoadConfig() { ...@@ -1425,14 +1430,6 @@ void Game::LoadConfig() {
} else if(!std::strcmp(strbuf, "errorlog")) { } else if(!std::strcmp(strbuf, "errorlog")) {
unsigned int val = std::strtol(valbuf, nullptr, 10); unsigned int val = std::strtol(valbuf, nullptr, 10);
enable_log = val & 0xff; enable_log = val & 0xff;
} else if(!std::strcmp(strbuf, "textfont")) {
int textfontsize = 0;
if (std::sscanf(linebuf, "%63s = %959s %d", strbuf, valbuf, &textfontsize) != 3)
continue;
gameConf.textfontsize = textfontsize;
BufferIO::DecodeUTF8(valbuf, gameConf.textfont);
} else if(!std::strcmp(strbuf, "numfont")) {
BufferIO::DecodeUTF8(valbuf, gameConf.numfont);
} else if(!std::strcmp(strbuf, "serverport")) { } else if(!std::strcmp(strbuf, "serverport")) {
gameConf.serverport = std::strtol(valbuf, nullptr, 10); gameConf.serverport = std::strtol(valbuf, nullptr, 10);
} else if(!std::strcmp(strbuf, "lasthost")) { } else if(!std::strcmp(strbuf, "lasthost")) {
...@@ -1501,7 +1498,7 @@ void Game::LoadConfig() { ...@@ -1501,7 +1498,7 @@ void Game::LoadConfig() {
gameConf.window_height = std::strtol(valbuf, nullptr, 10); gameConf.window_height = std::strtol(valbuf, nullptr, 10);
} else if(!std::strcmp(strbuf, "resize_popup_menu")) { } else if(!std::strcmp(strbuf, "resize_popup_menu")) {
gameConf.resize_popup_menu = std::strtol(valbuf, nullptr, 10) > 0; gameConf.resize_popup_menu = std::strtol(valbuf, nullptr, 10) > 0;
#ifdef YGOPRO_USE_IRRKLANG #ifdef YGOPRO_USE_AUDIO
} else if(!std::strcmp(strbuf, "enable_sound")) { } else if(!std::strcmp(strbuf, "enable_sound")) {
gameConf.enable_sound = std::strtol(valbuf, nullptr, 10) > 0; gameConf.enable_sound = std::strtol(valbuf, nullptr, 10) > 0;
} else if(!std::strcmp(strbuf, "sound_volume")) { } else if(!std::strcmp(strbuf, "sound_volume")) {
...@@ -1527,7 +1524,18 @@ void Game::LoadConfig() { ...@@ -1527,7 +1524,18 @@ void Game::LoadConfig() {
// options allowing multiple words // options allowing multiple words
if (std::sscanf(linebuf, "%63s = %959[^\n]", strbuf, valbuf) != 2) if (std::sscanf(linebuf, "%63s = %959[^\n]", strbuf, valbuf) != 2)
continue; continue;
if (!std::strcmp(strbuf, "nickname")) { if (!std::strcmp(strbuf, "textfont")) {
char* last_space = std::strrchr(valbuf, ' ');
if (last_space == nullptr)
continue;
int fontsize = std::strtol(last_space + 1, nullptr, 10);
if (fontsize > 0)
gameConf.textfontsize = fontsize;
*last_space = 0;
BufferIO::DecodeUTF8(valbuf, gameConf.textfont);
} else if (!std::strcmp(strbuf, "numfont")) {
BufferIO::DecodeUTF8(valbuf, gameConf.numfont);
} else if (!std::strcmp(strbuf, "nickname")) {
BufferIO::DecodeUTF8(valbuf, gameConf.nickname); BufferIO::DecodeUTF8(valbuf, gameConf.nickname);
} else if (!std::strcmp(strbuf, "gamename")) { } else if (!std::strcmp(strbuf, "gamename")) {
BufferIO::DecodeUTF8(valbuf, gameConf.gamename); BufferIO::DecodeUTF8(valbuf, gameConf.gamename);
...@@ -1545,7 +1553,7 @@ void Game::LoadConfig() { ...@@ -1545,7 +1553,7 @@ void Game::LoadConfig() {
std::fclose(fp); std::fclose(fp);
} }
void Game::SaveConfig() { void Game::SaveConfig() {
FILE* fp = std::fopen("system.conf", "w"); FILE* fp = myfopen("system.conf", "w");
std::fprintf(fp, "#config file\n#nickname & gamename should be less than 20 characters\n"); std::fprintf(fp, "#config file\n#nickname & gamename should be less than 20 characters\n");
char linebuf[CONFIG_LINE_SIZE]; char linebuf[CONFIG_LINE_SIZE];
std::fprintf(fp, "use_d3d = %d\n", gameConf.use_d3d ? 1 : 0); std::fprintf(fp, "use_d3d = %d\n", gameConf.use_d3d ? 1 : 0);
...@@ -1606,7 +1614,7 @@ void Game::SaveConfig() { ...@@ -1606,7 +1614,7 @@ void Game::SaveConfig() {
std::fprintf(fp, "window_width = %d\n", gameConf.window_width); std::fprintf(fp, "window_width = %d\n", gameConf.window_width);
std::fprintf(fp, "window_height = %d\n", gameConf.window_height); std::fprintf(fp, "window_height = %d\n", gameConf.window_height);
std::fprintf(fp, "resize_popup_menu = %d\n", gameConf.resize_popup_menu ? 1 : 0); std::fprintf(fp, "resize_popup_menu = %d\n", gameConf.resize_popup_menu ? 1 : 0);
#ifdef YGOPRO_USE_IRRKLANG #ifdef YGOPRO_USE_AUDIO
std::fprintf(fp, "enable_sound = %d\n", (chkEnableSound->isChecked() ? 1 : 0)); std::fprintf(fp, "enable_sound = %d\n", (chkEnableSound->isChecked() ? 1 : 0));
std::fprintf(fp, "enable_music = %d\n", (chkEnableMusic->isChecked() ? 1 : 0)); std::fprintf(fp, "enable_music = %d\n", (chkEnableMusic->isChecked() ? 1 : 0));
std::fprintf(fp, "#Volume of sound and music, between 0 and 100\n"); std::fprintf(fp, "#Volume of sound and music, between 0 and 100\n");
...@@ -1636,6 +1644,10 @@ void Game::ShowCardInfo(int code, bool resize) { ...@@ -1636,6 +1644,10 @@ void Game::ShowCardInfo(int code, bool resize) {
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(code), code); myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(code), code);
} }
stName->setText(formatBuffer); stName->setText(formatBuffer);
if(guiFont->getDimension(formatBuffer).Width > stName->getRelativePosition().getWidth() - gameConf.textfontsize)
stName->setToolTipText(formatBuffer);
else
stName->setToolTipText(nullptr);
int offset = 0; int offset = 0;
if (is_valid && !gameConf.hide_setname) { if (is_valid && !gameConf.hide_setname) {
auto& cd = cit->second; auto& cd = cit->second;
...@@ -1788,7 +1800,7 @@ void Game::ClearChatMsg() { ...@@ -1788,7 +1800,7 @@ void Game::ClearChatMsg() {
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
void Game::AddDebugMsg(const char* msg) { void Game::AddDebugMsg(const char* msg) {
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
fprintf(stderr, "%s\n", msg); std::fprintf(stderr, "%s\n", msg);
#else #else
if (enable_log & 0x1) { if (enable_log & 0x1) {
wchar_t wbuf[1024]; wchar_t wbuf[1024];
...@@ -1804,7 +1816,12 @@ void Game::AddDebugMsg(const char* msg) { ...@@ -1804,7 +1816,12 @@ void Game::AddDebugMsg(const char* msg) {
} }
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
void Game::ErrorLog(const char* msg) { void Game::ErrorLog(const char* msg) {
FILE* fp = std::fopen("error.log", "a"); #ifdef _WIN32
OutputDebugStringA(msg);
#else
std::fprintf(stderr, "%s\n", msg);
#endif
FILE* fp = myfopen("error.log", "a");
if(!fp) if(!fp)
return; return;
time_t nowtime = std::time(nullptr); time_t nowtime = std::time(nullptr);
...@@ -2113,6 +2130,9 @@ void Game::OnResize() { ...@@ -2113,6 +2130,9 @@ void Game::OnResize() {
btnBigCardZoomIn->setRelativePosition(Resize(205, 140, 295, 175)); btnBigCardZoomIn->setRelativePosition(Resize(205, 140, 295, 175));
btnBigCardZoomOut->setRelativePosition(Resize(205, 180, 295, 215)); btnBigCardZoomOut->setRelativePosition(Resize(205, 180, 295, 215));
btnBigCardClose->setRelativePosition(Resize(205, 230, 295, 265)); btnBigCardClose->setRelativePosition(Resize(205, 230, 295, 265));
irr::s32 barWidth = (xScale > 1) ? gameConf.textfontsize * xScale : gameConf.textfontsize;
env->getSkin()->setSize(irr::gui::EGDS_SCROLLBAR_SIZE, barWidth);
} }
void Game::ResizeChatInputWindow() { void Game::ResizeChatInputWindow() {
irr::s32 x = wInfos->getRelativePosition().LowerRightCorner.X + 6; irr::s32 x = wInfos->getRelativePosition().LowerRightCorner.X + 6;
......
...@@ -25,8 +25,12 @@ void ClickButton(irr::gui::IGUIElement* btn) { ...@@ -25,8 +25,12 @@ void ClickButton(irr::gui::IGUIElement* btn) {
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
#ifndef _WIN32 #if defined(FOPEN_WINDOWS_SUPPORT_UTF8)
std::setlocale(LC_CTYPE, ".UTF-8");
#elif defined(__APPLE__)
std::setlocale(LC_CTYPE, "UTF-8"); std::setlocale(LC_CTYPE, "UTF-8");
#elif !defined(_WIN32)
std::setlocale(LC_CTYPE, "");
#endif #endif
#if defined __APPLE__ && !defined YGOPRO_SERVER_MODE #if defined __APPLE__ && !defined YGOPRO_SERVER_MODE
CFURLRef bundle_url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); CFURLRef bundle_url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
......
...@@ -300,42 +300,23 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -300,42 +300,23 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
if(selected == -1) if(selected == -1)
break; break;
Replay replay; Replay replay;
wchar_t ex_filename[256]{}; wchar_t replay_filename[256]{};
wchar_t namebuf[4][20]{}; wchar_t namebuf[4][20]{};
wchar_t filename[256]{}; wchar_t filename[256]{};
wchar_t replay_path[256]{}; wchar_t replay_path[256]{};
BufferIO::CopyWideString(mainGame->lstReplayList->getListItem(selected), ex_filename); BufferIO::CopyWideString(mainGame->lstReplayList->getListItem(selected), replay_filename);
myswprintf(replay_path, L"./replay/%ls", ex_filename); myswprintf(replay_path, L"./replay/%ls", replay_filename);
if (!replay.OpenReplay(replay_path)) if (!replay.OpenReplay(replay_path))
break; break;
const ReplayHeader& rh = replay.pheader; if (replay.pheader.flag & REPLAY_SINGLE_MODE)
if(rh.flag & REPLAY_SINGLE_MODE)
break; break;
int player_count = (rh.flag & REPLAY_TAG) ? 4 : 2; for (size_t i = 0; i < replay.decks.size(); ++i) {
//player name BufferIO::CopyWideString(replay.players[Replay::GetDeckPlayer(i)].c_str(), namebuf[i]);
for(int i = 0; i < player_count; ++i)
replay.ReadName(namebuf[i]);
//skip pre infos
for(int i = 0; i < 4; ++i)
replay.ReadInt32();
//deck
std::vector<int> deckbuf;
for(int i = 0; i < player_count; ++i) {
deckbuf.clear();
int main = replay.ReadInt32();
deckbuf.push_back(main);
for (int j = 0; j < main; ++j) {
deckbuf.push_back(replay.ReadInt32());
}
int extra = replay.ReadInt32();
deckbuf.push_back(extra);
for (int j = 0; j < extra; ++j) {
deckbuf.push_back(replay.ReadInt32());
}
deckbuf.push_back(0);
FileSystem::SafeFileName(namebuf[i]); FileSystem::SafeFileName(namebuf[i]);
myswprintf(filename, L"deck/%ls-%d %ls.ydk", ex_filename, i + 1, namebuf[i]); }
deckManager.SaveDeckBuffer(deckbuf.data(), filename); for (size_t i = 0; i < replay.decks.size(); ++i) {
myswprintf(filename, L"./deck/%ls-%d %ls.ydk", replay_filename, i + 1, namebuf[i]);
DeckManager::SaveDeckArray(replay.decks[i], filename);
} }
mainGame->stACMessage->setText(dataManager.GetSysString(1335)); mainGame->stACMessage->setText(dataManager.GetSysString(1335));
mainGame->PopupElement(mainGame->wACMessage, 20); mainGame->PopupElement(mainGame->wACMessage, 20);
...@@ -546,7 +527,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -546,7 +527,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
wchar_t replay_path[256]{}; wchar_t replay_path[256]{};
myswprintf(replay_path, L"./replay/%ls", mainGame->lstReplayList->getListItem(sel)); myswprintf(replay_path, L"./replay/%ls", mainGame->lstReplayList->getListItem(sel));
if (!ReplayMode::cur_replay.OpenReplay(replay_path)) { if (!ReplayMode::cur_replay.OpenReplay(replay_path)) {
mainGame->stReplayInfo->setText(L""); mainGame->stReplayInfo->setText(L"Error");
break; break;
} }
wchar_t infobuf[256]{}; wchar_t infobuf[256]{};
...@@ -558,17 +539,17 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -558,17 +539,17 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
curtime = ReplayMode::cur_replay.pheader.seed; curtime = ReplayMode::cur_replay.pheader.seed;
std::wcsftime(infobuf, sizeof infobuf / sizeof infobuf[0], L"%Y/%m/%d %H:%M:%S\n", std::localtime(&curtime)); std::wcsftime(infobuf, sizeof infobuf / sizeof infobuf[0], L"%Y/%m/%d %H:%M:%S\n", std::localtime(&curtime));
repinfo.append(infobuf); repinfo.append(infobuf);
wchar_t namebuf[4][20]{}; if (ReplayMode::cur_replay.pheader.flag & REPLAY_SINGLE_MODE) {
ReplayMode::cur_replay.ReadName(namebuf[0]); wchar_t path[256]{};
ReplayMode::cur_replay.ReadName(namebuf[1]); BufferIO::DecodeUTF8(ReplayMode::cur_replay.script_name.c_str(), path);
if(ReplayMode::cur_replay.pheader.flag & REPLAY_TAG) { repinfo.append(path);
ReplayMode::cur_replay.ReadName(namebuf[2]); repinfo.append(L"\n");
ReplayMode::cur_replay.ReadName(namebuf[3]);
} }
const auto& player_names = ReplayMode::cur_replay.players;
if(ReplayMode::cur_replay.pheader.flag & REPLAY_TAG) if(ReplayMode::cur_replay.pheader.flag & REPLAY_TAG)
myswprintf(infobuf, L"%ls\n%ls\n===VS===\n%ls\n%ls\n", namebuf[0], namebuf[1], namebuf[2], namebuf[3]); myswprintf(infobuf, L"%ls\n%ls\n===VS===\n%ls\n%ls\n", player_names[0].c_str(), player_names[1].c_str(), player_names[2].c_str(), player_names[3].c_str());
else else
myswprintf(infobuf, L"%ls\n===VS===\n%ls\n", namebuf[0], namebuf[1]); myswprintf(infobuf, L"%ls\n===VS===\n%ls\n", player_names[0].c_str(), player_names[1].c_str());
repinfo.append(infobuf); repinfo.append(infobuf);
mainGame->ebRepStartTurn->setText(L"1"); mainGame->ebRepStartTurn->setText(L"1");
mainGame->SetStaticText(mainGame->stReplayInfo, 180, mainGame->guiFont, repinfo.c_str()); mainGame->SetStaticText(mainGame->stReplayInfo, 180, mainGame->guiFont, repinfo.c_str());
......
...@@ -86,6 +86,14 @@ public: ...@@ -86,6 +86,14 @@ public:
return DeleteDir(wdir); return DeleteDir(wdir);
} }
static bool RemoveFile(const wchar_t* wfile) {
return DeleteFileW(wfile);
}
static bool RemoveFile(const char* file) {
return DeleteFileA(file);
}
static void TraversalDir(const wchar_t* wpath, const std::function<void(const wchar_t*, bool)>& cb) { static void TraversalDir(const wchar_t* wpath, const std::function<void(const wchar_t*, bool)>& cb) {
wchar_t findstr[1024]; wchar_t findstr[1024];
std::swprintf(findstr, sizeof findstr / sizeof findstr[0], L"%ls/*", wpath); std::swprintf(findstr, sizeof findstr / sizeof findstr[0], L"%ls/*", wpath);
...@@ -195,6 +203,16 @@ public: ...@@ -195,6 +203,16 @@ public:
return success; return success;
} }
static bool RemoveFile(const wchar_t* wfile) {
char file[1024];
BufferIO::EncodeUTF8(wfile, file);
return RemoveFile(file);
}
static bool RemoveFile(const char* file) {
return unlink(file) == 0;
}
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
struct file_unit { struct file_unit {
std::string filename; std::string filename;
......
...@@ -27,7 +27,7 @@ struct HostInfo { ...@@ -27,7 +27,7 @@ struct HostInfo {
uint8_t no_shuffle_deck{}; uint8_t no_shuffle_deck{};
// byte padding[3] // byte padding[3]
uint32_t start_lp{}; int32_t start_lp{};
uint8_t start_hand{}; uint8_t start_hand{};
uint8_t draw_count{}; uint8_t draw_count{};
uint16_t time_limit{}; uint16_t time_limit{};
......
...@@ -6,6 +6,7 @@ end ...@@ -6,6 +6,7 @@ end
project "ygopro" project "ygopro"
if SERVER_MODE then if SERVER_MODE then
kind "ConsoleApp" kind "ConsoleApp"
cppdialect "C++14"
defines { "YGOPRO_SERVER_MODE" } defines { "YGOPRO_SERVER_MODE" }
...@@ -42,10 +43,6 @@ else ...@@ -42,10 +43,6 @@ else
links { "ocgcore", "clzma", "cspmemvfs", LUA_LIB_NAME, "sqlite3", "irrlicht", "freetype", "event" } links { "ocgcore", "clzma", "cspmemvfs", LUA_LIB_NAME, "sqlite3", "irrlicht", "freetype", "event" }
end end
if BUILD_IKPMP3 then
links { "ikpmp3" }
end
if BUILD_EVENT then if BUILD_EVENT then
includedirs { "../event/include" } includedirs { "../event/include" }
else else
...@@ -74,24 +71,40 @@ end ...@@ -74,24 +71,40 @@ end
libdirs { SQLITE_LIB_DIR } libdirs { SQLITE_LIB_DIR }
end end
if USE_IRRKLANG then if USE_AUDIO then
defines { "YGOPRO_USE_IRRKLANG" } defines { "YGOPRO_USE_AUDIO" }
includedirs { IRRKLANG_INCLUDE_DIR } if AUDIO_LIB == "miniaudio" then
if not IRRKLANG_PRO then defines { "YGOPRO_USE_MINIAUDIO" }
libdirs { IRRKLANG_LIB_DIR } includedirs { "../miniaudio" }
links { "miniaudio" }
if MINIAUDIO_SUPPORT_OPUS_VORBIS then
defines { "YGOPRO_MINIAUDIO_SUPPORT_OPUS_VORBIS" }
includedirs { "../miniaudio/extras/decoders/libopus", "../miniaudio/extras/decoders/libvorbis" }
if not MINIAUDIO_BUILD_OPUS_VORBIS then
links { "opusfile", "vorbisfile", "opus", "vorbis", "ogg" }
libdirs { OPUS_LIB_DIR, VORBIS_LIB_DIR, OGG_LIBDIR }
end
end
end
if AUDIO_LIB == "irrklang" then
defines { "YGOPRO_USE_IRRKLANG" }
includedirs { IRRKLANG_INCLUDE_DIR }
if not IRRKLANG_PRO then
libdirs { IRRKLANG_LIB_DIR }
end
if IRRKLANG_PRO_BUILD_IKPMP3 then
links { "ikpmp3" }
end
end end
end end
filter "system:windows" filter "system:windows"
defines { "_IRR_WCHAR_FILESYSTEM" } defines { "_IRR_WCHAR_FILESYSTEM" }
files "ygopro.rc" files "ygopro.rc"
if not SERVER_MODE then
libdirs { "$(DXSDK_DIR)Lib/x86" }
end
if SERVER_PRO2_SUPPORT then if SERVER_PRO2_SUPPORT then
targetname ("AI.Server") targetname ("AI.Server")
end end
if USE_IRRKLANG then if USE_AUDIO and AUDIO_LIB == "irrklang" then
links { "irrKlang" } links { "irrKlang" }
if IRRKLANG_PRO then if IRRKLANG_PRO then
defines { "IRRKLANG_STATIC" } defines { "IRRKLANG_STATIC" }
...@@ -118,14 +131,14 @@ end ...@@ -118,14 +131,14 @@ end
buildoptions { "--target=arm64-apple-macos12" } buildoptions { "--target=arm64-apple-macos12" }
linkoptions { "-arch arm64" } linkoptions { "-arch arm64" }
end end
if USE_IRRKLANG then if USE_AUDIO and AUDIO_LIB == "irrklang" then
links { "irrklang" } links { "irrklang" }
end end
filter "system:linux" filter "system:linux"
if not SERVER_MODE then if not SERVER_MODE then
links { "GL", "X11", "Xxf86vm" } links { "GL", "X11", "Xxf86vm" }
end end
if USE_IRRKLANG then if USE_AUDIO and AUDIO_LIB == "irrklang" then
links { "IrrKlang" } links { "IrrKlang" }
linkoptions{ IRRKLANG_LINK_RPATH } linkoptions{ IRRKLANG_LINK_RPATH }
end end
#include "replay.h" #include "replay.h"
#include "myfilesystem.h" #include "myfilesystem.h"
#include "network.h"
#include "lzma/LzmaLib.h" #include "lzma/LzmaLib.h"
namespace ygo { namespace ygo {
...@@ -48,9 +49,9 @@ void Replay::BeginRecord() { ...@@ -48,9 +49,9 @@ void Replay::BeginRecord() {
strftime(tmppath, 40, "./replay/%Y-%m-%d %H-%M-%S %%u.yrp", localedtime); strftime(tmppath, 40, "./replay/%Y-%m-%d %H-%M-%S %%u.yrp", localedtime);
char path[40]; char path[40];
sprintf(path, tmppath, server_port); sprintf(path, tmppath, server_port);
fp = std::fopen(path, "wb"); fp = myfopen(path, "wb");
#else #else
fp = std::fopen("./replay/_LastReplay.yrp", "wb"); fp = myfopen("./replay/_LastReplay.yrp", "wb");
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
if(!fp) if(!fp)
return; return;
...@@ -58,9 +59,7 @@ void Replay::BeginRecord() { ...@@ -58,9 +59,7 @@ void Replay::BeginRecord() {
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
} }
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
replay_size = 0; Reset();
comp_size = 0;
is_replaying = false;
is_recording = true; is_recording = true;
} }
void Replay::WriteHeader(ReplayHeader& header) { void Replay::WriteHeader(ReplayHeader& header) {
...@@ -156,11 +155,7 @@ bool Replay::OpenReplay(const wchar_t* name) { ...@@ -156,11 +155,7 @@ bool Replay::OpenReplay(const wchar_t* name) {
if(!rfp) if(!rfp)
return false; return false;
data_position = 0; Reset();
is_recording = false;
is_replaying = false;
replay_size = 0;
comp_size = 0;
if(std::fread(&pheader, sizeof pheader, 1, rfp) < 1) { if(std::fread(&pheader, sizeof pheader, 1, rfp) < 1) {
std::fclose(rfp); std::fclose(rfp);
return false; return false;
...@@ -183,6 +178,13 @@ bool Replay::OpenReplay(const wchar_t* name) { ...@@ -183,6 +178,13 @@ bool Replay::OpenReplay(const wchar_t* name) {
comp_size = 0; comp_size = 0;
} }
is_replaying = true; is_replaying = true;
can_read = true;
if (!ReadInfo()) {
Reset();
return false;
}
info_offset = data_position;
data_position = 0;
return true; return true;
} }
bool Replay::CheckReplay(const wchar_t* name) { bool Replay::CheckReplay(const wchar_t* name) {
...@@ -199,15 +201,7 @@ bool Replay::CheckReplay(const wchar_t* name) { ...@@ -199,15 +201,7 @@ bool Replay::CheckReplay(const wchar_t* name) {
bool Replay::DeleteReplay(const wchar_t* name) { bool Replay::DeleteReplay(const wchar_t* name) {
wchar_t fname[256]; wchar_t fname[256];
myswprintf(fname, L"./replay/%ls", name); myswprintf(fname, L"./replay/%ls", name);
#ifdef _WIN32 return FileSystem::RemoveFile(fname);
BOOL result = DeleteFileW(fname);
return !!result;
#else
char filefn[256];
BufferIO::EncodeUTF8(fname, filefn);
int result = unlink(filefn);
return result == 0;
#endif
} }
bool Replay::RenameReplay(const wchar_t* oldname, const wchar_t* newname) { bool Replay::RenameReplay(const wchar_t* oldname, const wchar_t* newname) {
wchar_t oldfname[256]; wchar_t oldfname[256];
...@@ -230,10 +224,6 @@ bool Replay::ReadNextResponse(unsigned char resp[]) { ...@@ -230,10 +224,6 @@ bool Replay::ReadNextResponse(unsigned char resp[]) {
unsigned char len{}; unsigned char len{};
if (!ReadData(&len, sizeof len)) if (!ReadData(&len, sizeof len))
return false; return false;
if (len > SIZE_RETURN_VALUE) {
is_replaying = false;
return false;
}
if (!ReadData(resp, len)) if (!ReadData(resp, len))
return false; return false;
return true; return true;
...@@ -250,10 +240,10 @@ void Replay::ReadHeader(ReplayHeader& header) { ...@@ -250,10 +240,10 @@ void Replay::ReadHeader(ReplayHeader& header) {
header = pheader; header = pheader;
} }
bool Replay::ReadData(void* data, size_t length) { bool Replay::ReadData(void* data, size_t length) {
if(!is_replaying) if (!is_replaying || !can_read)
return false; return false;
if (data_position + length > replay_size) { if (data_position + length > replay_size) {
is_replaying = false; can_read = false;
return false; return false;
} }
if (length) if (length)
...@@ -266,6 +256,73 @@ int32_t Replay::ReadInt32() { ...@@ -266,6 +256,73 @@ int32_t Replay::ReadInt32() {
} }
void Replay::Rewind() { void Replay::Rewind() {
data_position = 0; data_position = 0;
can_read = true;
}
void Replay::Reset() {
is_recording = false;
is_replaying = false;
can_read = false;
replay_size = 0;
comp_size = 0;
data_position = 0;
info_offset = 0;
players.clear();
params = { 0 };
decks.clear();
script_name.clear();
}
void Replay::SkipInfo(){
data_position += info_offset;
}
bool Replay::ReadInfo() {
int player_count = (pheader.flag & REPLAY_TAG) ? 4 : 2;
for (int i = 0; i < player_count; ++i) {
wchar_t name[20]{};
if (!ReadName(name))
return false;
players.push_back(name);
}
if (!ReadData(&params, sizeof params))
return false;
bool is_tag1 = pheader.flag & REPLAY_TAG;
bool is_tag2 = params.duel_flag & DUEL_TAG_MODE;
if (is_tag1 != is_tag2)
return false;
if (pheader.flag & REPLAY_SINGLE_MODE) {
uint16_t slen = Read<uint16_t>();
char filename[256]{};
if (slen == 0 || slen > sizeof(filename) - 1)
return false;
if (!ReadData(filename, slen))
return false;
filename[slen] = 0;
if (std::strncmp(filename, "./single/", 9))
return false;
script_name = filename + 9;
if (script_name.find_first_of(R"(/\)") != std::string::npos)
return false;
}
else {
for (int p = 0; p < player_count; ++p) {
DeckArray deck;
uint32_t main = Read<uint32_t>();
if (main > MAINC_MAX)
return false;
if (main)
deck.main.resize(main);
if (!ReadData(deck.main.data(), main * sizeof(uint32_t)))
return false;
uint32_t extra = Read<uint32_t>();
if (extra > MAINC_MAX)
return false;
if (extra)
deck.extra.resize(extra);
if (!ReadData(deck.extra.data(), extra * sizeof(uint32_t)))
return false;
decks.push_back(deck);
}
}
return true;
} }
} }
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define REPLAY_H #define REPLAY_H
#include "config.h" #include "config.h"
#include "deck_manager.h"
namespace ygo { namespace ygo {
...@@ -13,7 +14,7 @@ namespace ygo { ...@@ -13,7 +14,7 @@ namespace ygo {
#define REPLAY_UNIFORM 0x10 #define REPLAY_UNIFORM 0x10
// max size // max size
constexpr int MAX_REPLAY_SIZE = 0x20000; constexpr int MAX_REPLAY_SIZE = 0x80000;
constexpr int MAX_COMP_SIZE = UINT16_MAX + 1; constexpr int MAX_COMP_SIZE = UINT16_MAX + 1;
#ifdef YGOPRO_SERVER_MODE #ifdef YGOPRO_SERVER_MODE
...@@ -23,13 +24,20 @@ constexpr int MAX_COMP_SIZE = UINT16_MAX + 1; ...@@ -23,13 +24,20 @@ constexpr int MAX_COMP_SIZE = UINT16_MAX + 1;
#endif // YGOPRO_SERVER_MODE #endif // YGOPRO_SERVER_MODE
struct ReplayHeader { struct ReplayHeader {
unsigned int id{}; uint32_t id{};
unsigned int version{}; uint32_t version{};
unsigned int flag{}; uint32_t flag{};
unsigned int seed{}; uint32_t seed{};
unsigned int datasize{}; uint32_t datasize{};
unsigned int start_time{}; uint32_t start_time{};
unsigned char props[8]{}; uint8_t props[8]{};
};
struct DuelParameters {
int32_t start_lp{};
int32_t start_hand{};
int32_t draw_count{};
uint32_t duel_flag{};
}; };
class Replay { class Replay {
...@@ -51,10 +59,20 @@ public: ...@@ -51,10 +59,20 @@ public:
void SaveReplay(const wchar_t* name); void SaveReplay(const wchar_t* name);
// play // play
bool OpenReplay(const wchar_t* name);
static bool CheckReplay(const wchar_t* name); static bool CheckReplay(const wchar_t* name);
static bool DeleteReplay(const wchar_t* name); static bool DeleteReplay(const wchar_t* name);
static bool RenameReplay(const wchar_t* oldname, const wchar_t* newname); static bool RenameReplay(const wchar_t* oldname, const wchar_t* newname);
static size_t GetDeckPlayer(size_t deck_index) {
switch (deck_index) {
case 2:
return 3;
case 3:
return 2;
default:
return deck_index;
}
}
bool OpenReplay(const wchar_t* name);
bool ReadNextResponse(unsigned char resp[]); bool ReadNextResponse(unsigned char resp[]);
bool ReadName(wchar_t* data); bool ReadName(wchar_t* data);
void ReadHeader(ReplayHeader& header); void ReadHeader(ReplayHeader& header);
...@@ -67,6 +85,8 @@ public: ...@@ -67,6 +85,8 @@ public:
} }
int32_t ReadInt32(); int32_t ReadInt32();
void Rewind(); void Rewind();
void Reset();
void SkipInfo();
FILE* fp{ nullptr }; FILE* fp{ nullptr };
#ifdef _WIN32 #ifdef _WIN32
...@@ -77,12 +97,22 @@ public: ...@@ -77,12 +97,22 @@ public:
unsigned char* comp_data; unsigned char* comp_data;
size_t comp_size{}; size_t comp_size{};
std::vector<std::wstring> players; // 80 or 160 bytes
DuelParameters params; // 16 bytes
std::vector<DeckArray> decks; // 4 bytes, main deck, 4 bytes, extra deck
std::string script_name; // 2 bytes, script name (max: 256 bytes)
private: private:
bool ReadInfo();
unsigned char* replay_data; unsigned char* replay_data;
size_t replay_size{}; size_t replay_size{};
size_t data_position{}; size_t data_position{};
size_t info_offset{};
bool is_recording{}; bool is_recording{};
bool is_replaying{}; bool is_replaying{};
bool can_read{};
}; };
} }
......
...@@ -158,89 +158,65 @@ bool ReplayMode::StartDuel() { ...@@ -158,89 +158,65 @@ bool ReplayMode::StartDuel() {
const ReplayHeader& rh = cur_replay.pheader; const ReplayHeader& rh = cur_replay.pheader;
unsigned int seed = rh.seed; unsigned int seed = rh.seed;
std::mt19937 rnd(seed); std::mt19937 rnd(seed);
cur_replay.SkipInfo();
if(mainGame->dInfo.isTag) { if(mainGame->dInfo.isTag) {
cur_replay.ReadName(mainGame->dInfo.hostname); BufferIO::CopyWideString(cur_replay.players[0].c_str(), mainGame->dInfo.hostname);
cur_replay.ReadName(mainGame->dInfo.hostname_tag); BufferIO::CopyWideString(cur_replay.players[1].c_str(), mainGame->dInfo.hostname_tag);
cur_replay.ReadName(mainGame->dInfo.clientname_tag); BufferIO::CopyWideString(cur_replay.players[2].c_str(), mainGame->dInfo.clientname_tag);
cur_replay.ReadName(mainGame->dInfo.clientname); BufferIO::CopyWideString(cur_replay.players[3].c_str(), mainGame->dInfo.clientname);
} else { } else {
cur_replay.ReadName(mainGame->dInfo.hostname); BufferIO::CopyWideString(cur_replay.players[0].c_str(), mainGame->dInfo.hostname);
cur_replay.ReadName(mainGame->dInfo.clientname); BufferIO::CopyWideString(cur_replay.players[1].c_str(), mainGame->dInfo.clientname);
} }
pduel = create_duel(rnd()); pduel = create_duel(rnd());
int start_lp = cur_replay.ReadInt32(); mainGame->dInfo.duel_rule = cur_replay.params.duel_flag >> 16;
int start_hand = cur_replay.ReadInt32(); set_player_info(pduel, 0, cur_replay.params.start_lp, cur_replay.params.start_hand, cur_replay.params.draw_count);
int draw_count = cur_replay.ReadInt32(); set_player_info(pduel, 1, cur_replay.params.start_lp, cur_replay.params.start_hand, cur_replay.params.draw_count);
int opt = cur_replay.ReadInt32(); mainGame->dInfo.lp[0] = cur_replay.params.start_lp;
int duel_rule = opt >> 16; mainGame->dInfo.lp[1] = cur_replay.params.start_lp;
mainGame->dInfo.duel_rule = duel_rule; mainGame->dInfo.start_lp = cur_replay.params.start_lp;
set_player_info(pduel, 0, start_lp, start_hand, draw_count);
set_player_info(pduel, 1, start_lp, start_hand, draw_count);
mainGame->dInfo.lp[0] = start_lp;
mainGame->dInfo.lp[1] = start_lp;
mainGame->dInfo.start_lp = start_lp;
myswprintf(mainGame->dInfo.strLP[0], L"%d", mainGame->dInfo.lp[0]); myswprintf(mainGame->dInfo.strLP[0], L"%d", mainGame->dInfo.lp[0]);
myswprintf(mainGame->dInfo.strLP[1], L"%d", mainGame->dInfo.lp[1]); myswprintf(mainGame->dInfo.strLP[1], L"%d", mainGame->dInfo.lp[1]);
mainGame->dInfo.turn = 0; mainGame->dInfo.turn = 0;
if(!mainGame->dInfo.isSingleMode) { if(!(rh.flag & REPLAY_SINGLE_MODE)) {
if(!(opt & DUEL_TAG_MODE)) { if(!(rh.flag & REPLAY_TAG)) {
int main = cur_replay.ReadInt32(); for (int i = 0; i < 2; ++i) {
for(int i = 0; i < main; ++i) for (const auto& code : cur_replay.decks[i].main)
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE); new_card(pduel, code, i, i, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE);
int extra = cur_replay.ReadInt32(); for (const auto& code : cur_replay.decks[i].extra)
for(int i = 0; i < extra; ++i) new_card(pduel, code, i, i, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE); mainGame->dField.Initial(mainGame->LocalPlayer(i), cur_replay.decks[i].main.size(), cur_replay.decks[i].extra.size());
mainGame->dField.Initial(mainGame->LocalPlayer(0), main, extra); }
main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE);
extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(mainGame->LocalPlayer(1), main, extra);
} else { } else {
int main = cur_replay.ReadInt32(); for (const auto& code : cur_replay.decks[0].main)
for(int i = 0; i < main; ++i) new_card(pduel, code, 0, 0, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE);
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE); for (const auto& code : cur_replay.decks[0].extra)
int extra = cur_replay.ReadInt32(); new_card(pduel, code, 0, 0, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
for(int i = 0; i < extra; ++i) mainGame->dField.Initial(mainGame->LocalPlayer(0), cur_replay.decks[0].main.size(), cur_replay.decks[0].extra.size());
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE); for (const auto& code : cur_replay.decks[1].main)
mainGame->dField.Initial(mainGame->LocalPlayer(0), main, extra); new_tag_card(pduel, code, 0, LOCATION_DECK);
main = cur_replay.ReadInt32(); for (const auto& code : cur_replay.decks[1].extra)
for(int i = 0; i < main; ++i) new_tag_card(pduel, code, 0, LOCATION_EXTRA);
new_tag_card(pduel, cur_replay.ReadInt32(), 0, LOCATION_DECK); for (const auto& code : cur_replay.decks[2].main)
extra = cur_replay.ReadInt32(); new_card(pduel, code, 1, 1, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE);
for(int i = 0; i < extra; ++i) for (const auto& code : cur_replay.decks[2].extra)
new_tag_card(pduel, cur_replay.ReadInt32(), 0, LOCATION_EXTRA); new_card(pduel, code, 1, 1, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
main = cur_replay.ReadInt32(); mainGame->dField.Initial(mainGame->LocalPlayer(1), cur_replay.decks[2].main.size(), cur_replay.decks[2].extra.size());
for(int i = 0; i < main; ++i) for (const auto& code : cur_replay.decks[3].main)
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE); new_tag_card(pduel, code, 1, LOCATION_DECK);
extra = cur_replay.ReadInt32(); for (const auto& code : cur_replay.decks[3].extra)
for(int i = 0; i < extra; ++i) new_tag_card(pduel, code, 1, LOCATION_EXTRA);
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(mainGame->LocalPlayer(1), main, extra);
main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_tag_card(pduel, cur_replay.ReadInt32(), 1, LOCATION_DECK);
extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_tag_card(pduel, cur_replay.ReadInt32(), 1, LOCATION_EXTRA);
} }
} else { } else {
char filename[256]; char filename[256]{};
auto slen = cur_replay.Read<uint16_t>(); std::snprintf(filename, sizeof filename, "./single/%s", cur_replay.script_name.c_str());
if (slen > sizeof(filename) - 1) {
return false;
}
cur_replay.ReadData(filename, slen);
filename[slen] = 0;
if(!preload_script(pduel, filename)) { if(!preload_script(pduel, filename)) {
return false; return false;
} }
} }
if (!(rh.flag & REPLAY_UNIFORM)) if (!(rh.flag & REPLAY_UNIFORM))
opt |= DUEL_OLD_REPLAY; cur_replay.params.duel_flag |= DUEL_OLD_REPLAY;
start_duel(pduel, opt); start_duel(pduel, cur_replay.params.duel_flag);
return true; return true;
} }
void ReplayMode::EndDuel() { void ReplayMode::EndDuel() {
......
#include "sound_manager.h" #include "sound_manager.h"
#include "myfilesystem.h" #include "myfilesystem.h"
#if defined(YGOPRO_USE_MINIAUDIO) && defined(YGOPRO_MINIAUDIO_SUPPORT_OPUS_VORBIS)
#include <miniaudio_libopus.h>
#include <miniaudio_libvorbis.h>
#endif
#ifdef IRRKLANG_STATIC #ifdef IRRKLANG_STATIC
#include "../ikpmp3/ikpMP3.h" #include "../ikpmp3/ikpMP3.h"
#endif #endif
...@@ -9,10 +13,34 @@ namespace ygo { ...@@ -9,10 +13,34 @@ namespace ygo {
SoundManager soundManager; SoundManager soundManager;
bool SoundManager::Init() { bool SoundManager::Init() {
#ifdef YGOPRO_USE_IRRKLANG #ifdef YGOPRO_USE_AUDIO
bgm_scene = -1; bgm_scene = -1;
RefreshBGMList(); RefreshBGMList();
rnd.reset((unsigned int)std::time(nullptr)); rnd.reset((unsigned int)std::time(nullptr));
#ifdef YGOPRO_USE_MINIAUDIO
engineConfig = ma_engine_config_init();
#ifdef YGOPRO_MINIAUDIO_SUPPORT_OPUS_VORBIS
ma_decoding_backend_vtable* pCustomBackendVTables[] =
{
ma_decoding_backend_libvorbis,
ma_decoding_backend_libopus
};
resourceManagerConfig = ma_resource_manager_config_init();
resourceManagerConfig.ppCustomDecodingBackendVTables = pCustomBackendVTables;
resourceManagerConfig.customDecodingBackendCount = sizeof(pCustomBackendVTables) / sizeof(pCustomBackendVTables[0]);
resourceManagerConfig.pCustomDecodingBackendUserData = NULL;
if(ma_resource_manager_init(&resourceManagerConfig, &resourceManager) != MA_SUCCESS) {
return false;
}
engineConfig.pResourceManager = &resourceManager;
#endif
if(ma_engine_init(&engineConfig, &engineSound) != MA_SUCCESS || ma_engine_init(&engineConfig, &engineMusic) != MA_SUCCESS) {
return false;
} else {
return true;
}
#endif // YGOPRO_USE_MINIAUDIO
#ifdef YGOPRO_USE_IRRKLANG
engineSound = irrklang::createIrrKlangDevice(); engineSound = irrklang::createIrrKlangDevice();
engineMusic = irrklang::createIrrKlangDevice(); engineMusic = irrklang::createIrrKlangDevice();
if(!engineSound || !engineMusic) { if(!engineSound || !engineMusic) {
...@@ -24,10 +52,11 @@ bool SoundManager::Init() { ...@@ -24,10 +52,11 @@ bool SoundManager::Init() {
return true; return true;
} }
#endif // YGOPRO_USE_IRRKLANG #endif // YGOPRO_USE_IRRKLANG
// TODO: Implement other sound engines #endif // YGOPRO_USE_AUDIO
return false; return false;
} }
void SoundManager::RefreshBGMList() { void SoundManager::RefreshBGMList() {
#ifdef YGOPRO_USE_AUDIO
RefershBGMDir(L"", BGM_DUEL); RefershBGMDir(L"", BGM_DUEL);
RefershBGMDir(L"duel", BGM_DUEL); RefershBGMDir(L"duel", BGM_DUEL);
RefershBGMDir(L"menu", BGM_MENU); RefershBGMDir(L"menu", BGM_MENU);
...@@ -36,11 +65,17 @@ void SoundManager::RefreshBGMList() { ...@@ -36,11 +65,17 @@ void SoundManager::RefreshBGMList() {
RefershBGMDir(L"disadvantage", BGM_DISADVANTAGE); RefershBGMDir(L"disadvantage", BGM_DISADVANTAGE);
RefershBGMDir(L"win", BGM_WIN); RefershBGMDir(L"win", BGM_WIN);
RefershBGMDir(L"lose", BGM_LOSE); RefershBGMDir(L"lose", BGM_LOSE);
#endif
} }
void SoundManager::RefershBGMDir(std::wstring path, int scene) { void SoundManager::RefershBGMDir(std::wstring path, int scene) {
std::wstring search = L"./sound/BGM/" + path; std::wstring search = L"./sound/BGM/" + path;
FileSystem::TraversalDir(search.c_str(), [this, &path, scene](const wchar_t* name, bool isdir) { FileSystem::TraversalDir(search.c_str(), [this, &path, scene](const wchar_t* name, bool isdir) {
if(!isdir && (IsExtension(name, L".mp3") || IsExtension(name, L".ogg"))) { if(!isdir && (
IsExtension(name, L".mp3")
#if defined(YGOPRO_MINIAUDIO_SUPPORT_OPUS_VORBIS) || defined(YGOPRO_USE_IRRKLANG)
|| IsExtension(name, L".ogg")
#endif
)) {
std::wstring filename = path + L"/" + name; std::wstring filename = path + L"/" + name;
BGMList[BGM_ALL].push_back(filename); BGMList[BGM_ALL].push_back(filename);
BGMList[scene].push_back(filename); BGMList[scene].push_back(filename);
...@@ -48,137 +83,151 @@ void SoundManager::RefershBGMDir(std::wstring path, int scene) { ...@@ -48,137 +83,151 @@ void SoundManager::RefershBGMDir(std::wstring path, int scene) {
}); });
} }
void SoundManager::PlaySoundEffect(int sound) { void SoundManager::PlaySoundEffect(int sound) {
#ifdef YGOPRO_USE_IRRKLANG #ifdef YGOPRO_USE_AUDIO
if(!mainGame->chkEnableSound->isChecked()) if(!mainGame->chkEnableSound->isChecked())
return; return;
engineSound->setSoundVolume(mainGame->gameConf.sound_volume); char soundName[32];
switch(sound) { switch(sound) {
case SOUND_SUMMON: { case SOUND_SUMMON: {
engineSound->play2D("./sound/summon.wav"); strcpy(soundName, "summon");
break; break;
} }
case SOUND_SPECIAL_SUMMON: { case SOUND_SPECIAL_SUMMON: {
engineSound->play2D("./sound/specialsummon.wav"); strcpy(soundName, "specialsummon");
break; break;
} }
case SOUND_ACTIVATE: { case SOUND_ACTIVATE: {
engineSound->play2D("./sound/activate.wav"); strcpy(soundName, "activate");
break; break;
} }
case SOUND_SET: { case SOUND_SET: {
engineSound->play2D("./sound/set.wav"); strcpy(soundName, "set");
break; break;
} }
case SOUND_FILP: { case SOUND_FILP: {
engineSound->play2D("./sound/flip.wav"); strcpy(soundName, "flip");
break; break;
} }
case SOUND_REVEAL: { case SOUND_REVEAL: {
engineSound->play2D("./sound/reveal.wav"); strcpy(soundName, "reveal");
break; break;
} }
case SOUND_EQUIP: { case SOUND_EQUIP: {
engineSound->play2D("./sound/equip.wav"); strcpy(soundName, "equip");
break; break;
} }
case SOUND_DESTROYED: { case SOUND_DESTROYED: {
engineSound->play2D("./sound/destroyed.wav"); strcpy(soundName, "destroyed");
break; break;
} }
case SOUND_BANISHED: { case SOUND_BANISHED: {
engineSound->play2D("./sound/banished.wav"); strcpy(soundName, "banished");
break; break;
} }
case SOUND_TOKEN: { case SOUND_TOKEN: {
engineSound->play2D("./sound/token.wav"); strcpy(soundName, "token");
break;
}
case SOUND_NEGATE: {
strcpy(soundName, "negate");
break; break;
} }
case SOUND_ATTACK: { case SOUND_ATTACK: {
engineSound->play2D("./sound/attack.wav"); strcpy(soundName, "attack");
break; break;
} }
case SOUND_DIRECT_ATTACK: { case SOUND_DIRECT_ATTACK: {
engineSound->play2D("./sound/directattack.wav"); strcpy(soundName, "directattack");
break; break;
} }
case SOUND_DRAW: { case SOUND_DRAW: {
engineSound->play2D("./sound/draw.wav"); strcpy(soundName, "draw");
break; break;
} }
case SOUND_SHUFFLE: { case SOUND_SHUFFLE: {
engineSound->play2D("./sound/shuffle.wav"); strcpy(soundName, "shuffle");
break; break;
} }
case SOUND_DAMAGE: { case SOUND_DAMAGE: {
engineSound->play2D("./sound/damage.wav"); strcpy(soundName, "damage");
break; break;
} }
case SOUND_RECOVER: { case SOUND_RECOVER: {
engineSound->play2D("./sound/gainlp.wav"); strcpy(soundName, "gainlp");
break; break;
} }
case SOUND_COUNTER_ADD: { case SOUND_COUNTER_ADD: {
engineSound->play2D("./sound/addcounter.wav"); strcpy(soundName, "addcounter");
break; break;
} }
case SOUND_COUNTER_REMOVE: { case SOUND_COUNTER_REMOVE: {
engineSound->play2D("./sound/removecounter.wav"); strcpy(soundName, "removecounter");
break; break;
} }
case SOUND_COIN: { case SOUND_COIN: {
engineSound->play2D("./sound/coinflip.wav"); strcpy(soundName, "coinflip");
break; break;
} }
case SOUND_DICE: { case SOUND_DICE: {
engineSound->play2D("./sound/diceroll.wav"); strcpy(soundName, "diceroll");
break; break;
} }
case SOUND_NEXT_TURN: { case SOUND_NEXT_TURN: {
engineSound->play2D("./sound/nextturn.wav"); strcpy(soundName, "nextturn");
break; break;
} }
case SOUND_PHASE: { case SOUND_PHASE: {
engineSound->play2D("./sound/phase.wav"); strcpy(soundName, "phase");
break; break;
} }
case SOUND_MENU: { case SOUND_MENU: {
engineSound->play2D("./sound/menu.wav"); strcpy(soundName, "menu");
break; break;
} }
case SOUND_BUTTON: { case SOUND_BUTTON: {
engineSound->play2D("./sound/button.wav"); strcpy(soundName, "button");
break; break;
} }
case SOUND_INFO: { case SOUND_INFO: {
engineSound->play2D("./sound/info.wav"); strcpy(soundName, "info");
break; break;
} }
case SOUND_QUESTION: { case SOUND_QUESTION: {
engineSound->play2D("./sound/question.wav"); strcpy(soundName, "question");
break; break;
} }
case SOUND_CARD_PICK: { case SOUND_CARD_PICK: {
engineSound->play2D("./sound/cardpick.wav"); strcpy(soundName, "cardpick");
break; break;
} }
case SOUND_CARD_DROP: { case SOUND_CARD_DROP: {
engineSound->play2D("./sound/carddrop.wav"); strcpy(soundName, "carddrop");
break; break;
} }
case SOUND_PLAYER_ENTER: { case SOUND_PLAYER_ENTER: {
engineSound->play2D("./sound/playerenter.wav"); strcpy(soundName, "playerenter");
break; break;
} }
case SOUND_CHAT: { case SOUND_CHAT: {
engineSound->play2D("./sound/chatmessage.wav"); strcpy(soundName, "chatmessage");
break; break;
} }
default: default:
break; break;
} }
char soundPath[40];
std::snprintf(soundPath, 40, "./sound/%s.wav", soundName);
SetSoundVolume(mainGame->gameConf.sound_volume);
#ifdef YGOPRO_USE_MINIAUDIO
ma_engine_play_sound(&engineSound, soundPath, nullptr);
#endif
#ifdef YGOPRO_USE_IRRKLANG
engineSound->play2D(soundPath);
#endif #endif
#endif // YGOPRO_USE_AUDIO
} }
void SoundManager::PlayDialogSound(irr::gui::IGUIElement * element) { void SoundManager::PlayDialogSound(irr::gui::IGUIElement * element) {
#ifdef YGOPRO_USE_AUDIO
if(element == mainGame->wMessage) { if(element == mainGame->wMessage) {
PlaySoundEffect(SOUND_INFO); PlaySoundEffect(SOUND_INFO);
} else if(element == mainGame->wQuery) { } else if(element == mainGame->wQuery) {
...@@ -200,50 +249,90 @@ void SoundManager::PlayDialogSound(irr::gui::IGUIElement * element) { ...@@ -200,50 +249,90 @@ void SoundManager::PlayDialogSound(irr::gui::IGUIElement * element) {
} else if(element == mainGame->wFTSelect) { } else if(element == mainGame->wFTSelect) {
PlaySoundEffect(SOUND_QUESTION); PlaySoundEffect(SOUND_QUESTION);
} }
#endif // YGOPRO_USE_AUDIO
} }
void SoundManager::PlayMusic(char* song, bool loop) { bool SoundManager::IsPlayingMusic(wchar_t* music) {
#ifdef YGOPRO_USE_MINIAUDIO
if(music) {
return !mywcsncasecmp(currentPlayingMusic, music, 1024) && ma_sound_is_playing(&soundBGM);
} else {
return ma_sound_is_playing(&soundBGM);
}
#endif
#ifdef YGOPRO_USE_IRRKLANG #ifdef YGOPRO_USE_IRRKLANG
if(music) {
char cmusic[1024];
BufferIO::EncodeUTF8(music, cmusic);
return engineMusic->isCurrentlyPlaying(cmusic);
} else {
return soundBGM && !soundBGM->isFinished();
}
#endif
return false;
}
void SoundManager::PlayMusic(wchar_t* music, bool loop) {
#ifdef YGOPRO_USE_AUDIO
if(!mainGame->chkEnableMusic->isChecked()) if(!mainGame->chkEnableMusic->isChecked())
return; return;
if(!engineMusic->isCurrentlyPlaying(song)) { if(!IsPlayingMusic(music)) {
engineMusic->stopAllSounds(); StopBGM();
engineMusic->setSoundVolume(mainGame->gameConf.music_volume); SetMusicVolume(mainGame->gameConf.music_volume);
soundBGM = engineMusic->play2D(song, loop, false, true); #ifdef YGOPRO_USE_MINIAUDIO
BufferIO::CopyWStr(music, currentPlayingMusic, 1024);
ma_sound_init_from_file_w(&engineMusic, music, MA_SOUND_FLAG_ASYNC | MA_SOUND_FLAG_STREAM, nullptr, nullptr, &soundBGM);
ma_sound_set_looping(&soundBGM, loop);
ma_sound_start(&soundBGM);
#endif
#ifdef YGOPRO_USE_IRRKLANG
char cmusic[1024];
BufferIO::EncodeUTF8(music, cmusic);
soundBGM = engineMusic->play2D(cmusic, loop, false, true);
#endif
} }
#endif #endif
} }
void SoundManager::PlayBGM(int scene) { void SoundManager::PlayBGM(int scene) {
#ifdef YGOPRO_USE_IRRKLANG #ifdef YGOPRO_USE_AUDIO
if(!mainGame->chkEnableMusic->isChecked()) if(!mainGame->chkEnableMusic->isChecked())
return; return;
if(!mainGame->chkMusicMode->isChecked()) if(!mainGame->chkMusicMode->isChecked())
scene = BGM_ALL; scene = BGM_ALL;
char BGMName[1024]; if(scene != bgm_scene || !IsPlayingMusic()) {
if(scene != bgm_scene || (soundBGM && soundBGM->isFinished())) {
int count = BGMList[scene].size(); int count = BGMList[scene].size();
if(count <= 0) if(count <= 0)
return; return;
bgm_scene = scene; bgm_scene = scene;
int bgm = rnd.get_random_integer(0, count -1); int bgm = rnd.get_random_integer(0, count -1);
auto name = BGMList[scene][bgm].c_str(); auto name = BGMList[scene][bgm].c_str();
wchar_t fname[1024]; wchar_t BGMName[1024];
myswprintf(fname, L"./sound/BGM/%ls", name); myswprintf(BGMName, L"./sound/BGM/%ls", name);
BufferIO::EncodeUTF8(fname, BGMName);
PlayMusic(BGMName, false); PlayMusic(BGMName, false);
} }
#endif #endif
} }
void SoundManager::StopBGM() { void SoundManager::StopBGM() {
#ifdef YGOPRO_USE_MINIAUDIO
if(!currentPlayingMusic[0])
return;
memset(currentPlayingMusic, 0, sizeof(currentPlayingMusic));
ma_sound_uninit(&soundBGM);
#endif
#ifdef YGOPRO_USE_IRRKLANG #ifdef YGOPRO_USE_IRRKLANG
engineMusic->stopAllSounds(); engineMusic->stopAllSounds();
#endif #endif
} }
void SoundManager::SetSoundVolume(double volume) { void SoundManager::SetSoundVolume(double volume) {
#ifdef YGOPRO_USE_MINIAUDIO
ma_engine_set_volume(&engineSound, volume);
#endif
#ifdef YGOPRO_USE_IRRKLANG #ifdef YGOPRO_USE_IRRKLANG
engineSound->setSoundVolume(volume); engineSound->setSoundVolume(volume);
#endif #endif
} }
void SoundManager::SetMusicVolume(double volume) { void SoundManager::SetMusicVolume(double volume) {
#ifdef YGOPRO_USE_MINIAUDIO
ma_engine_set_volume(&engineMusic, volume);
#endif
#ifdef YGOPRO_USE_IRRKLANG #ifdef YGOPRO_USE_IRRKLANG
engineMusic->setSoundVolume(volume); engineMusic->setSoundVolume(volume);
#endif #endif
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
#include "game.h" #include "game.h"
#include "../ocgcore/mtrandom.h" #include "../ocgcore/mtrandom.h"
#ifdef YGOPRO_USE_MINIAUDIO
#include <miniaudio.h>
#endif
#ifdef YGOPRO_USE_IRRKLANG #ifdef YGOPRO_USE_IRRKLANG
#include <irrKlang.h> #include <irrKlang.h>
#endif #endif
...@@ -12,8 +15,19 @@ namespace ygo { ...@@ -12,8 +15,19 @@ namespace ygo {
class SoundManager { class SoundManager {
private: private:
std::vector<std::wstring> BGMList[8]; std::vector<std::wstring> BGMList[8];
int bgm_scene; int bgm_scene{};
mt19937 rnd; mt19937 rnd;
#ifdef YGOPRO_USE_MINIAUDIO
ma_engine_config engineConfig;
#ifdef YGOPRO_MINIAUDIO_SUPPORT_OPUS_VORBIS
ma_resource_manager_config resourceManagerConfig;
ma_resource_manager resourceManager;
#endif
ma_engine engineSound;
ma_engine engineMusic;
ma_sound soundBGM;
wchar_t currentPlayingMusic[1024]{};
#endif
#ifdef YGOPRO_USE_IRRKLANG #ifdef YGOPRO_USE_IRRKLANG
irrklang::ISoundEngine* engineSound; irrklang::ISoundEngine* engineSound;
irrklang::ISoundEngine* engineMusic; irrklang::ISoundEngine* engineMusic;
...@@ -26,7 +40,8 @@ public: ...@@ -26,7 +40,8 @@ public:
void RefreshBGMList(); void RefreshBGMList();
void PlaySoundEffect(int sound); void PlaySoundEffect(int sound);
void PlayDialogSound(irr::gui::IGUIElement * element); void PlayDialogSound(irr::gui::IGUIElement * element);
void PlayMusic(char* song, bool loop); bool IsPlayingMusic(wchar_t* music = 0);
void PlayMusic(wchar_t* music, bool loop);
void PlayBGM(int scene); void PlayBGM(int scene);
void StopBGM(); void StopBGM();
void SetSoundVolume(double volume); void SetSoundVolume(double volume);
...@@ -45,6 +60,7 @@ extern SoundManager soundManager; ...@@ -45,6 +60,7 @@ extern SoundManager soundManager;
#define SOUND_DESTROYED 108 #define SOUND_DESTROYED 108
#define SOUND_BANISHED 109 #define SOUND_BANISHED 109
#define SOUND_TOKEN 110 #define SOUND_TOKEN 110
#define SOUND_NEGATE 111
#define SOUND_ATTACK 201 #define SOUND_ATTACK 201
#define SOUND_DIRECT_ATTACK 202 #define SOUND_DIRECT_ATTACK 202
......
#[2025.4][2024.12 TCG][2025.1][2024.10][2024.7][2024.4][2024.1][2023.10][2023.7][2023.4][2023.1][2022.10][2022.7][2022.4][2022.1][2021.10][2021.7][2021.4][2021.1][2020.10][2020.7][2020.4][2020.1][2019.10][2019.7][2019.4][2019.1][2018.10][2018.7][2018.4][2018.1][2017.10][2017.7][2017.4][2017.1][2016.10][2016.7][2016.4][2016.1][2015.10][2015.4][2015.1][2014.10][2014.7][2014.4][2014.2][2013.9][2024.9 TCG][2024.4 TCG][2024.1 TCG][2023.9 TCG][2023.6 TCG][2023.2 TCG][2022.12 TCG][2022.10 TCG][2022.5 TCG][2022.2 TCG][2021.10 TCG][2021.7 TCG][2021.3 TCG][2020.12 TCG][2020.9 TCG][2020.6 TCG][2020.4 TCG][2020.1 TCG][2019.10 TCG][2019.7 TCG][2019.4 TCG][2019.1 TCG][2018.12 TCG][2018.9 TCG][2018.5 TCG][2018.2 TCG][2017.11 TCG][2017.9 TCG][2017.6 TCG][2017.3 TCG][2016.8 TCG][2016.4 TCG][2015.11 TCG][2015.7 TCG][2015.4 TCG][2015.1 TCG][2014.10 TCG][2014.7 TCG][2014.4 TCG][2014.1.1 TCG][2013.10.11 TCG][2013.3.1][2012.9.1][2012.3.1][2011.9.1] #[2025.4][2025.4 TCG][2025.1][2024.10][2024.7][2024.4][2024.1][2023.10][2023.7][2023.4][2023.1][2022.10][2022.7][2022.4][2022.1][2021.10][2021.7][2021.4][2021.1][2020.10][2020.7][2020.4][2020.1][2019.10][2019.7][2019.4][2019.1][2018.10][2018.7][2018.4][2018.1][2017.10][2017.7][2017.4][2017.1][2016.10][2016.7][2016.4][2016.1][2015.10][2015.4][2015.1][2014.10][2014.7][2014.4][2014.2][2013.9][2024.12 TCG][2024.9 TCG][2024.4 TCG][2024.1 TCG][2023.9 TCG][2023.6 TCG][2023.2 TCG][2022.12 TCG][2022.10 TCG][2022.5 TCG][2022.2 TCG][2021.10 TCG][2021.7 TCG][2021.3 TCG][2020.12 TCG][2020.9 TCG][2020.6 TCG][2020.4 TCG][2020.1 TCG][2019.10 TCG][2019.7 TCG][2019.4 TCG][2019.1 TCG][2018.12 TCG][2018.9 TCG][2018.5 TCG][2018.2 TCG][2017.11 TCG][2017.9 TCG][2017.6 TCG][2017.3 TCG][2016.8 TCG][2016.4 TCG][2015.11 TCG][2015.7 TCG][2015.4 TCG][2015.1 TCG][2014.10 TCG][2014.7 TCG][2014.4 TCG][2014.1.1 TCG][2013.10.11 TCG][2013.3.1][2012.9.1][2012.3.1][2011.9.1]
!2025.4 !2025.4
#forbidden #forbidden
20292186 0 --アーティファクト-デスサイズ 20292186 0 --アーティファクト-デスサイズ
...@@ -186,7 +186,7 @@ ...@@ -186,7 +186,7 @@
52947044 2 --フュージョン・デステニー 52947044 2 --フュージョン・デステニー
92714517 2 --ビッグウェルカム・ラビュリンス 92714517 2 --ビッグウェルカム・ラビュリンス
!2024.12 TCG !2025.4 TCG
#forbidden #forbidden
62320425 0 --Agido the Ancient Sentinel 62320425 0 --Agido the Ancient Sentinel
20292186 0 --Artifact Scythe 20292186 0 --Artifact Scythe
...@@ -207,8 +207,6 @@ ...@@ -207,8 +207,6 @@
25926710 0 --Kelbek the Ancient Vanguard 25926710 0 --Kelbek the Ancient Vanguard
57421866 0 --Level Eater 57421866 0 --Level Eater
34206604 0 --Magical Scientist 34206604 0 --Magical Scientist
21377582 0 --Master Peace, the True Dracoslaying King
36521307 0 --Mathmech Circular
23434538 0 --Maxx "C" 23434538 0 --Maxx "C"
96782886 0 --Mind Master 96782886 0 --Mind Master
23558733 0 --Phoenixian Cluster Amaryllis 23558733 0 --Phoenixian Cluster Amaryllis
...@@ -228,7 +226,9 @@ ...@@ -228,7 +226,9 @@
24094258 0 --Heavymetalfoes Electrumite 24094258 0 --Heavymetalfoes Electrumite
59934749 0 --Isolde, Two Tales of the Noble Knights 59934749 0 --Isolde, Two Tales of the Noble Knights
39064822 0 --Knightmare Goblin 39064822 0 --Knightmare Goblin
65330383 0 --Knightmare Gryphon
03679218 0 --Knightmare Mermaid 03679218 0 --Knightmare Mermaid
30342076 0 --Link Decoder
85243784 0 --Linkross 85243784 0 --Linkross
41999284 0 --Linkuriboh 41999284 0 --Linkuriboh
44097050 0 --Mecha Phantom Beast Auroradon 44097050 0 --Mecha Phantom Beast Auroradon
...@@ -245,6 +245,8 @@ ...@@ -245,6 +245,8 @@
03040496 0 --Chaos Ruler, the Chaotic Magical Dragon 03040496 0 --Chaos Ruler, the Chaotic Magical Dragon
62242678 0 --Hot Red Dragon Archfiend King Calamity 62242678 0 --Hot Red Dragon Archfiend King Calamity
63101919 0 --Tempest Magician 63101919 0 --Tempest Magician
21044178 0 --Abyss Dweller
00440556 0 --Bahamut Shark
27552504 0 --Beatrice, Lady of the Eternal 27552504 0 --Beatrice, Lady of the Eternal
48626373 0 --Kashtira Arise-Heart 48626373 0 --Kashtira Arise-Heart
34086406 0 --Lavalval Chain 34086406 0 --Lavalval Chain
...@@ -260,7 +262,6 @@ ...@@ -260,7 +262,6 @@
81122844 0 --Wind-Up Carrier Zenmaity 81122844 0 --Wind-Up Carrier Zenmaity
85115440 0 --Zoodiac Broadbull 85115440 0 --Zoodiac Broadbull
48905153 0 --Zoodiac Drident 48905153 0 --Zoodiac Drident
07394770 0 --Brilliant Fusion
69243953 0 --Butterfly Dagger - Elma 69243953 0 --Butterfly Dagger - Elma
57953380 0 --Card of Safe Return 57953380 0 --Card of Safe Return
60682203 0 --Cold Wave 60682203 0 --Cold Wave
...@@ -303,25 +304,23 @@ ...@@ -303,25 +304,23 @@
08124921 1 --Right Leg of the Forbidden One 08124921 1 --Right Leg of the Forbidden One
06728559 1 --Archnemeses Protos 06728559 1 --Archnemeses Protos
76794549 1 --Astrograph Sorcerer 76794549 1 --Astrograph Sorcerer
61901281 1 --Black Dragon Collapserpent 06637331 1 --Bystial Druiswurm
33854624 1 --Bystial Magnamhut 33854624 1 --Bystial Magnamhut
14536035 1 --Dark Grepher 14536035 1 --Dark Grepher
91800273 1 --Dimension Shifter
33396948 1 --Exodia the Forbidden One 33396948 1 --Exodia the Forbidden One
63542003 1 --Keldo the Sacred Protector 63542003 1 --Keldo the Sacred Protector
21377582 1 --Master Peace, the True Dracoslaying King
36521307 1 --Mathmech Circular
38572779 1 --Miscellaneousaurus 38572779 1 --Miscellaneousaurus
33508719 1 --Morphing Jar
99937011 1 --Mudora the Sword Oracle 99937011 1 --Mudora the Sword Oracle
12958919 1 --Phantom Skyblaster 12958919 1 --Phantom Skyblaster
38814750 1 --PSY-Framegear Gamma 38814750 1 --PSY-Framegear Gamma
09674034 1 --Snake-Eye Ash
90241276 1 --Snake-Eyes Poplar
20663556 1 --Substitoad 20663556 1 --Substitoad
37961969 1 --Tearlaments Havnis 37961969 1 --Tearlaments Havnis
74078255 1 --Tearlaments Merrli 74078255 1 --Tearlaments Merrli
00572850 1 --Tearlaments Scheiren 00572850 1 --Tearlaments Scheiren
91810826 1 --Tenpai Dragon Chundra 91810826 1 --Tenpai Dragon Chundra
41165831 1 --Unchained Soul of Sharvara
99234526 1 --White Dragon Wyverburster
78872731 1 --Zoodiac Ratpier 78872731 1 --Zoodiac Ratpier
39512984 1 --Gem-Knight Master Diamond 39512984 1 --Gem-Knight Master Diamond
80453041 1 --Phantom of Yubel 80453041 1 --Phantom of Yubel
...@@ -333,7 +332,10 @@ ...@@ -333,7 +332,10 @@
00581014 1 --Daigusto Emeral 00581014 1 --Daigusto Emeral
75433814 1 --Number 40: Gimmick Puppet of Strings 75433814 1 --Number 40: Gimmick Puppet of Strings
69170557 1 --Number C40: Gimmick Puppet of Dark Strings 69170557 1 --Number C40: Gimmick Puppet of Dark Strings
34909328 1 --Ryzeal Detonator
85106525 1 --Bonfire
44362883 1 --Branded Fusion 44362883 1 --Branded Fusion
07394770 1 --Brilliant Fusion
24224830 1 --Called by the Grave 24224830 1 --Called by the Grave
72892473 1 --Card Destruction 72892473 1 --Card Destruction
59750328 1 --Card of Demise 59750328 1 --Card of Demise
...@@ -341,6 +343,7 @@ ...@@ -341,6 +343,7 @@
04031928 1 --Change of Heart 04031928 1 --Change of Heart
99266988 1 --Chaos Space 99266988 1 --Chaos Space
67616300 1 --Chicken Game 67616300 1 --Chicken Game
65681983 1 --Crossout Designator
15854426 1 --Divine Wind of Mist Valley 15854426 1 --Divine Wind of Mist Valley
13035077 1 --Dragonic Diagram 13035077 1 --Dragonic Diagram
95308449 1 --Final Countdown 95308449 1 --Final Countdown
...@@ -368,6 +371,7 @@ ...@@ -368,6 +371,7 @@
45986603 1 --Snatch Steal 45986603 1 --Snatch Steal
73628505 1 --Terraforming 73628505 1 --Terraforming
11110587 1 --That Grass Looks Greener 11110587 1 --That Grass Looks Greener
25311006 1 --Triple Tactics Talent
46060017 1 --Zoodiac Barrage 46060017 1 --Zoodiac Barrage
58921041 1 --Anti-Spell Fragrance 58921041 1 --Anti-Spell Fragrance
53334471 1 --Gozen Match 53334471 1 --Gozen Match
...@@ -377,12 +381,19 @@ ...@@ -377,12 +381,19 @@
82732705 1 --Skill Drain 82732705 1 --Skill Drain
24207889 1 --There Can Be Only One 24207889 1 --There Can Be Only One
#semi limit #semi limit
34124316 2 --Cyber Jar 61901281 2 --Black Dragon Collapserpent
43694650 2 --Danger!? Jackalope? 34022970 2 --Ext Ryzeal
99745551 2 --Danger!? Tsuchinoko? 08633261 2 --Ice Ryzeal
40177746 2 --Eva 32061192 2 --Maliss <P> Dormouse
17330916 2 --Performapal Monkeyboard 69272449 2 --Maliss <P> White Rabbit
33508719 2 --Morphing Jar
09674034 2 --Snake-Eye Ash
90241276 2 --Snake-Eyes Poplar
35844557 2 --Sword Ryzeal
41165831 2 --Unchained Soul of Sharvara
99234526 2 --White Dragon Wyverburster
14532163 2 --Lightning Storm 14532163 2 --Lightning Storm
68337209 2 --Maliss in Underground
55584558 2 --Purrely Delicious Memory 55584558 2 --Purrely Delicious Memory
21347668 2 --Purrely Sleepy Memory 21347668 2 --Purrely Sleepy Memory
92107604 2 --Runick Fountain 92107604 2 --Runick Fountain
...@@ -8132,6 +8143,207 @@ ...@@ -8132,6 +8143,207 @@
53582587 2 --激流葬 53582587 2 --激流葬
29401950 2 --奈落の落とし穴 29401950 2 --奈落の落とし穴
!2024.12 TCG
#forbidden
62320425 0 --Agido the Ancient Sentinel
20292186 0 --Artifact Scythe
73356503 0 --Barrier Statue of the Stormwinds
09929398 0 --Blackwing - Gofu the Vague Shadow
94689206 0 --Block Dragon
69015963 0 --Cyber-Stein
15341821 0 --Dandylion
08903700 0 --Djinn Releaser of Rituals
51858306 0 --Eclipse Wyvern
55623480 0 --Fairy Tail - Snow
78706415 0 --Fiber Jar
93369354 0 --Fishborg Blaster
55204071 0 --Gimmick Puppet Nightmare
67441435 0 --Glow-Up Bulb
75732622 0 --Grinder Golem
41855169 0 --Jowgen the Spiritualist
25926710 0 --Kelbek the Ancient Vanguard
57421866 0 --Level Eater
34206604 0 --Magical Scientist
21377582 0 --Master Peace, the True Dracoslaying King
36521307 0 --Mathmech Circular
23434538 0 --Maxx "C"
96782886 0 --Mind Master
23558733 0 --Phoenixian Cluster Amaryllis
01357146 0 --Ronintoadin
91258852 0 --SPYRAL Master Plan
88071625 0 --The Tyrant Neptune
44910027 0 --Victory Dragon
17412721 0 --Elder Entity Norden
46640168 0 --Fiendsmith's Lacrima
43387895 0 --Supreme King Dragon Starving Venom
92731385 0 --Tearlaments Kitkallos
04280258 0 --Apollousa, Bow of the Goddess
50588353 0 --Crystron Halqifibrax
98095162 0 --Curious, the Lightsworn Dominion
59537380 0 --Guardragon Agarpain
86148577 0 --Guardragon Elpy
24094258 0 --Heavymetalfoes Electrumite
59934749 0 --Isolde, Two Tales of the Noble Knights
39064822 0 --Knightmare Goblin
03679218 0 --Knightmare Mermaid
85243784 0 --Linkross
41999284 0 --Linkuriboh
44097050 0 --Mecha Phantom Beast Auroradon
25725326 0 --Prank-Kids Meow-Meow-Mu
70369116 0 --Predaplant Verte Anaconda
72330894 0 --Simorgh, Bird of Sovereignty
27381364 0 --Spright Elf
61665245 0 --Summon Sorceress
33918636 0 --Superheavy Samurai Scarecrow
22593417 0 --Topologic Gumblar Dragon
83152482 0 --Union Carrier
84815190 0 --Baronne de Fleur
27548199 0 --Borreload Savage Dragon
03040496 0 --Chaos Ruler, the Chaotic Magical Dragon
62242678 0 --Hot Red Dragon Archfiend King Calamity
63101919 0 --Tempest Magician
27552504 0 --Beatrice, Lady of the Eternal
48626373 0 --Kashtira Arise-Heart
34086406 0 --Lavalval Chain
04423206 0 --M-X-Saber Invoker
54719828 0 --Number 16: Shock Master
10389142 0 --Number 42: Galaxy Tomahawk
63504681 0 --Number 86: Heroic Champion - Rhongomyniad
95474755 0 --Number 89: Diablosis the Mind Hacker
58820923 0 --Number 95: Galaxy-Eyes Dark Matter Dragon
52653092 0 --Number S0: Utopic ZEXAL
34945480 0 --Outer Entity Azathot
88581108 0 --True King of All Calamities
81122844 0 --Wind-Up Carrier Zenmaity
85115440 0 --Zoodiac Broadbull
48905153 0 --Zoodiac Drident
07394770 0 --Brilliant Fusion
69243953 0 --Butterfly Dagger - Elma
57953380 0 --Card of Safe Return
60682203 0 --Cold Wave
17375316 0 --Confiscation
44763025 0 --Delinquent Duo
23557835 0 --Dimension Fusion
42703248 0 --Giant Trunade
79571449 0 --Graceful Charity
19613556 0 --Heavy Storm
35059553 0 --Kaiser Colosseum
85602018 0 --Last Will
34906152 0 --Mass Driver
46411259 0 --Metamorphosis
41482598 0 --Mirage of Nightmare
76375976 0 --Mystic Mine
89023486 0 --Original Sinful Spoils - Snake-Eye
74191942 0 --Painful Choice
55144522 0 --Pot of Greed
70828912 0 --Premature Burial
63789924 0 --Smoke Grenade of the Thief
54447022 0 --Soul Charge
42829885 0 --The Forceful Sentry
43262273 0 --Appointer of the Red Lotus
01041278 0 --Branded Expulsion
61740673 0 --Imperial Order
28566710 0 --Last Turn
23002292 0 --Red Reboot
27174286 0 --Return from the Different Dimension
93016201 0 --Royal Oppression
57585212 0 --Self-Destruct Button
03280747 0 --Sixth Sense
23516703 0 --Summon Limit
64697231 0 --Trap Dustshoot
80604091 0 --Ultimate Offering
05851097 0 --Vanity's Emptiness
#limit
07902349 1 --Left Arm of the Forbidden One
44519536 1 --Left Leg of the Forbidden One
70903634 1 --Right Arm of the Forbidden One
08124921 1 --Right Leg of the Forbidden One
06728559 1 --Archnemeses Protos
76794549 1 --Astrograph Sorcerer
61901281 1 --Black Dragon Collapserpent
33854624 1 --Bystial Magnamhut
14536035 1 --Dark Grepher
33396948 1 --Exodia the Forbidden One
63542003 1 --Keldo the Sacred Protector
38572779 1 --Miscellaneousaurus
33508719 1 --Morphing Jar
99937011 1 --Mudora the Sword Oracle
12958919 1 --Phantom Skyblaster
38814750 1 --PSY-Framegear Gamma
09674034 1 --Snake-Eye Ash
90241276 1 --Snake-Eyes Poplar
20663556 1 --Substitoad
37961969 1 --Tearlaments Havnis
74078255 1 --Tearlaments Merrli
00572850 1 --Tearlaments Scheiren
91810826 1 --Tenpai Dragon Chundra
41165831 1 --Unchained Soul of Sharvara
99234526 1 --White Dragon Wyverburster
78872731 1 --Zoodiac Ratpier
39512984 1 --Gem-Knight Master Diamond
80453041 1 --Phantom of Yubel
73539069 1 --Striker Dragon
93896655 1 --Sunavalon Dryas
65563871 1 --Sunvine Healer
74586817 1 --PSY-Framelord Omega
90953320 1 --T.G. Hyper Librarian
00581014 1 --Daigusto Emeral
75433814 1 --Number 40: Gimmick Puppet of Strings
69170557 1 --Number C40: Gimmick Puppet of Dark Strings
44362883 1 --Branded Fusion
24224830 1 --Called by the Grave
72892473 1 --Card Destruction
59750328 1 --Card of Demise
91623717 1 --Chain Strike
04031928 1 --Change of Heart
99266988 1 --Chaos Space
67616300 1 --Chicken Game
15854426 1 --Divine Wind of Mist Valley
13035077 1 --Dragonic Diagram
95308449 1 --Final Countdown
81439173 1 --Foolish Burial
27970830 1 --Gateway of the Six
75500286 1 --Gold Sarcophagus
18144506 1 --Harpie's Feather Duster
66957584 1 --Infernity Launcher
01845204 1 --Instant Fusion
93946239 1 --Into the Void
71650854 1 --Magical Mid-Breaker Field
43040603 1 --Monster Gate
83764718 1 --Monster Reborn
33782437 1 --One Day of Peace
02295440 1 --One for One
84211599 1 --Pot of Prosperity
58577036 1 --Reasoning
32807846 1 --Reinforcement of the Army
66730191 1 --Sangen Kaimen
30336082 1 --Sangen Summoning
24940422 1 --Sekka's Light
73468603 1 --Set Rotation
52340444 1 --Sky Striker Mecha - Hornet Drones
71344451 1 --Slash Draw
45986603 1 --Snatch Steal
73628505 1 --Terraforming
11110587 1 --That Grass Looks Greener
46060017 1 --Zoodiac Barrage
58921041 1 --Anti-Spell Fragrance
53334471 1 --Gozen Match
32723153 1 --Magical Explosion
03734202 1 --Naturia Sacred Tree
90846359 1 --Rivalry of Warlords
82732705 1 --Skill Drain
24207889 1 --There Can Be Only One
#semi limit
34124316 2 --Cyber Jar
43694650 2 --Danger!? Jackalope?
99745551 2 --Danger!? Tsuchinoko?
40177746 2 --Eva
17330916 2 --Performapal Monkeyboard
14532163 2 --Lightning Storm
55584558 2 --Purrely Delicious Memory
21347668 2 --Purrely Sleepy Memory
92107604 2 --Runick Fountain
!2024.9 TCG !2024.9 TCG
#forbidden #forbidden
62320425 0 --Agido the Ancient Sentinel 62320425 0 --Agido the Ancient Sentinel
......
Subproject commit 74c7c053a393f397758c798e2860ab5972b56338 Subproject commit 283c1d74b4f427beecf2738ee3f85ab99a675124
...@@ -11,3 +11,4 @@ project "event" ...@@ -11,3 +11,4 @@ project "event"
filter "system:windows" filter "system:windows"
prebuildcommands { "xcopy /E /Y $(ProjectDir)..\\event\\WIN32-Code $(ProjectDir)..\\event\\include" } prebuildcommands { "xcopy /E /Y $(ProjectDir)..\\event\\WIN32-Code $(ProjectDir)..\\event\\include" }
files { "win32select.c", "evthread_win32.c", "buffer_iocp.c", "event_iocp.c", "bufferevent_async.c" } files { "win32select.c", "evthread_win32.c", "buffer_iocp.c", "event_iocp.c", "bufferevent_async.c" }
defines { "WIN32" } -- quirk of old libevent
defines {
"_IRR_STATIC_LIB_",
"NO_IRR_USE_NON_SYSTEM_BZLIB_",
"NO_IRR_COMPILE_WITH_BZIP2_",
"NO_IRR_COMPILE_WITH_CONSOLE_DEVICE_",
"NO_IRR_COMPILE_WITH_DIRECT3D_8_",
"NO_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_",
"NO_IRR_COMPILE_WITH_JOYSTICK_EVENTS_",
"NO_IRR_COMPILE_WITH_SOFTWARE_",
"NO_IRR_COMPILE_WITH_BURNINGSVIDEO_",
"NO_IRR_COMPILE_WITH_IRR_SCENE_LOADER_",
"NO_IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_",
"NO_IRR_COMPILE_WITH_IRR_MESH_LOADER_",
"NO_IRR_COMPILE_WITH_HALFLIFE_LOADER_",
"NO_IRR_COMPILE_WITH_MD2_LOADER_",
"NO_IRR_COMPILE_WITH_MD3_LOADER_",
"NO_IRR_COMPILE_WITH_3DS_LOADER_",
"NO_IRR_COMPILE_WITH_COLLADA_LOADER_",
"NO_IRR_COMPILE_WITH_CSM_LOADER_",
"NO_IRR_COMPILE_WITH_BSP_LOADER_",
"NO_IRR_COMPILE_WITH_DMF_LOADER_",
"NO_IRR_COMPILE_WITH_LMTS_LOADER_",
"NO_IRR_COMPILE_WITH_MY3D_LOADER_",
"NO_IRR_COMPILE_WITH_OBJ_LOADER_",
"NO_IRR_COMPILE_WITH_OCT_LOADER_",
"NO_IRR_COMPILE_WITH_LWO_LOADER_",
"NO_IRR_COMPILE_WITH_STL_LOADER_",
"NO_IRR_COMPILE_WITH_PLY_LOADER_",
"NO_IRR_COMPILE_WITH_SMF_LOADER_",
"NO_IRR_COMPILE_WITH_IRR_WRITER_",
"NO_IRR_COMPILE_WITH_COLLADA_WRITER_",
"NO_IRR_COMPILE_WITH_STL_WRITER_",
"NO_IRR_COMPILE_WITH_OBJ_WRITER_",
"NO_IRR_COMPILE_WITH_PLY_WRITER_",
"NO_IRR_COMPILE_WITH_PCX_LOADER_",
"NO_IRR_COMPILE_WITH_PPM_LOADER_",
"NO_IRR_COMPILE_WITH_PSD_LOADER_",
"NO_IRR_COMPILE_WITH_TGA_LOADER_",
"NO_IRR_COMPILE_WITH_WAL_LOADER_",
"NO_IRR_COMPILE_WITH_LMP_LOADER_",
"NO_IRR_COMPILE_WITH_RGB_LOADER_",
"NO_IRR_COMPILE_WITH_PCX_WRITER_",
"NO_IRR_COMPILE_WITH_PPM_WRITER_",
"NO_IRR_COMPILE_WITH_PSD_WRITER_",
"NO_IRR_COMPILE_WITH_TGA_WRITER_",
"NO__IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_",
"NO__IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_",
"NO__IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_",
}
...@@ -39,3 +39,6 @@ project "irrlicht" ...@@ -39,3 +39,6 @@ project "irrlicht"
filter { "system:windows" } filter { "system:windows" }
defines { "_IRR_WCHAR_FILESYSTEM" } defines { "_IRR_WCHAR_FILESYSTEM" }
filter { "system:macosx" }
cppdialect "gnu++14"
project "irrlicht" project "irrlicht"
kind "StaticLib" kind "StaticLib"
includedirs { "include", "source/Irrlicht", "source/Irrlicht/jpeglib", "source/Irrlicht/libpng", "source/Irrlicht/zlib" } includedirs {
"include",
dofile("defines.lua") "source/Irrlicht",
"source/Irrlicht/jpeglib",
"source/Irrlicht/libpng",
"source/Irrlicht/zlib"
}
exceptionhandling "Off" exceptionhandling "Off"
rtti "Off" rtti "Off"
files { "include/*.h", defines {
"source/Irrlicht/*.cpp", "_IRR_STATIC_LIB_",
"source/Irrlicht/lzma/*.h", "NO_IRR_USE_NON_SYSTEM_BZLIB_",
"source/Irrlicht/lzma/*.c", "NO_IRR_COMPILE_WITH_BZIP2_",
"source/Irrlicht/zlib/zlib.h", "NO_IRR_COMPILE_WITH_CONSOLE_DEVICE_",
"source/Irrlicht/zlib/adler32.c", "NO_IRR_COMPILE_WITH_DIRECT3D_8_",
"source/Irrlicht/zlib/compress.c", "NO_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_",
"source/Irrlicht/zlib/crc32.h", "NO_IRR_COMPILE_WITH_JOYSTICK_EVENTS_",
"source/Irrlicht/zlib/crc32.c", "NO_IRR_COMPILE_WITH_SOFTWARE_",
"source/Irrlicht/zlib/deflate.h", "NO_IRR_COMPILE_WITH_BURNINGSVIDEO_",
"source/Irrlicht/zlib/deflate.c", "NO_IRR_COMPILE_WITH_IRR_SCENE_LOADER_",
"source/Irrlicht/zlib/inffast.h", "NO_IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_",
"source/Irrlicht/zlib/inffast.c", "NO_IRR_COMPILE_WITH_IRR_MESH_LOADER_",
"source/Irrlicht/zlib/inflate.h", "NO_IRR_COMPILE_WITH_HALFLIFE_LOADER_",
"source/Irrlicht/zlib/inflate.c", "NO_IRR_COMPILE_WITH_MD2_LOADER_",
"source/Irrlicht/zlib/inftrees.h", "NO_IRR_COMPILE_WITH_MD3_LOADER_",
"source/Irrlicht/zlib/inftrees.c", "NO_IRR_COMPILE_WITH_3DS_LOADER_",
"source/Irrlicht/zlib/trees.h", "NO_IRR_COMPILE_WITH_COLLADA_LOADER_",
"source/Irrlicht/zlib/trees.c", "NO_IRR_COMPILE_WITH_CSM_LOADER_",
"source/Irrlicht/zlib/uncompr.c", "NO_IRR_COMPILE_WITH_BSP_LOADER_",
"source/Irrlicht/zlib/zutil.h", "NO_IRR_COMPILE_WITH_DMF_LOADER_",
"source/Irrlicht/zlib/zutil.c", "NO_IRR_COMPILE_WITH_LMTS_LOADER_",
"source/Irrlicht/jpeglib/jaricom.c", "NO_IRR_COMPILE_WITH_MY3D_LOADER_",
"source/Irrlicht/jpeglib/jcapimin.c", "NO_IRR_COMPILE_WITH_OBJ_LOADER_",
"source/Irrlicht/jpeglib/jcapistd.c", "NO_IRR_COMPILE_WITH_OCT_LOADER_",
"source/Irrlicht/jpeglib/jcarith.c", "NO_IRR_COMPILE_WITH_LWO_LOADER_",
"source/Irrlicht/jpeglib/jccoefct.c", "NO_IRR_COMPILE_WITH_STL_LOADER_",
"source/Irrlicht/jpeglib/jccolor.c", "NO_IRR_COMPILE_WITH_PLY_LOADER_",
"source/Irrlicht/jpeglib/jcdctmgr.c", "NO_IRR_COMPILE_WITH_SMF_LOADER_",
"source/Irrlicht/jpeglib/jchuff.c", "NO_IRR_COMPILE_WITH_IRR_WRITER_",
"source/Irrlicht/jpeglib/jcinit.c", "NO_IRR_COMPILE_WITH_COLLADA_WRITER_",
"source/Irrlicht/jpeglib/jcmainct.c", "NO_IRR_COMPILE_WITH_STL_WRITER_",
"source/Irrlicht/jpeglib/jcmarker.c", "NO_IRR_COMPILE_WITH_OBJ_WRITER_",
"source/Irrlicht/jpeglib/jcmaster.c", "NO_IRR_COMPILE_WITH_PLY_WRITER_",
"source/Irrlicht/jpeglib/jcomapi.c", "NO_IRR_COMPILE_WITH_PCX_LOADER_",
"source/Irrlicht/jpeglib/jcparam.c", "NO_IRR_COMPILE_WITH_PPM_LOADER_",
"source/Irrlicht/jpeglib/jcprepct.c", "NO_IRR_COMPILE_WITH_PSD_LOADER_",
"source/Irrlicht/jpeglib/jcsample.c", "NO_IRR_COMPILE_WITH_TGA_LOADER_",
"source/Irrlicht/jpeglib/jctrans.c", "NO_IRR_COMPILE_WITH_WAL_LOADER_",
"source/Irrlicht/jpeglib/jdapimin.c", "NO_IRR_COMPILE_WITH_LMP_LOADER_",
"source/Irrlicht/jpeglib/jdapistd.c", "NO_IRR_COMPILE_WITH_RGB_LOADER_",
"source/Irrlicht/jpeglib/jdarith.c", "NO_IRR_COMPILE_WITH_PCX_WRITER_",
"source/Irrlicht/jpeglib/jdatadst.c", "NO_IRR_COMPILE_WITH_PPM_WRITER_",
"source/Irrlicht/jpeglib/jdatasrc.c", "NO_IRR_COMPILE_WITH_PSD_WRITER_",
"source/Irrlicht/jpeglib/jdcoefct.c", "NO_IRR_COMPILE_WITH_TGA_WRITER_",
"source/Irrlicht/jpeglib/jdcolor.c", "NO__IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_",
"source/Irrlicht/jpeglib/jddctmgr.c", "NO__IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_",
"source/Irrlicht/jpeglib/jdhuff.c", "NO__IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_",
"source/Irrlicht/jpeglib/jdinput.c", "NO_IRR_COMPILE_WITH_ZIP_ENCRYPTION_",
"source/Irrlicht/jpeglib/jdmainct.c", "PNG_INTEL_SSE",
"source/Irrlicht/jpeglib/jdmarker.c", "PNG_ARM_NEON_OPT=0",
"source/Irrlicht/jpeglib/jdmaster.c", "PNG_ARM_NEON_IMPLEMENTATION=0",
"source/Irrlicht/jpeglib/jdmerge.c", }
"source/Irrlicht/jpeglib/jdpostct.c",
"source/Irrlicht/jpeglib/jdsample.c", files {
"source/Irrlicht/jpeglib/jdtrans.c", "include/*.h",
"source/Irrlicht/jpeglib/jerror.c", "source/Irrlicht/*.cpp",
"source/Irrlicht/jpeglib/jfdctflt.c", "source/Irrlicht/zlib/zlib.h",
"source/Irrlicht/jpeglib/jfdctfst.c", "source/Irrlicht/zlib/adler32.c",
"source/Irrlicht/jpeglib/jfdctint.c", "source/Irrlicht/zlib/compress.c",
"source/Irrlicht/jpeglib/jidctflt.c", "source/Irrlicht/zlib/crc32.h",
"source/Irrlicht/jpeglib/jidctfst.c", "source/Irrlicht/zlib/crc32.c",
"source/Irrlicht/jpeglib/jidctint.c", "source/Irrlicht/zlib/deflate.h",
"source/Irrlicht/jpeglib/jmemmgr.c", "source/Irrlicht/zlib/deflate.c",
"source/Irrlicht/jpeglib/jmemnobs.c", "source/Irrlicht/zlib/inffast.h",
"source/Irrlicht/jpeglib/jquant1.c", "source/Irrlicht/zlib/inffast.c",
"source/Irrlicht/jpeglib/jquant2.c", "source/Irrlicht/zlib/inflate.h",
"source/Irrlicht/jpeglib/jutils.c", "source/Irrlicht/zlib/inflate.c",
"source/Irrlicht/libpng/png.c", "source/Irrlicht/zlib/inftrees.h",
"source/Irrlicht/libpng/pngerror.c", "source/Irrlicht/zlib/inftrees.c",
"source/Irrlicht/libpng/pngget.c", "source/Irrlicht/zlib/trees.h",
"source/Irrlicht/libpng/pngmem.c", "source/Irrlicht/zlib/trees.c",
"source/Irrlicht/libpng/pngpread.c", "source/Irrlicht/zlib/uncompr.c",
"source/Irrlicht/libpng/pngread.c", "source/Irrlicht/zlib/zutil.h",
"source/Irrlicht/libpng/pngrio.c", "source/Irrlicht/zlib/zutil.c",
"source/Irrlicht/libpng/pngrtran.c", "source/Irrlicht/jpeglib/jaricom.c",
"source/Irrlicht/libpng/pngrutil.c", "source/Irrlicht/jpeglib/jcapimin.c",
"source/Irrlicht/libpng/pngset.c", "source/Irrlicht/jpeglib/jcapistd.c",
"source/Irrlicht/libpng/pngtrans.c", "source/Irrlicht/jpeglib/jcarith.c",
"source/Irrlicht/libpng/pngwio.c", "source/Irrlicht/jpeglib/jccoefct.c",
"source/Irrlicht/libpng/pngwrite.c", "source/Irrlicht/jpeglib/jccolor.c",
"source/Irrlicht/libpng/pngwtran.c", "source/Irrlicht/jpeglib/jcdctmgr.c",
"source/Irrlicht/libpng/pngwutil.c", "source/Irrlicht/jpeglib/jchuff.c",
"source/Irrlicht/aesGladman/*.h", "source/Irrlicht/jpeglib/jcinit.c",
"source/Irrlicht/aesGladman/*.cpp" } "source/Irrlicht/jpeglib/jcmainct.c",
"source/Irrlicht/jpeglib/jcmarker.c",
"source/Irrlicht/jpeglib/jcmaster.c",
"source/Irrlicht/jpeglib/jcomapi.c",
"source/Irrlicht/jpeglib/jcparam.c",
"source/Irrlicht/jpeglib/jcprepct.c",
"source/Irrlicht/jpeglib/jcsample.c",
"source/Irrlicht/jpeglib/jctrans.c",
"source/Irrlicht/jpeglib/jdapimin.c",
"source/Irrlicht/jpeglib/jdapistd.c",
"source/Irrlicht/jpeglib/jdarith.c",
"source/Irrlicht/jpeglib/jdatadst.c",
"source/Irrlicht/jpeglib/jdatasrc.c",
"source/Irrlicht/jpeglib/jdcoefct.c",
"source/Irrlicht/jpeglib/jdcolor.c",
"source/Irrlicht/jpeglib/jddctmgr.c",
"source/Irrlicht/jpeglib/jdhuff.c",
"source/Irrlicht/jpeglib/jdinput.c",
"source/Irrlicht/jpeglib/jdmainct.c",
"source/Irrlicht/jpeglib/jdmarker.c",
"source/Irrlicht/jpeglib/jdmaster.c",
"source/Irrlicht/jpeglib/jdmerge.c",
"source/Irrlicht/jpeglib/jdpostct.c",
"source/Irrlicht/jpeglib/jdsample.c",
"source/Irrlicht/jpeglib/jdtrans.c",
"source/Irrlicht/jpeglib/jerror.c",
"source/Irrlicht/jpeglib/jfdctflt.c",
"source/Irrlicht/jpeglib/jfdctfst.c",
"source/Irrlicht/jpeglib/jfdctint.c",
"source/Irrlicht/jpeglib/jidctflt.c",
"source/Irrlicht/jpeglib/jidctfst.c",
"source/Irrlicht/jpeglib/jidctint.c",
"source/Irrlicht/jpeglib/jmemmgr.c",
"source/Irrlicht/jpeglib/jmemnobs.c",
"source/Irrlicht/jpeglib/jquant1.c",
"source/Irrlicht/jpeglib/jquant2.c",
"source/Irrlicht/jpeglib/jutils.c",
"source/Irrlicht/libpng/png.c",
"source/Irrlicht/libpng/pngerror.c",
"source/Irrlicht/libpng/pngget.c",
"source/Irrlicht/libpng/pngmem.c",
"source/Irrlicht/libpng/pngpread.c",
"source/Irrlicht/libpng/pngread.c",
"source/Irrlicht/libpng/pngrio.c",
"source/Irrlicht/libpng/pngrtran.c",
"source/Irrlicht/libpng/pngrutil.c",
"source/Irrlicht/libpng/pngset.c",
"source/Irrlicht/libpng/pngtrans.c",
"source/Irrlicht/libpng/pngwio.c",
"source/Irrlicht/libpng/pngwrite.c",
"source/Irrlicht/libpng/pngwtran.c",
"source/Irrlicht/libpng/pngwutil.c",
"source/Irrlicht/libpng/intel/intel_init.c",
"source/Irrlicht/libpng/intel/filter_sse2_intrinsics.c",
}
filter { "system:windows" } filter { "system:windows" }
defines { "_IRR_WCHAR_FILESYSTEM" } defines { "_IRR_WCHAR_FILESYSTEM" }
includedirs { "$(DXSDK_DIR)Include" } includedirs { "$(DXSDK_DIR)Include" }
libdirs { "$(DXSDK_DIR)Lib/x86" }
links { "imm32" }
filter { "system:linux" } filter { "system:linux" }
links { "X11", "Xxf86vm" } links { "X11", "Xxf86vm" }
filter { "system:macosx" }
cppdialect "gnu++14"
defines { "GL_SILENCE_DEPRECATION" }
undefines { "NO_IRR_COMPILE_WITH_JOYSTICK_EVENTS_" }
files {
"source/Irrlicht/MacOSX/*.mm",
"source/Irrlicht/MacOSX/*.h",
}
filter { "system:macosx", "files:source/Irrlicht/Irrlicht.cpp or source/Irrlicht/COpenGLDriver.cpp" }
compileas "Objective-C++"
project "miniaudio"
kind "StaticLib"
files { "miniaudio.c", "miniaudio.h" }
defines { "MA_NO_ENCODING", "MA_NO_GENERATION", "MA_NO_NEON" }
if MINIAUDIO_SUPPORT_OPUS_VORBIS then
files { "extras/decoders/libopus/*", "extras/decoders/libvorbis/*" }
if MINIAUDIO_BUILD_OPUS_VORBIS then
files {
"external/ogg/src/bitwise.c",
"external/ogg/src/framing.c",
"external/opus/src/opus.c",
"external/opus/src/opus_decoder.c",
"external/opus/src/opus_multistream.c",
"external/opus/src/opus_multistream_decoder.c",
"external/opus/celt/bands.c",
"external/opus/celt/celt.c",
"external/opus/celt/celt_decoder.c",
"external/opus/celt/celt_lpc.c",
"external/opus/celt/cwrs.c",
"external/opus/celt/entcode.c",
"external/opus/celt/entdec.c",
"external/opus/celt/entenc.c",
"external/opus/celt/kiss_fft.c",
"external/opus/celt/laplace.c",
"external/opus/celt/mathops.c",
"external/opus/celt/mdct.c",
"external/opus/celt/modes.c",
"external/opus/celt/pitch.c",
"external/opus/celt/quant_bands.c",
"external/opus/celt/rate.c",
"external/opus/celt/vq.c",
"external/opus/celt/x86/pitch_avx.c",
"external/opus/celt/x86/pitch_sse.c",
"external/opus/celt/x86/vq_sse2.c",
"external/opus/celt/x86/x86_celt_map.c",
"external/opus/celt/x86/x86cpu.c",
"external/opus/silk/bwexpander.c",
"external/opus/silk/bwexpander_32.c",
"external/opus/silk/CNG.c",
"external/opus/silk/code_signs.c",
"external/opus/silk/dec_API.c",
"external/opus/silk/decode_core.c",
"external/opus/silk/decode_frame.c",
"external/opus/silk/decode_indices.c",
"external/opus/silk/decode_parameters.c",
"external/opus/silk/decode_pitch.c",
"external/opus/silk/decode_pulses.c",
"external/opus/silk/decoder_set_fs.c",
"external/opus/silk/gain_quant.c",
"external/opus/silk/init_decoder.c",
"external/opus/silk/lin2log.c",
"external/opus/silk/log2lin.c",
"external/opus/silk/LPC_analysis_filter.c",
"external/opus/silk/LPC_fit.c",
"external/opus/silk/LPC_inv_pred_gain.c",
"external/opus/silk/NLSF_decode.c",
"external/opus/silk/NLSF_stabilize.c",
"external/opus/silk/NLSF_unpack.c",
"external/opus/silk/NLSF2A.c",
"external/opus/silk/pitch_est_tables.c",
"external/opus/silk/PLC.c",
"external/opus/silk/resampler.c",
"external/opus/silk/resampler_private_AR2.c",
"external/opus/silk/resampler_private_down_FIR.c",
"external/opus/silk/resampler_private_IIR_FIR.c",
"external/opus/silk/resampler_private_up2_HQ.c",
"external/opus/silk/resampler_rom.c",
"external/opus/silk/shell_coder.c",
"external/opus/silk/sort.c",
"external/opus/silk/stereo_decode_pred.c",
"external/opus/silk/stereo_MS_to_LR.c",
"external/opus/silk/sum_sqr_shift.c",
"external/opus/silk/table_LSF_cos.c",
"external/opus/silk/tables_gain.c",
"external/opus/silk/tables_LTP.c",
"external/opus/silk/tables_NLSF_CB_NB_MB.c",
"external/opus/silk/tables_NLSF_CB_WB.c",
"external/opus/silk/tables_other.c",
"external/opus/silk/tables_pitch_lag.c",
"external/opus/silk/tables_pulses_per_block.c",
"external/opusfile/src/info.c",
"external/opusfile/src/internal.c",
"external/opusfile/src/opusfile.c",
"external/opusfile/src/stream.c",
"external/vorbis/lib/bitrate.c",
"external/vorbis/lib/block.c",
"external/vorbis/lib/codebook.c",
"external/vorbis/lib/envelope.c",
"external/vorbis/lib/floor0.c",
"external/vorbis/lib/floor1.c",
"external/vorbis/lib/info.c",
"external/vorbis/lib/lpc.c",
"external/vorbis/lib/lsp.c",
"external/vorbis/lib/mapping0.c",
"external/vorbis/lib/mdct.c",
"external/vorbis/lib/psy.c",
"external/vorbis/lib/registry.c",
"external/vorbis/lib/res0.c",
"external/vorbis/lib/sharedbook.c",
"external/vorbis/lib/smallft.c",
"external/vorbis/lib/synthesis.c",
"external/vorbis/lib/vorbisfile.c",
"external/vorbis/lib/window.c",
}
includedirs {
"external/ogg/include",
"external/opus/include",
"external/opus/celt",
"external/opus/silk",
"external/opusfile/include",
"external/vorbis/include",
}
defines {
"OPUS_BUILD", "USE_ALLOCA", "HAVE_LRINTF", "OP_HAVE_LRINTF",
"OPUS_X86_PRESUME_SSE", "OPUS_X86_PRESUME_SSE2",
"OPUS_HAVE_RTCD", "OPUS_X86_MAY_HAVE_SSE", "OPUS_X86_MAY_HAVE_SSE4_1", "OPUS_X86_MAY_HAVE_AVX2",
}
else
includedirs { OPUS_INCLUDE_DIR, VORBIS_INCLUDE_DIR, OGG_INCLUDE_DIR }
end
end
filter "system:linux"
links { "dl", "pthread", "m" }
-- default global settings -- default global settings
BUILD_LUA = true BUILD_LUA = true
LUA_LIB_NAME = "lua"
BUILD_EVENT = os.istarget("windows") BUILD_EVENT = os.istarget("windows")
BUILD_FREETYPE = os.istarget("windows") BUILD_FREETYPE = os.istarget("windows")
BUILD_SQLITE = os.istarget("windows") BUILD_SQLITE = os.istarget("windows")
BUILD_IRRLICHT = not os.istarget("macosx") BUILD_IRRLICHT = true
USE_IRRKLANG = true
USE_AUDIO = false
AUDIO_LIB = "miniaudio"
MINIAUDIO_SUPPORT_OPUS_VORBIS = true
MINIAUDIO_BUILD_OPUS_VORBIS = os.istarget("windows")
IRRKLANG_PRO = false IRRKLANG_PRO = false
LUA_LIB_NAME = "lua" IRRKLANG_PRO_BUILD_IKPMP3 = false
SERVER_MODE = true SERVER_MODE = true
SERVER_ZIP_SUPPORT = false SERVER_ZIP_SUPPORT = false
SERVER_PRO2_SUPPORT = false SERVER_PRO2_SUPPORT = false
SERVER_TAG_SURRENDER_CONFIRM = false SERVER_TAG_SURRENDER_CONFIRM = false
USE_IRRKLANG = false
-- read settings from command line or environment variables -- read settings from command line or environment variables
...@@ -21,7 +26,7 @@ newoption { trigger = "build-lua", category = "YGOPro - lua", description = "" } ...@@ -21,7 +26,7 @@ newoption { trigger = "build-lua", category = "YGOPro - lua", description = "" }
newoption { trigger = "no-build-lua", category = "YGOPro - lua", description = "" } newoption { trigger = "no-build-lua", category = "YGOPro - lua", description = "" }
newoption { trigger = "lua-include-dir", category = "YGOPro - lua", description = "", value = "PATH" } newoption { trigger = "lua-include-dir", category = "YGOPro - lua", description = "", value = "PATH" }
newoption { trigger = "lua-lib-dir", category = "YGOPro - lua", description = "", value = "PATH" } newoption { trigger = "lua-lib-dir", category = "YGOPro - lua", description = "", value = "PATH" }
newoption { trigger = "lua-lib-name", category = "YGOPro - lua", description = "", value = "NAME", default = "lua" } newoption { trigger = "lua-lib-name", category = "YGOPro - lua", description = "", value = "NAME", default = LUA_LIB_NAME }
newoption { trigger = "lua-deb", category = "YGOPro - lua", description = "" } newoption { trigger = "lua-deb", category = "YGOPro - lua", description = "" }
newoption { trigger = "build-event", category = "YGOPro - event", description = "" } newoption { trigger = "build-event", category = "YGOPro - event", description = "" }
...@@ -44,8 +49,24 @@ newoption { trigger = "no-build-irrlicht", category = "YGOPro - irrlicht", descr ...@@ -44,8 +49,24 @@ newoption { trigger = "no-build-irrlicht", category = "YGOPro - irrlicht", descr
newoption { trigger = "irrlicht-include-dir", category = "YGOPro - irrlicht", description = "", value = "PATH" } newoption { trigger = "irrlicht-include-dir", category = "YGOPro - irrlicht", description = "", value = "PATH" }
newoption { trigger = "irrlicht-lib-dir", category = "YGOPro - irrlicht", description = "", value = "PATH" } newoption { trigger = "irrlicht-lib-dir", category = "YGOPro - irrlicht", description = "", value = "PATH" }
newoption { trigger = "use-irrklang", category = "YGOPro - irrklang", description = "" } newoption { trigger = "no-audio", category = "YGOPro", description = "" }
newoption { trigger = "no-use-irrklang", category = "YGOPro - irrklang", description = "" } newoption { trigger = "audio-lib", category = "YGOPro", description = "", value = "miniaudio, irrklang", default = AUDIO_LIB }
newoption { trigger = "miniaudio-include-dir", category = "YGOPro - miniaudio", description = "", value = "PATH" }
newoption { trigger = "miniaudio-lib-dir", category = "YGOPro - miniaudio", description = "", value = "PATH" }
newoption { trigger = "miniaudio-support-opus-vorbis", category = "YGOPro - miniaudio", description = "" }
newoption { trigger = "no-miniaudio-support-opus-vorbis", category = "YGOPro - miniaudio", description = "" }
newoption { trigger = "build-opus-vorbis", category = "YGOPro - miniaudio", description = "" }
newoption { trigger = "no-build-opus-vorbis", category = "YGOPro - miniaudio", description = "" }
newoption { trigger = "opus-include-dir", category = "YGOPro - miniaudio", description = "", value = "PATH" }
newoption { trigger = "opus-lib-dir", category = "YGOPro - miniaudio", description = "", value = "PATH" }
newoption { trigger = "vorbis-include-dir", category = "YGOPro - miniaudio", description = "", value = "PATH" }
newoption { trigger = "vorbis-lib-dir", category = "YGOPro - miniaudio", description = "", value = "PATH" }
newoption { trigger = "ogg-include-dir", category = "YGOPro - miniaudio", description = "", value = "PATH" }
newoption { trigger = "ogg-lib-dir", category = "YGOPro - miniaudio", description = "", value = "PATH" }
newoption { trigger = "use-irrklang", category = "YGOPro - irrklang", description = "Deprecated, use audio-lib=irrklang" }
newoption { trigger = "no-use-irrklang", category = "YGOPro - irrklang", description = "Deprecated, use no-audio" }
newoption { trigger = "irrklang-include-dir", category = "YGOPro - irrklang", description = "", value = "PATH" } newoption { trigger = "irrklang-include-dir", category = "YGOPro - irrklang", description = "", value = "PATH" }
newoption { trigger = "irrklang-lib-dir", category = "YGOPro - irrklang", description = "", value = "PATH" } newoption { trigger = "irrklang-lib-dir", category = "YGOPro - irrklang", description = "", value = "PATH" }
...@@ -162,37 +183,75 @@ if not BUILD_IRRLICHT then ...@@ -162,37 +183,75 @@ if not BUILD_IRRLICHT then
IRRLICHT_LIB_DIR = GetParam("irrlicht-lib-dir") or os.findlib("irrlicht") IRRLICHT_LIB_DIR = GetParam("irrlicht-lib-dir") or os.findlib("irrlicht")
end end
if GetParam("use-irrklang") then if GetParam("no-audio") then
USE_IRRKLANG = true USE_AUDIO = false
elseif GetParam("no-use-miniaudio") then
print("Warning: --no-use-miniaudio is deprecated, use --no-audio")
USE_AUDIO = false
elseif GetParam("use-miniaudio") then
print("Warning: --use-miniaudio is deprecated, use --audio-lib=miniaudio")
USE_AUDIO = true
AUDIO_LIB = "miniaudio"
elseif GetParam("no-use-irrklang") then elseif GetParam("no-use-irrklang") then
USE_IRRKLANG = false print("Warning: --no-use-irrklang is deprecated, use --no-audio")
end USE_AUDIO = false
if USE_IRRKLANG then elseif GetParam("use-irrklang") then
IRRKLANG_INCLUDE_DIR = GetParam("irrklang-include-dir") or "../irrklang/include" print("Warning: --use-irrklang is deprecated, use --audio-lib=irrklang")
if os.istarget("windows") then USE_AUDIO = true
IRRKLANG_LIB_DIR = "../irrklang/lib/Win32-visualStudio" AUDIO_LIB = "irrklang"
elseif os.istarget("linux") then
IRRKLANG_LIB_DIR = "../irrklang/bin/linux-gcc-64"
IRRKLANG_LINK_RPATH = "-Wl,-rpath=./irrklang/bin/linux-gcc-64/"
elseif os.istarget("macosx") then
IRRKLANG_LIB_DIR = "../irrklang/bin/macosx-gcc"
end
IRRKLANG_LIB_DIR = GetParam("irrklang-lib-dir") or IRRKLANG_LIB_DIR
end end
if GetParam("irrklang-pro") and os.istarget("windows") then if USE_AUDIO then
IRRKLANG_PRO = true AUDIO_LIB = GetParam("audio-lib") or AUDIO_LIB
elseif GetParam("no-irrklang-pro") then if AUDIO_LIB == "miniaudio" then
IRRKLANG_PRO = false if GetParam("miniaudio-support-opus-vorbis") then
end MINIAUDIO_SUPPORT_OPUS_VORBIS = true
if IRRKLANG_PRO then elseif GetParam("no-miniaudio-support-opus-vorbis") then
-- irrklang pro can't use the pro lib to debug MINIAUDIO_SUPPORT_OPUS_VORBIS = false
IRRKLANG_PRO_RELEASE_LIB_DIR = GetParam("irrklang-pro-release-lib-dir") or "../irrklang/lib/Win32-vs2019" end
IRRKLANG_PRO_DEBUG_LIB_DIR = GetParam("irrklang-pro-debug-lib-dir") or "../irrklang/lib/Win32-visualStudio-debug" if MINIAUDIO_SUPPORT_OPUS_VORBIS then
if GetParam("no-build-opus-vorbis") then
MINIAUDIO_BUILD_OPUS_VORBIS = false
elseif GetParam("build-opus-vorbis") 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_LIB_DIR = GetParam("opus-lib-dir") or os.findlib("opusfile")
VORBIS_INCLUDE_DIR = GetParam("vorbis-include-dir") or os.findheader("vorbis")
VORBIS_LIB_DIR = GetParam("vorbis-lib-dir") or os.findlib("vorbis")
OGG_INCLUDE_DIR = GetParam("ogg-include-dir") or os.findheader("ogg")
OCG_LIB_DIR = GetParam("ogg-lib-dir") or os.findlib("ogg")
end
end
elseif AUDIO_LIB == "irrklang" then
print("Warning: irrKlang is deprecated and may be removed in future, please consider switching to miniaudio")
IRRKLANG_INCLUDE_DIR = GetParam("irrklang-include-dir") or "../irrklang/include"
if os.istarget("windows") then
IRRKLANG_LIB_DIR = "../irrklang/lib/Win32-visualStudio"
elseif os.istarget("linux") then
IRRKLANG_LIB_DIR = "../irrklang/bin/linux-gcc-64"
IRRKLANG_LINK_RPATH = "-Wl,-rpath=./irrklang/bin/linux-gcc-64/"
elseif os.istarget("macosx") then
IRRKLANG_LIB_DIR = "../irrklang/bin/macosx-gcc"
end
IRRKLANG_LIB_DIR = GetParam("irrklang-lib-dir") or IRRKLANG_LIB_DIR
if GetParam("irrklang-pro") and os.istarget("windows") then
IRRKLANG_PRO = true
elseif GetParam("no-irrklang-pro") then
IRRKLANG_PRO = false
end
if IRRKLANG_PRO then
-- irrklang pro can't use the pro lib to debug
IRRKLANG_PRO_RELEASE_LIB_DIR = GetParam("irrklang-pro-release-lib-dir") or "../irrklang/lib/Win32-vs2019"
IRRKLANG_PRO_DEBUG_LIB_DIR = GetParam("irrklang-pro-debug-lib-dir") or "../irrklang/lib/Win32-visualStudio-debug"
end
IRRKLANG_PRO_BUILD_IKPMP3 = GetParam("build-ikpmp3") or IRRKLANG_PRO
else
error("Unknown audio library: " .. AUDIO_LIB)
end
end end
BUILD_IKPMP3 = USE_IRRKLANG and (GetParam("build-ikpmp3") or IRRKLANG_PRO)
if GetParam("winxp-support") and os.istarget("windows") then if GetParam("winxp-support") and os.istarget("windows") then
WINXP_SUPPORT = true WINXP_SUPPORT = true
end end
...@@ -229,7 +288,6 @@ workspace "YGOPro" ...@@ -229,7 +288,6 @@ workspace "YGOPro"
end end
filter "system:windows" filter "system:windows"
defines { "WIN32", "_WIN32" }
entrypoint "mainCRTStartup" entrypoint "mainCRTStartup"
systemversion "latest" systemversion "latest"
startproject "YGOPro" startproject "YGOPro"
...@@ -242,7 +300,6 @@ workspace "YGOPro" ...@@ -242,7 +300,6 @@ workspace "YGOPro"
filter "system:macosx" filter "system:macosx"
libdirs { "/usr/local/lib" } libdirs { "/usr/local/lib" }
buildoptions { "-stdlib=libc++" }
if MAC_ARM then if MAC_ARM then
buildoptions { "--target=arm64-apple-macos12" } buildoptions { "--target=arm64-apple-macos12" }
end end
...@@ -315,6 +372,11 @@ end ...@@ -315,6 +372,11 @@ end
if BUILD_SQLITE then if BUILD_SQLITE then
include "sqlite3" include "sqlite3"
end end
if BUILD_IKPMP3 and not SERVER_MODE then if USE_AUDIO then
include "ikpmp3" if AUDIO_LIB=="miniaudio" then
include "miniaudio"
end
if IRRKLANG_PRO_BUILD_IKPMP3 then
include "ikpmp3"
end
end end
Subproject commit ce34d01b80d5ff553e8b43ba750dcf5c34592984 Subproject commit 0e0afc1170d72c5fead4bce86bc7e222936ae050
...@@ -8,6 +8,7 @@ equip.wav ...@@ -8,6 +8,7 @@ equip.wav
destroyed.wav destroyed.wav
banished.wav banished.wav
token.wav token.wav
negate.wav
attack.wav attack.wav
directattack.wav directattack.wav
draw.wav draw.wav
......
...@@ -663,6 +663,7 @@ ...@@ -663,6 +663,7 @@
!counter 0x106b 狂爱指示物 !counter 0x106b 狂爱指示物
!counter 0x6c 访问指示物 !counter 0x6c 访问指示物
!counter 0x6d 祝台指示物 !counter 0x6d 祝台指示物
!counter 0x6e 四季指示物
#setnames, using tab for comment #setnames, using tab for comment
!setname 0x1 正义盟军 AOJ !setname 0x1 正义盟军 AOJ
!setname 0x2 次世代 ジェネクス !setname 0x2 次世代 ジェネクス
...@@ -1245,9 +1246,15 @@ ...@@ -1245,9 +1246,15 @@
!setname 0x1c0 龙华 竜華 !setname 0x1c0 龙华 竜華
!setname 0x1c1 阿尔戈☆群星 ARGS !setname 0x1c1 阿尔戈☆群星 ARGS
!setname 0x1c2 喷水引擎 アクア・ジェット !setname 0x1c2 喷水引擎 アクア・ジェット
!setname 0x1c3 Mitsurugi !setname 0x1c3 Mitsurugi
!setname 0x1c4 征龙 征竜 !setname 0x1c4 征龙 征竜
!setname 0x1c5 再世 再世 !setname 0x1c5 再世 再世
!setname 0x1c6 统王 ドミナス !setname 0x1c6 统王 ドミナス
!setname 0x1c7 塞勒凯特 Serket !setname 0x1c7 塞勒凯特 Serket
!setname 0x1c8 阿匹卜 Apophis !setname 0x1c8 阿匹卜 Apophis
!setname 0x1c9 星辰 ドラゴンテイル
!setname 0x1ca 味美喵 ヤミー
!setname 0x1cb K9
!setname 0x1cc 瞬间移动 テレポート
!setname 0x1cd 神艺 アルトメギア
!setname 0x1ce 狱神 獄神
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