1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

merge beta branch into develop

This commit is contained in:
Ivan Savenko 2022-12-29 22:08:53 +02:00
commit b275d9de72
11 changed files with 149 additions and 32 deletions

View File

@ -1079,7 +1079,8 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
if (displayIndex < 0)
displayIndex = 0;
}
#ifdef VCMI_IOS
#if defined(VCMI_ANDROID) || defined(VCMI_IOS)
SDL_GetWindowSize(mainWindow, &w, &h);
#else
if(!checkVideoMode(displayIndex, w, h))

View File

@ -409,6 +409,8 @@ void CMusicHandler::release()
void CMusicHandler::playMusic(const std::string & musicURI, bool loop, bool fromStart)
{
boost::mutex::scoped_lock guard(mutex);
if (current && current->isPlaying() && current->isTrack(musicURI))
return;
@ -422,6 +424,8 @@ void CMusicHandler::playMusicFromSet(const std::string & musicSet, const std::st
void CMusicHandler::playMusicFromSet(const std::string & whichSet, bool loop, bool fromStart)
{
boost::mutex::scoped_lock guard(mutex);
auto selectedSet = musicsSet.find(whichSet);
if (selectedSet == musicsSet.end())
{
@ -441,8 +445,6 @@ void CMusicHandler::queueNext(std::unique_ptr<MusicEntry> queued)
if (!initialized)
return;
boost::mutex::scoped_lock guard(mutex);
next = std::move(queued);
if (current.get() == nullptr || !current->stop(1000))
@ -487,13 +489,32 @@ void CMusicHandler::setVolume(ui32 percent)
void CMusicHandler::musicFinishedCallback()
{
boost::mutex::scoped_lock guard(mutex);
// boost::mutex::scoped_lock guard(mutex);
// FIXME: WORKAROUND FOR A POTENTIAL DEADLOCK
// It is possible for:
// 1) SDL thread to call this method on end of playback
// 2) VCMI code to call queueNext() method to queue new file
// this leads to:
// 1) SDL thread waiting to acquire music lock in this method (while keeping internal SDL mutex locked)
// 2) VCMI thread waiting to acquire internal SDL mutex (while keeping music mutex locked)
// Because of that (and lack of clear way to fix that)
// We will try to acquire lock here and if failed - do nothing
// This may break music playback till next song is enqued but won't deadlock the game
if (!mutex.try_lock())
{
logGlobal->error("Failed to acquire mutex! Unable to restart music!");
return;
}
if (current.get() != nullptr)
{
// if music is looped, play it again
if (current->play())
{
mutex.unlock();
return;
}
else
current.reset();
}
@ -503,6 +524,7 @@ void CMusicHandler::musicFinishedCallback()
current.reset(next.release());
current->play();
}
mutex.unlock();
}
MusicEntry::MusicEntry(CMusicHandler *owner, std::string setName, std::string musicURI, bool looped, bool fromStart):
@ -597,7 +619,7 @@ bool MusicEntry::play()
bool MusicEntry::stop(int fade_ms)
{
if (Mix_PlayingMusic())
if (playing)
{
playing = false;
loop = 0;

View File

@ -2251,6 +2251,8 @@ void CPlayerInterface::artifactRemoved(const ArtifactLocation &al)
if (artWin)
artWin->artifactRemoved(al);
}
waitWhileDialog();
}
void CPlayerInterface::artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst)
@ -2265,6 +2267,8 @@ void CPlayerInterface::artifactMoved(const ArtifactLocation &src, const Artifact
}
if(!GH.objsToBlit.empty())
GH.objsToBlit.back()->redraw();
waitWhileDialog();
}
void CPlayerInterface::artifactPossibleAssembling(const ArtifactLocation & dst)

View File

@ -235,7 +235,11 @@ std::shared_ptr<CButton> CMenuEntry::createButton(CMenuScreen * parent, const Js
if(posy < 0)
posy = pos.h + posy;
return std::make_shared<CButton>(Point(posx, posy), button["name"].String(), help, command, (int)button["hotkey"].Float());
auto result = std::make_shared<CButton>(Point(posx, posy), button["name"].String(), help, command, (int)button["hotkey"].Float());
if (button["center"].Bool())
result->moveBy(Point(-result->pos.w/2, -result->pos.h/2));
return result;
}
CMenuEntry::CMenuEntry(CMenuScreen * parent, const JsonNode & config)

View File

@ -11,12 +11,16 @@
[
{"type" : "lod", "path" : "Data/H3ab_bmp.lod"},
{"type" : "lod", "path" : "Data/H3bitmap.lod"},
{"type" : "lod", "path" : "Data/h3abp_bm.lod"}, // Polish version of H3 only
{"type" : "lod", "path" : "Data/H3pbitma.lod"}, // Polish version of H3 only
{"type" : "dir", "path" : "Data"}
],
"SPRITES/":
[
{"type" : "lod", "path" : "Data/H3ab_spr.lod"},
{"type" : "lod", "path" : "Data/H3sprite.lod"},
{"type" : "lod", "path" : "Data/h3abp_sp.lod"}, // Polish version of H3 only
{"type" : "lod", "path" : "Data/H3psprit.lod"}, // Polish version of H3 only
{"type" : "dir", "path" : "Sprites"}
],
"SOUNDS/":

View File

@ -10,29 +10,29 @@
"background" : "gamselbk",
//"scalable" : true, //background will be scaled to screen size
//"video" : {"x": 8, "y": 105, "name":"CREDITS.SMK" },//Floating WoG logo. Disabled due to different position in various versions of H3.
//"images" : [],//Optioal, contains any additional images in the same format as video
//"images" : [],//Optional, contains any additional images in the same format as video
"items" :
[
{
"name" : "main",
"buttons":
[
{"x": 540, "y": 10, "name":"MMENUNG", "hotkey" : 110, "help": 3, "command": "to new"},
{"x": 532, "y": 132, "name":"MMENULG", "hotkey" : 108, "help": 4, "command": "to load"},
{"x": 524, "y": 251, "name":"MMENUHS", "hotkey" : 104, "help": 5, "command": "highscores"},
{"x": 557, "y": 359, "name":"MMENUCR", "hotkey" : 99, "help": 6, "command": "to credits"},
{"x": 586, "y": 468, "name":"MMENUQT", "hotkey" : 27, "help": 7, "command": "exit"}
{"x": 644, "y": 70, "center" : true, "name":"MMENUNG", "hotkey" : 110, "help": 3, "command": "to new"},
{"x": 645, "y": 192, "center" : true, "name":"MMENULG", "hotkey" : 108, "help": 4, "command": "to load"},
{"x": 643, "y": 296, "center" : true, "name":"MMENUHS", "hotkey" : 104, "help": 5, "command": "highscores"},
{"x": 643, "y": 414, "center" : true, "name":"MMENUCR", "hotkey" : 99, "help": 6, "command": "to credits"},
{"x": 643, "y": 520, "center" : true, "name":"MMENUQT", "hotkey" : 27, "help": 7, "command": "exit"}
]
},
{
"name" : "new",
"buttons":
[
{"x": 545, "y": 4, "name":"GTSINGL", "hotkey" : 115, "help": 10, "command": "start single"},
{"x": 568, "y": 120, "name":"GTMULTI", "hotkey" : 109, "help": 12, "command": "start multi"},
{"x": 541, "y": 233, "name":"GTCAMPN", "hotkey" : 99, "help": 11, "command": "to campaign"},
{"x": 545, "y": 358, "name":"GTTUTOR", "hotkey" : 116, "help": 13, "command": "start tutorial"},
{"x": 582, "y": 464, "name":"GTBACK", "hotkey" : 27, "help": 14, "command": "to main"}
{"x": 649, "y": 65, "center" : true, "name":"GTSINGL", "hotkey" : 115, "help": 10, "command": "start single"},
{"x": 649, "y": 180, "center" : true, "name":"GTMULTI", "hotkey" : 109, "help": 12, "command": "start multi"},
{"x": 646, "y": 298, "center" : true, "name":"GTCAMPN", "hotkey" : 99, "help": 11, "command": "to campaign"},
{"x": 647, "y": 412, "center" : true, "name":"GTTUTOR", "hotkey" : 116, "help": 13, "command": "start tutorial"},
{"x": 645, "y": 517, "center" : true, "name":"GTBACK", "hotkey" : 27, "help": 14, "command": "to main"}
],
"images": [ {"x": 114, "y": 312, "name":"NEWGAME"} ]
},
@ -40,11 +40,11 @@
"name" : "load",
"buttons":
[
{"x": 545, "y": 8, "name":"GTSINGL", "hotkey" : 115, "help": 10, "command": "load single"},
{"x": 568, "y": 120, "name":"GTMULTI", "hotkey" : 109, "help": 12, "command": "load multi"},
{"x": 541, "y": 233, "name":"GTCAMPN", "hotkey" : 99, "help": 11, "command": "load campaign"},
{"x": 545, "y": 358, "name":"GTTUTOR", "hotkey" : 116, "help": 13, "command": "load tutorial"},
{"x": 582, "y": 464, "name":"GTBACK", "hotkey" : 27, "help": 14, "command": "to main"}
{"x": 649, "y": 65, "center" : true, "name":"GTSINGL", "hotkey" : 115, "help": 10, "command": "load single"},
{"x": 649, "y": 180, "center" : true, "name":"GTMULTI", "hotkey" : 109, "help": 12, "command": "load multi"},
{"x": 646, "y": 298, "center" : true, "name":"GTCAMPN", "hotkey" : 99, "help": 11, "command": "load campaign"},
{"x": 647, "y": 412, "center" : true, "name":"GTTUTOR", "hotkey" : 116, "help": 13, "command": "load tutorial"},
{"x": 645, "y": 517, "center" : true, "name":"GTBACK", "hotkey" : 27, "help": 14, "command": "to main"}
],
"images": [ {"x": 114, "y": 312, "name":"LOADGAME"} ]
},
@ -52,11 +52,11 @@
"name" : "campaign",
"buttons":
[
{"x": 535, "y": 4, "name":"CSSSOD", "hotkey" : 119, "command": "campaigns sod"},
{"x": 494, "y": 117, "name":"CSSROE", "hotkey" : 114, "command": "campaigns roe"},
{"x": 486, "y": 241, "name":"CSSARM", "hotkey" : 97, "command": "campaigns ab"},
{"x": 550, "y": 358, "name":"CSSCUS", "hotkey" : 99, "command": "start campaign"},
{"x": 582, "y": 464, "name":"GTBACK", "hotkey" : 27, "command": "to new"}
{"x": 634, "y": 67, "center" : true, "name":"CSSSOD", "hotkey" : 119, "command": "campaigns sod"},
{"x": 637, "y": 181, "center" : true, "name":"CSSROE", "hotkey" : 114, "command": "campaigns roe"},
{"x": 638, "y": 301, "center" : true, "name":"CSSARM", "hotkey" : 97, "command": "campaigns ab"},
{"x": 638, "y": 413, "center" : true, "name":"CSSCUS", "hotkey" : 99, "command": "start campaign"},
{"x": 639, "y": 518, "center" : true, "name":"CSSEXIT", "hotkey" : 27, "command": "to new"}
],
}
]

1
debian/rules vendored
View File

@ -8,6 +8,7 @@ override_dh_auto_configure:
dh_auto_configure -- \
-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=ON \
-DCMAKE_INSTALL_RPATH=/usr/lib/$(DEB_HOST_MULTIARCH)/vcmi \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DBIN_DIR=games \
-DFORCE_BUNDLED_FL=OFF \
-DENABLE_TEST=0

View File

@ -152,12 +152,12 @@ void CArchiveLoader::initSNDArchive(const std::string &mountPoint, CFileInputStr
char filename[40];
reader.read(reinterpret_cast<ui8*>(filename), 40);
//for some reason entries in snd have format NAME\0WAVRUBBISH....
//we need to replace first \0 with dot and take the 3 chars with extension (and drop the rest)
// for some reason entries in snd have format NAME\0WAVRUBBISH....
// and Polish version does not have extension at all
// we need to replace first \0 with dot and add wav extension manuall - we don't expect other types here anyway
ArchiveEntry entry;
entry.name = filename; // till 1st \0
entry.name += '.';
entry.name += std::string(filename + entry.name.size(), 3);
entry.name += ".wav";
entry.offset = reader.readInt32();
entry.fullSize = reader.readInt32();

View File

@ -31,9 +31,18 @@ using namespace boost::asio::ip;
#define LIL_ENDIAN
#endif
struct ConnectionBuffers
{
boost::asio::streambuf readBuffer;
boost::asio::streambuf writeBuffer;
};
void CConnection::init()
{
enableBufferedWrite = false;
enableBufferedRead = false;
connectionBuffers = std::make_unique<ConnectionBuffers>();
socket->set_option(boost::asio::ip::tcp::no_delay(true));
try
{
@ -72,6 +81,7 @@ CConnection::CConnection(std::string host, ui16 port, std::string Name, std::str
int i;
boost::system::error_code error = asio::error::host_not_found;
socket = std::make_shared<tcp::socket>(*io_service);
tcp::resolver resolver(*io_service);
tcp::resolver::iterator end, pom, endpoint_iterator = resolver.resolve(tcp::resolver::query(host, std::to_string(port)),error);
if(error)
@ -138,10 +148,39 @@ CConnection::CConnection(std::shared_ptr<TAcceptor> acceptor, std::shared_ptr<bo
}
init();
}
void CConnection::flushBuffers()
{
if(!enableBufferedWrite)
return;
try
{
asio::write(*socket, connectionBuffers->writeBuffer);
}
catch(...)
{
//connection has been lost
connected = false;
throw;
}
enableBufferedWrite = false;
}
int CConnection::write(const void * data, unsigned size)
{
try
{
if(enableBufferedWrite)
{
std::ostream ostream(&connectionBuffers->writeBuffer);
ostream.write(static_cast<const char *>(data), size);
return size;
}
int ret;
ret = static_cast<int>(asio::write(*socket,asio::const_buffers_1(asio::const_buffer(data,size))));
return ret;
@ -153,10 +192,29 @@ int CConnection::write(const void * data, unsigned size)
throw;
}
}
int CConnection::read(void * data, unsigned size)
{
try
{
if(enableBufferedRead)
{
auto available = connectionBuffers->readBuffer.size();
while(available < size)
{
auto bytesRead = socket->read_some(connectionBuffers->readBuffer.prepare(1024));
connectionBuffers->readBuffer.commit(bytesRead);
available = connectionBuffers->readBuffer.size();
}
std::istream istream(&connectionBuffers->readBuffer);
istream.read(static_cast<char *>(data), size);
return size;
}
int ret = static_cast<int>(asio::read(*socket,asio::mutable_buffers_1(asio::mutable_buffer(data,size))));
return ret;
}
@ -167,6 +225,7 @@ int CConnection::read(void * data, unsigned size)
throw;
}
}
CConnection::~CConnection()
{
if(handler)
@ -210,6 +269,8 @@ void CConnection::reportState(vstd::CLoggerBase * out)
CPack * CConnection::retrievePack()
{
enableBufferedRead = true;
CPack * pack = nullptr;
boost::unique_lock<boost::mutex> lock(*mutexRead);
iser & pack;
@ -222,6 +283,9 @@ CPack * CConnection::retrievePack()
{
pack->c = this->shared_from_this();
}
enableBufferedRead = false;
return pack;
}
@ -229,7 +293,12 @@ void CConnection::sendPack(const CPack * pack)
{
boost::unique_lock<boost::mutex> lock(*mutexWrite);
logNetwork->trace("Sending a pack of type %s", typeid(*pack).name());
enableBufferedWrite = true;
oser & pack;
flushBuffers();
}
void CConnection::disableStackSendingByID()

View File

@ -52,6 +52,7 @@ typedef boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::so
VCMI_LIB_NAMESPACE_BEGIN
struct CPack;
struct ConnectionBuffers;
/// Main class for network communication
/// Allows establishing connection and bidirectional read-write
@ -63,8 +64,14 @@ class DLL_LINKAGE CConnection
int write(const void * data, unsigned size) override;
int read(void * data, unsigned size) override;
void flushBuffers();
std::shared_ptr<boost::asio::io_service> io_service; //can be empty if connection made from socket
bool enableBufferedWrite;
bool enableBufferedRead;
std::unique_ptr<ConnectionBuffers> connectionBuffers;
public:
BinaryDeserializer iser;
BinarySerializer oser;

View File

@ -87,6 +87,11 @@ warning ()
warn_user=true
}
#checks whether specified directory exists. Also works with globs
dir_exists() {
[ -d "$1" ]
}
# check if selected options are correct.
if [[ -n "$data_dir" ]]
@ -177,7 +182,7 @@ then
cd "$data_dir" && innoextract "$gog_file"
# some versions of gog.com installer (or innoextract tool?) place game files inside /app directory
if [[ -d "$data_dir"/app ]]
if dir_exists "$data_dir"/app/[Dd][Aa][Tt][Aa]
then
data_dir="$data_dir"/app
fi