Skip to content

Commit

Permalink
Merge pull request #105 from IonAgorria/fixes
Browse files Browse the repository at this point in the history
Small fixes
  • Loading branch information
DileSoft authored May 19, 2022
2 parents f59de84 + 8bcb954 commit f58b3ae
Show file tree
Hide file tree
Showing 40 changed files with 257 additions and 176 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/windows_msvc_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
with:
vcpkgDirectory: '${{ github.workspace }}/vcpkg'
appendedCacheKey: '${{ env.VCPKG_DEFAULT_TRIPLET }}'
vcpkgGitCommitId: 1085a57da0725c19e19586025438e8c16f34c890
vcpkgGitCommitId: bd1ef2df46303989eeb048eb7aa9b816aa46365e
vcpkgJsonGlob: 'vcpkg.json'
runVcpkgInstall: false
- name: Configure developer command prompt
Expand Down
7 changes: 2 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ ELSE()
#ARM32/ARM64
IF (NOT PERIMETER_ARCH_64)
MESSAGE("CPU is ARM, using VFP WARNING: untested")
add_compile_options(-mfpmath=vfp)
add_compile_options(-mfpu=vfp)
ENDIF()
ENDIF()
ENDIF()
Expand Down Expand Up @@ -247,10 +247,7 @@ IF(NOT MSVC_CL_BUILD)
ENDIF()

add_compile_options(-Wno-unknown-pragmas) #TODO we should remove these pragmas?
IF (NOT ${CMAKE_SYSTEM_PROCESSOR} MATCHES "e2k")
#Compiler for Elbrus don't support this option
add_compile_options(-Werror=dangling-else)
ENDIF()
add_compile_options(-Werror=dangling-else)
add_compile_options(-Werror=return-type)
# add_compile_options(-Werror=switch) #TODO enable for strict check of switch block
# add_compile_options(-Werror=write-strings) #TODO enable this again
Expand Down
16 changes: 16 additions & 0 deletions MODDING.eng.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,19 @@ Original custom `.btdb` format is also accepted but `.txt` may be lot easier to

If you don't wish to replace existing texts if game already has loaded them you can add `_noreplace` to the file name
such as `MyTexts_noreplace.txt` or `MyTexts_noreplace.btdb`

## Stack Traces

Perimeter Release builds contain basic function names but it seems that in some OSes (Win10/11) the stacktrace
isn't properly printed, still is possible to reconstruct the stacktrace with proper symbol names by using the
a specific part of logfile.txt with same binary that stacktrace was made with. We can know what binary was by ensuring
that the version+date matches the one we are using like for example: `Version 3.0.10 Final (Apr 10 2022 00:39:40)`

Then we pick this line from logfile.txt:
`stack_reference=0x00007FF6176E4100 stack_frames=0x00007FF6176E4AFB,0x00007FF6176E5183,0x00007FF6176E545C,.......`

and call the binary with it like:
`perimeter stack_reference=0x00007FF6176E4100 stack_frames=0x00007FF6176E4AFB,0x0000.......`

which should print us a stacktrace with function names if your OS works with them, on Linux+WINE it seems to be possible
to reconstruct stacktraces with function names.
18 changes: 9 additions & 9 deletions Source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ SET(perimeter_LINK_LIBS
Render
Sound
Network
#Libraries
${SDL2_LIBRARY}
${SDL2_IMAGE_LIBRARY}
${SDL2_MIXER_LIBRARY}
${SDL2_NET_LIBRARY}
)

IF(FFMPEG_FOUND)
Expand Down Expand Up @@ -66,7 +61,7 @@ IF(NOT PERIMETER_WINDOWS)
ExternalProject_Add(dxvk-native
GIT_REPOSITORY https://github.com/IonAgorria/dxvk-native
GIT_TAG "2e91e784a86bc1355100518cd90eee48433551ac"
GIT_SHALLOW ON
GIT_SHALLOW OFF
BUILD_ALWAYS OFF
CONFIGURE_HANDLED_BY_BUILD ON
CONFIGURE_COMMAND ${DXVK_NATIVE_BUILD_COMMAND} ../dxvk-native --buildtype=release -Denable_d3d11=false -Denable_d3d10=false -Denable_dxgi=false
Expand Down Expand Up @@ -328,9 +323,14 @@ IF(PERIMETER_DEBUG)
SET(perimeter_LINK_LIBS ${perimeter_LINK_LIBS} XPrmLib)
ENDIF()

#Add SDL2 main
SET(perimeter_LINK_LIBS ${perimeter_LINK_LIBS}
${SDL2MAIN_LIBRARY}
SET(perimeter_LINK_LIBS
#Libraries
${perimeter_LINK_LIBS}
${SDL2MAIN_LIBRARY}
${SDL2_LIBRARY}
${SDL2_IMAGE_LIBRARY}
${SDL2_MIXER_LIBRARY}
${SDL2_NET_LIBRARY}
)

TARGET_LINK_LIBRARIES(perimeter ${perimeter_LINK_LIBS})
Expand Down
2 changes: 1 addition & 1 deletion Source/Game/GameContent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ void findGameContent() {
terminate_with_char(rootPathStr, PATH_SEP);
scannedPaths.insert(rootPathStr);
std::filesystem::path rootPath = std::filesystem::u8path(rootPathStr);
printf("Checking game content from: %s\n", rootPathStr.c_str());
printf("Checking game content from: %s absolute: %s\n", rootPathStr.c_str(), std::filesystem::absolute(rootPath).u8string().c_str());
if (std::filesystem::exists(rootPath)) {
clear_content_entries();
set_content_root_path(rootPath);
Expand Down
103 changes: 59 additions & 44 deletions Source/Game/Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,7 @@ void decode_stacktrace() {

void show_help() {
printf(
"Perimeter %s\n%s\n\n"
"Modding and debugging:\n"
" mods=0 - Disables mods folder loading\n"
" edit=1 - Enables mission editor mode, use map loading args or file open dialog will appear\n"
Expand Down Expand Up @@ -840,8 +841,12 @@ void show_help() {
" content=path/of/game - Use this path for game data/content (must contain Resource, Scripts...)\n"
" clearlocale=1 - Clears current default and displays language dialog\n"
" locale=Russian - Use different language than current default\n"
" --version -v - Shows version\n"
" --help -h /? - This help\n"
);
,
currentShortVersion,
currentVersion
);
ErrH.Exit();
}

Expand All @@ -862,6 +867,9 @@ int SDL_main(int argc, char *argv[])
std::string arg = string_to_lower(argv[i]);
if (arg == "help" || arg == "--help" || arg == "-h" || arg == "/?") {
show_help();
} else if (arg == "--version" || arg == "-v") {
printf("Perimeter %s\n%s\n", currentShortVersion, currentVersion);
ErrH.Exit();
}
}

Expand Down Expand Up @@ -1105,7 +1113,7 @@ void app_event_poll() {

if (closing) {
if(gameShell) {
if (gameShell->GameActive) {
if (gameShell->GameActive && !isShiftPressed()) {
//When game is running we want to gracefully shutdown the game by showing main menu
sKey k(VK_ESCAPE, true);
gameShell->KeyPressed(k);
Expand Down Expand Up @@ -1142,30 +1150,57 @@ void setLogicFp()
}

//-------------------------------------------------
#ifndef PERIMETER_EXODUS
//TODO remove this ifdef block once dialog stuff is ported

bool _setupFileDialog(std::string& filename, const char* initialDir, const char* extention, const char* title, bool save) {
std::u16string u16string_filename = utf8_to_utf16(filename.c_str());
u16string_filename.resize(2048);

UTF8_TO_WCHAR(initialDir, initialDir);
UTF8_TO_WCHAR(extention, extention);
UTF8_TO_WCHAR(title, title);

std::u16string filter = utf8_to_utf16(title);
filter += static_cast<char16_t>('\0');
filter += static_cast<char16_t>('*');
filter += static_cast<char16_t>('.');
filter += utf8_to_utf16(extention);
filter += static_cast<char16_t>('\0');
filter += static_cast<char16_t>('\0');

OPENFILENAMEW ofn;
memset(&ofn,0,sizeof(OPENFILENAMEW));
ofn.lpstrFile = checked_reinterpret_cast_ptr<char16_t, wchar_t>(u16string_filename.data());
ofn.nMaxFile = u16string_filename.capacity()-1;
ofn.lStructSize = sizeof(OPENFILENAMEW);
ofn.hwndOwner = hWndVisGeneric;
std::string fullTitle = save ? "Save: " : "Open: ";
fullTitle += title;
UTF8_TO_WCHAR(fullTitle, fullTitle.c_str());
ofn.lpstrTitle = wchar_fullTitle;
ofn.lpstrFilter = checked_reinterpret_cast_ptr<char16_t, wchar_t>(filter.data());;
ofn.lpstrInitialDir = wchar_initialDir;
ofn.Flags = OFN_PATHMUSTEXIST|OFN_HIDEREADONLY|OFN_EXPLORER|OFN_NOCHANGEDIR;
ofn.lpstrDefExt = wchar_extention;

if (save) {
if (!GetSaveFileNameW(&ofn))
return false;
} else {
if (!GetOpenFileNameW(&ofn))
return false;
}

filename = utf16_to_utf8(u16string_filename);
return true;
}
#endif

bool openFileDialog(std::string& filename, const char* initialDir, const char* extention, const char* title)
{
XBuffer filter;
filter < title < '\0' < "*." < extention < '\0' < '\0';

#ifndef PERIMETER_EXODUS
OPENFILENAMEA ofn;
memset(&ofn,0,sizeof(ofn));
char fname[2048];
strcpy(fname,filename.c_str());
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hWndVisGeneric;
std::string fullTitle = std::string("Open: ") + title;
ofn.lpstrTitle = fullTitle.c_str();
ofn.lpstrFilter = filter;
ofn.lpstrFile = fname;
ofn.nMaxFile = sizeof(fname)-1;
ofn.lpstrInitialDir = initialDir;
ofn.Flags = OFN_PATHMUSTEXIST|OFN_HIDEREADONLY|OFN_EXPLORER|OFN_NOCHANGEDIR;
ofn.lpstrDefExt = extention;
if(!GetOpenFileNameA(&ofn))
return false;
filename = fname;
return true;
return _setupFileDialog(filename, initialDir, extention, title, false);
#else
//TODO
return false;
Expand All @@ -1174,28 +1209,8 @@ bool openFileDialog(std::string& filename, const char* initialDir, const char* e

bool saveFileDialog(std::string& filename, const char* initialDir, const char* extention, const char* title)
{
XBuffer filter;
filter < title < '\0' < "*." < extention < '\0' < '\0';

#ifndef PERIMETER_EXODUS
OPENFILENAMEA ofn;
memset(&ofn,0,sizeof(ofn));
char fname[2048];
strcpy(fname,filename.c_str());
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hWndVisGeneric;
std::string fullTitle = std::string("Save: ") + title;
ofn.lpstrTitle = fullTitle.c_str();
ofn.lpstrFilter = filter;
ofn.lpstrFile = fname;
ofn.nMaxFile = sizeof(fname)-1;
ofn.lpstrInitialDir = initialDir;
ofn.Flags = OFN_PATHMUSTEXIST|OFN_HIDEREADONLY|OFN_EXPLORER|OFN_NOCHANGEDIR;
ofn.lpstrDefExt = extention;
if(!GetSaveFileNameA(&ofn))
return false;
filename = fname;
return true;
return _setupFileDialog(filename, initialDir, extention, title, true);
#else
//TODO
return false;
Expand Down
5 changes: 2 additions & 3 deletions Source/Game/Universe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -713,12 +713,11 @@ bool MissionDescription::loadMission(SavePrm& savePrm) const
bool MissionDescription::saveMission(const SavePrm& savePrm, bool userSave) const
{
MissionDescription data = *this;

data.playerAmountScenarioMax = static_cast<int>(!userSave ? savePrm.manualData.players.size() : universe()->Players.size() - 1);

data.gameContent = missionNumber < 0 ? terGameContentSelect : getGameContentCampaign();

if(!userSave){
if(!userSave) {
data.playerAmountScenarioMax = static_cast<int>(savePrm.manualData.players.size());
data.activePlayerID = 0;
data.fitPlayerArrays();
for (int i = 0; i < data.playersData.size(); i++) {
Expand Down
4 changes: 2 additions & 2 deletions Source/Game/qd_textdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ bool qdTextDB::load(const std::string& locale, const char* file_name, const char

load_lines(lines, replace_old_texts, locale);
} else {
bool russian = locale == "russian";
bool russian = startsWith(locale, "russian");
int text_cnt;
fh > text_cnt;

Expand Down Expand Up @@ -269,7 +269,7 @@ void qdTextDB::load_lines(const std::vector<std::string>& lines, bool replace_ol

void qdTextDB::load_supplementary_texts(const std::string& locale) {
//Load per language texts
if (locale == "russian") {
if (startsWith(locale, "russian")) {
load_lines({
"GAME_CONTENT.PERIMETER=Периметр",
"GAME_CONTENT.PERIMETER_ET=Периметр: Завет Императора",
Expand Down
5 changes: 5 additions & 0 deletions Source/Network/NetConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ uint32_t NetAddress::crc() const {
}

uint16_t NetAddress::port() const {
#if SDL_DATA_ALIGNED
//In SDL2_net When SDL_DATA_ALIGNED is set it uses SDLNet_Read16 without const, probably a mistake
return SDLNet_Read16(const_cast<Uint16*>(&addr.port));
#else
return SDLNet_Read16(&addr.port);
#endif
}

std::string NetAddress::getString() const {
Expand Down
7 changes: 5 additions & 2 deletions Source/Network/NetConnectionAux.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ class NetConnectionInfo {

//Release build - 0 (1) bit
#if defined(_FINAL_VERSION_) && !defined(PERIMETER_DEBUG)
val |= 1;
//Don't set if debug_key_handler is active in Release
if (!check_command_line("debug_key_handler")) {
val |= 1;
}
#endif

//Compiler type - 1-7 (7) bits
Expand All @@ -66,7 +69,7 @@ class NetConnectionInfo {
xassert(compiler <= 0x7F);
val |= compiler<<1;

//OS type - 8-15 (8) bits
//OS type - 8-16 (8) bits
arch_flags os;
#if defined(__linux__)
os = 1;
Expand Down
14 changes: 4 additions & 10 deletions Source/Network/P2P_interface1Th.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,24 +433,18 @@ void PNetCenter::HandlerInputNetCommand()
fprintf(stderr, "%d Error network synchronization, dumped at: %s\n", clocki(), crash_dir.c_str());

std::unique_ptr<LocalizedText> text = std::make_unique<LocalizedText>(
qdTextDB::instance().getText("Interface.Menu.Messages.Multiplayer.Nonsinchronization")
qdTextDB::instance().getText("Interface.Menu.Messages.Multiplayer.Nonsinchronization"),
getLocale()
);
text->text += " " + std::to_string(nc.desync_amount);
ExecuteInterfaceCommand(
PNC_INTERFACE_COMMAND_INFO_MESSAGE,
std::move(text)
);

#if !defined(PERIMETER_DEBUG) && !defined(_DO_LOG_)
//Do not send binary and script data to host except host itself
if (m_localNETID != m_hostNETID) {
md->binaryData.alloc(0);
md->scriptsData.alloc(0);
}
#endif

//Trim some data in partial mode
if (nc.desync_amount < PNC_DESYNC_RESTORE_MODE_FULL) {
//Also trim some data in partial mode
if (m_localNETID != m_hostNETID || nc.desync_amount < PNC_DESYNC_RESTORE_MODE_FULL) {
md->binaryData.alloc(0);
md->scriptsData.alloc(0);
}
Expand Down
23 changes: 14 additions & 9 deletions Source/Network/P2P_interface2Th.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -949,7 +949,7 @@ end_while_01:;
fprintf(stderr, "Dumped desync restore data at: %s\n", crash_dir.c_str());
create_directories(crash_dir);
for (auto& client : to_restore) {
std::string path = crash_dir + std::to_string(client->netidPlayer) + "_" + client->playerName;
std::string path = crash_dir + std::to_string(client->netidPlayer);

if (client->desync_netlog.tell()) {
XStream ffnl(setExtension(path, "log").c_str(), XS_OUT, 0);
Expand All @@ -964,13 +964,18 @@ end_while_01:;

client->desync_missionDescription->setSaveName(path.c_str());

XStream ffp(setExtension(path, "prm").c_str(), XS_OUT, 0);
ffp.write(mission.saveData, mission.saveData.length());
ffp.close();
//Save client mission data if any
if (mission.saveData.length()) {
XStream ffp(setExtension(path, "prm").c_str(), XS_OUT, 0);
ffp.write(mission.saveData, mission.saveData.length());
ffp.close();
}

XStream ffb(setExtension(path, "bin").c_str(), XS_OUT, 0);
ffb.write(mission.binaryData, mission.binaryData.length());
ffb.close();
if (mission.binaryData.length()) {
XStream ffb(setExtension(path, "bin").c_str(), XS_OUT, 0);
ffb.write(mission.binaryData, mission.binaryData.length());
ffb.close();
}

//Load save data into IA and deserialize
SavePrm savePrm;
Expand Down Expand Up @@ -1340,11 +1345,11 @@ void PNetCenter::HostReceiveQuant()
mission.disconnect2PlayerData(ncChRT.idxPlayerData_);
if (isSave) {
if (ncChRT.newRealPlayerType_ == REAL_PLAYER_TYPE_OPEN || ncChRT.newRealPlayerType_ == REAL_PLAYER_TYPE_PLAYER_AI) {
pd.realPlayerType = pd.realPlayerType;
pd.realPlayerType = ncChRT.newRealPlayerType_;
}
} else {
if (ncChRT.newRealPlayerType_ == REAL_PLAYER_TYPE_OPEN || ncChRT.newRealPlayerType_ == REAL_PLAYER_TYPE_CLOSE) {
pd.realPlayerType = pd.realPlayerType;
pd.realPlayerType = ncChRT.newRealPlayerType_;
}
}
RemovePlayer(delPlayerNETID);
Expand Down
Loading

0 comments on commit f58b3ae

Please sign in to comment.