Commit a18e1436 authored by wind2009's avatar wind2009

Merge branch 'server' into server-develop

parents 5ed73cba f49949d1
......@@ -12,6 +12,7 @@ jobs:
fail-fast: false
matrix:
os: [windows-2019, windows-2022]
audiolib: [miniaudio, irrklang]
runs-on: ${{ matrix.os }}
......@@ -90,13 +91,75 @@ jobs:
7z x ${{ steps.sqlite.outputs.filepath }}
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
if: matrix.audiolib == 'irrklang'
id: irrKlang
uses: mercury233/action-cache-download-file@v1.0.0
with:
url: https://www.ambiera.at/downloads/irrKlang-32bit-1.6.0.zip
- name: Extract irrKlang
if: matrix.audiolib == 'irrklang'
run: |
7z x ${{ steps.irrKlang.outputs.filepath }}
move irrKlang-1.6.0 irrKlang
......@@ -134,16 +197,26 @@ jobs:
xcopy /E premake\* .
xcopy /E resource\* .
- name: Use premake to generate Visual Studio solution (2019)
if: matrix.os == 'windows-2019'
- name: Use premake to generate Visual Studio solution (2019, miniaudio)
if: matrix.os == 'windows-2019' && matrix.audiolib == 'miniaudio'
run: |
.\premake5.exe vs2019 --winxp-support
- name: Use premake to generate Visual Studio solution (2022)
if: matrix.os == 'windows-2022'
- name: Use premake to generate Visual Studio solution (2022, miniaudio)
if: matrix.os == 'windows-2022' && matrix.audiolib == 'miniaudio'
run: |
.\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
uses: microsoft/setup-msbuild@v2
......@@ -154,7 +227,7 @@ jobs:
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: YGOPro-${{ matrix.os }}
name: YGOPro-${{ matrix.os }}-${{ matrix.audiolib }}
path: |
bin/release/YGOPro.exe
......@@ -197,7 +270,7 @@ jobs:
- name: Install dependencies
run: |
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
id: premake
......@@ -222,6 +295,13 @@ jobs:
tar xf ${{ steps.lua.outputs.filepath }}
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
run: |
git clone --depth=1 https://github.com/mercury233/irrlicht
......@@ -234,8 +314,8 @@ jobs:
- name: Use premake to generate make files
run: |
./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
run: |
......@@ -283,9 +363,9 @@ jobs:
# git pull origin master
# cd ..
# - name: Install dependencies
# run: |
# brew install freetype libevent libx11 sqlite zlib
- name: Install dependencies
run: |
brew install freetype libevent libx11 sqlite opus opusfile libvorbis
- name: Download premake
id: premake
......@@ -310,15 +390,16 @@ jobs:
tar xf ${{ steps.lua.outputs.filepath }}
mv lua-5.4.7 lua
- name: Download irrlicht
- name: Download miniaudio
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: |
cd irrlicht/source/Irrlicht/MacOSX
xcodebuild -project MacOSX.xcodeproj
cd ../../../..
git clone --depth=1 https://github.com/mercury233/irrlicht
- name: Copy premake files
run: |
......@@ -330,25 +411,26 @@ jobs:
run: |
./premake5 gmake \
--cc=clang \
--no-use-irrklang \
--freetype-include-dir="/usr/local/include/freetype2" \
--irrlicht-include-dir="../irrlicht/include" \
--irrlicht-lib-dir="../irrlicht/source/Irrlicht/MacOSX/build/Release"
--opus-include-dir="/usr/local/include/opus"
- name: Use premake to generate make files (ARM64)
if: runner.arch == 'ARM64'
run: |
./premake5 gmake \
--cc=clang \
--no-use-irrklang \
--event-include-dir="/opt/homebrew/include" \
--event-lib-dir="/opt/homebrew/lib" \
--freetype-include-dir="/opt/homebrew/include/freetype2" \
--freetype-lib-dir="/opt/homebrew/lib" \
--sqlite-include-dir="/opt/homebrew/opt/sqlite/include" \
--sqlite-lib-dir="/opt/homebrew/opt/sqlite/lib" \
--irrlicht-include-dir="../irrlicht/include" \
--irrlicht-lib-dir="../irrlicht/source/Irrlicht/MacOSX/build/Release"
--miniaudio-include-dir="/opt/homebrew/include" \
--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
run: |
......
......@@ -10,6 +10,8 @@
/pics
/replay
/single
/sound
!/sound/files.txt
/WindBot
/cards.cdb
/error.log
......@@ -32,6 +34,7 @@
/irrklang
/ikpmp3
/lua
/miniaudio
/sqlite3
/gframe/*.ico
/gframe/ygopro.rc
......
......@@ -99,7 +99,7 @@ exec_windows:
- mat_windows
- mat_submodules
script:
- bash -c 'cp -rf premake/* .'
- bash -c 'cp -rf premake/* . ; cp -rf resource/* .'
- '.\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'
- copy bin\release\ygopro.exe .
......
......@@ -27,6 +27,7 @@ install:
before_build:
- xcopy /E premake\* .
- xcopy /E resource\* .
- premake5 vs2022
configuration: Release
......@@ -49,6 +50,7 @@ for:
- move irrlicht-1.8.5 irrlicht
- xcopy /E premake\* .
- xcopy /E resource\* .
- cd irrlicht
- patch -p1 < irrlicht.patch
......
......@@ -72,6 +72,21 @@ inline FILE* mywfopen(const wchar_t* filename, const char* mode) {
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)
#include <irrlicht.h>
#endif
......
......@@ -131,7 +131,7 @@ bool DataManager::LoadDB(const wchar_t* wfile) {
}
#ifndef YGOPRO_SERVER_MODE
bool DataManager::LoadStrings(const char* file) {
FILE* fp = std::fopen(file, "r");
FILE* fp = myfopen(file, "r");
if(!fp)
return false;
char linebuf[TEXT_LINE_SIZE]{};
......@@ -475,9 +475,7 @@ unsigned char* DataManager::ReadScriptFromIrrFS(const char* script_name, int* sl
}
#endif //YGOPRO_SERVER_MODE
unsigned char* DataManager::ReadScriptFromFile(const char* script_name, int* slen) {
wchar_t fname[256]{};
BufferIO::DecodeUTF8(script_name, fname);
FILE* fp = mywfopen(fname, "rb");
FILE* fp = myfopen(script_name, "rb");
if (!fp)
return nullptr;
size_t len = std::fread(scriptBuffer, 1, sizeof scriptBuffer, fp);
......
......@@ -12,7 +12,7 @@ DeckManager deckManager;
void DeckManager::LoadLFListSingle(const char* path) {
auto cur = _lfList.rend();
FILE* fp = std::fopen(path, "r");
FILE* fp = myfopen(path, "r");
char linebuf[256]{};
wchar_t strBuffer[256]{};
char str1[16]{};
......@@ -321,7 +321,7 @@ bool DeckManager::LoadCurrentDeck(int category_index, const wchar_t* category_na
mainGame->deckBuilder.RefreshPackListScroll();
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"))
return false;
FILE* fp = OpenDeckFile(file, "w");
......@@ -329,26 +329,18 @@ bool DeckManager::SaveDeck(Deck& deck, const wchar_t* file) {
return false;
std::fprintf(fp, "#created by ...\n#main\n");
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");
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");
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);
return true;
}
bool DeckManager::DeleteDeck(const wchar_t* file) {
#ifdef _WIN32
BOOL result = DeleteFileW(file);
return !!result;
#else
char filefn[256];
BufferIO::EncodeUTF8(file, filefn);
int result = unlink(filefn);
return result == 0;
#endif
return FileSystem::RemoveFile(file);
}
bool DeckManager::CreateCategory(const wchar_t* name) {
if(!FileSystem::IsDirExists(L"./deck") && !FileSystem::MakeDir(L"./deck"))
......@@ -377,34 +369,21 @@ bool DeckManager::DeleteCategory(const wchar_t* name) {
return false;
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"))
return false;
FILE* fp = OpenDeckFile(name, "w");
if (!fp)
return false;
int it = 0;
const int mainc = deckbuf[it];
++it;
std::fprintf(fp, "#created by ...\n#main\n");
for (int i = 0; i < mainc; ++i) {
std::fprintf(fp, "%d\n", deckbuf[it]);
++it;
}
const int extrac = deckbuf[it];
++it;
for (const auto& code : deck.main)
std::fprintf(fp, "%u\n", code);
std::fprintf(fp, "#extra\n");
for (int i = 0; i < extrac; ++i) {
std::fprintf(fp, "%d\n", deckbuf[it]);
++it;
}
const int sidec = deckbuf[it];
++it;
for (const auto& code : deck.extra)
std::fprintf(fp, "%u\n", code);
std::fprintf(fp, "!side\n");
for (int i = 0; i < sidec; ++i) {
std::fprintf(fp, "%d\n", deckbuf[it]);
++it;
}
for (const auto& code : deck.side)
std::fprintf(fp, "%u\n", code);
std::fclose(fp);
return true;
}
......
......@@ -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 {
public:
Deck current_deck;
......@@ -68,7 +74,6 @@ public:
#ifndef YGOPRO_SERVER_MODE
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 SaveDeckBuffer(const int deckbuf[], const wchar_t* name);
#endif //YGOPRO_SERVER_MODE
static uint32_t LoadDeck(Deck& deck, uint32_t dbuf[], int mainc, int sidec, bool is_packlist = false);
......@@ -79,11 +84,12 @@ public:
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 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 CreateCategory(const wchar_t* name);
static bool RenameCategory(const wchar_t* oldname, const wchar_t* newname);
static bool DeleteCategory(const wchar_t* name);
static bool SaveDeckArray(const DeckArray& deck, const wchar_t* name);
#endif //YGOPRO_SERVER_MODE
};
......
......@@ -3034,6 +3034,7 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
case MSG_CHAIN_DISABLED: {
int ct = BufferIO::ReadUInt8(pbuf);
if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping) {
soundManager.PlaySoundEffect(SOUND_NEGATE);
mainGame->showcardcode = mainGame->dField.chains[ct - 1].code;
mainGame->showcarddif = 0;
mainGame->showcard = 3;
......@@ -3868,7 +3869,9 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
break;
}
case MSG_RELOAD_FIELD: {
if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping) {
mainGame->gMutex.lock();
}
mainGame->dField.Clear();
mainGame->dInfo.duel_rule = BufferIO::ReadUInt8(pbuf);
int val = 0;
......@@ -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));
mainGame->dField.last_chain = true;
}
if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping) {
mainGame->gMutex.unlock();
}
break;
}
}
......
......@@ -151,6 +151,9 @@ bool Game::Initialize() {
numFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 16);
if(!numFont) {
const wchar_t* numFontPaths[] = {
L"./fonts/numFont.ttf",
L"./fonts/numFont.ttc",
L"./fonts/numFont.otf",
L"C:/Windows/Fonts/arialbd.ttf",
L"/usr/share/fonts/truetype/DroidSansFallbackFull.ttf",
L"/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc",
......@@ -158,9 +161,6 @@ bool Game::Initialize() {
L"/usr/share/fonts/noto-cjk/NotoSansCJK-Bold.ttc",
L"/System/Library/Fonts/SFNSTextCondensed-Bold.otf",
L"/System/Library/Fonts/SFNS.ttf",
L"./fonts/numFont.ttf",
L"./fonts/numFont.ttc",
L"./fonts/numFont.otf"
};
for(const wchar_t* path : numFontPaths) {
BufferIO::CopyWideString(path, gameConf.numfont);
......@@ -172,6 +172,9 @@ bool Game::Initialize() {
textFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize);
if(!textFont) {
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.ttf",
L"C:/Windows/Fonts/simsun.ttc",
......@@ -183,9 +186,7 @@ bool Game::Initialize() {
L"/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc",
L"/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc",
L"/System/Library/Fonts/PingFang.ttc",
L"./fonts/textFont.ttf",
L"./fonts/textFont.ttc",
L"./fonts/textFont.otf"
L"/System/Library/Fonts/STHeiti Medium.ttc",
};
for(const wchar_t* path : textFontPaths) {
BufferIO::CopyWideString(path, gameConf.textfont);
......@@ -203,7 +204,7 @@ bool Game::Initialize() {
}
});
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;
}
if(!numFont) {
......@@ -215,6 +216,10 @@ bool Game::Initialize() {
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);
lpcFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 48);
guiFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize);
......@@ -1354,7 +1359,7 @@ void Game::RefreshBot() {
if(!gameConf.enable_bot_mode)
return;
botInfo.clear();
FILE* fp = std::fopen("bot.conf", "r");
FILE* fp = myfopen("bot.conf", "r");
char linebuf[256]{};
char strbuf[256]{};
if(fp) {
......@@ -1407,7 +1412,7 @@ void Game::RefreshBot() {
}
}
void Game::LoadConfig() {
FILE* fp = std::fopen("system.conf", "r");
FILE* fp = myfopen("system.conf", "r");
if(!fp)
return;
char linebuf[CONFIG_LINE_SIZE]{};
......@@ -1425,14 +1430,6 @@ void Game::LoadConfig() {
} else if(!std::strcmp(strbuf, "errorlog")) {
unsigned int val = std::strtol(valbuf, nullptr, 10);
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")) {
gameConf.serverport = std::strtol(valbuf, nullptr, 10);
} else if(!std::strcmp(strbuf, "lasthost")) {
......@@ -1501,7 +1498,7 @@ void Game::LoadConfig() {
gameConf.window_height = std::strtol(valbuf, nullptr, 10);
} else if(!std::strcmp(strbuf, "resize_popup_menu")) {
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")) {
gameConf.enable_sound = std::strtol(valbuf, nullptr, 10) > 0;
} else if(!std::strcmp(strbuf, "sound_volume")) {
......@@ -1527,7 +1524,18 @@ void Game::LoadConfig() {
// options allowing multiple words
if (std::sscanf(linebuf, "%63s = %959[^\n]", strbuf, valbuf) != 2)
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);
} else if (!std::strcmp(strbuf, "gamename")) {
BufferIO::DecodeUTF8(valbuf, gameConf.gamename);
......@@ -1545,7 +1553,7 @@ void Game::LoadConfig() {
std::fclose(fp);
}
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");
char linebuf[CONFIG_LINE_SIZE];
std::fprintf(fp, "use_d3d = %d\n", gameConf.use_d3d ? 1 : 0);
......@@ -1606,7 +1614,7 @@ void Game::SaveConfig() {
std::fprintf(fp, "window_width = %d\n", gameConf.window_width);
std::fprintf(fp, "window_height = %d\n", gameConf.window_height);
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_music = %d\n", (chkEnableMusic->isChecked() ? 1 : 0));
std::fprintf(fp, "#Volume of sound and music, between 0 and 100\n");
......@@ -1636,6 +1644,10 @@ void Game::ShowCardInfo(int code, bool resize) {
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(code), code);
}
stName->setText(formatBuffer);
if(guiFont->getDimension(formatBuffer).Width > stName->getRelativePosition().getWidth() - gameConf.textfontsize)
stName->setToolTipText(formatBuffer);
else
stName->setToolTipText(nullptr);
int offset = 0;
if (is_valid && !gameConf.hide_setname) {
auto& cd = cit->second;
......@@ -1788,7 +1800,7 @@ void Game::ClearChatMsg() {
#endif //YGOPRO_SERVER_MODE
void Game::AddDebugMsg(const char* msg) {
#ifdef YGOPRO_SERVER_MODE
fprintf(stderr, "%s\n", msg);
std::fprintf(stderr, "%s\n", msg);
#else
if (enable_log & 0x1) {
wchar_t wbuf[1024];
......@@ -1804,7 +1816,12 @@ void Game::AddDebugMsg(const char* msg) {
}
#ifndef YGOPRO_SERVER_MODE
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)
return;
time_t nowtime = std::time(nullptr);
......@@ -2113,6 +2130,9 @@ void Game::OnResize() {
btnBigCardZoomIn->setRelativePosition(Resize(205, 140, 295, 175));
btnBigCardZoomOut->setRelativePosition(Resize(205, 180, 295, 215));
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() {
irr::s32 x = wInfos->getRelativePosition().LowerRightCorner.X + 6;
......
......@@ -25,8 +25,12 @@ void ClickButton(irr::gui::IGUIElement* btn) {
#endif //YGOPRO_SERVER_MODE
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");
#elif !defined(_WIN32)
std::setlocale(LC_CTYPE, "");
#endif
#if defined __APPLE__ && !defined YGOPRO_SERVER_MODE
CFURLRef bundle_url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
......
......@@ -300,42 +300,23 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
if(selected == -1)
break;
Replay replay;
wchar_t ex_filename[256]{};
wchar_t replay_filename[256]{};
wchar_t namebuf[4][20]{};
wchar_t filename[256]{};
wchar_t replay_path[256]{};
BufferIO::CopyWideString(mainGame->lstReplayList->getListItem(selected), ex_filename);
myswprintf(replay_path, L"./replay/%ls", ex_filename);
BufferIO::CopyWideString(mainGame->lstReplayList->getListItem(selected), replay_filename);
myswprintf(replay_path, L"./replay/%ls", replay_filename);
if (!replay.OpenReplay(replay_path))
break;
const ReplayHeader& rh = replay.pheader;
if(rh.flag & REPLAY_SINGLE_MODE)
break;
int player_count = (rh.flag & REPLAY_TAG) ? 4 : 2;
//player name
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);
if (replay.pheader.flag & REPLAY_SINGLE_MODE)
break;
for (size_t i = 0; i < replay.decks.size(); ++i) {
BufferIO::CopyWideString(replay.players[Replay::GetDeckPlayer(i)].c_str(), 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->PopupElement(mainGame->wACMessage, 20);
......@@ -546,7 +527,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
wchar_t replay_path[256]{};
myswprintf(replay_path, L"./replay/%ls", mainGame->lstReplayList->getListItem(sel));
if (!ReplayMode::cur_replay.OpenReplay(replay_path)) {
mainGame->stReplayInfo->setText(L"");
mainGame->stReplayInfo->setText(L"Error");
break;
}
wchar_t infobuf[256]{};
......@@ -558,17 +539,17 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
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));
repinfo.append(infobuf);
wchar_t namebuf[4][20]{};
ReplayMode::cur_replay.ReadName(namebuf[0]);
ReplayMode::cur_replay.ReadName(namebuf[1]);
if(ReplayMode::cur_replay.pheader.flag & REPLAY_TAG) {
ReplayMode::cur_replay.ReadName(namebuf[2]);
ReplayMode::cur_replay.ReadName(namebuf[3]);
if (ReplayMode::cur_replay.pheader.flag & REPLAY_SINGLE_MODE) {
wchar_t path[256]{};
BufferIO::DecodeUTF8(ReplayMode::cur_replay.script_name.c_str(), path);
repinfo.append(path);
repinfo.append(L"\n");
}
const auto& player_names = ReplayMode::cur_replay.players;
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
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);
mainGame->ebRepStartTurn->setText(L"1");
mainGame->SetStaticText(mainGame->stReplayInfo, 180, mainGame->guiFont, repinfo.c_str());
......
......@@ -86,6 +86,14 @@ public:
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) {
wchar_t findstr[1024];
std::swprintf(findstr, sizeof findstr / sizeof findstr[0], L"%ls/*", wpath);
......@@ -195,6 +203,16 @@ public:
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
struct file_unit {
std::string filename;
......
......@@ -27,7 +27,7 @@ struct HostInfo {
uint8_t no_shuffle_deck{};
// byte padding[3]
uint32_t start_lp{};
int32_t start_lp{};
uint8_t start_hand{};
uint8_t draw_count{};
uint16_t time_limit{};
......
......@@ -6,6 +6,7 @@ end
project "ygopro"
if SERVER_MODE then
kind "ConsoleApp"
cppdialect "C++14"
defines { "YGOPRO_SERVER_MODE" }
......@@ -42,10 +43,6 @@ else
links { "ocgcore", "clzma", "cspmemvfs", LUA_LIB_NAME, "sqlite3", "irrlicht", "freetype", "event" }
end
if BUILD_IKPMP3 then
links { "ikpmp3" }
end
if BUILD_EVENT then
includedirs { "../event/include" }
else
......@@ -74,24 +71,40 @@ end
libdirs { SQLITE_LIB_DIR }
end
if USE_IRRKLANG then
if USE_AUDIO then
defines { "YGOPRO_USE_AUDIO" }
if AUDIO_LIB == "miniaudio" then
defines { "YGOPRO_USE_MINIAUDIO" }
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
filter "system:windows"
defines { "_IRR_WCHAR_FILESYSTEM" }
files "ygopro.rc"
if not SERVER_MODE then
libdirs { "$(DXSDK_DIR)Lib/x86" }
end
if SERVER_PRO2_SUPPORT then
targetname ("AI.Server")
end
if USE_IRRKLANG then
if USE_AUDIO and AUDIO_LIB == "irrklang" then
links { "irrKlang" }
if IRRKLANG_PRO then
defines { "IRRKLANG_STATIC" }
......@@ -118,14 +131,14 @@ end
buildoptions { "--target=arm64-apple-macos12" }
linkoptions { "-arch arm64" }
end
if USE_IRRKLANG then
if USE_AUDIO and AUDIO_LIB == "irrklang" then
links { "irrklang" }
end
filter "system:linux"
if not SERVER_MODE then
links { "GL", "X11", "Xxf86vm" }
end
if USE_IRRKLANG then
if USE_AUDIO and AUDIO_LIB == "irrklang" then
links { "IrrKlang" }
linkoptions{ IRRKLANG_LINK_RPATH }
end
#include "replay.h"
#include "myfilesystem.h"
#include "network.h"
#include "lzma/LzmaLib.h"
namespace ygo {
......@@ -48,9 +49,9 @@ void Replay::BeginRecord() {
strftime(tmppath, 40, "./replay/%Y-%m-%d %H-%M-%S %%u.yrp", localedtime);
char path[40];
sprintf(path, tmppath, server_port);
fp = std::fopen(path, "wb");
fp = myfopen(path, "wb");
#else
fp = std::fopen("./replay/_LastReplay.yrp", "wb");
fp = myfopen("./replay/_LastReplay.yrp", "wb");
#endif //YGOPRO_SERVER_MODE
if(!fp)
return;
......@@ -58,9 +59,7 @@ void Replay::BeginRecord() {
#ifdef YGOPRO_SERVER_MODE
}
#endif //YGOPRO_SERVER_MODE
replay_size = 0;
comp_size = 0;
is_replaying = false;
Reset();
is_recording = true;
}
void Replay::WriteHeader(ReplayHeader& header) {
......@@ -156,11 +155,7 @@ bool Replay::OpenReplay(const wchar_t* name) {
if(!rfp)
return false;
data_position = 0;
is_recording = false;
is_replaying = false;
replay_size = 0;
comp_size = 0;
Reset();
if(std::fread(&pheader, sizeof pheader, 1, rfp) < 1) {
std::fclose(rfp);
return false;
......@@ -183,6 +178,13 @@ bool Replay::OpenReplay(const wchar_t* name) {
comp_size = 0;
}
is_replaying = true;
can_read = true;
if (!ReadInfo()) {
Reset();
return false;
}
info_offset = data_position;
data_position = 0;
return true;
}
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) {
wchar_t fname[256];
myswprintf(fname, L"./replay/%ls", name);
#ifdef _WIN32
BOOL result = DeleteFileW(fname);
return !!result;
#else
char filefn[256];
BufferIO::EncodeUTF8(fname, filefn);
int result = unlink(filefn);
return result == 0;
#endif
return FileSystem::RemoveFile(fname);
}
bool Replay::RenameReplay(const wchar_t* oldname, const wchar_t* newname) {
wchar_t oldfname[256];
......@@ -230,10 +224,6 @@ bool Replay::ReadNextResponse(unsigned char resp[]) {
unsigned char len{};
if (!ReadData(&len, sizeof len))
return false;
if (len > SIZE_RETURN_VALUE) {
is_replaying = false;
return false;
}
if (!ReadData(resp, len))
return false;
return true;
......@@ -250,10 +240,10 @@ void Replay::ReadHeader(ReplayHeader& header) {
header = pheader;
}
bool Replay::ReadData(void* data, size_t length) {
if(!is_replaying)
if (!is_replaying || !can_read)
return false;
if (data_position + length > replay_size) {
is_replaying = false;
can_read = false;
return false;
}
if (length)
......@@ -266,6 +256,73 @@ int32_t Replay::ReadInt32() {
}
void Replay::Rewind() {
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 @@
#define REPLAY_H
#include "config.h"
#include "deck_manager.h"
namespace ygo {
......@@ -13,7 +14,7 @@ namespace ygo {
#define REPLAY_UNIFORM 0x10
// max size
constexpr int MAX_REPLAY_SIZE = 0x20000;
constexpr int MAX_REPLAY_SIZE = 0x80000;
constexpr int MAX_COMP_SIZE = UINT16_MAX + 1;
#ifdef YGOPRO_SERVER_MODE
......@@ -23,13 +24,20 @@ constexpr int MAX_COMP_SIZE = UINT16_MAX + 1;
#endif // YGOPRO_SERVER_MODE
struct ReplayHeader {
unsigned int id{};
unsigned int version{};
unsigned int flag{};
unsigned int seed{};
unsigned int datasize{};
unsigned int start_time{};
unsigned char props[8]{};
uint32_t id{};
uint32_t version{};
uint32_t flag{};
uint32_t seed{};
uint32_t datasize{};
uint32_t start_time{};
uint8_t props[8]{};
};
struct DuelParameters {
int32_t start_lp{};
int32_t start_hand{};
int32_t draw_count{};
uint32_t duel_flag{};
};
class Replay {
......@@ -51,10 +59,20 @@ public:
void SaveReplay(const wchar_t* name);
// play
bool OpenReplay(const wchar_t* name);
static bool CheckReplay(const wchar_t* name);
static bool DeleteReplay(const wchar_t* name);
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 ReadName(wchar_t* data);
void ReadHeader(ReplayHeader& header);
......@@ -67,6 +85,8 @@ public:
}
int32_t ReadInt32();
void Rewind();
void Reset();
void SkipInfo();
FILE* fp{ nullptr };
#ifdef _WIN32
......@@ -77,12 +97,22 @@ public:
unsigned char* comp_data;
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:
bool ReadInfo();
unsigned char* replay_data;
size_t replay_size{};
size_t data_position{};
size_t info_offset{};
bool is_recording{};
bool is_replaying{};
bool can_read{};
};
}
......
......@@ -158,89 +158,65 @@ bool ReplayMode::StartDuel() {
const ReplayHeader& rh = cur_replay.pheader;
unsigned int seed = rh.seed;
std::mt19937 rnd(seed);
cur_replay.SkipInfo();
if(mainGame->dInfo.isTag) {
cur_replay.ReadName(mainGame->dInfo.hostname);
cur_replay.ReadName(mainGame->dInfo.hostname_tag);
cur_replay.ReadName(mainGame->dInfo.clientname_tag);
cur_replay.ReadName(mainGame->dInfo.clientname);
BufferIO::CopyWideString(cur_replay.players[0].c_str(), mainGame->dInfo.hostname);
BufferIO::CopyWideString(cur_replay.players[1].c_str(), mainGame->dInfo.hostname_tag);
BufferIO::CopyWideString(cur_replay.players[2].c_str(), mainGame->dInfo.clientname_tag);
BufferIO::CopyWideString(cur_replay.players[3].c_str(), mainGame->dInfo.clientname);
} else {
cur_replay.ReadName(mainGame->dInfo.hostname);
cur_replay.ReadName(mainGame->dInfo.clientname);
BufferIO::CopyWideString(cur_replay.players[0].c_str(), mainGame->dInfo.hostname);
BufferIO::CopyWideString(cur_replay.players[1].c_str(), mainGame->dInfo.clientname);
}
pduel = create_duel(rnd());
int start_lp = cur_replay.ReadInt32();
int start_hand = cur_replay.ReadInt32();
int draw_count = cur_replay.ReadInt32();
int opt = cur_replay.ReadInt32();
int duel_rule = opt >> 16;
mainGame->dInfo.duel_rule = duel_rule;
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;
mainGame->dInfo.duel_rule = cur_replay.params.duel_flag >> 16;
set_player_info(pduel, 0, cur_replay.params.start_lp, cur_replay.params.start_hand, cur_replay.params.draw_count);
set_player_info(pduel, 1, cur_replay.params.start_lp, cur_replay.params.start_hand, cur_replay.params.draw_count);
mainGame->dInfo.lp[0] = cur_replay.params.start_lp;
mainGame->dInfo.lp[1] = cur_replay.params.start_lp;
mainGame->dInfo.start_lp = cur_replay.params.start_lp;
myswprintf(mainGame->dInfo.strLP[0], L"%d", mainGame->dInfo.lp[0]);
myswprintf(mainGame->dInfo.strLP[1], L"%d", mainGame->dInfo.lp[1]);
mainGame->dInfo.turn = 0;
if(!mainGame->dInfo.isSingleMode) {
if(!(opt & DUEL_TAG_MODE)) {
int main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE);
int extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
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 {
int main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE);
int extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(mainGame->LocalPlayer(0), main, extra);
main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_tag_card(pduel, cur_replay.ReadInt32(), 0, LOCATION_DECK);
extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_tag_card(pduel, cur_replay.ReadInt32(), 0, LOCATION_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);
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);
if(!(rh.flag & REPLAY_SINGLE_MODE)) {
if(!(rh.flag & REPLAY_TAG)) {
for (int i = 0; i < 2; ++i) {
for (const auto& code : cur_replay.decks[i].main)
new_card(pduel, code, i, i, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE);
for (const auto& code : cur_replay.decks[i].extra)
new_card(pduel, code, i, i, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(mainGame->LocalPlayer(i), cur_replay.decks[i].main.size(), cur_replay.decks[i].extra.size());
}
} else {
char filename[256];
auto slen = cur_replay.Read<uint16_t>();
if (slen > sizeof(filename) - 1) {
return false;
for (const auto& code : cur_replay.decks[0].main)
new_card(pduel, code, 0, 0, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE);
for (const auto& code : cur_replay.decks[0].extra)
new_card(pduel, code, 0, 0, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(mainGame->LocalPlayer(0), cur_replay.decks[0].main.size(), cur_replay.decks[0].extra.size());
for (const auto& code : cur_replay.decks[1].main)
new_tag_card(pduel, code, 0, LOCATION_DECK);
for (const auto& code : cur_replay.decks[1].extra)
new_tag_card(pduel, code, 0, LOCATION_EXTRA);
for (const auto& code : cur_replay.decks[2].main)
new_card(pduel, code, 1, 1, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE);
for (const auto& code : cur_replay.decks[2].extra)
new_card(pduel, code, 1, 1, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(mainGame->LocalPlayer(1), cur_replay.decks[2].main.size(), cur_replay.decks[2].extra.size());
for (const auto& code : cur_replay.decks[3].main)
new_tag_card(pduel, code, 1, LOCATION_DECK);
for (const auto& code : cur_replay.decks[3].extra)
new_tag_card(pduel, code, 1, LOCATION_EXTRA);
}
cur_replay.ReadData(filename, slen);
filename[slen] = 0;
} else {
char filename[256]{};
std::snprintf(filename, sizeof filename, "./single/%s", cur_replay.script_name.c_str());
if(!preload_script(pduel, filename)) {
return false;
}
}
if (!(rh.flag & REPLAY_UNIFORM))
opt |= DUEL_OLD_REPLAY;
start_duel(pduel, opt);
cur_replay.params.duel_flag |= DUEL_OLD_REPLAY;
start_duel(pduel, cur_replay.params.duel_flag);
return true;
}
void ReplayMode::EndDuel() {
......
This diff is collapsed.
......@@ -3,6 +3,9 @@
#include "game.h"
#include "../ocgcore/mtrandom.h"
#ifdef YGOPRO_USE_MINIAUDIO
#include <miniaudio.h>
#endif
#ifdef YGOPRO_USE_IRRKLANG
#include <irrKlang.h>
#endif
......@@ -12,8 +15,19 @@ namespace ygo {
class SoundManager {
private:
std::vector<std::wstring> BGMList[8];
int bgm_scene;
int bgm_scene{};
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
irrklang::ISoundEngine* engineSound;
irrklang::ISoundEngine* engineMusic;
......@@ -26,7 +40,8 @@ public:
void RefreshBGMList();
void PlaySoundEffect(int sound);
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 StopBGM();
void SetSoundVolume(double volume);
......@@ -45,6 +60,7 @@ extern SoundManager soundManager;
#define SOUND_DESTROYED 108
#define SOUND_BANISHED 109
#define SOUND_TOKEN 110
#define SOUND_NEGATE 111
#define SOUND_ATTACK 201
#define SOUND_DIRECT_ATTACK 202
......
This diff is collapsed.
Subproject commit 74c7c053a393f397758c798e2860ab5972b56338
Subproject commit 283c1d74b4f427beecf2738ee3f85ab99a675124
......@@ -11,3 +11,4 @@ project "event"
filter "system:windows"
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" }
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"
filter { "system:windows" }
defines { "_IRR_WCHAR_FILESYSTEM" }
filter { "system:macosx" }
cppdialect "gnu++14"
project "irrlicht"
kind "StaticLib"
includedirs { "include", "source/Irrlicht", "source/Irrlicht/jpeglib", "source/Irrlicht/libpng", "source/Irrlicht/zlib" }
includedirs {
"include",
"source/Irrlicht",
"source/Irrlicht/jpeglib",
"source/Irrlicht/libpng",
"source/Irrlicht/zlib"
}
dofile("defines.lua")
exceptionhandling "Off"
rtti "Off"
files { "include/*.h",
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_",
"NO_IRR_COMPILE_WITH_ZIP_ENCRYPTION_",
"PNG_INTEL_SSE",
"PNG_ARM_NEON_OPT=0",
"PNG_ARM_NEON_IMPLEMENTATION=0",
}
files {
"include/*.h",
"source/Irrlicht/*.cpp",
"source/Irrlicht/lzma/*.h",
"source/Irrlicht/lzma/*.c",
"source/Irrlicht/zlib/zlib.h",
"source/Irrlicht/zlib/adler32.c",
"source/Irrlicht/zlib/compress.c",
......@@ -90,15 +148,25 @@ project "irrlicht"
"source/Irrlicht/libpng/pngwrite.c",
"source/Irrlicht/libpng/pngwtran.c",
"source/Irrlicht/libpng/pngwutil.c",
"source/Irrlicht/aesGladman/*.h",
"source/Irrlicht/aesGladman/*.cpp" }
"source/Irrlicht/libpng/intel/intel_init.c",
"source/Irrlicht/libpng/intel/filter_sse2_intrinsics.c",
}
filter { "system:windows" }
defines { "_IRR_WCHAR_FILESYSTEM" }
includedirs { "$(DXSDK_DIR)Include" }
libdirs { "$(DXSDK_DIR)Lib/x86" }
links { "imm32" }
filter { "system:linux" }
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
BUILD_LUA = true
LUA_LIB_NAME = "lua"
BUILD_EVENT = os.istarget("windows")
BUILD_FREETYPE = os.istarget("windows")
BUILD_SQLITE = os.istarget("windows")
BUILD_IRRLICHT = not os.istarget("macosx")
USE_IRRKLANG = true
BUILD_IRRLICHT = true
USE_AUDIO = false
AUDIO_LIB = "miniaudio"
MINIAUDIO_SUPPORT_OPUS_VORBIS = true
MINIAUDIO_BUILD_OPUS_VORBIS = os.istarget("windows")
IRRKLANG_PRO = false
LUA_LIB_NAME = "lua"
IRRKLANG_PRO_BUILD_IKPMP3 = false
SERVER_MODE = true
SERVER_ZIP_SUPPORT = false
SERVER_PRO2_SUPPORT = false
SERVER_TAG_SURRENDER_CONFIRM = false
USE_IRRKLANG = false
-- read settings from command line or environment variables
......@@ -21,7 +26,7 @@ newoption { trigger = "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-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 = "build-event", category = "YGOPro - event", description = "" }
......@@ -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-lib-dir", category = "YGOPro - irrlicht", description = "", value = "PATH" }
newoption { trigger = "use-irrklang", category = "YGOPro - irrklang", description = "" }
newoption { trigger = "no-use-irrklang", category = "YGOPro - irrklang", description = "" }
newoption { trigger = "no-audio", category = "YGOPro", 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-lib-dir", category = "YGOPro - irrklang", description = "", value = "PATH" }
......@@ -162,12 +183,49 @@ if not BUILD_IRRLICHT then
IRRLICHT_LIB_DIR = GetParam("irrlicht-lib-dir") or os.findlib("irrlicht")
end
if GetParam("use-irrklang") then
USE_IRRKLANG = true
if GetParam("no-audio") then
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
USE_IRRKLANG = false
print("Warning: --no-use-irrklang is deprecated, use --no-audio")
USE_AUDIO = false
elseif GetParam("use-irrklang") then
print("Warning: --use-irrklang is deprecated, use --audio-lib=irrklang")
USE_AUDIO = true
AUDIO_LIB = "irrklang"
end
if USE_IRRKLANG then
if USE_AUDIO then
AUDIO_LIB = GetParam("audio-lib") or AUDIO_LIB
if AUDIO_LIB == "miniaudio" then
if GetParam("miniaudio-support-opus-vorbis") then
MINIAUDIO_SUPPORT_OPUS_VORBIS = true
elseif GetParam("no-miniaudio-support-opus-vorbis") then
MINIAUDIO_SUPPORT_OPUS_VORBIS = false
end
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"
......@@ -178,21 +236,22 @@ if USE_IRRKLANG then
IRRKLANG_LIB_DIR = "../irrklang/bin/macosx-gcc"
end
IRRKLANG_LIB_DIR = GetParam("irrklang-lib-dir") or IRRKLANG_LIB_DIR
end
if GetParam("irrklang-pro") and os.istarget("windows") then
if GetParam("irrklang-pro") and os.istarget("windows") then
IRRKLANG_PRO = true
elseif GetParam("no-irrklang-pro") then
elseif GetParam("no-irrklang-pro") then
IRRKLANG_PRO = false
end
if IRRKLANG_PRO then
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
BUILD_IKPMP3 = USE_IRRKLANG and (GetParam("build-ikpmp3") or IRRKLANG_PRO)
if GetParam("winxp-support") and os.istarget("windows") then
WINXP_SUPPORT = true
end
......@@ -229,7 +288,6 @@ workspace "YGOPro"
end
filter "system:windows"
defines { "WIN32", "_WIN32" }
entrypoint "mainCRTStartup"
systemversion "latest"
startproject "YGOPro"
......@@ -242,7 +300,6 @@ workspace "YGOPro"
filter "system:macosx"
libdirs { "/usr/local/lib" }
buildoptions { "-stdlib=libc++" }
if MAC_ARM then
buildoptions { "--target=arm64-apple-macos12" }
end
......@@ -315,6 +372,11 @@ end
if BUILD_SQLITE then
include "sqlite3"
end
if BUILD_IKPMP3 and not SERVER_MODE then
if USE_AUDIO then
if AUDIO_LIB=="miniaudio" then
include "miniaudio"
end
if IRRKLANG_PRO_BUILD_IKPMP3 then
include "ikpmp3"
end
end
Subproject commit ce34d01b80d5ff553e8b43ba750dcf5c34592984
Subproject commit 0e0afc1170d72c5fead4bce86bc7e222936ae050
......@@ -8,6 +8,7 @@ equip.wav
destroyed.wav
banished.wav
token.wav
negate.wav
attack.wav
directattack.wav
draw.wav
......
......@@ -663,6 +663,7 @@
!counter 0x106b 狂爱指示物
!counter 0x6c 访问指示物
!counter 0x6d 祝台指示物
!counter 0x6e 四季指示物
#setnames, using tab for comment
!setname 0x1 正义盟军 AOJ
!setname 0x2 次世代 ジェネクス
......@@ -1245,9 +1246,15 @@
!setname 0x1c0 龙华 竜華
!setname 0x1c1 阿尔戈☆群星 ARGS
!setname 0x1c2 喷水引擎 アクア・ジェット
!setname 0x1c3 Mitsurugi
!setname 0x1c3 Mitsurugi
!setname 0x1c4 征龙 征竜
!setname 0x1c5 再世 再世
!setname 0x1c6 统王 ドミナス
!setname 0x1c7 塞勒凯特 Serket
!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