mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
263 lines
7.1 KiB
C++
263 lines
7.1 KiB
C++
/* 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 2
|
|
* 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, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
//=============================================================================
|
|
//
|
|
// AGS Platform-specific functions
|
|
//
|
|
//=============================================================================
|
|
|
|
#include "ags/shared/util/wgt2allg.h"
|
|
#include "ags/engine/platform/base/agsplatformdriver.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/agsplugin.h"
|
|
#include "ags/engine/ac/timer.h"
|
|
#include "ags/engine/media/audio/audio_system.h"
|
|
#include "ags/lib/system/datetime.h"
|
|
#include "ags/lib/std/algorithm.h"
|
|
#include "ags/lib/std/thread.h"
|
|
|
|
#if defined (AGS_HAS_CD_AUDIO)
|
|
#include "libcda.h"
|
|
#endif
|
|
|
|
namespace AGS3 {
|
|
|
|
using namespace AGS::Shared;
|
|
using namespace AGS::Engine;
|
|
|
|
// We don't have many places where we delay longer than a frame, but where we
|
|
// do, we should give the audio layer a chance to update.
|
|
// 16 milliseconds is rough period for 60fps
|
|
const auto MaximumDelayBetweenPolling = std::chrono::milliseconds(16);
|
|
|
|
AGSPlatformDriver *AGSPlatformDriver::instance = nullptr;
|
|
AGSPlatformDriver *platform = nullptr;
|
|
|
|
// ******** DEFAULT IMPLEMENTATIONS *******
|
|
|
|
void AGSPlatformDriver::AboutToQuitGame() {
|
|
}
|
|
void AGSPlatformDriver::PostAllegroInit(bool windowed) {
|
|
}
|
|
void AGSPlatformDriver::AttachToParentConsole() {
|
|
}
|
|
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() {
|
|
}
|
|
void AGSPlatformDriver::RegisterGameWithGameExplorer() {
|
|
}
|
|
void AGSPlatformDriver::UnRegisterGameWithGameExplorer() {
|
|
}
|
|
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::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)
|
|
|
|
// from ac_cdplayer
|
|
extern int use_cdplayer;
|
|
extern int need_to_stop_cd;
|
|
|
|
int numcddrives = 0;
|
|
|
|
int cd_player_init() {
|
|
int erro = cd_init();
|
|
if (erro) return -1;
|
|
numcddrives = 1;
|
|
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);
|
|
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 = std::min<std::chrono::milliseconds>(delayUntil - now, 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
|