Commit 3c17d240 authored by edo9300's avatar edo9300

Merge remote-tracking branch 'refs/remotes/Fluorohydride/master'

# Conflicts:
#	gframe/config.h
#	gframe/drawing.cpp
#	gframe/event_handler.cpp
#	gframe/game.cpp
#	gframe/premake4.lua
#	gframe/replay.cpp
#	gframe/replay_mode.cpp
#	gframe/single_mode.cpp
#	lflist.conf
#	ocgcore
#	script
#	strings.conf
parents 8164b5cc 9b88042a
......@@ -65,7 +65,7 @@ public:
*pstr = 0;
return l;
}
// UCS-2 to UTF-8
// UTF-16/UTF-32 to UTF-8
static int EncodeUTF8(const wchar_t * wsrc, char * str) {
char* pstr = str;
while(*wsrc != 0) {
......@@ -76,18 +76,35 @@ public:
str[0] = ((*wsrc >> 6) & 0x1f) | 0xc0;
str[1] = ((*wsrc) & 0x3f) | 0x80;
str += 2;
} else {
} else if(*wsrc < 0x10000 && (*wsrc < 0xd800 || *wsrc > 0xdfff)) {
str[0] = ((*wsrc >> 12) & 0xf) | 0xe0;
str[1] = ((*wsrc >> 6) & 0x3f) | 0x80;
str[2] = ((*wsrc) & 0x3f) | 0x80;
str += 3;
} else {
#ifdef _WIN32
unsigned unicode = 0;
unicode |= (*wsrc++ & 0x3ff) << 10;
unicode |= *wsrc & 0x3ff;
unicode += 0x10000;
str[0] = ((unicode >> 18) & 0x7) | 0xf0;
str[1] = ((unicode >> 12) & 0x3f) | 0x80;
str[2] = ((unicode >> 6) & 0x3f) | 0x80;
str[3] = ((unicode) & 0x3f) | 0x80;
#else
str[0] = ((*wsrc >> 18) & 0x7) | 0xf0;
str[1] = ((*wsrc >> 12) & 0x3f) | 0x80;
str[2] = ((*wsrc >> 6) & 0x3f) | 0x80;
str[3] = ((*wsrc) & 0x3f) | 0x80;
#endif // _WIN32
str += 4;
}
wsrc++;
}
*str = 0;
return str - pstr;
}
// UTF-8 to UCS-2
// UTF-8 to UTF-16/UTF-32
static int DecodeUTF8(const char * src, wchar_t * wstr) {
const char* p = src;
wchar_t* wp = wstr;
......@@ -102,7 +119,14 @@ public:
*wp = (((unsigned)p[0] & 0xf) << 12) | (((unsigned)p[1] & 0x3f) << 6) | ((unsigned)p[2] & 0x3f);
p += 3;
} else if((*p & 0xf8) == 0xf0) {
#ifdef _WIN32
unsigned unicode = (((unsigned)p[0] & 0x7) << 18) | (((unsigned)p[1] & 0x3f) << 12) | (((unsigned)p[2] & 0x3f) << 6) | ((unsigned)p[3] & 0x3f);
unicode -= 0x10000;
*wp++ = (unicode >> 10) | 0xd800;
*wp = (unicode & 0x3ff) | 0xdc00;
#else
*wp = (((unsigned)p[0] & 0x7) << 18) | (((unsigned)p[1] & 0x3f) << 12) | (((unsigned)p[2] & 0x3f) << 6) | ((unsigned)p[3] & 0x3f);
#endif // _WIN32
p += 4;
} else
p++;
......
......@@ -1470,8 +1470,23 @@ void ClientField::UpdateDeclarableCodeType(bool enter) {
ancard.push_back(trycode);
return;
}
if((pname[0] == 0 || pname[1] == 0) && !enter)
if((pname[0] == 0 || pname[1] == 0) && !enter) {
std::vector<int> cache;
cache.swap(ancard);
int sel = mainGame->lstANCard->getSelected();
int selcode = (sel == -1) ? 0 : cache[sel];
mainGame->lstANCard->clear();
for(const auto& trycode : cache) {
if(dataManager.GetString(trycode, &cstr) && dataManager.GetData(trycode, &cd) && is_declarable(cd, declarable_type)) {
ancard.push_back(trycode);
mainGame->lstANCard->addItem(cstr.name.c_str());
if(trycode == selcode)
mainGame->lstANCard->setSelected(cstr.name.c_str());
}
}
if(!ancard.empty())
return;
}
mainGame->lstANCard->clear();
ancard.clear();
for(auto cit = dataManager._strings.begin(); cit != dataManager._strings.end(); ++cit) {
......@@ -1502,8 +1517,23 @@ void ClientField::UpdateDeclarableCodeOpcode(bool enter) {
ancard.push_back(trycode);
return;
}
if((pname[0] == 0 || pname[1] == 0) && !enter)
if((pname[0] == 0 || pname[1] == 0) && !enter) {
std::vector<int> cache;
cache.swap(ancard);
int sel = mainGame->lstANCard->getSelected();
int selcode = (sel == -1) ? 0 : cache[sel];
mainGame->lstANCard->clear();
for(const auto& trycode : cache) {
if(dataManager.GetString(trycode, &cstr) && dataManager.GetData(trycode, &cd) && is_declarable(cd, opcode)) {
ancard.push_back(trycode);
mainGame->lstANCard->addItem(cstr.name.c_str());
if(trycode == selcode)
mainGame->lstANCard->setSelected(cstr.name.c_str());
}
}
if(!ancard.empty())
return;
}
mainGame->lstANCard->clear();
ancard.clear();
for(auto cit = dataManager._strings.begin(); cit != dataManager._strings.end(); ++cit) {
......
......@@ -12,11 +12,9 @@
#include <ws2tcpip.h>
#ifdef _MSC_VER
#define myswprintf _swprintf
#define mywcsncasecmp _wcsnicmp
#define mystrncasecmp _strnicmp
#else
#define myswprintf swprintf
#define mywcsncasecmp wcsncasecmp
#define mystrncasecmp strncasecmp
#endif
......@@ -44,7 +42,6 @@
#define SOCKET_ERRNO() (errno)
#include <wchar.h>
#define myswprintf(buf, fmt, ...) swprintf(buf, 4096, fmt, ##__VA_ARGS__)
#define mywcsncasecmp wcsncasecmp
#define mystrncasecmp strncasecmp
inline int _wtoi(const wchar_t * s) {
......@@ -53,6 +50,11 @@ inline int _wtoi(const wchar_t * s) {
}
#endif
template<size_t N, typename... TR>
inline int myswprintf(wchar_t(&buf)[N], const wchar_t* fmt, TR... args) {
return swprintf(buf, N, fmt, args...);
}
#include <irrlicht.h>
#include <irrKlang.h>
#include <GL/gl.h>
......
......@@ -1171,7 +1171,7 @@ void Game::DrawDeckBd() {
driver->draw2DRectangle(0x80000000, Resize(806, 164 + i * 66, 1019, 230 + i * 66));
DrawThumb(ptr, position2di(810, 165 + i * 66), deckBuilder.filterList);
if(ptr->second.type & TYPE_MONSTER) {
wchar_t* form = L"\u2605";
const wchar_t* form = L"\u2605";
if (ptr->second.type & TYPE_XYZ) form = L"\u2606";
myswprintf(textBuffer, L"%ls", dataManager.GetName(ptr->first));
textFont->draw(textBuffer, Resize(859, 164 + i * 66, 955, 185 + i * 66), 0xff000000, false, false);
......
......@@ -3631,7 +3631,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
mainGame->gMutex.Lock();
mainGame->ebANCard->setText(L"");
mainGame->wANCard->setText(textBuffer);
mainGame->dField.UpdateDeclarableCode(true);
mainGame->dField.UpdateDeclarableCode(false);
mainGame->PopupElement(mainGame->wANCard);
mainGame->gMutex.Unlock();
return false;
......@@ -3670,7 +3670,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
mainGame->gMutex.Lock();
mainGame->ebANCard->setText(L"");
mainGame->wANCard->setText(textBuffer);
mainGame->dField.UpdateDeclarableCode(true);
mainGame->dField.UpdateDeclarableCode(false);
mainGame->PopupElement(mainGame->wANCard);
mainGame->gMutex.Unlock();
return false;
......
......@@ -1434,6 +1434,12 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
if(mcard->position & POS_FACEDOWN)
mcard = 0;
}
} else if(hovered_location == LOCATION_EXTRA) {
if(extra[hovered_controler].size()) {
mcard = extra[hovered_controler].back();
if(mcard->position & POS_FACEDOWN)
mcard = 0;
}
} else if(hovered_location == LOCATION_DECK) {
if(deck[hovered_controler].size())
mcard = deck[hovered_controler].back();
......@@ -1495,7 +1501,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
}else{
myswprintf(formatBuffer, L"\n%ls/%ls", mcard->atkstring, mcard->defstring);
str.append(formatBuffer);
wchar_t* form = L"\u2605";
const wchar_t* form = L"\u2605";
if (mcard->rank) form = L"\u2606";
if (mcard->rank && mcard->level)
myswprintf(formatBuffer, L"\n\u2606%d/\u2605%d %ls/%ls", mcard->level, mcard->rank, dataManager.FormatRace(mcard->race), dataManager.FormatAttribute(mcard->attribute));
......
......@@ -1322,7 +1322,7 @@ void Game::ShowCardInfo(int code, bool resize) {
wcscat(formatBuffer, dataManager.FormatLinkMarker(cd.link_marker));
}
else {
wchar_t* form = L"\u2605";
const wchar_t* form = L"\u2605";
if(cd.type & TYPE_XYZ) form = L"\u2606";
myswprintf(formatBuffer, L"[%ls%d] ", form, cd.level);
wchar_t adBuffer[16];
......
......@@ -11,22 +11,6 @@ bool exit_on_return = false;
bool open_file = false;
wchar_t open_file_name[256] = L"";
void GetParameter(char* param, const char* arg) {
#ifdef _WIN32
wchar_t arg1[260];
MultiByteToWideChar(CP_ACP, 0, arg, -1, arg1, 260);
BufferIO::EncodeUTF8(arg1, param);
#else
strcpy(param, arg);
#endif
}
void GetParameterW(wchar_t* param, const char* arg) {
#ifdef _WIN32
MultiByteToWideChar(CP_ACP, 0, arg, -1, param, 260);
#else
BufferIO::DecodeUTF8(arg, param);
#endif
}
void ClickButton(irr::gui::IGUIElement* btn) {
irr::SEvent event;
event.EventType = irr::EET_GUI_EVENT;
......@@ -50,11 +34,15 @@ int main(int argc, char* argv[]) {
#endif //__APPLE__
#ifdef _WIN32
#ifndef _DEBUG
char* pstrext;
if(argc == 2 && (pstrext = strrchr(argv[1], '.'))
&& (!mystrncasecmp(pstrext, ".ydk", 4) || !mystrncasecmp(pstrext, ".yrp", 4))) {
wchar_t exepath[MAX_PATH];
GetModuleFileNameW(NULL, exepath, MAX_PATH);
wchar_t* p = wcsrchr(exepath, '\\');
*p = '\0';
SetCurrentDirectoryW(exepath);
}
#endif //_DEBUG
#endif //_WIN32
#ifdef _WIN32
......@@ -71,103 +59,114 @@ int main(int argc, char* argv[]) {
if(!ygo::mainGame->Initialize())
return 0;
#ifdef _WIN32
int wargc;
wchar_t** wargv = CommandLineToArgvW(GetCommandLineW(), &wargc);
#else
int wargc = argc;
wchar_t (*wargv)[256] = new wchar_t[wargc][256];
for(int i = 0; i < argc; ++i) {
BufferIO::DecodeUTF8(argv[i], wargv[i]);
}
#endif //_WIN32
bool keep_on_return = false;
for(int i = 1; i < argc; ++i) {
if(argv[i][0] == '-' && argv[i][1] == 'e') {
for(int i = 1; i < wargc; ++i) {
if(wargv[i][0] == L'-' && wargv[i][1] == L'e' && wargv[i][2] != L'\0') {
char param[128];
GetParameter(param, &argv[i][2]);
BufferIO::EncodeUTF8(&wargv[i][2], param);
ygo::dataManager.LoadDB(param);
continue;
}
if(!strcmp(argv[i], "-e")) { // extra database
if(!wcscmp(wargv[i], L"-e")) { // extra database
++i;
if(i < wargc) {
char param[128];
GetParameter(param, &argv[i][0]);
BufferIO::EncodeUTF8(wargv[i], param);
ygo::dataManager.LoadDB(param);
}
continue;
} else if(!strcmp(argv[i], "-n")) { // nickName
} else if(!wcscmp(wargv[i], L"-n")) { // nickName
++i;
wchar_t param[128];
GetParameterW(param, &argv[i][0]);
ygo::mainGame->ebNickName->setText(param);
if(i < wargc)
ygo::mainGame->ebNickName->setText(wargv[i]);
continue;
} else if(!strcmp(argv[i], "-h")) { // Host address
} else if(!wcscmp(wargv[i], L"-h")) { // Host address
++i;
wchar_t param[128];
GetParameterW(param, &argv[i][0]);
ygo::mainGame->ebJoinHost->setText(param);
if(i < wargc)
ygo::mainGame->ebJoinHost->setText(wargv[i]);
continue;
} else if(!strcmp(argv[i], "-p")) { // host Port
} else if(!wcscmp(wargv[i], L"-p")) { // host Port
++i;
wchar_t param[128];
GetParameterW(param, &argv[i][0]);
ygo::mainGame->ebJoinPort->setText(param);
if(i < wargc)
ygo::mainGame->ebJoinPort->setText(wargv[i]);
continue;
} else if(!strcmp(argv[i], "-w")) { // host passWord
} else if(!wcscmp(wargv[i], L"-w")) { // host passWord
++i;
wchar_t param[128];
GetParameterW(param, &argv[i][0]);
ygo::mainGame->ebJoinPass->setText(param);
if(i < wargc)
ygo::mainGame->ebJoinPass->setText(wargv[i]);
continue;
} else if(!strcmp(argv[i], "-k")) { // Keep on return
} else if(!wcscmp(wargv[i], L"-k")) { // Keep on return
exit_on_return = false;
keep_on_return = true;
} else if(!strcmp(argv[i], "-d")) { // Deck
if(i + 2 < argc) { // select deck
} else if(!wcscmp(wargv[i], L"-d")) { // Deck
++i;
GetParameterW(ygo::mainGame->gameConf.lastdeck, &argv[i][0]);
if(i + 1 < wargc) { // select deck
wcscpy(ygo::mainGame->gameConf.lastdeck, wargv[i]);
continue;
} else { // open deck
exit_on_return = !keep_on_return;
if(i < argc) {
if(i < wargc) {
open_file = true;
GetParameterW(open_file_name, &argv[i + 1][0]);
wcscpy(open_file_name, wargv[i]);
}
ClickButton(ygo::mainGame->btnDeckEdit);
break;
}
} else if(!strcmp(argv[i], "-c")) { // Create host
} else if(!wcscmp(wargv[i], L"-c")) { // Create host
exit_on_return = !keep_on_return;
ygo::mainGame->HideElement(ygo::mainGame->wMainMenu);
ClickButton(ygo::mainGame->btnHostConfirm);
break;
} else if(!strcmp(argv[i], "-j")) { // Join host
} else if(!wcscmp(wargv[i], L"-j")) { // Join host
exit_on_return = !keep_on_return;
ygo::mainGame->HideElement(ygo::mainGame->wMainMenu);
ClickButton(ygo::mainGame->btnJoinHost);
break;
} else if(!strcmp(argv[i], "-r")) { // Replay
} else if(!wcscmp(wargv[i], L"-r")) { // Replay
exit_on_return = !keep_on_return;
if(i < argc) {
++i;
if(i < wargc) {
open_file = true;
GetParameterW(open_file_name, &argv[i + 1][0]);
wcscpy(open_file_name, wargv[i]);
}
ClickButton(ygo::mainGame->btnReplayMode);
if(open_file)
ClickButton(ygo::mainGame->btnLoadReplay);
break;
} else if(!strcmp(argv[i], "-s")) { // Single
} else if(!wcscmp(wargv[i], L"-s")) { // Single
exit_on_return = !keep_on_return;
if(i < argc) {
++i;
if(i < wargc) {
open_file = true;
GetParameterW(open_file_name, &argv[i + 1][0]);
wcscpy(open_file_name, wargv[i]);
}
ClickButton(ygo::mainGame->btnSingleMode);
if(open_file)
ClickButton(ygo::mainGame->btnLoadSinglePlay);
break;
} else if(argc == 2 && strlen(argv[1]) >= 4) {
char* pstrext = argv[1] + strlen(argv[1]) - 4;
if(!mystrncasecmp(pstrext, ".ydk", 4)) {
} else if(wargc == 2 && wcslen(wargv[1]) >= 4) {
wchar_t* pstrext = wargv[1] + wcslen(wargv[1]) - 4;
if(!mywcsncasecmp(pstrext, L".ydk", 4)) {
open_file = true;
GetParameterW(open_file_name, &argv[1][0]);
wcscpy(open_file_name, wargv[i]);
exit_on_return = !keep_on_return;
ClickButton(ygo::mainGame->btnDeckEdit);
break;
}
if(!mystrncasecmp(pstrext, ".yrp", 4)) {
if(!mywcsncasecmp(pstrext, L".yrp", 4)) {
open_file = true;
GetParameterW(open_file_name, &argv[1][0]);
wcscpy(open_file_name, wargv[i]);
exit_on_return = !keep_on_return;
ClickButton(ygo::mainGame->btnReplayMode);
ClickButton(ygo::mainGame->btnLoadReplay);
......@@ -175,6 +174,11 @@ int main(int argc, char* argv[]) {
}
}
}
#ifdef _WIN32
LocalFree(wargv);
#else
delete[] wargv;
#endif
ygo::mainGame->MainLoop();
#ifdef _WIN32
WSACleanup();
......
......@@ -222,7 +222,7 @@ namespace ygo {
size_t slen = cur_replay.ReadInt16();
cur_replay.ReadData(filename, slen);
filename[slen] = 0;
if(!preload_script(pduel, filename, slen))
if(!preload_script(pduel, filename, 0))
return false;
}
start_duel(pduel, opt);
......
......@@ -17,7 +17,7 @@ project "ygopro"
configuration {"windows", "not vs*"}
includedirs { "/mingw/include/irrlicht", "/mingw/include/freetype2" }
configuration "not vs*"
buildoptions { "-std=gnu++0x", "-fno-rtti", "-fpermissive" }
buildoptions { "-std=c++14", "-fno-rtti", "-fpermissive" }
configuration "not windows"
includedirs { "/usr/include/lua", "/usr/include/lua5.3", "/usr/include/lua/5.3", "/usr/include/irrlicht", "/usr/include/freetype2" }
excludes { "COSOperator.*" }
......
......@@ -198,7 +198,10 @@ bool Replay::OpenReplay(const wchar_t* name) {
}
if(!fp)
return false;
fread(&pheader, sizeof(pheader), 1, fp);
if(fread(&pheader, sizeof(pheader), 1, fp) < 1) {
fclose(fp);
return false;
}
if(pheader.flag & REPLAY_COMPRESSED) {
comp_size = fread(comp_data, 1, 0x20000, fp);
fclose(fp);
......@@ -227,9 +230,9 @@ bool Replay::CheckReplay(const wchar_t* name) {
if(!rfp)
return false;
ReplayHeader rheader;
fread(&rheader, sizeof(ReplayHeader), 1, rfp);
size_t count = fread(&rheader, sizeof(ReplayHeader), 1, rfp);
fclose(rfp);
return (rheader.id == 0x31707279 || rheader.id == 0x58707279) && rheader.version >= 0x12d0;
return count == 1 && (rheader.id == 0x31707279 || rheader.id == 0x58707279) && rheader.version >= 0x12d0;
}
bool Replay::ReadNextPacket(ReplayPacket* packet) {
if (pdata - replay_data >= (int)replay_size)
......
......@@ -54,17 +54,18 @@ int SingleMode::SinglePlayThread(void* param) {
myswprintf(mainGame->dInfo.strLP[1], L"%d", mainGame->dInfo.lp[1]);
BufferIO::CopyWStr(mainGame->ebNickName->getText(), mainGame->dInfo.hostname[0], 20);
mainGame->dInfo.clientname[0][0] = 0;
mainGame->dInfo.player_type = 0;
mainGame->dInfo.turn = 0;
char filename[256];
size_t slen = 0;
if(open_file) {
open_file = false;
slen = BufferIO::EncodeUTF8(open_file_name, filename);
if(!preload_script(pduel, filename, slen)) {
if(!preload_script(pduel, filename, 0)) {
wchar_t fname[256];
myswprintf(fname, L"./single/%ls", open_file_name);
slen = BufferIO::EncodeUTF8(fname, filename);
if(!preload_script(pduel, filename, slen))
if(!preload_script(pduel, filename, 0))
slen = 0;
}
} else {
......@@ -72,7 +73,7 @@ int SingleMode::SinglePlayThread(void* param) {
wchar_t fname[256];
myswprintf(fname, L"./single/%ls", name);
slen = BufferIO::EncodeUTF8(fname, filename);
if(!preload_script(pduel, filename, slen))
if(!preload_script(pduel, filename, 0))
slen = 0;
}
if(slen == 0) {
......
......@@ -1609,7 +1609,7 @@ void TagDuel::TimeConfirm(DuelPlayer* dp) {
event_add(etimer, &timeout);
}
void TagDuel::RefreshMzone(int player, int flag, int use_cache) {
char query_buffer[0x2000];
char query_buffer[0x4000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
......@@ -1637,7 +1637,7 @@ void TagDuel::RefreshMzone(int player, int flag, int use_cache) {
NetServer::ReSendToPlayer(*pit);
}
void TagDuel::RefreshSzone(int player, int flag, int use_cache) {
char query_buffer[0x2000];
char query_buffer[0x4000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
......@@ -1665,7 +1665,7 @@ void TagDuel::RefreshSzone(int player, int flag, int use_cache) {
NetServer::ReSendToPlayer(*pit);
}
void TagDuel::RefreshHand(int player, int flag, int use_cache) {
char query_buffer[0x2000];
char query_buffer[0x4000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
......@@ -1695,7 +1695,7 @@ void TagDuel::RefreshHand(int player, int flag, int use_cache) {
NetServer::ReSendToPlayer(*pit);
}
void TagDuel::RefreshGrave(int player, int flag, int use_cache) {
char query_buffer[0x2000];
char query_buffer[0x4000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
......@@ -1711,7 +1711,7 @@ void TagDuel::RefreshGrave(int player, int flag, int use_cache) {
replay_stream.push_back(p);
}
void TagDuel::RefreshExtra(int player, int flag, int use_cache) {
char query_buffer[0x2000];
char query_buffer[0x4000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
......@@ -1722,7 +1722,7 @@ void TagDuel::RefreshExtra(int player, int flag, int use_cache) {
replay_stream.push_back(p);
}
void TagDuel::RefreshSingle(int player, int location, int sequence, int flag) {
char query_buffer[0x2000];
char query_buffer[0x4000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_CARD);
BufferIO::WriteInt8(qbuf, player);
......
......@@ -29,7 +29,7 @@ solution "ygo"
configuration "vs*"
flags "EnableSSE2"
buildoptions { "-wd4996" }
buildoptions { "-wd4996", "/utf-8" }
defines { "_CRT_SECURE_NO_WARNINGS" }
configuration "not vs*"
......
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