1414#include < chrono>
1515#ifdef _WIN32
1616#include < timeapi.h>
17+ #else
18+ #include < spawn.h>
19+ #ifdef __APPLE__
20+ #include < crt_externs.h>
21+ #define GetEnviron () (*_NSGetEnviron ())
22+ #else
23+ extern char **environ;
24+ #define GetEnviron () environ
25+ #endif
1726#endif
1827#ifdef __APPLE__
1928#include < CoreFoundation/CoreFoundation.h>
@@ -92,6 +101,8 @@ bool Game::Initialize() {
92101 device->getLogger ()->setLogLevel (irr::ELOG_LEVEL ::ELL_ERROR );
93102#endif
94103 deckManager.LoadLFList ();
104+ if (gameConf.default_lflist >= (int )deckManager._lfList .size () || gameConf.default_lflist < 0 )
105+ gameConf.default_lflist = 0 ;
95106 driver = device->getVideoDriver ();
96107 driver->setTextureCreationFlag (irr::video::ETCF_CREATE_MIP_MAPS , false );
97108 driver->setTextureCreationFlag (irr::video::ETCF_OPTIMIZED_FOR_QUALITY , true );
@@ -517,6 +528,7 @@ bool Game::Initialize() {
517528 for (int i = 0 ; i < 3 ; ++i) {
518529 btnHand[i] = env->addButton (irr::core::rect<irr::s32>(10 + 105 * i, 10 , 105 + 105 * i, 144 ), wHand, BUTTON_HAND1 + i, L" " );
519530 btnHand[i]->setImage (imageManager.tHand [i]);
531+ btnHand[i]->setUseAlphaChannel (true );
520532 }
521533 //
522534 wFTSelect = env->addWindow (irr::core::rect<irr::s32>(550 , 240 , 780 , 340 ), false , L" " );
@@ -576,11 +588,15 @@ bool Game::Initialize() {
576588 wPosSelect->getCloseButton ()->setVisible (false );
577589 wPosSelect->setVisible (false );
578590 btnPSAU = env->addButton (irr::core::rect<irr::s32>(27 , 35 , 164 , 172 ), wPosSelect, BUTTON_POS_AU );
591+ btnPSAU->setUseAlphaChannel (true );
579592 btnPSAD = env->addButton (irr::core::rect<irr::s32>(27 , 35 , 164 , 172 ), wPosSelect, BUTTON_POS_AD );
593+ btnPSAD->setUseAlphaChannel (true );
580594 btnFacedownImgInfo[btnPSAD] = {0 , false };
581595 btnPSAD->setVisible (false ); // PSAD = PoSition Attack face-Down, is not allowed in the rules, so the width of wPosSelect only support 3 buttons
582596 btnPSDU = env->addButton (irr::core::rect<irr::s32>(169 , 35 , 306 , 172 ), wPosSelect, BUTTON_POS_DU );
597+ btnPSDU->setUseAlphaChannel (true );
583598 btnPSDD = env->addButton (irr::core::rect<irr::s32>(311 , 35 , 448 , 172 ), wPosSelect, BUTTON_POS_DD );
599+ btnPSDD->setUseAlphaChannel (true );
584600 btnFacedownImgInfo[btnPSDD] = {0 , true };
585601 // card select
586602 wCardSelect = env->addWindow (irr::core::rect<irr::s32>(320 , 100 , 1000 , 400 ), false , L" " );
@@ -591,6 +607,7 @@ bool Game::Initialize() {
591607 stCardPos[i]->setBackgroundColor (0xffffffff );
592608 stCardPos[i]->setTextAlignment (irr::gui::EGUIA_CENTER , irr::gui::EGUIA_CENTER );
593609 btnCardSelect[i] = env->addButton (irr::core::rect<irr::s32>(30 + 125 * i, 55 , 150 + 125 * i, 225 ), wCardSelect, BUTTON_CARD_0 + i);
610+ btnCardSelect[i]->setUseAlphaChannel (true );
594611 }
595612 scrCardList = env->addScrollBar (true , irr::core::rect<irr::s32>(30 , 235 , 650 , 255 ), wCardSelect, SCROLL_CARD_SELECT );
596613 btnSelectOK = env->addButton (irr::core::rect<irr::s32>(300 , 265 , 380 , 290 ), wCardSelect, BUTTON_CARD_SEL_OK , dataManager.GetSysString (1211 ));
@@ -603,6 +620,7 @@ bool Game::Initialize() {
603620 stDisplayPos[i]->setBackgroundColor (0xffffffff );
604621 stDisplayPos[i]->setTextAlignment (irr::gui::EGUIA_CENTER , irr::gui::EGUIA_CENTER );
605622 btnCardDisplay[i] = env->addButton (irr::core::rect<irr::s32>(30 + 125 * i, 55 , 150 + 125 * i, 225 ), wCardDisplay, BUTTON_DISPLAY_0 + i);
623+ btnCardDisplay[i]->setUseAlphaChannel (true );
606624 }
607625 scrDisplayList = env->addScrollBar (true , irr::core::rect<irr::s32>(30 , 235 , 650 , 255 ), wCardDisplay, SCROLL_CARD_DISPLAY );
608626 btnDisplayOK = env->addButton (irr::core::rect<irr::s32>(300 , 265 , 380 , 290 ), wCardDisplay, BUTTON_CARD_DISP_OK , dataManager.GetSysString (1211 ));
@@ -2398,5 +2416,50 @@ void Game::SetCursor(irr::gui::ECURSOR_ICON icon) {
23982416 cursor->setActiveIcon (icon);
23992417 }
24002418}
2419+ bool Game::SpawnAsync (const std::wstring& exePath, const std::vector<std::wstring>& args) {
2420+ #ifdef _WIN32
2421+ std::wstring cmdLine = L" \" " + exePath + L" \" " ;
2422+ for (const auto & arg : args) {
2423+ cmdLine += L" \" " + arg + L" \" " ;
2424+ }
2425+
2426+ STARTUPINFOW si;
2427+ PROCESS_INFORMATION pi;
2428+ ZeroMemory (&si, sizeof (si));
2429+ si.cb = sizeof (si);
2430+ ZeroMemory (&pi, sizeof (pi));
2431+
2432+ // CreateProcessW can modify the command line buffer, so we need to create a mutable copy of it
2433+ // TODO: Move to C++17 and use cmdLine.data() directly without copying to a vector
2434+ std::vector<wchar_t > cmdBuffer (cmdLine.begin (), cmdLine.end ());
2435+ cmdBuffer.push_back (L' \0 ' );
2436+
2437+ if (!CreateProcessW (exePath.c_str (), cmdBuffer.data (), nullptr , nullptr , FALSE , 0 , nullptr , nullptr , &si, &pi)) {
2438+ return false ;
2439+ }
2440+
2441+ CloseHandle (pi.hThread );
2442+ CloseHandle (pi.hProcess );
2443+ return true ;
2444+ #else
2445+ std::string exePathUTF8 = BufferIO::EncodeUTF8String (exePath);
2446+
2447+ std::vector<std::string> utf8Args;
2448+ utf8Args.emplace_back (exePathUTF8);
2449+ for (const auto & arg : args) {
2450+ utf8Args.push_back (BufferIO::EncodeUTF8String (arg));
2451+ }
2452+
2453+ std::vector<char *> execArgs;
2454+ execArgs.reserve (utf8Args.size () + 1 );
2455+ for (auto & arg : utf8Args) {
2456+ execArgs.push_back (const_cast <char *>(arg.c_str ()));
2457+ }
2458+ execArgs.push_back (nullptr );
2459+
2460+ pid_t pid{}; // ignore pid return value, use SIG_IGN to prevent zombie process
2461+ return posix_spawn (&pid, exePathUTF8.c_str (), nullptr , nullptr , execArgs.data (), GetEnviron ()) == 0 ;
2462+ #endif
2463+ }
24012464
24022465}
0 commit comments