Merge pull request #520 from winterheart/sleep-crossplatform

Crossplatform enhancements
This commit is contained in:
Louis Gombert 2024-08-21 21:33:29 +02:00 committed by GitHub
commit d91f4357f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
48 changed files with 286 additions and 856 deletions

View File

@ -50,9 +50,7 @@
#ifndef __BRIEFPARSE_H_
#define __BRIEFPARSE_H_
#if defined(POSIX)
#include "linux_fix.h" //for stricmp
#endif
#include "crossplat.h" //for stricmp
#include "TelComEfxStructs.h"
#include "grdefs.h"

View File

@ -798,9 +798,10 @@
* $NoKeywords: $
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <cstdio>
#include <cstring>
#include "chrono_timer.h"
#include "gameloop.h"
#include "game.h"
#include "render.h"
@ -814,56 +815,39 @@
#include "player.h"
#include "damage.h"
#include "ship.h"
#include "objinit.h"
#include "gameevent.h"
#include "gametexture.h"
#include "AIMain.h"
#include "ddvid.h"
#include "ddio.h"
#include "hud.h"
#include "terrain.h"
#include "BOA.h"
#include "lighting.h"
#include "findintersection.h"
#include "soar.h"
#include "multi.h"
#include "hud.h"
#include "bsp.h"
#include "gauges.h"
#include "SmallViews.h"
#include "newui.h"
#include "Inventory.h"
#include "physics.h"
#include "Controller.h"
#include "controls.h"
#include "gamesequence.h"
#include "cockpit.h"
#include "help.h"
#include "game.h"
#include "aipath.h"
#include "game2dll.h"
#include "Mission.h"
#include "object_lighting.h"
#include "fireball.h"
#include "weather.h"
#include "stringtable.h"
#include "streamaudio.h"
#include "voice.h"
#include "soundload.h"
#include "sounds.h"
#include "ambient.h"
#include "ship.h"
#include "config.h"
#include "matcen.h"
#include "dedicated_server.h"
#include "D3ForceFeedback.h"
#include "levelgoal.h"
#include "demofile.h"
#include "pilot.h"
#include "rtperformance.h"
#include "demofile.h"
#include "d3music.h"
// #include "gamespy.h"
#include "osiris_dll.h"
#include "aiambient.h"
#include "marker.h"
@ -871,7 +855,6 @@
#include "postrender.h"
#include "debuggraph.h"
#include "gamesave.h"
#include "psrand.h"
#include "spew.h"
#include "grtext.h"
#include "gamefont.h"
@ -3041,7 +3024,7 @@ void GameFrame(void) {
Cinematic_Frame();
} else {
Sleep(3);
D3::ChronoTimer::SleepMS(3);
}
// do music always.
@ -3089,7 +3072,7 @@ void GameFrame(void) {
if ((current_timer - last_timer) < Min_allowed_frametime) {
sleeptime = (uint32_t)Min_allowed_frametime - (current_timer - last_timer);
// mprintf(0,"Sleeping for %d ms\n",sleeptime);
Sleep(sleeptime);
D3::ChronoTimer::SleepMS(sleeptime);
}
static int graph_id = -2;

View File

@ -883,7 +883,6 @@ void Osiris_UnloadLevelModule(void) {
// -1 if it is in data\scripts
// 0-x which extracted script id it is
int _get_full_path_to_module(char *module_name, char *fullpath, char *basename) {
char modfilename[_MAX_PATH];
char ppath[_MAX_PATH], pext[256];
char adjusted_name[_MAX_PATH], adjusted_fname[_MAX_PATH];
char *p;
@ -911,12 +910,12 @@ int _get_full_path_to_module(char *module_name, char *fullpath, char *basename)
}
// determine real name of script
mod_GetRealModuleName(adjusted_name, modfilename);
std::filesystem::path modfilename = mod_GetRealModuleName(adjusted_name);
int exist = cfexist(modfilename);
switch (exist) {
case CFES_ON_DISK:
ddio_MakePath(fullpath, LocalScriptDir, modfilename, NULL);
ddio_MakePath(fullpath, LocalScriptDir, modfilename.u8string().c_str(), NULL);
return -1;
break;
case CFES_IN_LIBRARY: {

View File

@ -492,9 +492,10 @@
* $NoKeywords: $
*/
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <cstdlib>
#include <cstring>
#include "chrono_timer.h"
#include "mono.h"
#include "renderer.h"
#include "render.h"
@ -2557,7 +2558,7 @@ void TelComHandleAllEvents(tTelComInfo *tcs) {
volatile float next_time = last_frame_time + (1 / TELCOM_FRAMERATE_CAP);
if (curr_time < next_time) {
Sleep((next_time - curr_time) * 1000.0f);
D3::ChronoTimer::SleepMS((int)((next_time - curr_time) * 1000.0f));
}
if (last_frame_time == 0) {
frame_time = 0.1f;

View File

@ -77,8 +77,11 @@
* $NoKeywords: $
*/
#include <cstring>
#include "mono.h"
#include "pstypes.h"
#include "crossplat.h"
#include "ddio.h"
#include "grtext.h"
#include "renderer.h"
@ -87,17 +90,10 @@
#include "bitmap.h"
#include "descent.h"
#include "mem.h"
#include "3d.h"
#include "d3music.h"
#include "hlsoundlib.h"
#include <string.h>
#include <math.h>
#include "psrand.h"
#if defined(POSIX)
#include "linux_fix.h"
#endif
/*
$$TABLE_GAMEFILE "GameCredits.txt"
$$TABLE_GAMEFILE "credits.omf"

View File

@ -112,31 +112,25 @@
typedef int socklen_t;
#endif
#include "pstypes.h"
#include "crossplat.h"
#include "pserror.h"
#include "pstring.h"
#include "cfile.h"
#include "inffile.h"
#include "dedicated_server.h"
#include "multi.h"
#include "args.h"
#include "AppConsole.h"
#include "ddio.h"
#include "newui.h"
#include "ui.h"
#include "multi_dll_mgr.h"
#include "multi_ui.h"
#include "Mission.h"
#include "multi_server.h"
#include "Macros.h"
#include "game.h"
#include "mem.h"
#include "stringtable.h"
#include "multi_save_settings.h"
#include "objinfo.h"
#include "rtperformance.h"
#include "player.h"
#include "stringtable.h"
#include "init.h"
#include "ship.h"
#include "hud.h"
@ -794,7 +788,6 @@ void PrintDedicatedMessage(const char *fmt, ...) {
#include <sys/socket.h>
#include <unistd.h>
#include "linux_fix.h"
#include "errno.h"
#define BOOL bool
#ifndef SOCKET

View File

@ -132,6 +132,7 @@
#include <filesystem>
#include "application.h"
#include "crossplat.h"
// The name of this product
#ifdef DEMO

View File

@ -1642,7 +1642,10 @@
*
*/
#include "pstypes.h"
#include <algorithm>
#include <cstring>
#include "chrono_timer.h"
#include "pserror.h"
#include "player.h"
#include "game.h"
@ -1667,24 +1670,15 @@
#include "fireball.h"
#include "Mission.h"
#include "LoadLevel.h"
#include "gamecinematics.h"
#include "init.h"
#include "sounds.h"
#include "weapon.h"
#include "stringtable.h"
#include "dedicated_server.h"
#include "demofile.h"
#include "args.h"
#include "ui.h"
#include "newui.h"
#include "multi_dll_mgr.h"
#include "BOA.h"
#include "attach.h"
#include "mission_download.h"
// #include "gamespy.h"
#include "multi_world_state.h"
#include "ObjScript.h"
#include "audiotaunts.h"
@ -1695,25 +1689,14 @@
#include "spew.h"
#include "physics.h"
#include "SmallViews.h"
#include "demofile.h"
#include "debuggraph.h"
#include "levelgoal.h"
#include "osiris_share.h"
#include "cockpit.h"
#include "hud.h"
#include <string.h>
#include <memory.h>
#include <stdlib.h>
#include "psrand.h"
#include "../md5/md5.h"
void MultiProcessShipChecksum(MD5 *md5, int ship_index);
#include <algorithm>
player_pos_suppress Player_pos_fix[MAX_PLAYERS];
// Define this if you want to have secondaries be sent as reliable packets
@ -1866,7 +1849,7 @@ void BailOnMultiplayer(const char *message) {
ShowProgressScreen(message);
MultiLeaveGame();
Sleep(2000);
D3::ChronoTimer::SleepMS(2000);
}
// Adds the trunctuated position data to an outgoing packet
@ -3537,7 +3520,7 @@ void MultiSendConnectBail() {
if (wait_to_send) {
for (int t = 0; t < 10; t++) {
nw_DoNetworkIdle();
Sleep(100);
D3::ChronoTimer::SleepMS(100);
}
}
@ -3555,7 +3538,7 @@ void MultiDoConnectBail() {
return;
ShowProgressScreen(TXT_MULTI_SERVERCHANGEA, TXT_MULTI_SERVERCHANGEB);
Sleep(3000);
D3::ChronoTimer::SleepMS(3000);
MultiLeaveGame();
SetFunctionMode(MENU_MODE);
}
@ -3633,7 +3616,7 @@ void MultiSendLevelEnded(int success, int next_level) {
// Do this so it gets sent off now.
for (int t = 0; t < 10; t++) {
nw_DoNetworkIdle();
Sleep(100);
D3::ChronoTimer::SleepMS(100);
}
}
@ -3717,7 +3700,7 @@ void MultiDoServerQuit(uint8_t *data) {
}
mprintf(0, "Server quitting!\n");
MultiLeaveGame();
Sleep(2000);
D3::ChronoTimer::SleepMS(2000);
}
void MultiDoDisconnect(uint8_t *data) {
@ -3762,7 +3745,7 @@ void MultiDoServerRejectedChecksum(uint8_t *data) {
SKIP_HEADER(data, &count);
ShowProgressScreen(TXT_MLTLEVELNOMATCH);
MultiLeaveGame();
Sleep(2000);
D3::ChronoTimer::SleepMS(2000);
}
// Lets us know if the server says its ok to join

View File

@ -498,10 +498,6 @@
#include "object_external.h"
#include "player_external.h"
#if defined(POSIX)
#include "linux_fix.h"
#endif
#include "multi_external.h" //defines and structs are in here
extern bool Multi_bail_ui_menu;

View File

@ -134,6 +134,7 @@
*
*/
#include "chrono_timer.h"
#include "multi.h"
#include "multi_client.h"
#include "game.h"
@ -297,7 +298,7 @@ int ServerTimedOut() {
if (!nw_CheckReliableSocket(NetPlayers[Player_num].reliable_socket)) {
mprintf(0, "Reliable connection to the server was broken. Disconnecting.\n");
ShowProgressScreen(TXT_RELIABLE_OVERRUN);
Sleep(1000);
D3::ChronoTimer::SleepMS(1000);
return 1;
}
if ((timer_GetTime() - Netgame.last_server_time) > SERVER_DISCONNECT_TIME)
@ -345,7 +346,7 @@ void MultiDoClientFrame() {
mprintf(0, "Server disconnected while waiting for gametime!\n");
MultiLeaveGame();
ShowProgressScreen(TXT_MLTDISCFRMSERV);
Sleep(2000);
D3::ChronoTimer::SleepMS(2000);
} else if ((timer_GetTime() - Last_gametime_req) > NET_CLIENT_GAMETIME_REQ_RETRY) {
NetPlayers[Player_num].sequence = NETSEQ_NEED_GAMETIME;
}
@ -486,7 +487,7 @@ void MultiDoClientFrame() {
mprintf(0, "Server disconnected!\n");
MultiLeaveGame();
ShowProgressScreen(TXT_MLTDISCFRMSERV);
Sleep(2000);
D3::ChronoTimer::SleepMS(2000);
}
}
}

View File

@ -253,22 +253,18 @@
*
*/
#include "chrono_timer.h"
#include "multi.h"
#include "multi_server.h"
#include "player.h"
#include "game.h"
#include "ddio.h"
#include "Mission.h"
// #include "gametrack.h"
#include "stringtable.h"
#include "pilot.h"
#include "ship.h"
#include "args.h"
#include "ui.h"
#include "newui.h"
#include "multi_dll_mgr.h"
#include "LoadLevel.h"
// #define USE_DIRECTPLAY
@ -375,10 +371,10 @@ int TryToJoinServer(network_address *addr) {
char str[255];
snprintf(str, sizeof(str), "%s", TXT(Join_response_strings[Ok_to_join]));
ShowProgressScreen(str);
Sleep(2000);
D3::ChronoTimer::SleepMS(2000);
} else {
ShowProgressScreen(TXT_MLTNORESPONSE);
Sleep(2000);
D3::ChronoTimer::SleepMS(2000);
}
return 0;
} else
@ -643,11 +639,11 @@ int MultiPollForLevelInfo() {
if (!Got_level_info) {
ShowProgressScreen(TXT_MLTNOLEVELINFO);
MultiLeaveGame();
Sleep(2000);
D3::ChronoTimer::SleepMS(2000);
} else if (Got_level_info < 0) {
ShowProgressScreen(TXT(Join_response_strings[-Got_level_info]));
MultiLeaveGame();
Sleep(2000);
D3::ChronoTimer::SleepMS(2000);
} else {
Got_level_info = 0;
return 1;
@ -864,7 +860,7 @@ void MultiCloseGame() {
}
#endif
Sleep(1000); // Sleep for one second
D3::ChronoTimer::SleepMS(1000); // Sleep for one second
if (Netgame.local_role == LR_SERVER) {
int i;
@ -880,7 +876,7 @@ void MultiCloseGame() {
for (i = 0; i < 100; i++) {
nw_DoNetworkIdle();
Sleep(10);
D3::ChronoTimer::SleepMS(10);
}
NetPlayers[Player_num].flags &= ~NPF_CONNECTED;

View File

@ -276,13 +276,14 @@
*
* $NoKeywords: $
*/
#include "chrono_timer.h"
#include "ui.h"
#include "newui.h"
#include "game.h"
#include "gamefont.h"
#include "multi.h"
#include "multi_client.h"
#include "manage.h"
#include "Mission.h"
#include "pilot.h"
#include "pstypes.h"
@ -298,8 +299,6 @@
#include "multi_server.h"
#include "multi_ui.h"
#include "ship.h"
#include "soundload.h"
#include "spew.h"
#include "DllWrappers.h"
#include "appdatabase.h"
#include "module.h"
@ -815,7 +814,7 @@ int PollUI(void) {
// Limit this to a fixed framerate
if (UI_LastPoll) {
if ((timer_GetTime() - UI_LastPoll) < MIN_FRAMETIME)
Sleep((timer_GetTime() - UI_LastPoll) * 1000);
D3::ChronoTimer::SleepMS((timer_GetTime() - UI_LastPoll) * 1000);
}
UI_LastPoll = timer_GetTime();

View File

@ -85,6 +85,9 @@
#ifndef _multi_dll_header
#define _multi_dll_header
#include "newui.h"
#include "ui.h"
#define MT_EVT_LOGIN 1
#define MT_EVT_FIRST_FRAME 2
#define MT_EVT_FRAME 3

View File

@ -187,10 +187,6 @@
#ifndef NEWUI_H
#define NEWUI_H
#if defined(POSIX)
#include "linux_fix.h" //fix some of the stricmp's
#endif
#include "newui_core.h"
// flags for creating a newui window

View File

@ -22,21 +22,13 @@
#include <cstring>
#include <cstdarg>
#include <cerrno>
#include <cctype>
#include <filesystem>
#include <map>
#include <memory>
#include <vector>
#if !defined(POSIX)
// Non-Linux Build Includes
#include <io.h>
#else
// Linux Build Includes
#include "linux_fix.h"
#endif
#include "byteswap.h"
#include "crossplat.h"
#include "pserror.h"
#include "ddio.h"
#include "psglob.h"

View File

@ -30,7 +30,7 @@
#include <filesystem>
#include "cfile.h"
#include "pstypes.h"
#include "crossplat.h"
#include "psclass.h"
enum InfFileError {

View File

@ -17,6 +17,8 @@
*/
#include <chrono>
#include <thread>
#include "chrono_timer.h"
namespace D3 {
@ -38,4 +40,8 @@ int64_t ChronoTimer::GetTimeUS() {
.count();
}
void ChronoTimer::SleepMS(int delay) {
std::this_thread::sleep_for(std::chrono::milliseconds(delay));
}
} // namespace D3

View File

@ -41,6 +41,9 @@ public:
/// Get time in microseconds after class initialization (i.e. application start)
static int64_t GetTimeUS();
/// Sleep for delay milliseconds
static void SleepMS(int delay);
};
}

View File

@ -73,8 +73,9 @@
#endif
#include "ddio.h"
#include "pserror.h"
#include "crossplat.h"
#include "mem.h"
#include "pserror.h"
#define _MAX_DIR 256

View File

@ -23,9 +23,7 @@
#include "briefinglocalizer.h"
#include "briefinglocalizerDlg.h"
#if defined(POSIX)
#include "linux_fix.h"
#endif
#include "crossplat.h"
#include <sys/types.h>
#include <sys/stat.h>

View File

@ -20,7 +20,7 @@
#include <windows.h>
#include "ddraw.h"
#elif defined(POSIX)
#include "linux_fix.h"
#include "crossplat.h"
#include "lnxscreenmode.h"
#else
#endif

View File

@ -22,10 +22,7 @@
#include <filesystem>
#include "cfile.h"
#if defined(POSIX)
#include "linux_fix.h" //needed for stricmp's throughout bitmap lib
#endif
#include "crossplat.h" //needed for stricmp's throughout bitmap lib
#define MAX_BITMAPS 5000
#define NUM_MIP_LEVELS 5

65
lib/crossplat.h Normal file
View File

@ -0,0 +1,65 @@
/*
* Descent 3
* Copyright (C) 2024 Parallax Software
* Copyright (C) 2024 Descent Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CROSSPLAT_H_
#define CROSSPLAT_H_
// Crossplatform stubs and replacements
#if defined(WIN32)
#include <cstring> // strupr, stricmp, strnicmp
#include <cstdlib> // _MAX_PATH, _MAX_FNAME, _MAX_EXT for WIN32
#include <io.h> // _chmod
#elif defined(POSIX)
#include <cctype> // toupper
#include <cstring> // strcasecmp, strncasecmp
#include <sys/stat.h> // chmod
inline char *strupr(char *string) {
while (string && *string) {
*string = toupper(*string);
string++;
}
return string;
}
// Replace missing defines from stdlib.h
#define _MAX_PATH 260 /* max. length of full pathname*/
#define _MAX_FNAME 256 /* max. length of path component*/
#define _MAX_EXT 256 /* max. length of extension component*/
// _cdecl replacement
#define __cdecl __attribute__((cdecl))
// __stdcall replacement
#define __stdcall __attribute__((stdcall))
#define stricmp(a, b) strcasecmp(a, b)
#define strnicmp(a, b, c) strncasecmp(a, b, c)
#define _chmod(a, b) chmod(a, b)
#else
#error "Unknown platform!"
#endif
#endif

View File

@ -52,9 +52,6 @@
#ifndef __LNXVIDEOMODE_H__
#define __LNXVIDEOMODE_H__
#if defined(POSIX)
#include "linux_fix.h"
#endif
#include <SDL.h>
#define MODE_OK 0

View File

@ -26,10 +26,6 @@
#include "bitmap.h"
#include "manage_external.h"
#if defined(POSIX)
#include "linux_fix.h" //for strnicmp,etc.
#endif
#define LOCAL_TABLE "Table.loc"
#define TEMP_LOCAL_TABLE "Tablr.loc"

View File

@ -71,6 +71,7 @@
#define __DLMODULE_H_
#include <cstdint>
#include <filesystem>
#ifdef __cplusplus
#define CPPEXTERN extern "C"
@ -93,6 +94,17 @@
# define DLLFUNCCALL STDCALL
# define DLLFUNCCALLPTR STDCALLPTR
// Platform-specific library extensions
#if defined(WIN32)
#define MODULE_EXT ".dll"
#elif defined(__LINUX__)
#define MODULE_EXT ".so"
#elif defined(MACOSX)
#define MODULE_EXT ".dylib"
#else
#error Unsupported platform!
#endif
#ifdef WIN32
//=========================Windows Definition============================
#include "windows.h"
@ -133,15 +145,19 @@ struct module {
#define MODF_NOW 0x002 // Resolve all symbols before returning
#define MODF_GLOBAL 0x200 //
// Returns the real name of the module. If a given file has an extension, it will
// just return that filename. If the given file has no given extension, the
// system specific extension is concatted and returned.
void mod_GetRealModuleName(const char *modfilename, char *realmodfilename);
/**
* Returns real name of the module. If a given file has an extension, it will just return that filename.
* If the given file has no extension or has extension from another platform,
* the system specific extension is added/replaced and returned.
* @param mod_filename input module filename
* @return resolved filename
*/
std::filesystem::path mod_GetRealModuleName(const std::filesystem::path &mod_filename);
// Loads a dynamic module into memory for use. If no extension is given, the default
// system specific extension is used.
// Returns true on success, false otherwise
bool mod_LoadModule(module *handle, const char *modfilename, int flags = MODF_LAZY);
bool mod_LoadModule(module *handle, const std::filesystem::path &imodfilename, int flags = MODF_LAZY);
// Frees a previously loaded module from memory, it can no longer be used
// Returns true on success, false otherwise
@ -155,6 +171,6 @@ MODPROCADDRESS mod_GetSymbol(module *handle, const char *symstr, uint8_t parmbyt
// Returns an error code to what the last error was. When this function is called the last error is cleared, so by
// calling this function it not only returns the last error, but it removes it, so if you were to call this function
// again, it would return no error
int mod_GetLastError(void);
int mod_GetLastError();
#endif

View File

@ -212,8 +212,6 @@ static inline void INADDR_GET_SUN_SUNB(struct in_addr *st, uint8_t *s_b1, uint8_
#include "SDL.h"
#include "SDL_thread.h"
#include "linux_fix.h"
#define SOCKET int
#define BOOL bool
#define SOCKADDR_IN sockaddr_in

View File

@ -54,6 +54,8 @@
#ifndef PSCLASS_H
#define PSCLASS_H
#include <cstdint>
// a universal list node to use with the list type
template <class T> struct tListNode {
T t;
@ -83,7 +85,7 @@ template <class T> class tList {
public:
tList() {
m_link = m_mark = NULL;
m_link = m_mark = nullptr;
m_length = 0;
};
~tList() { tList::free(); };
@ -101,14 +103,14 @@ public:
};
// returns the node at the current link location in iteration.
tListNode<T> *get() const { return m_mark ? m_mark : NULL; };
tListNode<T> *get() const { return m_mark ? m_mark : nullptr; };
// length
int length() const { return m_length; };
// frees list
void free() {
m_link = m_mark = NULL;
m_link = m_mark = nullptr;
m_length = 0;
};
@ -119,7 +121,7 @@ public:
m_mark->next = node;
} else {
m_link = node;
node->next = NULL;
node->next = nullptr;
}
m_mark = node;
m_length++;
@ -129,7 +131,7 @@ public:
tListNode<T> *unlink() {
tListNode<T> *freenode, *node;
if (!m_link)
return NULL;
return nullptr;
if (m_link == m_mark) {
freenode = m_mark;
m_mark = m_link = m_link->next;
@ -140,7 +142,7 @@ public:
freenode = m_mark;
node->next = m_mark->next;
}
freenode->next = NULL;
freenode->next = nullptr;
return freenode;
};
};

View File

@ -22,18 +22,10 @@
#include <cstdlib>
#include <cstdint>
#if defined(POSIX)
#include "linux_fix.h"
#endif
// The maximum length for a file name, including extension. It *does not* include the
// terminating NULL, so a buffer to hold a filename needs to be PSFILENAME_LEN+1 bytes long.
#define PSFILENAME_LEN 35
// The maximum length of a path (or path+filename). The seems (from looking at the code) to
// include the terminating NULL. lengthened to 512 to prevent problems with some long pathnames.
#define PSPATHNAME_LEN _MAX_PATH
#if !defined(__APPLE__)
#define HOST_BIGENDIAN @HOST_BIGENDIAN @
#else

View File

@ -1,5 +1,4 @@
set(HEADERS
linux_fix.h
lnxapp.h
lnxcontroller.h
registry.h)

View File

@ -1,46 +0,0 @@
/*
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __LINUX_FIX_H_
#define __LINUX_FIX_H_
#include <sys/stat.h>
#define LOKI_VERSION ""
#define HGLOBAL void *
void Sleep(int millis);
char *strupr(char *string);
#define _stat stat
// Replace missing defines from stdlib.h
#define _MAX_PATH 260 /* max. length of full pathname*/
#define _MAX_FNAME 256 /* max. length of path component*/
#define _MAX_EXT 256 /* max. length of extension component*/
// _cdecl replacement
#define __cdecl __attribute__((cdecl))
// __stdcall replacement
#define __stdcall __attribute__((stdcall))
#define stricmp(a, b) strcasecmp(a, b)
#define strnicmp(a, b, c) strncasecmp(a, b, c)
#define _chmod(a, b) chmod(a, b)
#endif

View File

@ -69,15 +69,14 @@
*/
#include <cstdlib>
#include <cctype>
#if defined(POSIX)
#include <sys/time.h>
#include <termios.h>
#else
#include "winsock.h"
#endif
#include "application.h"
#include "chrono_timer.h"
#include "lnxapp.h"
#ifdef buttons // termios.h defines buttons, but SDL's headers use that symbol.
@ -95,21 +94,6 @@ bool con_Create(int flags);
void con_Destroy();
void con_Defer();
void Sleep(int millis) {
struct timeval tv{};
tv.tv_sec = 0;
tv.tv_usec = millis * 1000;
select(0, nullptr, nullptr, nullptr, &tv);
}
char *strupr(char *string) {
while (string && *string) {
*string = toupper(*string);
string++;
}
return string;
}
static uint32_t LinuxAppFlags = 0;
// static Display *LinuxAppDisplay=NULL;
static bool LinuxAppSetAtExit = false;
@ -211,7 +195,7 @@ void oeLnxApplication::set_defer_handler(void (*func)(bool)) { m_DeferFunc = fun
// delays app for a certain amount of time
void oeLnxApplication::delay(float secs) {
int msecs = (int)(secs * 1000.0f);
Sleep(msecs);
D3::ChronoTimer::SleepMS(msecs);
}
// Function to get the flags

View File

@ -19,10 +19,6 @@
#ifndef LNXAPP_H
#define LNXAPP_H
#if defined(POSIX)
#include "linux_fix.h"
#endif
// if no-display/input specifier is given, it will use defaults
#define APPFLAG_USESERVICE 0x00000100 // console (run no output/input)
#define APPFLAG_USESVGA 0x00000200 // console (use svgalib for input/output. NOTE: not used in code)

View File

@ -441,9 +441,7 @@
#include <cstring>
#include <filesystem>
#if defined(POSIX)
#include "linux_fix.h"
#endif
#include "chrono_timer.h"
#include "descent.h"
#include "manage.h"
#include "pserror.h"
@ -1470,7 +1468,7 @@ int SwitcherooFiles(const char *name, char *tempname) {
}*/
int num_tries = 0;
while (!ddio_DeleteFile(name) && num_tries < MAX_TRIES) {
Sleep(100);
D3::ChronoTimer::SleepMS(100);
num_tries++;
}
if (num_tries >= MAX_TRIES) {
@ -1481,7 +1479,7 @@ int SwitcherooFiles(const char *name, char *tempname) {
}
num_tries = 0;
while ((rename(tempname, name)) && num_tries <= MAX_TRIES) {
Sleep(100);
D3::ChronoTimer::SleepMS(100);
num_tries++;
}
if (num_tries >= MAX_TRIES) {

View File

@ -4,6 +4,5 @@ set(CPPS
add_library(module STATIC ${HEADERS} ${CPPS})
target_link_libraries(module PRIVATE
ddio
misc
)

View File

@ -1,5 +1,5 @@
/*
* Descent 3
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
@ -91,233 +91,101 @@
*
* $NoKeywords: $
*/
#include "module.h"
#include "pstypes.h"
#include "pserror.h"
#include "ddio.h"
#include <algorithm>
#include <filesystem>
#include <string>
#include <vector>
#if defined(POSIX)
#include <dlfcn.h>
static bool mod_FindRealFileNameCaseInsenstive(const char *directory, const char *filename, char *new_filename);
#endif
#include "crossplat.h"
#include "module.h"
#include "pstypes.h"
#include "pserror.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#if defined(POSIX)
#include "linux_fix.h"
#endif
#if defined(WIN32) // INSTEAD OF MAKING MODULE HAVE DEPENDENCIES, PUT THE 2 DDIO FUNCTIONS I NEED HERE
// Split a pathname into its component parts
static void dd_SplitPath(const char *srcPath, char *path, char *filename, char *ext) {
char drivename[_MAX_DRIVE], dirname[_MAX_DIR];
_splitpath(srcPath, drivename, dirname, filename, ext);
if (path)
sprintf(path, "%s%s", drivename, dirname);
}
// Constructs a path in the local file system's syntax
// newPath: stores the constructed path
// absolutePathHeader: absolute path on which the sub directories will be appended
// (specified in local file system syntax)
// takes a variable number of subdirectories which will be concatenated on to the path
// the last argument in the list of sub dirs *MUST* be NULL to terminate the list
static void dd_MakePath(char *newPath, const char *absolutePathHeader, const char *subDir, ...) {
const char delimiter = '\\';
va_list args;
char *currentDir = NULL;
int pathLength = 0;
assert(newPath);
assert(absolutePathHeader);
assert(subDir);
/**
* Returns fixed case file name to actual case on disk for case-sensitive filesystems (Linux).
* This is actually copy of cf_FindRealFileNameCaseInsensitive() from CFILE.
* @param fname the fixed case name to map to reality
* @param directory optional directory to search within (default - current path)
* @return filename with actual case name or empty path if there no mapping in filesystem
* @note This function returns only filename without directory part, i.e.
* mod_FindRealFileNameCaseInsensitive("test/test.txt") will return only "test.txt" on success.
*/
std::filesystem::path mod_FindRealFileNameCaseInsensitive(const std::filesystem::path &fname,
const std::filesystem::path &directory = ".") {
// Dumb check, maybe there already all ok?
if (std::filesystem::exists((directory / fname))) {
return fname.filename();
}
if (newPath != absolutePathHeader) {
strcpy(newPath, absolutePathHeader);
}
// Add the first sub directory
pathLength = strlen(newPath);
if (newPath[pathLength - 1] != delimiter) {
newPath[pathLength] = delimiter; // add the delimiter
newPath[pathLength + 1] = 0; // terminate the string
}
strcat(newPath, subDir);
std::filesystem::path result, search_path, search_file;
// Add the additional subdirectories
va_start(args, subDir);
while ((currentDir = va_arg(args, char *)) != NULL) {
pathLength = strlen(newPath);
if (newPath[pathLength - 1] != delimiter) {
newPath[pathLength] = delimiter; // add the delimiter
newPath[pathLength + 1] = 0; // terminate the string
}
strcat(newPath, currentDir);
search_path = directory / fname.parent_path();
search_file = fname.filename();
// If directory does not exist, nothing to search.
if (!std::filesystem::is_directory(search_path) || search_file.empty()) {
return {};
}
va_end(args);
}
#elif defined(POSIX)
// Split a pathname into its component parts
static void dd_SplitPath(const char *srcPath, char *path, char *filename, char *ext) {
int pathStart = -1;
int pathEnd = -1;
int fileStart = -1;
int fileEnd = -1;
int extStart = -1;
int extEnd = -1;
int totalLen = strlen(srcPath);
// Check for an extension
///////////////////////////////////////
int t = totalLen - 1;
while ((srcPath[t] != '.') && (srcPath[t] != '/') && (t >= 0))
t--;
// see if we are at an extension
if ((t >= 0) && (srcPath[t] == '.')) {
// we have an extension
extStart = t;
extEnd = totalLen - 1;
if (ext) {
strncpy(ext, &(srcPath[extStart]), extEnd - extStart + 1);
ext[extEnd - extStart + 1] = '\0';
}
// Search component in search_path
auto const &it = std::filesystem::directory_iterator(search_path);
auto found = std::find_if(it, end(it), [&search_file, &search_path, &result](const auto &dir_entry) {
return stricmp(dir_entry.path().filename().u8string().c_str(), search_file.u8string().c_str()) == 0;
});
if (found != end(it)) {
// Match, append to result
result = found->path();
search_path = result;
} else {
// no extension
if (ext)
ext[0] = '\0';
// Component not found, mission failed
return {};
}
// Check for file name
////////////////////////////////////
int temp = (extStart != -1) ? (extStart) : (totalLen - 1);
while ((srcPath[temp] != '/') && (temp >= 0))
temp--;
if (temp < 0)
temp = 0;
if (srcPath[temp] == '/') {
// we have a file
fileStart = temp + 1;
if (extStart != -1)
fileEnd = extStart - 1;
else
fileEnd = totalLen - 1;
if (filename) {
strncpy(filename, &(srcPath[fileStart]), fileEnd - fileStart + 1);
filename[fileEnd - fileStart + 1] = '\0';
}
pathStart = 0;
pathEnd = fileStart - 2;
// Copy the rest into the path name
if (path) {
strncpy(path, &(srcPath[pathStart]), pathEnd - pathStart + 1);
path[pathEnd - pathStart + 1] = 0;
}
} else {
// only file, no path
fileStart = 0;
if (extStart != -1)
fileEnd = extStart - 1;
else
fileEnd = totalLen - 1;
if (filename) {
strncpy(filename, &(srcPath[fileStart]), fileEnd - fileStart + 1);
filename[fileEnd - fileStart + 1] = 0;
}
// Only file no path
if (path) {
path[0] = 0;
}
}
return result.filename();
}
// Constructs a path in the local file system's syntax
// newPath: stores the constructed path
// absolutePathHeader: absolute path on which the sub directories will be appended
// (specified in local file system syntax)
// takes a variable number of subdirectories which will be concatenated on to the path
// the last argument in the list of sub dirs *MUST* be NULL to terminate the list
static void dd_MakePath(char *newPath, const char *absolutePathHeader, const char *subDir, ...) {
const char delimiter = '/';
va_list args;
char *currentDir = NULL;
int pathLength = 0;
ASSERT(newPath);
ASSERT(absolutePathHeader);
ASSERT(subDir);
if (newPath != absolutePathHeader) {
strcpy(newPath, absolutePathHeader);
}
// Add the first sub directory
pathLength = strlen(newPath);
if (newPath[pathLength - 1] != delimiter) {
newPath[pathLength] = delimiter; // add the delimiter
newPath[pathLength + 1] = 0; // terminate the string
}
strcat(newPath, subDir);
// Add the additional subdirectories
va_start(args, subDir);
while ((currentDir = va_arg(args, char *)) != NULL) {
pathLength = strlen(newPath);
if (newPath[pathLength - 1] != delimiter) {
newPath[pathLength] = delimiter; // add the delimiter
newPath[pathLength + 1] = 0; // terminate the string
}
strcat(newPath, currentDir);
}
va_end(args);
}
#endif
int ModLastError = MODERR_NOERROR;
// Returns the real name of the module. If a given file has an extension, it will
// just return that filename. If the given file has no given extension, the
// system specific extension is concatted and returned.
void mod_GetRealModuleName(const char *modfilename, char *realmodfilename) {
char pathname[_MAX_PATH], filename[_MAX_FNAME], extension[_MAX_EXT];
dd_SplitPath(modfilename, pathname, filename, extension);
if (*extension == '\0')
#if defined(WIN32)
strcat(filename, ".dll");
#elif defined(__LINUX__)
strcat(filename, ".so");
#elif defined(MACOSX)
strcat(filename, ".dylib");
#else
#error Unsupported platform!
#endif
else {
#if defined(WIN32)
if (!stricmp(extension, ".so") || !stricmp(extension, "msl") || !stricmp(extension, "dylib"))
strcat(filename, ".dll");
else
strcat(filename, extension);
#elif defined(__LINUX__)
if (!stricmp(extension, ".dll") || !stricmp(extension, "msl") || !stricmp(extension, "dylib"))
strcat(filename, ".so");
else
strcat(filename, extension);
#elif defined(MACOSX)
if (!stricmp(extension, ".dll") || !stricmp(extension, "msl") || !stricmp(extension, "so"))
strcat(filename, ".dylib");
else
strcat(filename, extension);
#else
#error Unsupported platform!
#endif
std::filesystem::path mod_GetRealModuleName(const std::filesystem::path &mod_filename) {
std::filesystem::path filename = mod_filename;
std::string ext = mod_filename.extension().u8string();
if (ext.empty()) {
filename.replace_extension(MODULE_EXT);
return filename;
}
if (*pathname != '\0')
dd_MakePath(realmodfilename, pathname, filename, NULL);
else
strcpy(realmodfilename, filename);
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
if (ext == MODULE_EXT) {
return filename;
}
const std::vector<std::string> replace_exts = {
".dll",
".dylib",
".msl",
".so",
};
for (const auto &replace_ext : replace_exts) {
if (ext == replace_ext) {
filename.replace_extension(MODULE_EXT);
return filename;
}
}
return filename;
}
// Loads a dynamic module into memory for use.
// Returns true on success, false otherwise
// modfilename is the name of the module (without an extension such as DLL, or so)
bool mod_LoadModule(module *handle, const char *imodfilename, int flags) {
if (!imodfilename) {
bool mod_LoadModule(module *handle, const std::filesystem::path &imodfilename, int flags) {
if (imodfilename.empty()) {
ModLastError = MODERR_OTHER;
return false;
}
@ -325,11 +193,10 @@ bool mod_LoadModule(module *handle, const char *imodfilename, int flags) {
ModLastError = MODERR_INVALIDHANDLE;
return false;
}
handle->handle = NULL;
char modfilename[_MAX_PATH];
mod_GetRealModuleName(imodfilename, modfilename);
handle->handle = nullptr;
std::filesystem::path modfilename = mod_GetRealModuleName(imodfilename);
#if defined(WIN32)
handle->handle = LoadLibrary(modfilename);
handle->handle = LoadLibrary(modfilename.u8string().c_str());
if (!handle->handle) {
// There was an error loading the module
DWORD err = GetLastError();
@ -357,27 +224,27 @@ bool mod_LoadModule(module *handle, const char *imodfilename, int flags) {
f |= RTLD_NOW;
if (flags & MODF_GLOBAL)
f |= RTLD_GLOBAL;
handle->handle = dlopen(modfilename, f);
handle->handle = dlopen(modfilename.u8string().c_str(), f);
if (!handle->handle) {
// ok we couldn't find the given name...try other ways
char dir[_MAX_PATH], fname[_MAX_PATH], nname[_MAX_PATH], ext[64];
dd_SplitPath(modfilename, dir, fname, ext);
strcat(fname, ext);
std::filesystem::path parent_path = modfilename.parent_path();
std::filesystem::path new_filename = mod_FindRealFileNameCaseInsensitive(parent_path, modfilename.filename());
if (!mod_FindRealFileNameCaseInsenstive(dir, fname, nname)) {
if (new_filename.empty()) {
mprintf(0, "Module Load Err: %s\n", dlerror());
ModLastError = MODERR_MODNOTFOUND;
return false;
}
// ok we have a different filename
mprintf(0, "MOD: Attempting to open %s instead of %s\n", new_filename.u8string().c_str(),
modfilename.u8string().c_str());
modfilename = parent_path / new_filename;
handle->handle = dlopen(modfilename.u8string().c_str(), f);
if (!handle->handle) {
mprintf(0, "Module Load Err: %s\n", dlerror());
ModLastError = MODERR_MODNOTFOUND;
return false;
} else {
// ok we have a different filename
dd_MakePath(modfilename, dir, nname, NULL);
mprintf(0, "MOD: Attempting to open %s instead of %s\n", modfilename, fname);
handle->handle = dlopen(modfilename, f);
if (!handle->handle) {
mprintf(0, "Module Load Err: %s\n", dlerror());
ModLastError = MODERR_MODNOTFOUND;
return false;
}
}
}
#endif
@ -402,9 +269,10 @@ bool mod_FreeModule(module *handle) {
#elif defined(POSIX)
dlclose(handle->handle); // dlclose() returns an int, but no docs say what values!!!
#endif
handle->handle = NULL;
handle->handle = nullptr;
return ret;
}
// Returns a pointer to a function within a loaded module. If it returns NULL there was an error. Check
// mod_GetLastError to see if there was an error symstr is the name of the function you want to get the symbol for (Do
// NOT give any pre/suffix to this name) parmbytes is the size (in bytes) of the parameter list the function should have
@ -413,15 +281,15 @@ MODPROCADDRESS mod_GetSymbol(module *handle, const char *symstr, uint8_t parmbyt
MODPROCADDRESS sym;
if (!handle) {
ModLastError = MODERR_INVALIDHANDLE;
return NULL;
return nullptr;
}
if (!symstr) {
ModLastError = MODERR_OTHER;
return NULL;
return nullptr;
}
if (!handle->handle) {
ModLastError = MODERR_NOMOD;
return NULL;
return nullptr;
}
#if defined(WIN32)
// We need to first form the correct symbol name (for Windows)
@ -465,15 +333,16 @@ MODPROCADDRESS mod_GetSymbol(module *handle, const char *symstr, uint8_t parmbyt
sym = dlsym(handle->handle, symstr);
if (!sym) {
ModLastError = MODERR_OTHER;
return NULL;
return nullptr;
}
#endif
return sym;
}
// Returns an error code to what the last error was. When this function is called the last error is cleared, so by
// calling this function it not only returns the last error, but it removes it, so if you were to call this function
// again, it would return no error
int mod_GetLastError(void) {
int mod_GetLastError() {
// Clear out the errors
#if defined(WIN32)
SetLastError(0);
@ -484,224 +353,3 @@ int mod_GetLastError(void) {
ModLastError = MODERR_NOERROR;
return ret;
}
#if defined(POSIX)
#include <assert.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <utime.h>
#include <glob.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
void dd_GetWorkingDir(char *path, int len);
bool dd_SetWorkingDir(const char *path);
// retrieve the current working folder where file operation will occur.
void dd_GetWorkingDir(char *path, int len) { getcwd(path, len); }
bool dd_SetWorkingDir(const char *path) { return (chdir(path)) ? false : true; }
// These functions allow one to find a file
static int globerrfn(const char *path, int err) {
mprintf(0, "Error accessing %s: %s .... \n", path, strerror(err));
return 0;
}
class CModFindFiles {
public:
CModFindFiles() { globindex = -1; }
bool Start(const char *wildcard, char *namebuf);
bool Next(char *namebuf);
void Close(void);
private:
int globindex;
glob_t ffres;
};
bool CModFindFiles::Start(const char *wildcard, char *namebuf) {
ASSERT(wildcard);
ASSERT(namebuf);
if (globindex != -1)
Close();
int rc, flags;
flags = GLOB_MARK;
rc = glob(wildcard, flags, globerrfn, &ffres);
if (rc == GLOB_NOSPACE) {
mprintf(0, "Out of space during glob\n");
globindex = -1;
return false;
}
if (!ffres.gl_pathc) {
globindex = -1;
return false;
}
globindex = 0;
char ext[256];
dd_SplitPath(ffres.gl_pathv[0], NULL, namebuf, ext);
strcat(namebuf, ext);
return true;
}
bool CModFindFiles::Next(char *namebuf) {
ASSERT(namebuf);
if (globindex == -1)
return false;
globindex++;
if (globindex >= ffres.gl_pathc)
return false;
char ext[256];
dd_SplitPath(ffres.gl_pathv[globindex], NULL, namebuf, ext);
strcat(namebuf, ext);
return true;
}
void CModFindFiles::Close(void) {
if (globindex == -1)
return;
globindex = -1;
globfree(&ffres);
}
bool mod_FindRealFileNameCaseInsenstive(const char *directory, const char *fname, char *new_filename) {
bool use_dir = false;
char dir_to_use[_MAX_PATH];
char file_to_use[_MAX_PATH];
char *real_dir, *real_file;
if (directory) {
// there is a directory for this path
use_dir = true;
real_dir = (char *)directory;
real_file = (char *)fname;
} else {
// there may be a directory in the path (*sigh*)
char t_ext[256];
char t_dir[_MAX_PATH];
char t_filename[_MAX_PATH];
dd_SplitPath(fname, t_dir, t_filename, t_ext);
if (strlen(t_dir) > 0) {
use_dir = true;
strcpy(dir_to_use, t_dir);
real_dir = (char *)dir_to_use;
strcpy(file_to_use, t_filename);
strcat(file_to_use, t_ext);
real_file = (char *)file_to_use;
mprintf(1, "MOD: Found directory \"%s\" in filename, new filename is \"%s\"\n", real_dir, real_file);
} else {
use_dir = false;
real_dir = NULL;
real_file = (char *)fname;
}
}
// build up a list of filenames in the current directory that begin with the lowercase and
// upper case first letter of the filename
// do the case of the first letter to start
int case_val;
char wildcard_pattern[_MAX_PATH];
int iterations = 1;
bool found_match = false;
if ((real_file[0] >= 'a' && real_file[0] <= 'z') || (real_file[0] >= 'A' && real_file[0] <= 'Z')) {
// alpha first letter...we need to do 2 iterations
iterations = 2;
}
for (case_val = 0; case_val < iterations; case_val++) {
if (case_val) {
// do the opposite case of the first letter
char first_letter;
first_letter = real_file[0];
if (first_letter >= 'a' && first_letter <= 'z') {
// we need to uppercase the letter
first_letter = toupper(first_letter);
} else {
// we need to lowercase the letter
first_letter = tolower(first_letter);
}
// create a wildcard patter full of ? replacing letters (except the first one)
char *wptr = wildcard_pattern;
char *fptr = &real_file[1];
*wptr = first_letter;
wptr++;
while (*fptr) {
if (isalpha(*fptr)) {
*wptr = '?';
} else {
*wptr = *fptr;
}
fptr++;
wptr++;
}
*wptr = '\0';
} else {
// use the case of the first letter
// create a wildcard patter full of ? replacing letters (except the first one)
char *wptr = wildcard_pattern;
char *fptr = &real_file[1];
*wptr = real_file[0];
wptr++;
while (*fptr) {
if (isalpha(*fptr)) {
*wptr = '?';
} else {
*wptr = *fptr;
}
fptr++;
wptr++;
}
*wptr = '\0';
}
// now tack on a directory if we are to use a directory
char *wpattern;
char fullpath[_MAX_PATH];
if (use_dir) {
dd_MakePath(fullpath, real_dir, wildcard_pattern, NULL);
wpattern = fullpath;
} else {
wpattern = wildcard_pattern;
}
// ok, we have our wildcard pattern, get all the files that match it
// and search them looking for a match (case insensitive)
char namebuffer[_MAX_PATH];
bool gotfile;
CModFindFiles ff;
for (gotfile = ff.Start(wpattern, namebuffer); gotfile; gotfile = ff.Next(namebuffer)) {
if (!stricmp(namebuffer, real_file)) {
// we found a match!
found_match = true;
break;
}
}
ff.Close();
if (found_match) {
strcpy(new_filename, namebuffer);
mprintf(1, "MOD: Using \"%s\" instead of \"%s\"\n", new_filename, real_file);
break;
}
}
return found_match;
}
#endif

View File

@ -270,14 +270,10 @@
#include <regex>
#include <string>
#include "crossplat.h"
#include "ship.h"
#include "pstypes.h"
#if defined(POSIX)
#include <cstring>
#include "linux_fix.h"
#endif
// Uncomment out this line of code to build the demo version of the multiplayer connection dlls
// #define DEMO 1
@ -659,8 +655,7 @@ MultiGameOptionsMenu_fp DLLMultiGameOptionsMenu;
// Loads a dynamic module into memory for use.
// Returns true on success, false otherwise
// typedef bool (*mod_LoadModule_fp)(module *handle,const char *modfilename,int flags=MODF_NOW);
typedef bool (*mod_LoadModule_fp)(module *handle, const char *modfilename, int flags);
typedef bool (*mod_LoadModule_fp)(module *handle, const std::filesystem::path &modfilename, int flags);
mod_LoadModule_fp DLLmod_LoadModule;
// Frees a previously loaded module from memory, it can no longer be used
@ -762,8 +757,6 @@ struct vmt_descent3_struct {
uint32_t MTClientVer = 100;
char MTUpdateURL[300] = "";
multi_api API;
player *DLLMPlayers;

View File

@ -97,7 +97,6 @@
#include <sys/time.h>
#include <unistd.h>
#include "linux_fix.h"
// Linux includes/defines
#if defined(__LINUX__)

View File

@ -70,9 +70,9 @@
typedef int socklen_t;
#endif
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#if defined(POSIX)
// sorry, I'm lazy, I guess we could copy the defines
@ -82,6 +82,7 @@ typedef int socklen_t;
#endif
#include "CFtp.h"
#include "crossplat.h"
// MTS: only used in this file?
#if defined(POSIX)

View File

@ -7,5 +7,6 @@ set(CPPS
add_library(inetfile STATIC ${HEADERS} ${CPPS})
target_link_libraries(inetfile PRIVATE
ddio
mem
)

View File

@ -124,31 +124,16 @@
#include <process.h>
#endif
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include "inetgetfile.h"
#include "Chttpget.h"
#ifndef WIN32
#include "chrono_timer.h"
#include "crossplat.h"
#include "mem.h"
#else
#define mem_malloc(a) malloc(a)
#define mem_free(a) free(a)
#endif
#if defined(POSIX)
#include "SDL_thread.h"
inline void Sleep(int millis) {
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = millis * 1000;
select(0, NULL, NULL, NULL, &tv);
}
#endif
#define NW_AGHBN_CANCEL 1
#define NW_AGHBN_LOOKUP 2
@ -185,7 +170,7 @@ void ChttpGet::AbortGet() {
#endif
m_Aborting = true;
while (!m_Aborted)
Sleep(50); // Wait for the thread to end
D3::ChronoTimer::SleepMS(50); // Wait for the thread to end
#ifdef WIN32
OutputDebugString("Aborted....\n");
#endif

View File

@ -80,6 +80,7 @@
#include "inetgetfile.h"
#include "CFtp.h"
#include "Chttpget.h"
#include "chrono_timer.h"
extern char *Proxy_server;
extern int16_t Proxy_port;
@ -160,7 +161,7 @@ InetGetFile::InetGetFile(char *URL, char *localfile, char *proxyip, int16_t prox
} else {
m_HardError = INET_ERROR_CANT_PARSE_URL;
}
Sleep(1000);
D3::ChronoTimer::SleepMS(1000);
}
InetGetFile::InetGetFile(char *URL, char *localfile) {
@ -193,7 +194,7 @@ InetGetFile::InetGetFile(char *URL, char *localfile) {
} else {
m_HardError = INET_ERROR_CANT_PARSE_URL;
}
Sleep(1000);
D3::ChronoTimer::SleepMS(1000);
}
InetGetFile::~InetGetFile() {

View File

@ -29,6 +29,7 @@
#endif
#include "chat_api.h"
#include "crossplat.h"
#include "grdefs.h"
#include "mtstrings.h"
#include "networking.h"

View File

@ -728,21 +728,6 @@ void DLLFUNCCALL DLLMultiCall(int eventnum) {
DLLPollUI();
if (MT_Initialized) {
DLLPollUI();
if (!MTVersionCheck()) {
if (Login_aborted) {
MT_Initialized = 0;
} else {
// If the first call fails, try again
DLLPollUI();
if (!MTVersionCheck()) {
DLLPollUI();
if (!MTVersionCheck()) {
// If this call fails, we have a problem, and when MT_EVT_LOGIN is called we will let the user know.
UnvalidatedDLL = 1;
}
}
}
}
}
DLLCloseSplashScreen();
if (!MT_Initialized) {
@ -2147,10 +2132,8 @@ void CheckPXOForAnomalies() {
if (stricmp(DLLMPlayers[i].tracker_id, DLLMPlayers[j].tracker_id) == 0) {
// Ok, what we have here is multiple users with the same tracker ID.
// This is bad. It could be user error, but it could be something worse.
FILE *errfile;
char errfilepath[_MAX_PATH];
DLLddio_MakePath(errfilepath, DLLLocalD3Dir, "pxo.err", NULL);
errfile = fopen(errfilepath, "at");
std::filesystem::path errfilepath = std::filesystem::path(DLLLocalD3Dir) / "pxo.err";
FILE *errfile = fopen(errfilepath.u8string().c_str(), "at");
if (errfile) {
fprintf(errfile, "Dup TID: %s & %s / %s\n", DLLMPlayers[j].callsign, DLLMPlayers[i].callsign,
DLLMPlayers[i].tracker_id);
@ -2317,121 +2300,6 @@ void DoMTGameOver(void) {
DLLDescentDefer();
}
int MTVersionCheck() {
#ifdef WIN32
int rcode;
InetGetFile *inetfile;
char sznewdll[_MAX_PATH], szolddll[_MAX_PATH], szbakdll[_MAX_PATH];
char fulldllpath[_MAX_PATH * 2];
// char dllpath[_MAX_PATH];
DLLAVInit = NULL;
DLLAVCall = NULL;
DLLAVClose = NULL;
DLLAVGetVersion = NULL;
DLLRunCheck = NULL;
// Start by getting the current MT version and see if a newer is needed
// Load the DLL and get it's version
// Specify the correct path
DLLddio_MakePath(fulldllpath, DLLLocalD3Dir, "mtav.dll", NULL);
if (!DLLmod_LoadModule(&MTAVDLLHandle, fulldllpath, MODF_LAZY)) {
DLLmprintf(0, "Unable to load Mastertracker Auto version update DLL (mtav.dll)\n");
// Try restoring a backup of the DLL
DLLddio_MakePath(szolddll, DLLLocalD3Dir, "mtav.dll", NULL);
DLLddio_MakePath(szbakdll, DLLLocalD3Dir, "mtav.bak", NULL);
CopyFile(szbakdll, szolddll, FALSE);
return 0;
}
DLLAVInit = (DLLAVInit_fp *)DLLmod_GetSymbol(&MTAVDLLHandle, "DLLAVInit", 4);
if (!DLLAVInit) {
DLLmprintf(0, "Unable to Find DLLAVInit() function in mtav.dll\n");
DLLmod_FreeModule(&MTAVDLLHandle);
// Try restoring a backup of the DLL
DLLddio_MakePath(szolddll, DLLLocalD3Dir, "mtav.dll", NULL);
DLLddio_MakePath(szbakdll, DLLLocalD3Dir, "mtav.bak", NULL);
CopyFile(szbakdll, szolddll, FALSE);
return 0;
}
DLLAVGetVersion = (DLLAVGetVersion_fp *)DLLmod_GetSymbol(&MTAVDLLHandle, "DLLAVGetVersion", 4);
if (!DLLAVGetVersion) {
DLLmprintf(0, "Unable to Find DLLAVGetVersion() function in mtav.dll\n");
DLLmod_FreeModule(&MTAVDLLHandle);
// Try restoring a backup of the DLL
DLLddio_MakePath(szolddll, DLLLocalD3Dir, "mtav.dll", NULL);
DLLddio_MakePath(szbakdll, DLLLocalD3Dir, "mtav.bak", NULL);
CopyFile(szbakdll, szolddll, FALSE);
return 0;
}
DLLRunCheck = (DLLRunCheck_fp *)DLLmod_GetSymbol(&MTAVDLLHandle, "DLLRunCheck", 4);
if (!DLLRunCheck) {
DLLmprintf(0, "Unable to Find DLLRunCheck() function in mtav.dll\n");
DLLmod_FreeModule(&MTAVDLLHandle);
// Try restoring a backup of the DLL
DLLddio_MakePath(szolddll, DLLLocalD3Dir, "mtav.dll", NULL);
DLLddio_MakePath(szbakdll, DLLLocalD3Dir, "mtav.bak", NULL);
CopyFile(szbakdll, szolddll, FALSE);
return 0;
}
uint32_t mtver;
DLLAVGetVersion((int *)&mtver);
if (MTAVersionCheck(mtver, MTUpdateURL)) {
DLLmprintf(0, "VersionCheck() returned an unexpected return code!\n");
DLLmod_FreeModule(&MTAVDLLHandle);
return 0;
}
DLLmprintf(0, "Getting Version # from Mastertracker.\n");
do {
//
rcode = MTAVersionCheck(0, NULL);
} while (rcode == 0);
if (rcode == -2) {
// Don't try anymore... it timed out.
Login_aborted = true;
}
if (rcode == 1) {
if (MTUpdateURL[0]) {
// We need to get a new DLL
DLLmprintf(0, "Mastertracker says we need a new version, which is at %s.\n", MTUpdateURL);
sprintf(sznewdll, "%s\\newmtav.dll", DLLLocalD3Dir);
DLLddio_MakePath(sznewdll, DLLLocalD3Dir, "newmtav.dll", NULL);
inetfile = new InetGetFile(MTUpdateURL, sznewdll);
while (1) {
DLLPollUI();
if (inetfile->IsFileError()) {
// Error here
DLLmprintf(0, "Mastertracker update DLL not received. Error code: %d.\n", inetfile->GetErrorCode());
DLLmod_FreeModule(&MTAVDLLHandle);
return 0;
}
if (inetfile->IsFileReceived()) {
DLLmprintf(0, "Mastertracker update DLL received.\n");
DLLmod_FreeModule(&MTAVDLLHandle);
DLLddio_MakePath(szolddll, DLLLocalD3Dir, "mtav.dll", NULL);
DLLddio_MakePath(szbakdll, DLLLocalD3Dir, "mtav.bak", NULL);
// We have the file, now backup & copy it and try to reload.
CopyFile(szolddll, szbakdll, FALSE);
CopyFile(sznewdll, szolddll, FALSE);
return 0;
}
};
} else {
DLLmprintf(0, "Mastertracker says we are up to date\n");
// Here is where we call into the DLL so it can do it's magic
DLLAVInit(0);
DLLmod_FreeModule(&MTAVDLLHandle);
return 1;
}
} else {
DLLmprintf(0, "Mastertracker timeout while getting version\n");
DLLmod_FreeModule(&MTAVDLLHandle);
return 0;
}
#endif
return 1;
}
int JoinNewLobby(const char *lobby) {
int rcode;
const char *p;

View File

@ -134,7 +134,6 @@ int StartMultiplayerGameMenu();
void MultiplayerOptionsMenu();
void DoMTFrame();
void DoMTGameOver();
int MTVersionCheck();
int JoinNewLobby(const char *lobby);
const char *SendWhisper(const char *name);
int JoinPrivateLobby();

View File

@ -111,10 +111,10 @@
#include <cstdlib>
#include <cstring>
#include "pstypes.h"
#include "networking.h"
#include "mt_net.h"
#include "byteswap.h"
#include "crossplat.h"
#define LOGIN_LEN 33
#define REAL_NAME_LEN 66

View File

@ -22,7 +22,8 @@
#include <cstdio>
#include <cstdlib>
#include <cstdarg>
#include "linux_fix.h"
#include "crossplat.h" // for stricmp
void _splitpath(const char *path, char *drive, char *dir, char *fname, char *ext);

View File

@ -269,14 +269,9 @@
#include <cstdint>
#if defined(POSIX)
#include "linux_fix.h" //for stricmp's through code
#endif
#include "uires.h"
#include "pserror.h"
#include "grdefs.h"
#include "pserror.h"
#include "uires.h"
// Class identification