Commit 8852d5f2 authored by mercury233's avatar mercury233

Merge branch 'server' into next-mt

parents 0054cb23 42290b43
......@@ -118,28 +118,23 @@ void ClientField::Clear() {
tag_surrender = false;
tag_teammate_surrender = false;
}
void ClientField::Initial(int player, int deckc, int extrac) {
ClientCard* pcard;
for(int i = 0; i < deckc; ++i) {
pcard = new ClientCard;
deck[player].push_back(pcard);
pcard->owner = player;
pcard->controler = player;
pcard->location = LOCATION_DECK;
pcard->sequence = i;
pcard->position = POS_FACEDOWN_DEFENSE;
GetCardLocation(pcard, &pcard->curPos, &pcard->curRot, true);
}
for(int i = 0; i < extrac; ++i) {
pcard = new ClientCard;
extra[player].push_back(pcard);
pcard->owner = player;
pcard->controler = player;
pcard->location = LOCATION_EXTRA;
pcard->sequence = i;
pcard->position = POS_FACEDOWN_DEFENSE;
GetCardLocation(pcard, &pcard->curPos, &pcard->curRot, true);
}
void ClientField::Initial(int player, int deckc, int extrac, int sidec) {
auto load_location = [&](std::vector<ClientCard*>& container, int count, uint8_t location) {
for(int i = 0; i < count; ++i) {
ClientCard* pcard = new ClientCard;
container.push_back(pcard);
pcard->owner = player;
pcard->controler = player;
pcard->location = location;
pcard->sequence = i;
pcard->position = POS_FACEDOWN_DEFENSE;
GetCardLocation(pcard, &pcard->curPos, &pcard->curRot, true);
}
};
load_location(deck[player], deckc, LOCATION_DECK);
load_location(extra[player], extrac, LOCATION_EXTRA);
load_location(remove[player], sidec, LOCATION_REMOVED);
}
void ClientField::ResetSequence(std::vector<ClientCard*>& list, bool reset_height) {
unsigned char seq = 0;
......
......@@ -95,7 +95,7 @@ public:
ClientField();
~ClientField();
void Clear();
void Initial(int player, int deckc, int extrac);
void Initial(int player, int deckc, int extrac, int sidec = 0);
void ResetSequence(std::vector<ClientCard*>& list, bool reset_height);
ClientCard* GetCard(int controler, int location, int sequence, int sub_seq = 0);
void AddCard(ClientCard* pcard, int controler, int location, int sequence);
......
......@@ -1261,12 +1261,8 @@ void Game::DrawDeckBd() {
driver->draw2DRectangle(Resize(805, 160, 1020, 630), 0x400000ff, 0x400000ff, 0x40000000, 0x40000000);
driver->draw2DRectangleOutline(Resize(804, 159, 1020, 630));
}
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
constexpr int MAX_RESULT = 9;
#else
constexpr int MAX_RESULT = 7;
#endif
for(int i = 0; i < MAX_RESULT && i + scrFilter->getPos() < (int)deckBuilder.results.size(); ++i) {
int max_result = mainGame->gameConf.use_image_load_background_thread ? 9 : 7;
for(int i = 0; i < max_result && i + scrFilter->getPos() < (int)deckBuilder.results.size(); ++i) {
code_pointer ptr = deckBuilder.results[i + scrFilter->getPos()];
if(i >= 7)
{
......
......@@ -432,11 +432,11 @@ void DuelClient::HandleSTOCPacketLan(unsigned char* data, int len) {
int deckc = BufferIO::ReadInt16(pdata);
int extrac = BufferIO::ReadInt16(pdata);
int sidec = BufferIO::ReadInt16(pdata);
mainGame->dField.Initial(0, deckc, extrac);
mainGame->dField.Initial(0, deckc, extrac, sidec);
deckc = BufferIO::ReadInt16(pdata);
extrac = BufferIO::ReadInt16(pdata);
sidec = BufferIO::ReadInt16(pdata);
mainGame->dField.Initial(1, deckc, extrac);
mainGame->dField.Initial(1, deckc, extrac, sidec);
mainGame->gMutex.unlock();
break;
}
......
......@@ -1397,6 +1397,10 @@ void Game::LoadConfig() {
gameConf.use_d3d = std::strtol(valbuf, nullptr, 10) > 0;
} else if(!std::strcmp(strbuf, "use_image_scale")) {
gameConf.use_image_scale = std::strtol(valbuf, nullptr, 10) > 0;
} else if (!std::strcmp(strbuf, "use_image_scale_multi_thread")) {
gameConf.use_image_scale_multi_thread = std::strtol(valbuf, nullptr, 10) > 0;
} else if (!std::strcmp(strbuf, "use_image_load_background_thread")) {
gameConf.use_image_load_background_thread = std::strtol(valbuf, nullptr, 10) > 0;
} else if(!std::strcmp(strbuf, "errorlog")) {
unsigned int val = std::strtol(valbuf, nullptr, 10);
enable_log = val & 0xff;
......@@ -1528,6 +1532,8 @@ void Game::SaveConfig() {
char linebuf[CONFIG_LINE_SIZE];
std::fprintf(fp, "use_d3d = %d\n", gameConf.use_d3d ? 1 : 0);
std::fprintf(fp, "use_image_scale = %d\n", gameConf.use_image_scale ? 1 : 0);
std::fprintf(fp, "use_image_scale_multi_thread = %d\n", gameConf.use_image_scale_multi_thread ? 1 : 0);
std::fprintf(fp, "use_image_load_background_thread = %d\n", gameConf.use_image_load_background_thread ? 1 : 0);
std::fprintf(fp, "antialias = %d\n", gameConf.antialias);
std::fprintf(fp, "errorlog = %u\n", enable_log);
BufferIO::CopyWideString(ebNickName->getText(), gameConf.nickname);
......
......@@ -58,6 +58,12 @@ bool IsExtension(const char* filename, const char(&extension)[N]) {
struct Config {
bool use_d3d{ false };
bool use_image_scale{ true };
bool use_image_scale_multi_thread{ true };
#ifdef _OPENMP
bool use_image_load_background_thread{ false };
#else
bool use_image_load_background_thread{ true };
#endif
unsigned short antialias{ 0 };
unsigned short serverport{ 7911 };
unsigned char textfontsize{ 14 };
......@@ -325,7 +331,7 @@ public:
irr::gui::CGUITTFont* numFont;
irr::gui::CGUITTFont* adFont;
irr::gui::CGUITTFont* lpcFont;
std::map<irr::gui::CGUIImageButton*, int> imageLoading;
std::unordered_map<irr::gui::CGUIImageButton*, int> imageLoading;
//card image
irr::gui::IGUIStaticText* wCardImg;
irr::gui::IGUIImage* imgCard;
......
#include "image_manager.h"
#include "game.h"
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
#include <thread>
#endif
#ifdef _OPENMP
#include <omp.h>
#endif
......@@ -22,10 +20,8 @@ bool ImageManager::Initial() {
tUnknownFit = nullptr;
tUnknownThumb = nullptr;
tBigPicture = nullptr;
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
tLoading = nullptr;
tThumbLoadingThreadRunning = false;
#endif
tAct = driver->getTexture("textures/act.png");
tAttack = driver->getTexture("textures/attack.png");
tChain = driver->getTexture("textures/chain.png");
......@@ -66,11 +62,7 @@ void ImageManager::ClearTexture() {
driver->removeTexture(tit->second);
}
for(auto tit = tThumb.begin(); tit != tThumb.end(); ++tit) {
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
if(tit->second && tit->second != tLoading)
#else
if(tit->second)
#endif
driver->removeTexture(tit->second);
}
if(tBigPicture != nullptr) {
......@@ -80,14 +72,12 @@ void ImageManager::ClearTexture() {
tMap[0].clear();
tMap[1].clear();
tThumb.clear();
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
tThumbLoadingMutex.lock();
tThumbLoading.clear();
while(!tThumbLoadingCodes.empty())
tThumbLoadingCodes.pop();
tThumbLoadingThreadRunning = false;
tThumbLoadingMutex.unlock();
#endif
tFields.clear();
}
void ImageManager::RemoveTexture(int code) {
......@@ -123,10 +113,8 @@ void ImageManager::ResizeTexture() {
driver->removeTexture(tUnknown);
driver->removeTexture(tUnknownFit);
driver->removeTexture(tUnknownThumb);
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
driver->removeTexture(tLoading);
tLoading = GetTextureFromFile("textures/cover.jpg", imgWidthThumb, imgHeightThumb);
#endif
tUnknown = GetTextureFromFile("textures/unknown.jpg", CARD_IMG_WIDTH, CARD_IMG_HEIGHT);
tUnknownFit = GetTextureFromFile("textures/unknown.jpg", imgWidthFit, imgHeightFit);
tUnknownThumb = GetTextureFromFile("textures/unknown.jpg", imgWidthThumb, imgHeightThumb);
......@@ -150,7 +138,7 @@ void imageScaleNNAA(irr::video::IImage *src, irr::video::IImage *dest) {
const double rx = (double)srcDim.Width / destDim.Width;
const double ry = (double)srcDim.Height / destDim.Height;
#pragma omp parallel
#pragma omp parallel if(mainGame->gameConf.use_image_scale_multi_thread)
{
double sx, sy, minsx, maxsx, minsy, maxsy, area, ra, ga, ba, aa, pw, ph, pa;
irr::video::SColor pxl, npxl;
......@@ -298,7 +286,6 @@ irr::video::ITexture* ImageManager::GetBigPicture(int code, float zoom) {
tBigPicture = texture;
return texture;
}
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
int ImageManager::LoadThumbThread() {
while(true) {
imageManager.tThumbLoadingMutex.lock();
......@@ -354,13 +341,11 @@ int ImageManager::LoadThumbThread() {
imageManager.tThumbLoadingMutex.unlock();
return 0;
}
#endif // YGOPRO_USE_THUMB_LOAD_THREAD
irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
if(code == 0)
return tUnknownThumb;
#ifndef YGOPRO_USE_THUMB_LOAD_THREAD
auto tit = tThumb.find(code);
if(tit == tThumb.end()) {
if(tit == tThumb.end() && !mainGame->gameConf.use_image_load_background_thread) {
char file[256];
std::snprintf(file, sizeof file, "expansions/pics/thumbnail/%d.jpg", code);
int width = CARD_THUMB_WIDTH * mainGame->xScale;
......@@ -381,23 +366,24 @@ irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
tThumb[code] = img;
return (img == NULL) ? tUnknownThumb : img;
}
#else // YGOPRO_USE_THUMB_LOAD_THREAD
imageManager.tThumbLoadingMutex.lock();
auto lit = tThumbLoading.find(code);
if(lit != tThumbLoading.end()) {
if(lit->second != nullptr) {
char file[256];
std::snprintf(file, sizeof file, "pics/thumbnail/%d.jpg", code);
irr::video::ITexture* texture = driver->addTexture(file, lit->second); // textures must be added in the main thread due to OpenGL
lit->second->drop();
tThumb[code] = texture;
} else {
tThumb[code] = nullptr;
if(tit == tThumb.end() || tit->second == tLoading) {
imageManager.tThumbLoadingMutex.lock();
auto lit = tThumbLoading.find(code);
if(lit != tThumbLoading.end()) {
if(lit->second != nullptr) {
char file[256];
std::snprintf(file, sizeof file, "pics/thumbnail/%d.jpg", code);
irr::video::ITexture* texture = driver->addTexture(file, lit->second); // textures must be added in the main thread due to OpenGL
lit->second->drop();
tThumb[code] = texture;
} else {
tThumb[code] = nullptr;
}
tThumbLoading.erase(lit);
}
tThumbLoading.erase(lit);
imageManager.tThumbLoadingMutex.unlock();
tit = tThumb.find(code);
}
imageManager.tThumbLoadingMutex.unlock();
auto tit = tThumb.find(code);
if(tit == tThumb.end()) {
tThumb[code] = tLoading;
imageManager.tThumbLoadingMutex.lock();
......@@ -409,7 +395,6 @@ irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
imageManager.tThumbLoadingMutex.unlock();
return tLoading;
}
#endif // YGOPRO_USE_THUMB_LOAD_THREAD
if(tit->second)
return tit->second;
else
......
#ifndef IMAGEMANAGER_H
#define IMAGEMANAGER_H
#ifndef _OPENMP
#define YGOPRO_USE_THUMB_LOAD_THREAD
#endif
#include "config.h"
#include "data_manager.h"
#include <unordered_map>
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
#include <queue>
#include <mutex>
#endif
namespace ygo {
......@@ -27,19 +21,15 @@ public:
irr::video::ITexture* GetBigPicture(int code, float zoom);
irr::video::ITexture* GetTextureThumb(int code);
irr::video::ITexture* GetTextureField(int code);
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
static int LoadThumbThread();
#endif
std::unordered_map<int, irr::video::ITexture*> tMap[2];
std::unordered_map<int, irr::video::ITexture*> tThumb;
std::unordered_map<int, irr::video::ITexture*> tFields;
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
std::unordered_map<int, irr::video::IImage*> tThumbLoading;
std::queue<int> tThumbLoadingCodes;
std::mutex tThumbLoadingMutex;
bool tThumbLoadingThreadRunning;
#endif
irr::IrrlichtDevice* device;
irr::video::IVideoDriver* driver;
irr::video::ITexture* tCover[4];
......@@ -47,9 +37,7 @@ public:
irr::video::ITexture* tUnknownFit;
irr::video::ITexture* tUnknownThumb;
irr::video::ITexture* tBigPicture;
#ifdef YGOPRO_USE_THUMB_LOAD_THREAD
irr::video::ITexture* tLoading;
#endif
irr::video::ITexture* tAct;
irr::video::ITexture* tAttack;
irr::video::ITexture* tNegated;
......
......@@ -145,6 +145,7 @@ void Replay::SaveReplay(const wchar_t* name) {
std::fwrite(comp_data, comp_size, 1, rfp);
std::fclose(rfp);
}
#ifndef YGOPRO_SERVER_MODE
bool Replay::OpenReplay(const wchar_t* name) {
FILE* rfp = mywfopen(name, "rb");
if(!rfp) {
......@@ -169,7 +170,7 @@ bool Replay::OpenReplay(const wchar_t* name) {
std::fclose(rfp);
return false;
}
if (pheader.base.id == REPLAY_ID_YRP2 && std::fread(&pheader.seed_sequence, sizeof pheader.seed_sequence, 1, rfp) < 1) {
if (pheader.base.id == REPLAY_ID_YRP2 && std::fread(reinterpret_cast<unsigned char*>(&pheader) + sizeof pheader.base, sizeof pheader - sizeof pheader.base, 1, rfp) < 1) {
std::fclose(rfp);
return false;
}
......@@ -260,6 +261,7 @@ void Replay::Rewind() {
data_position = 0;
can_read = true;
}
#endif // YGOPRO_SERVER_MODE
void Replay::Reset() {
is_recording = false;
is_replaying = false;
......@@ -273,6 +275,7 @@ void Replay::Reset() {
decks.clear();
script_name.clear();
}
#ifndef YGOPRO_SERVER_MODE
void Replay::SkipInfo(){
if (data_position == 0)
data_position += info_offset;
......@@ -330,5 +333,6 @@ bool Replay::ReadInfo() {
}
return true;
}
#endif // YGOPRO_SERVER_MODE
}
......@@ -83,6 +83,9 @@ public:
return deck_index;
}
}
#ifdef YGOPRO_SERVER_MODE
void Reset();
#else
bool OpenReplay(const wchar_t* name);
bool ReadNextResponse(unsigned char resp[]);
bool ReadName(wchar_t* data);
......@@ -99,6 +102,7 @@ public:
void Reset();
void SkipInfo();
bool IsReplaying() const;
#endif // YGOPRO_SERVER_MODE
FILE* fp{ nullptr };
#ifdef _WIN32
......@@ -116,7 +120,9 @@ public:
std::string script_name; // 2 bytes, script name (max: 256 bytes)
private:
#ifndef YGOPRO_SERVER_MODE
bool ReadInfo();
#endif
unsigned char* replay_data;
size_t replay_size{};
......
......@@ -541,9 +541,9 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
rh.base.flag = REPLAY_UNIFORM;
rh.base.start_time = (uint32_t)std::time(nullptr);
#ifdef YGOPRO_SERVER_MODE
if(pre_seed_specified[duel_count])
memcpy(rh.seed_sequence, pre_seed[duel_count], SEED_COUNT * sizeof(uint32_t));
else
if (pre_seed_specified[duel_count])
memcpy(rh.seed_sequence, pre_seed[duel_count], SEED_COUNT * sizeof(uint32_t));
else
#endif
for (auto& x : rh.seed_sequence)
x = rd();
......
......@@ -517,9 +517,9 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
rh.base.flag = REPLAY_UNIFORM | REPLAY_TAG;
rh.base.start_time = (uint32_t)std::time(nullptr);
#ifdef YGOPRO_SERVER_MODE
if(pre_seed_specified[0])
memcpy(rh.seed_sequence, pre_seed[0], SEED_COUNT * sizeof(uint32_t));
else
if (pre_seed_specified[0])
memcpy(rh.seed_sequence, pre_seed[0], SEED_COUNT * sizeof(uint32_t));
else
#endif
for (auto& x : rh.seed_sequence)
x = rd();
......
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