Initial commit
This commit is contained in:
280
engines/ags/engine/platform/base/ags_platform_driver.cpp
Normal file
280
engines/ags/engine/platform/base/ags_platform_driver.cpp
Normal file
@@ -0,0 +1,280 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// AGS Platform-specific functions
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "ags/shared/util/wgt2_allg.h"
|
||||
#include "ags/engine/platform/base/ags_platform_driver.h"
|
||||
#include "ags/shared/ac/common.h"
|
||||
#include "ags/engine/ac/runtime_defines.h"
|
||||
#include "ags/shared/util/string_utils.h"
|
||||
#include "ags/shared/util/stream.h"
|
||||
#include "ags/shared/gfx/bitmap.h"
|
||||
#include "ags/plugins/ags_plugin.h"
|
||||
#include "ags/engine/ac/timer.h"
|
||||
#include "ags/engine/media/audio/audio_system.h"
|
||||
#include "ags/lib/system/datetime.h"
|
||||
#include "common/std/algorithm.h"
|
||||
#include "common/std/thread.h"
|
||||
#include "ags/globals.h"
|
||||
|
||||
#if defined (AGS_HAS_CD_AUDIO)
|
||||
#include "ags/shared/libcda.h"
|
||||
#endif
|
||||
|
||||
namespace AGS3 {
|
||||
|
||||
using namespace AGS::Shared;
|
||||
using namespace AGS::Engine;
|
||||
|
||||
AGSPlatformDriver *AGSPlatformDriver::instance = nullptr;
|
||||
|
||||
// ******** DEFAULT IMPLEMENTATIONS *******
|
||||
|
||||
void AGSPlatformDriver::PostAllegroInit(bool windowed) {
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::AttachToParentConsole() {
|
||||
}
|
||||
|
||||
int AGSPlatformDriver::GetLastSystemError() {
|
||||
return _G(errnum);
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::DisplaySwitchOut() {
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::DisplaySwitchIn() {
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::PauseApplication() {
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::ResumeApplication() {
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::GetSystemDisplayModes(std::vector<DisplayMode> &dms) {
|
||||
}
|
||||
|
||||
bool AGSPlatformDriver::EnterFullscreenMode(const DisplayMode &dm) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AGSPlatformDriver::ExitFullscreenMode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::AdjustWindowStyleForFullscreen() {
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::AdjustWindowStyleForWindowed() {
|
||||
}
|
||||
|
||||
Size AGSPlatformDriver::ValidateWindowSize(const Size &sz, bool borderless) const {
|
||||
// TODO: ScummVM screen limits are hardcoded to 9999x9999
|
||||
// in sys_get_desktop_resolution
|
||||
Size w(9999,9999);
|
||||
return w;
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::PlayVideo(const char *name, int skip, int flags) {
|
||||
}
|
||||
|
||||
const char *AGSPlatformDriver::GetAllegroFailUserHint() {
|
||||
return "Make sure you have latest version of Allegro 4 libraries installed, and your system is running in graphical mode.";
|
||||
}
|
||||
|
||||
const char *AGSPlatformDriver::GetDiskWriteAccessTroubleshootingText() {
|
||||
return "Make sure you have write permissions, and also check the disk's free space.";
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::GetSystemTime(ScriptDateTime *sdt) {
|
||||
time_t t = getUnixTime();
|
||||
|
||||
//note: subject to year 2038 problem due to shoving time_t in an integer
|
||||
sdt->rawUnixTime = static_cast<int>(t);
|
||||
|
||||
tm newTime;
|
||||
localTime(&newTime);
|
||||
sdt->hour = newTime.tm_hour;
|
||||
sdt->minute = newTime.tm_min;
|
||||
sdt->second = newTime.tm_sec;
|
||||
sdt->day = newTime.tm_mday;
|
||||
sdt->month = newTime.tm_mon + 1;
|
||||
sdt->year = newTime.tm_year + 1900;
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::WriteStdOut(const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
Common::String str = Common::String::vformat(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
debug("%s", str.c_str());
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::WriteStdErr(const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
Common::String str = Common::String::vformat(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
debug("ERROR: %s", str.c_str());
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::YieldCPU() {
|
||||
// NOTE: this is called yield, but if we actually yield instead of delay,
|
||||
// we get a massive increase in CPU usage.
|
||||
this->Delay(10);
|
||||
//std::this_thread::yield();
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::InitialiseAbufAtStartup() {
|
||||
// because loading the game file accesses abuf, it must exist
|
||||
// No no no, David Blain, no magic here :P
|
||||
//abuf = BitmapHelper::CreateBitmap(10,10,8);
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::FinishedUsingGraphicsMode() {
|
||||
// don't need to do anything on any OS except DOS
|
||||
}
|
||||
|
||||
SetupReturnValue AGSPlatformDriver::RunSetup(const ConfigTree & /*cfg_in*/, ConfigTree & /*cfg_out*/) {
|
||||
return kSetup_Cancel;
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::SetCommandArgs(const char *const argv[], size_t argc) {
|
||||
_cmdArgs = argv;
|
||||
_cmdArgCount = argc;
|
||||
}
|
||||
|
||||
Common::String AGSPlatformDriver::GetCommandArg(size_t arg_index) {
|
||||
return arg_index < _cmdArgCount ? _cmdArgs[arg_index] : nullptr;
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::SetGameWindowIcon() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
int AGSPlatformDriver::ConvertKeycodeToScanCode(int keycode) {
|
||||
keycode -= ('A' - Common::KEYCODE_a);
|
||||
return keycode;
|
||||
}
|
||||
|
||||
bool AGSPlatformDriver::LockMouseToWindow() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void AGSPlatformDriver::UnlockMouse() {
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
||||
// IOutputHandler implementation
|
||||
//-----------------------------------------------
|
||||
|
||||
void AGSPlatformDriver::PrintMessage(const Shared::DebugMessage &msg) {
|
||||
if (_logToStdErr) {
|
||||
if (msg.GroupName.IsEmpty())
|
||||
WriteStdErr("%s", msg.Text.GetCStr());
|
||||
else
|
||||
WriteStdErr("%s : %s", msg.GroupName.GetCStr(), msg.Text.GetCStr());
|
||||
} else {
|
||||
if (msg.GroupName.IsEmpty())
|
||||
WriteStdOut("%s", msg.Text.GetCStr());
|
||||
else
|
||||
WriteStdOut("%s : %s", msg.GroupName.GetCStr(), msg.Text.GetCStr());
|
||||
}
|
||||
}
|
||||
|
||||
// ********** CD Player Functions common to Win and Linux ********
|
||||
|
||||
#if defined (AGS_HAS_CD_AUDIO)
|
||||
|
||||
int numcddrives = 0;
|
||||
|
||||
int cd_player_init() {
|
||||
int erro = cd_init();
|
||||
if (erro) return -1;
|
||||
numcddrives = 1;
|
||||
_G(use_cdplayer) = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cd_player_control(int cmdd, int datt) {
|
||||
// WINDOWS & LINUX VERSION
|
||||
if (cmdd == 1) {
|
||||
if (cd_current_track() > 0) return 1;
|
||||
return 0;
|
||||
} else if (cmdd == 2) {
|
||||
cd_play_from(datt);
|
||||
_G(need_to_stop_cd) = 1;
|
||||
} else if (cmdd == 3)
|
||||
cd_pause();
|
||||
else if (cmdd == 4)
|
||||
cd_resume();
|
||||
else if (cmdd == 5) {
|
||||
int first, last;
|
||||
if (cd_get_tracks(&first, &last) == 0)
|
||||
return (last - first) + 1;
|
||||
else return 0;
|
||||
} else if (cmdd == 6)
|
||||
cd_eject();
|
||||
else if (cmdd == 7)
|
||||
cd_close();
|
||||
else if (cmdd == 8)
|
||||
return numcddrives;
|
||||
else if (cmdd == 9);
|
||||
else quit("!CDAudio: Unknown command code");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // AGS_HAS_CD_AUDIO
|
||||
|
||||
void AGSPlatformDriver::Delay(int millis) {
|
||||
auto now = AGS_Clock::now();
|
||||
auto delayUntil = now + std::chrono::milliseconds(millis);
|
||||
|
||||
for (;;) {
|
||||
if (now >= delayUntil) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto duration = MIN<std::chrono::milliseconds>(delayUntil - now,
|
||||
_G(MaximumDelayBetweenPolling));
|
||||
std::this_thread::sleep_for(duration);
|
||||
now = AGS_Clock::now(); // update now
|
||||
|
||||
if (now >= delayUntil) {
|
||||
break;
|
||||
}
|
||||
|
||||
// don't allow it to check for debug messages, since this Delay()
|
||||
// call might be from within a debugger polling loop
|
||||
now = AGS_Clock::now(); // update now
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AGS3
|
||||
241
engines/ags/engine/platform/base/ags_platform_driver.h
Normal file
241
engines/ags/engine/platform/base/ags_platform_driver.h
Normal file
@@ -0,0 +1,241 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// AGS Cross-Platform Header
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef AGS_ENGINE_PLATFORM_BASE_AGS_PLATFORM_DRIVER_H
|
||||
#define AGS_ENGINE_PLATFORM_BASE_AGS_PLATFORM_DRIVER_H
|
||||
|
||||
#include "common/std/vector.h"
|
||||
#include "ags/engine/ac/date_time.h"
|
||||
#include "ags/engine/ac/path_helper.h"
|
||||
#include "ags/shared/debugging/output_handler.h"
|
||||
#include "ags/shared/util/geometry.h"
|
||||
#include "ags/shared/util/ini_util.h"
|
||||
#include "ags/lib/allegro/error.h"
|
||||
|
||||
namespace AGS3 {
|
||||
|
||||
namespace AGS {
|
||||
namespace Shared {
|
||||
class Stream;
|
||||
} // namespace Shared
|
||||
|
||||
namespace Engine {
|
||||
struct DisplayMode;
|
||||
} // namespace Engine
|
||||
} // namespace AGS
|
||||
|
||||
using namespace AGS; // FIXME later
|
||||
|
||||
enum eScriptSystemOSID {
|
||||
eOS_DOS = 1,
|
||||
eOS_Win,
|
||||
eOS_Linux,
|
||||
eOS_Mac,
|
||||
eOS_Android,
|
||||
eOS_iOS,
|
||||
eOS_PSP,
|
||||
eOS_Web
|
||||
};
|
||||
|
||||
enum SetupReturnValue {
|
||||
kSetup_Cancel,
|
||||
kSetup_Done,
|
||||
kSetup_RunGame
|
||||
};
|
||||
|
||||
struct AGSPlatformDriver
|
||||
// be used as a output target for logging system
|
||||
: public AGS::Shared::IOutputHandler {
|
||||
virtual ~AGSPlatformDriver() { instance = nullptr; }
|
||||
|
||||
// Called at the creation of the platform driver
|
||||
virtual void MainInit() { };
|
||||
// Called right before the formal backend init
|
||||
virtual void PreBackendInit() { };
|
||||
// Called right after the formal backend init
|
||||
virtual void PostBackendInit() { };
|
||||
// Called right before the backend is deinitialized
|
||||
virtual void PreBackendExit() { };
|
||||
// Called right after the backend is deinitialized
|
||||
virtual void PostBackendExit() { };
|
||||
|
||||
virtual void Delay(int millis);
|
||||
virtual void DisplayAlert(const char *, ...) = 0;
|
||||
virtual void AttachToParentConsole();
|
||||
virtual int GetLastSystemError();
|
||||
// Optionally fill in config tree from the platform-specific config source
|
||||
virtual void ReadConfiguration(Shared::ConfigTree & /*cfg*/) {}
|
||||
// Get root directory for storing per-game shared data
|
||||
virtual FSLocation GetAllUsersDataDirectory() {
|
||||
return FSLocation(".");
|
||||
}
|
||||
// Get root directory for storing per-game saved games
|
||||
virtual FSLocation GetUserSavedgamesDirectory() {
|
||||
return FSLocation(".");
|
||||
}
|
||||
// Get root directory for storing per-game user configuration files
|
||||
virtual FSLocation GetUserConfigDirectory() {
|
||||
return FSLocation(".");
|
||||
}
|
||||
// Get directory for storing all-games user configuration files
|
||||
virtual FSLocation GetUserGlobalConfigDirectory() {
|
||||
return FSLocation(".");
|
||||
}
|
||||
// Get default directory for program output (logs)
|
||||
virtual FSLocation GetAppOutputDirectory() {
|
||||
return FSLocation(".");
|
||||
}
|
||||
// Tells whether it's not permitted to write to the local directory (cwd, or game dir),
|
||||
// and only specified user/app directories should be used.
|
||||
// FIXME: this is a part of a hotfix, review uses of this function later.
|
||||
virtual bool IsLocalDirRestricted() { return true; }
|
||||
// Returns array of characters illegal to use in file names
|
||||
virtual const char *GetIllegalFileChars() {
|
||||
return "\\/";
|
||||
}
|
||||
virtual const char *GetDiskWriteAccessTroubleshootingText();
|
||||
virtual const char *GetGraphicsTroubleshootingText() {
|
||||
return "";
|
||||
}
|
||||
virtual uint64_t GetDiskFreeSpaceMB(const Shared::String &path) = 0;
|
||||
virtual const char *GetNoMouseErrorString() = 0;
|
||||
// Tells whether build is capable of controlling mouse movement properly
|
||||
virtual bool IsMouseControlSupported(bool windowed) {
|
||||
return false;
|
||||
}
|
||||
// Tells whether this platform's backend library deals with mouse cursor
|
||||
// virtual->real coordinate transformation itself (otherwise AGS engine should do it)
|
||||
virtual bool IsBackendResponsibleForMouseScaling() {
|
||||
return false;
|
||||
}
|
||||
virtual const char *GetAllegroFailUserHint();
|
||||
virtual eScriptSystemOSID GetSystemOSID() = 0;
|
||||
virtual void GetSystemTime(ScriptDateTime *);
|
||||
virtual void PlayVideo(const char *name, int skip, int flags);
|
||||
virtual void InitialiseAbufAtStartup();
|
||||
virtual void PostAllegroInit(bool windowed);
|
||||
virtual void PostAllegroExit() = 0;
|
||||
virtual const char *GetBackendFailUserHint() {
|
||||
return nullptr;
|
||||
}
|
||||
virtual void FinishedUsingGraphicsMode();
|
||||
virtual SetupReturnValue RunSetup(const Shared::ConfigTree &cfg_in, Shared::ConfigTree &cfg_out);
|
||||
virtual void SetGameWindowIcon();
|
||||
// Formats message and writes to standard platform's output;
|
||||
// Always adds trailing '\n' after formatted string
|
||||
virtual void WriteStdOut(const char *fmt, ...);
|
||||
// Formats message and writes to platform's error output;
|
||||
// Always adds trailing '\n' after formatted string
|
||||
virtual void WriteStdErr(const char *fmt, ...);
|
||||
// Display a text in a message box with a "warning" icon.
|
||||
// Platforms which do not support this should do nothing.
|
||||
virtual void DisplayMessageBox(const char *text) = 0;
|
||||
virtual void YieldCPU();
|
||||
// Called when the game window is being switch out from
|
||||
virtual void DisplaySwitchOut();
|
||||
// Called when the game window is being switch back to
|
||||
virtual void DisplaySwitchIn();
|
||||
// Called when the application is being paused completely (e.g. when player alt+tabbed from it).
|
||||
// This function should suspend any platform-specific realtime processing.
|
||||
virtual void PauseApplication();
|
||||
// Called when the application is being resumed.
|
||||
virtual void ResumeApplication();
|
||||
// Returns a list of supported display modes
|
||||
virtual void GetSystemDisplayModes(std::vector<Engine::DisplayMode> &dms);
|
||||
// Switch to system fullscreen mode; store previous mode parameters
|
||||
virtual bool EnterFullscreenMode(const Engine::DisplayMode &dm);
|
||||
// Return back to the mode was before switching to fullscreen
|
||||
virtual bool ExitFullscreenMode();
|
||||
// Adjust application window's parameters to suit fullscreen mode
|
||||
virtual void AdjustWindowStyleForFullscreen();
|
||||
// Adjust application window's parameters to suit windowed mode
|
||||
virtual void AdjustWindowStyleForWindowed();
|
||||
virtual int ConvertKeycodeToScanCode(int keyCode);
|
||||
// Adjust window's * client size * to ensure it is in the supported limits
|
||||
virtual Size ValidateWindowSize(const Size &sz, bool borderless) const;
|
||||
|
||||
virtual int InitializeCDPlayer() = 0; // return 0 on success
|
||||
virtual int CDPlayerCommand(int cmdd, int datt) = 0;
|
||||
virtual void ShutdownCDPlayer() = 0;
|
||||
|
||||
// Returns command line argument in a UTF-8 format
|
||||
virtual Common::String GetCommandArg(size_t arg_index);
|
||||
|
||||
virtual bool LockMouseToWindow();
|
||||
virtual void UnlockMouse();
|
||||
|
||||
static AGSPlatformDriver *GetDriver();
|
||||
|
||||
// Store command line arguments for the future use
|
||||
void SetCommandArgs(const char *const argv[], size_t argc);
|
||||
|
||||
// Set whether PrintMessage should output to stdout or stderr
|
||||
void SetOutputToErr(bool on) {
|
||||
_logToStdErr = on;
|
||||
}
|
||||
// Set whether DisplayAlert is allowed to show modal GUIs on some systems;
|
||||
// it will print to either stdout or stderr otherwise, depending on above flag
|
||||
void SetGUIMode(bool on) {
|
||||
_guiMode = on;
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
||||
// IOutputHandler implementation
|
||||
//-----------------------------------------------
|
||||
// Writes to the standard platform's output, prepending "AGS: " prefix to the message
|
||||
void PrintMessage(const AGS::Shared::DebugMessage &msg) override;
|
||||
|
||||
protected:
|
||||
// TODO: this is a quick solution for IOutputHandler implementation
|
||||
// logging either to stdout or stderr. Normally there should be
|
||||
// separate implementation, one for each kind of output, but
|
||||
// with both going through PlatformDriver need to figure a better
|
||||
// design first.
|
||||
bool _logToStdErr = false;
|
||||
// Defines whether engine is allowed to display important warnings
|
||||
// and errors by showing a message box kind of GUI.
|
||||
bool _guiMode = false;
|
||||
|
||||
const char *const *_cmdArgs = nullptr;
|
||||
size_t _cmdArgCount = 0u;
|
||||
|
||||
private:
|
||||
static AGSPlatformDriver *instance;
|
||||
};
|
||||
|
||||
#if defined (AGS_HAS_CD_AUDIO)
|
||||
int cd_player_init();
|
||||
int cd_player_control(int cmdd, int datt);
|
||||
#endif
|
||||
|
||||
// [IKM] What is a need to have this global var if you can get AGSPlatformDriver
|
||||
// instance by calling AGSPlatformDriver::GetDriver()?
|
||||
|
||||
|
||||
} // namespace AGS3
|
||||
|
||||
#endif
|
||||
273
engines/ags/engine/platform/base/sys_main.cpp
Normal file
273
engines/ags/engine/platform/base/sys_main.cpp
Normal file
@@ -0,0 +1,273 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/system.h"
|
||||
#include "ags/engine/platform/base/sys_main.h"
|
||||
#include "ags/shared/util/geometry.h"
|
||||
#include "ags/shared/util/string.h"
|
||||
|
||||
namespace AGS3 {
|
||||
|
||||
using namespace AGS::Engine;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// INIT / SHUTDOWN
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
int sys_main_init(/*config*/) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_main_shutdown() {
|
||||
sys_window_destroy();
|
||||
}
|
||||
|
||||
void sys_set_background_mode(bool /*on*/) {
|
||||
// TODO: consider if we want any implementation here, and what...
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// DISPLAY UTILS
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const int DEFAULT_DISPLAY_INDEX = 0;
|
||||
|
||||
int sys_get_window_display_index() {
|
||||
#if (AGS_PLATFORM_DESKTOP && !AGS_PLATFORM_SCUMMVM)
|
||||
int index = -1;
|
||||
SDL_Window *window = sys_get_window();
|
||||
if (window)
|
||||
index = SDL_GetWindowDisplayIndex(window);
|
||||
return index >= 0 ? index : DEFAULT_DISPLAY_INDEX;
|
||||
#else
|
||||
return DEFAULT_DISPLAY_INDEX;
|
||||
#endif
|
||||
}
|
||||
|
||||
int sys_get_desktop_resolution(int &width, int &height) {
|
||||
// TODO: ScummVM has a hardcoded dummy desktop resolution. See if there's any
|
||||
// need to change the values, given we're hardcoded for pretend full-screen
|
||||
width = 9999;
|
||||
height = 9999;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_get_desktop_modes(std::vector<AGS::Engine::DisplayMode> &dms, int color_depth) {
|
||||
#ifdef TODO
|
||||
SDL_DisplayMode mode;
|
||||
const int display_id = sys_get_window_display_index();
|
||||
const int count = SDL_GetNumDisplayModes(display_id);
|
||||
dms.clear();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (SDL_GetDisplayMode(display_id, i, &mode) != 0) {
|
||||
SDL_Log("SDL_GetDisplayMode failed: %s", SDL_GetError());
|
||||
continue;
|
||||
}
|
||||
const int bitsdepth = SDL_BITSPERPIXEL(mode.format);
|
||||
if ((color_depth == 0) || (bitsdepth != color_depth)) {
|
||||
continue;
|
||||
}
|
||||
AGS::Engine::DisplayMode dm;
|
||||
dm.Width = mode.w;
|
||||
dm.Height = mode.h;
|
||||
dm.ColorDepth = bitsdepth;
|
||||
dm.RefreshRate = mode.refresh_rate;
|
||||
dms.push_back(dm);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void sys_renderer_set_output(const AGS::Shared::String &name) {
|
||||
#ifndef AGS_PLATFORM_SCUMMVM
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, name.GetCStr());
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// AUDIO UTILS
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool sys_audio_init(const AGS::Shared::String &driver_name) {
|
||||
#ifdef AGS_PLATFORM_SCUMMVM
|
||||
return true;
|
||||
#else
|
||||
// IMPORTANT: we must use a combination of SDL_setenv and SDL_InitSubSystem
|
||||
// here, and NOT use SDL_AudioInit, because SDL_AudioInit does not increment
|
||||
// subsystem's reference count. Which in turn may cause problems down the
|
||||
// way when initializing any additional SDL-based audio lib or plugin;
|
||||
// at the very least - the mojoAl (OpenAL's implementation we're using).
|
||||
bool res = false;
|
||||
// If user config contained a driver request, then apply one for a try
|
||||
if (!driver_name.IsEmpty())
|
||||
SDL_setenv("SDL_AUDIODRIVER", driver_name.GetCStr(), 1);
|
||||
const char *env_drv = SDL_getenv("SDL_AUDIODRIVER");
|
||||
Debug::Printf("Requested audio driver: %s", env_drv ? env_drv : "default");
|
||||
res = SDL_InitSubSystem(SDL_INIT_AUDIO) == 0;
|
||||
// If there have been an explicit request that failed, then try to force
|
||||
// SDL to go through a list of supported drivers and see if that succeeds.
|
||||
if (!res && env_drv) {
|
||||
Debug::Printf(kDbgMsg_Error, "Failed to initialize requested audio driver '%s'; error: %s", env_drv, SDL_GetError());
|
||||
Debug::Printf("Attempt to initialize any audio driver from the known list");
|
||||
SDL_setenv("SDL_AUDIODRIVER", "", 1);
|
||||
res = SDL_InitSubSystem(SDL_INIT_AUDIO) == 0;
|
||||
}
|
||||
if (res)
|
||||
Debug::Printf(kDbgMsg_Info, "Audio driver: %s", SDL_GetCurrentAudioDriver());
|
||||
else
|
||||
Debug::Printf(kDbgMsg_Error, "Failed to initialize any audio driver; error: %s", SDL_GetError());
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sys_audio_shutdown() {
|
||||
#ifndef AGS_PLATFORM_SCUMMVM
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// WINDOW UTILS
|
||||
// ----------------------------------------------------------------------------
|
||||
// TODO: support multiple windows? in case we need some for diag purposes etc
|
||||
|
||||
#ifdef TODO
|
||||
static SDL_Window *window = nullptr;
|
||||
|
||||
SDL_Window *sys_window_create(const char *window_title, int w, int h, WindowMode mode, int ex_flags) {
|
||||
if (window) {
|
||||
sys_window_destroy();
|
||||
}
|
||||
// TODO: support display index selection (?)
|
||||
Uint32 flags = 0;
|
||||
switch (mode) {
|
||||
case kWnd_Windowed: flags |= SDL_WINDOW_RESIZABLE; break;
|
||||
case kWnd_Fullscreen: flags |= SDL_WINDOW_FULLSCREEN; break;
|
||||
case kWnd_FullDesktop: flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; break;
|
||||
}
|
||||
flags |= ex_flags;
|
||||
#if (AGS_PLATFORM_MOBILE)
|
||||
// Resizable flag is necessary for fullscreen app rotation
|
||||
flags |= SDL_WINDOW_RESIZABLE;
|
||||
#endif
|
||||
window = SDL_CreateWindow(
|
||||
window_title,
|
||||
SDL_WINDOWPOS_CENTERED_DISPLAY(DEFAULT_DISPLAY_INDEX),
|
||||
SDL_WINDOWPOS_CENTERED_DISPLAY(DEFAULT_DISPLAY_INDEX),
|
||||
w,
|
||||
h,
|
||||
flags
|
||||
);
|
||||
#if (AGS_PLATFORM_DESKTOP)
|
||||
// CHECKME: this is done because SDL2 has some bug(s) during
|
||||
// centering. See: https://github.com/libsdl-org/SDL/issues/6875
|
||||
// TODO: SDL2 docs mentioned that on some systems the window border size
|
||||
// may be known only after the window is displayed, which means that
|
||||
// this may have to be called with a short delay (but how to know when?)
|
||||
if (mode == kWnd_Windowed)
|
||||
sys_window_center();
|
||||
#endif
|
||||
return window;
|
||||
}
|
||||
#else
|
||||
SDL_Window *sys_window_create(const char *window_title, int w, int h, bool windowed, int ex_flags) {
|
||||
error("TODO: sys_window_create");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_Window *sys_get_window() {
|
||||
//return window;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void sys_window_set_style(WindowMode mode, int /*ex_flags*/) {
|
||||
#ifdef TODO
|
||||
if (!window) return;
|
||||
Uint32 flags = 0;
|
||||
switch (mode) {
|
||||
case kWnd_Fullscreen: flags = SDL_WINDOW_FULLSCREEN; break;
|
||||
case kWnd_FullDesktop: flags = SDL_WINDOW_FULLSCREEN_DESKTOP; break;
|
||||
}
|
||||
SDL_SetWindowFullscreen(window, flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
void sys_window_show_cursor(bool on) {
|
||||
g_system->showMouse(on);
|
||||
}
|
||||
|
||||
bool sys_window_lock_mouse(bool on) {
|
||||
#ifdef TODO
|
||||
if (!window) return false;
|
||||
SDL_SetWindowGrab(window, static_cast<SDL_bool>(on));
|
||||
return on; // TODO: test if successful?
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
void sys_window_set_mouse(int x, int y) {
|
||||
g_system->warpMouse(x, y);
|
||||
}
|
||||
|
||||
void sys_window_destroy() {
|
||||
#ifdef TODO
|
||||
if (window) {
|
||||
SDL_DestroyWindow(window);
|
||||
window = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void sys_window_set_title(const char *title) {
|
||||
// No implementation in ScummVM
|
||||
}
|
||||
|
||||
void sys_window_set_icon() {
|
||||
// No implementation in ScummVM
|
||||
}
|
||||
|
||||
bool sys_window_set_size(int w, int h, bool center) {
|
||||
error("TODO: sys_window_set_size");
|
||||
return false;
|
||||
}
|
||||
|
||||
void sys_window_center(int display_index) {
|
||||
// No implementation in ScummVM
|
||||
}
|
||||
|
||||
void sys_window_fit_in_display(int display_index) {
|
||||
// No implementation in ScummVM
|
||||
}
|
||||
|
||||
#if AGS_PLATFORM_OS_WINDOWS
|
||||
void *sys_win_get_window() {
|
||||
if (!window) return nullptr;
|
||||
SDL_SysWMinfo wmInfo;
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
SDL_GetWindowWMInfo(window, &wmInfo);
|
||||
HWND hwnd = wmInfo.info.win.window;
|
||||
return hwnd;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace AGS3
|
||||
102
engines/ags/engine/platform/base/sys_main.h
Normal file
102
engines/ags/engine/platform/base/sys_main.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// The main backend interface.
|
||||
//
|
||||
// TODO: split up later if it gets filled with functions in all categories.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "ags/shared/core/platform.h"
|
||||
#include "ags/shared/util/string.h"
|
||||
#include "common/std/vector.h"
|
||||
#include "ags/engine/gfx/gfx_defines.h"
|
||||
|
||||
namespace AGS3 {
|
||||
|
||||
// Initializes main backend system;
|
||||
// should be called before anything else backend related.
|
||||
// Returns 0 on success, non-0 on failure.
|
||||
int sys_main_init(/*config*/);
|
||||
// Shutdown main backend system;
|
||||
// should be called last, after everything else backend related is shutdown.
|
||||
void sys_main_shutdown();
|
||||
// Sets whether the engine wants to update while the window has no focus.
|
||||
// TODO: this is a placeholder at the moment, check later if we need any implementation
|
||||
void sys_set_background_mode(bool on);
|
||||
|
||||
// Display utilities.
|
||||
//
|
||||
// Queries the display index on which the window is currently positioned.
|
||||
// Returns default display index in case window does not exist yet, or on any error.
|
||||
int sys_get_window_display_index();
|
||||
// Queries current desktop resolution.
|
||||
int sys_get_desktop_resolution(int &width, int &height);
|
||||
// Queries supported desktop modes.
|
||||
void sys_get_desktop_modes(std::vector<AGS::Engine::DisplayMode> &dms, int color_depth = 0);
|
||||
// Sets output driver for the backend's renderer
|
||||
void sys_renderer_set_output(const AGS::Shared::String &name);
|
||||
|
||||
// Audio utilities.
|
||||
//
|
||||
// Tries to init the audio backend; optionally requests particular driver
|
||||
bool sys_audio_init(const AGS::Shared::String &driver_name = "");
|
||||
// Shutdown audio backend
|
||||
void sys_audio_shutdown();
|
||||
|
||||
// Window utilities.
|
||||
//
|
||||
struct SDL_Window;
|
||||
// Create a new single game window.
|
||||
SDL_Window *sys_window_create(const char *window_title, int w, int h, AGS::Engine::WindowMode mode, int ex_flags = 0);
|
||||
// Returns current game window, if one exists, or null.
|
||||
SDL_Window *sys_get_window();
|
||||
// Sets current window style, does nothing if window was not created.
|
||||
void sys_window_set_style(AGS::Engine::WindowMode mode, int ex_flags = 0);
|
||||
// Set new window size; optionally center new window on screen
|
||||
bool sys_window_set_size(int w, int h, bool center);
|
||||
// Centers the window on screen, optionally choose the display to position on
|
||||
void sys_window_center(int display_index = -1);
|
||||
// Reduces window's size to fit into the said display bounds, and repositions to the display's center
|
||||
void sys_window_fit_in_display(int display_index);
|
||||
// Shows or hides system cursor when it's in the game window
|
||||
void sys_window_show_cursor(bool on);
|
||||
// Locks on unlocks mouse inside the window.
|
||||
// Returns new state of the mouse lock.
|
||||
bool sys_window_lock_mouse(bool on);
|
||||
// Sets mouse position within the game window
|
||||
void sys_window_set_mouse(int x, int y);
|
||||
// Destroy current game window, if one exists.
|
||||
void sys_window_destroy();
|
||||
// Set window title text.
|
||||
void sys_window_set_title(const char *title);
|
||||
// Set window icon.
|
||||
// TODO: this is a placeholder, until we figure out the best way to set icon with SDL on wanted systems.
|
||||
void sys_window_set_icon();
|
||||
|
||||
#if AGS_PLATFORM_OS_WINDOWS
|
||||
// Returns game window's handle.
|
||||
void *sys_win_get_window();
|
||||
#endif
|
||||
|
||||
} // namespace AGS3
|
||||
Reference in New Issue
Block a user