[Scummvm-git-logs] scummvm master -> 5ad9352f8ee3f82759b263a3bf07e006305cec81
dreammaster
dreammaster at scummvm.org
Sat Jul 31 21:34:35 UTC 2021
This automated email contains information about 18 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
0aba516dac AGS: fixed SpriteFile may try loading a non-existing sprite
3f215aa374 AGS: Added BufferedSectionStream, limited to an offset range
7a632b9a85 AGS: AssetManager opens assets for reading restricted to the section
311f60f1f1 AGS: Separate functions for resetting input states
101be6b282 AGS: fixed lipsync data lost when doing RunAGSGame()
12b9c52fba AGS: IGraphicsDriver must also know native game color depth
4bcaeb6609 AGS: Use native color depth when creating vscreen and fading
d86792075c AGS: Fixed some old games crashing because of empty views
9e50e3268e AGS: Moved RoomAreaMask enum and GetMask functions to RoomStruct
c8f827197c AGS: Implemented getting DrawingSurface for room masks
770541024e AGS: Reworked tests ensuring always valid room area IDs are returned
ae6479ffee AGS: Recache walkbehinds after the mask was drawn upon
a9afcf230b AGS: Class FindFile, working as a file iterator with a name pattern
cb73fd2f2a AGS: Class FindFileRecursive, for iterating over nested subdirs
c56b82b5f6 AGS: Codestyle members of DataExtParser
47fe5901d5 AGS: Removed unused old code
79defb2f0f AGS: Updated upstream sync point comment
5ad9352f8e AGS: Re-add accidentally removed Object::get_Solid export
Commit: 0aba516daca320f51d7524b8b3cc971db4beff76
https://github.com/scummvm/scummvm/commit/0aba516daca320f51d7524b8b3cc971db4beff76
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:08-07:00
Commit Message:
AGS: fixed SpriteFile may try loading a non-existing sprite
>From upstream 5800e80ceaa26b8725d6bd3337de3aec5b204dc5
Changed paths:
engines/ags/shared/ac/sprite_cache.cpp
diff --git a/engines/ags/shared/ac/sprite_cache.cpp b/engines/ags/shared/ac/sprite_cache.cpp
index 945a26c5ac..b4a944de56 100644
--- a/engines/ags/shared/ac/sprite_cache.cpp
+++ b/engines/ags/shared/ac/sprite_cache.cpp
@@ -761,6 +761,9 @@ HAGSError SpriteFile::LoadSprite(sprkey_t index, Shared::Bitmap *&sprite) {
new Error(String::FromFormat("LoadSprite: slot index %d out of bounds (%d - %d).",
index, 0, _spriteData.size() - 1));
+ if (_spriteData[index].Offset == 0)
+ return HError::None(); // sprite is not in file
+
SeekToSprite(index);
_curPos = -2; // mark undefined pos
@@ -802,11 +805,17 @@ HAGSError SpriteFile::LoadSprite(sprkey_t index, Shared::Bitmap *&sprite) {
}
HError SpriteFile::LoadSpriteData(sprkey_t index, Size &metric, int &bpp,
- std::vector<char> &data) {
+ std::vector<char> &data) {
+ metric = Size();
+ bpp = 0;
+
if (index < 0 || (size_t)index >= _spriteData.size())
new Error(String::FromFormat("LoadSprite: slot index %d out of bounds (%d - %d).",
index, 0, _spriteData.size() - 1));
+ if (_spriteData[index].Offset == 0)
+ return HError::None(); // sprite is not in file
+
SeekToSprite(index);
_curPos = -2; // mark undefined pos
Commit: 3f215aa374f3db32b28121d7345fe87122ceceb5
https://github.com/scummvm/scummvm/commit/3f215aa374f3db32b28121d7345fe87122ceceb5
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:08-07:00
Commit Message:
AGS: Added BufferedSectionStream, limited to an offset range
>From upstream e7d6d4927a073f405012ca0c97361e7d519637a8
Changed paths:
engines/ags/shared/util/buffered_stream.cpp
engines/ags/shared/util/buffered_stream.h
diff --git a/engines/ags/shared/util/buffered_stream.cpp b/engines/ags/shared/util/buffered_stream.cpp
index 71106716af..4c11346181 100644
--- a/engines/ags/shared/util/buffered_stream.cpp
+++ b/engines/ags/shared/util/buffered_stream.cpp
@@ -38,6 +38,7 @@ BufferedStream::BufferedStream(const String &file_name, FileOpenMode open_mode,
_end = -1;
if (FileStream::Seek(0, kSeekEnd)) {
+ _start = 0;
_end = FileStream::GetPosition();
if (!FileStream::Seek(0, kSeekBegin))
_end = -1;
@@ -126,23 +127,35 @@ int32_t BufferedStream::WriteByte(uint8_t val) {
bool BufferedStream::Seek(soff_t offset, StreamSeek origin) {
soff_t want_pos = -1;
switch (origin) {
- case StreamSeek::kSeekCurrent:
- want_pos = _position + offset;
- break;
- case StreamSeek::kSeekBegin:
- want_pos = 0 + offset;
- break;
- case StreamSeek::kSeekEnd:
- want_pos = _end + offset;
- break;
- break;
+ case StreamSeek::kSeekCurrent: want_pos = _position + offset; break;
+ case StreamSeek::kSeekBegin: want_pos = _start + offset; break;
+ case StreamSeek::kSeekEnd: want_pos = _end + offset; break;
+ default: break;
}
// clamp
- _position = std::min(std::max(want_pos, (soff_t)0), _end);
+ _position = std::min(std::max(want_pos, (soff_t)_start), _end);
return _position == want_pos;
}
+BufferedSectionStream::BufferedSectionStream(const String &file_name, soff_t start_pos, soff_t end_pos,
+ FileOpenMode open_mode, FileWorkMode work_mode, DataEndianess stream_endianess)
+ : BufferedStream(file_name, open_mode, work_mode, stream_endianess) {
+ assert(start_pos <= end_pos);
+ start_pos = std::min(start_pos, end_pos);
+ _start = std::min(start_pos, _end);
+ _end = std::min(end_pos, _end);
+ Seek(0, kSeekBegin);
+}
+
+soff_t BufferedSectionStream::GetPosition() const {
+ return BufferedStream::GetPosition() - _start;
+}
+
+soff_t BufferedSectionStream::GetLength() const {
+ return _end - _start;
+}
+
} // namespace Shared
} // namespace AGS
} // namespace AGS3
diff --git a/engines/ags/shared/util/buffered_stream.h b/engines/ags/shared/util/buffered_stream.h
index 523a3f321b..b6d2575689 100644
--- a/engines/ags/shared/util/buffered_stream.h
+++ b/engines/ags/shared/util/buffered_stream.h
@@ -54,14 +54,27 @@ public:
bool Seek(soff_t offset, StreamSeek origin) override;
+protected:
+ soff_t _start;
+ soff_t _end;
+
private:
+ void FillBufferFromPosition(soff_t position);
+
+ soff_t _position;
soff_t _bufferPosition;
std::vector<char> _buffer;
+};
- soff_t _position;
- soff_t _end;
- void FillBufferFromPosition(soff_t position);
+// Creates a BufferedStream limited by an arbitrary offset range
+class BufferedSectionStream : public BufferedStream {
+public:
+ BufferedSectionStream(const String &file_name, soff_t start_pos, soff_t end_pos,
+ FileOpenMode open_mode, FileWorkMode work_mode, DataEndianess stream_endianess = kLittleEndian);
+
+ soff_t GetPosition() const override;
+ soff_t GetLength() const override;
};
} // namespace Shared
Commit: 7a632b9a8561b1caca770d6809feea72ba5d322d
https://github.com/scummvm/scummvm/commit/7a632b9a8561b1caca770d6809feea72ba5d322d
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:09-07:00
Commit Message:
AGS: AssetManager opens assets for reading restricted to the section
>From upstream c016ee79da0418482d029ae086dfbef9e5272af9
Changed paths:
engines/ags/shared/core/asset_manager.cpp
engines/ags/shared/util/file.cpp
engines/ags/shared/util/file.h
diff --git a/engines/ags/shared/core/asset_manager.cpp b/engines/ags/shared/core/asset_manager.cpp
index 7f3a874326..432aff0e47 100644
--- a/engines/ags/shared/core/asset_manager.cpp
+++ b/engines/ags/shared/core/asset_manager.cpp
@@ -265,9 +265,10 @@ Stream *AssetManager::OpenAsset(const String &asset_name, soff_t *asset_size, Fi
Stream *AssetManager::OpenAsset(const String &asset_name, const String &filter, soff_t *asset_size, FileOpenMode open_mode, FileWorkMode work_mode) const {
AssetLocation loc;
if (GetAsset(asset_name, filter, false, &loc, open_mode, work_mode)) {
- Stream *s = File::OpenFile(loc.FileName, open_mode, work_mode);
+ Stream *s = work_mode == kFile_Read ?
+ File::OpenFile(loc.FileName, loc.Offset, loc.Offset + loc.Size) :
+ File::OpenFile(loc.FileName, open_mode, work_mode);
if (s) {
- s->Seek(loc.Offset, kSeekBegin);
if (asset_size)
*asset_size = loc.Size;
}
diff --git a/engines/ags/shared/util/file.cpp b/engines/ags/shared/util/file.cpp
index 15189f208c..872c724e54 100644
--- a/engines/ags/shared/util/file.cpp
+++ b/engines/ags/shared/util/file.cpp
@@ -237,6 +237,16 @@ Stream *File::OpenFileCI(const String &file_name, FileOpenMode open_mode, FileWo
#endif
}
+Stream *File::OpenFile(const String &filename, soff_t start_off, soff_t end_off) {
+ FileStream *fs = new BufferedSectionStream(filename, start_off, end_off, kFile_Open, kFile_Read);
+ if (fs != nullptr && !fs->IsValid()) {
+ delete fs;
+ return nullptr;
+ }
+
+ return fs;
+}
+
} // namespace Shared
} // namespace AGS
} // namespace AGS3
diff --git a/engines/ags/shared/util/file.h b/engines/ags/shared/util/file.h
index e2442f96ce..8f144970ae 100644
--- a/engines/ags/shared/util/file.h
+++ b/engines/ags/shared/util/file.h
@@ -68,7 +68,10 @@ bool GetFileModesFromCMode(const String &cmode, FileOpenMode &open_mode,
// Gets C-style file mode from FileOpenMode and FileWorkMode
String GetCMode(FileOpenMode open_mode, FileWorkMode work_mode);
+// Opens file in the given mode
Stream *OpenFile(const String &filename, FileOpenMode open_mode, FileWorkMode work_mode);
+// Opens file for reading restricted to the arbitrary offset range
+Stream *OpenFile(const String &filename, soff_t start_off, soff_t end_off);
// Convenience helpers
// Create a totally new file, overwrite existing one
inline Stream *CreateFile(const String &filename) {
Commit: 311f60f1f1b8276754a25d24f6fa26eba59980d6
https://github.com/scummvm/scummvm/commit/311f60f1f1b8276754a25d24f6fa26eba59980d6
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:09-07:00
Commit Message:
AGS: Separate functions for resetting input states
>From upstream ece319e73f7ee783740dc936c1f4c910a900f56a
Changed paths:
engines/ags/engine/ac/game.cpp
engines/ags/engine/ac/sys_events.cpp
engines/ags/engine/ac/sys_events.h
engines/ags/engine/device/mouse_w32.cpp
engines/ags/engine/main/engine.cpp
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index ddc28902a4..cd07778d9b 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -1052,8 +1052,8 @@ HSaveError load_game(const String &path, int slotNumber, bool &data_overwritten)
src.InputStream.reset();
_G(our_eip) = _G(oldeip);
- // ensure keyboard buffer is clean
- ags_clear_input_buffer();
+ // ensure input state is reset
+ ags_clear_input_state();
// call "After Restore" event callback
run_on_event(GE_RESTORE_GAME, RuntimeScriptValue().SetInt32(slotNumber));
return HSaveError::None();
@@ -1232,7 +1232,7 @@ int __GetLocationType(int xxx, int yyy, int allowHotspot0) {
// Called whenever game looses input focus
void display_switch_out() {
_G(switched_away) = true;
- ags_clear_input_buffer();
+ ags_clear_input_state();
// Always unlock mouse when switching out from the game
_GP(mouse).UnlockFromWindow();
}
@@ -1266,8 +1266,7 @@ void display_switch_out_suspend() {
// Called whenever game gets input focus
void display_switch_in() {
- _G(switched_away) = false;
- ags_clear_input_buffer();
+ ags_clear_input_state();
// If auto lock option is set, lock mouse to the game window
if (_GP(usetup).mouse_auto_lock && _GP(scsystem).windowed)
_GP(mouse).TryLockToWindow();
diff --git a/engines/ags/engine/ac/sys_events.cpp b/engines/ags/engine/ac/sys_events.cpp
index 6e6347b68d..9cf78d8504 100644
--- a/engines/ags/engine/ac/sys_events.cpp
+++ b/engines/ags/engine/ac/sys_events.cpp
@@ -235,15 +235,28 @@ int ags_check_mouse_wheel() {
return result;
}
-
-
-void ags_clear_input_buffer() {
+void ags_clear_input_state() {
+ // Clear everything related to the input field
::AGS::g_events->clearEvents();
_G(mouse_accum_relx) = 0;
_G(mouse_accum_rely) = 0;
_G(mouse_button_state) = 0;
_G(mouse_accum_button_state) = 0;
- _G(mouse_clear_at_time) = AGS_Clock::now() + std::chrono::milliseconds(50);
+ _G(mouse_clear_at_time) = AGS_Clock::now();
+}
+
+void ags_clear_input_buffer() {
+ ::AGS::g_events->clearEvents();
+ // accumulated state only helps to not miss clicks
+ _G(mouse_accum_button_state) = 0;
+ // forget about recent mouse relative movement too
+ _G(mouse_accum_relx) = 0;
+ _G(mouse_accum_rely) = 0;
+}
+
+void ags_clear_mouse_movement() {
+ _G(mouse_accum_relx) = 0;
+ _G(mouse_accum_rely) = 0;
}
// TODO: this is an awful function that should be removed eventually.
diff --git a/engines/ags/engine/ac/sys_events.h b/engines/ags/engine/ac/sys_events.h
index bd60202726..2af6f194b0 100644
--- a/engines/ags/engine/ac/sys_events.h
+++ b/engines/ags/engine/ac/sys_events.h
@@ -96,8 +96,14 @@ extern int ags_check_mouse_wheel();
// Other input utilities
//
-// Clears buffered keypresses and mouse clicks, if any
-extern void ags_clear_input_buffer();
+// Clears buffered keypresses and mouse clicks;
+// resets current key/mb states
+void ags_clear_input_state();
+// Clears buffered keypresses and mouse clicks, if any;
+// does NOT reset current key/mb states
+void ags_clear_input_buffer();
+// Clears buffered mouse movement
+void ags_clear_mouse_movement();
// Halts execution until any user input
// TODO: seriously not a good design, replace with event listening
extern void ags_wait_until_keypress();
diff --git a/engines/ags/engine/device/mouse_w32.cpp b/engines/ags/engine/device/mouse_w32.cpp
index ead5ee40e9..9a4491c496 100644
--- a/engines/ags/engine/device/mouse_w32.cpp
+++ b/engines/ags/engine/device/mouse_w32.cpp
@@ -192,11 +192,16 @@ float Mouse::GetSpeed() {
}
void Mouse::UpdateGraphicArea() {
- // TODO
+ Mouse::ControlRect = _GP(GameScaling).ScaleRange(_GP(play).GetMainViewport());
+ Debug::Printf("Mouse cursor graphic area: (%d,%d)-(%d,%d) (%dx%d)",
+ Mouse::ControlRect.Left, Mouse::ControlRect.Top, Mouse::ControlRect.Right, Mouse::ControlRect.Bottom,
+ Mouse::ControlRect.GetWidth(), Mouse::ControlRect.GetHeight());
}
void Mouse::SetMovementControl(bool flag) {
- // TODO
+ ControlEnabled = false;
+ warning("movement control not supported, mouse control can't be enabled");
+ ags_clear_mouse_movement();
}
} // namespace AGS3
diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp
index 53d7932bff..7794d10f7e 100644
--- a/engines/ags/engine/main/engine.cpp
+++ b/engines/ags/engine/main/engine.cpp
@@ -1311,7 +1311,7 @@ bool engine_try_switch_windowed_gfxmode() {
init_desktop = get_desktop_size();
engine_post_gfxmode_setup(init_desktop);
}
- ags_clear_input_buffer();
+ ags_clear_input_state();
return res;
}
Commit: 101be6b282121abeb8562f091c6df5834b67eafc
https://github.com/scummvm/scummvm/commit/101be6b282121abeb8562f091c6df5834b67eafc
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:09-07:00
Commit Message:
AGS: fixed lipsync data lost when doing RunAGSGame()
>From upstream 599fb0c0882bdc511d2dd9e533a5b996b9ba4bc9
Changed paths:
engines/ags/engine/game/game_init.cpp
engines/ags/engine/main/engine.cpp
diff --git a/engines/ags/engine/game/game_init.cpp b/engines/ags/engine/game/game_init.cpp
index f853381390..7503d3daac 100644
--- a/engines/ags/engine/game/game_init.cpp
+++ b/engines/ags/engine/game/game_init.cpp
@@ -30,11 +30,13 @@
#include "ags/shared/ac/game_setup_struct.h"
#include "ags/engine/ac/game_state.h"
#include "ags/engine/ac/gui.h"
+#include "ags/engine/ac/lip_sync.h"
#include "ags/engine/ac/move_list.h"
#include "ags/engine/ac/dynobj/all_dynamic_classes.h"
#include "ags/engine/ac/dynobj/all_script_classes.h"
#include "ags/engine/ac/statobj/ags_static_object.h"
#include "ags/engine/ac/statobj/static_array.h"
+#include "ags/shared/core/asset_manager.h"
#include "ags/engine/debugging/debug_log.h"
#include "ags/shared/debugging/out.h"
#include "ags/shared/font/ags_font_renderer.h"
@@ -43,6 +45,7 @@
#include "ags/shared/gfx/bitmap.h"
#include "ags/engine/gfx/ddb.h"
#include "ags/shared/gui/gui_label.h"
+#include "ags/engine/media/audio/audio_system.h"
#include "ags/engine/platform/base/ags_platform_driver.h"
#include "ags/plugins/plugin_engine.h"
#include "ags/shared/script/cc_error.h"
@@ -260,6 +263,29 @@ void LoadFonts(GameDataVersion data_ver) {
}
}
+void LoadLipsyncData() {
+ std::unique_ptr<Stream> speechsync(_GP(AssetMgr)->OpenAsset("syncdata.dat", "voice"));
+ if (!speechsync)
+ return;
+ // this game has voice lip sync
+ int lipsync_fmt = speechsync->ReadInt32();
+ if (lipsync_fmt != 4) {
+ Debug::Printf(kDbgMsg_Info, "Unknown speech lip sync format (%d).\nLip sync disabled.", lipsync_fmt);
+ } else {
+ _G(numLipLines) = speechsync->ReadInt32();
+ _G(splipsync) = (SpeechLipSyncLine *)malloc(sizeof(SpeechLipSyncLine) * _G(numLipLines));
+ for (int ee = 0; ee < _G(numLipLines); ee++) {
+ _G(splipsync)[ee].numPhonemes = speechsync->ReadInt16();
+ speechsync->Read(_G(splipsync)[ee].filename, 14);
+ _G(splipsync)[ee].endtimeoffs = (int *)malloc(_G(splipsync)[ee].numPhonemes * sizeof(int));
+ speechsync->ReadArrayOfInt32(_G(splipsync)[ee].endtimeoffs, _G(splipsync)[ee].numPhonemes);
+ _G(splipsync)[ee].frame = (short *)malloc(_G(splipsync)[ee].numPhonemes * sizeof(short));
+ speechsync->ReadArrayOfInt16(_G(splipsync)[ee].frame, _G(splipsync)[ee].numPhonemes);
+ }
+ }
+ Debug::Printf(kDbgMsg_Info, "Lipsync data found and loaded");
+}
+
void AllocScriptModules() {
_GP(moduleInst).resize(_G(numScriptModules), nullptr);
_GP(moduleInstFork).resize(_G(numScriptModules), nullptr);
diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp
index 7794d10f7e..e5fa1c899b 100644
--- a/engines/ags/engine/main/engine.cpp
+++ b/engines/ags/engine/main/engine.cpp
@@ -294,27 +294,7 @@ void engine_locate_speech_pak() {
_G(platform)->DisplayAlert("Unable to read voice pack, file could be corrupted or of unknown format.\nSpeech voice-over will be disabled.");
return;
}
- // TODO: why is this read right here??? move this to InitGameState!
- Stream *speechsync = _GP(AssetMgr)->OpenAsset("syncdata.dat");
- if (speechsync != nullptr) {
- // this game has voice lip sync
- int lipsync_fmt = speechsync->ReadInt32();
- if (lipsync_fmt != 4) {
- Debug::Printf(kDbgMsg_Info, "Unknown speech lip sync format (%d).\nLip sync disabled.", lipsync_fmt);
- } else {
- _G(numLipLines) = speechsync->ReadInt32();
- _G(splipsync) = (SpeechLipSyncLine *)malloc(sizeof(SpeechLipSyncLine) * _G(numLipLines));
- for (int ee = 0; ee < _G(numLipLines); ee++) {
- _G(splipsync)[ee].numPhonemes = speechsync->ReadInt16();
- speechsync->Read(_G(splipsync)[ee].filename, 14);
- _G(splipsync)[ee].endtimeoffs = (int32_t *)malloc(_G(splipsync)[ee].numPhonemes * sizeof(int));
- speechsync->ReadArrayOfInt32(_G(splipsync)[ee].endtimeoffs, _G(splipsync)[ee].numPhonemes);
- _G(splipsync)[ee].frame = (short *)malloc(_G(splipsync)[ee].numPhonemes * sizeof(short));
- speechsync->ReadArrayOfInt16(_G(splipsync)[ee].frame, _G(splipsync)[ee].numPhonemes);
- }
- }
- delete speechsync;
- }
+
Debug::Printf(kDbgMsg_Info, "Voice pack found and initialized.");
_GP(play).want_speech = 1;
} else if (Path::ComparePaths(_GP(ResPaths).DataDir, _GP(ResPaths).VoiceDir2) != 0) {
Commit: 12b9c52fbabc0a385d49e7b7310d57428f6105c7
https://github.com/scummvm/scummvm/commit/12b9c52fbabc0a385d49e7b7310d57428f6105c7
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:09-07:00
Commit Message:
AGS: IGraphicsDriver must also know native game color depth
>From upstream 0f9392acc1dd71b9b849af0eefbccdd92be12b30
Changed paths:
engines/ags/engine/gfx/ali_3d_scummvm.cpp
engines/ags/engine/gfx/ali_3d_scummvm.h
engines/ags/engine/gfx/gfx_defines.h
engines/ags/engine/gfx/gfx_driver_base.cpp
engines/ags/engine/gfx/gfx_driver_base.h
engines/ags/engine/gfx/graphics_driver.h
engines/ags/engine/main/engine.cpp
engines/ags/engine/main/graphics_mode.cpp
engines/ags/engine/main/graphics_mode.h
diff --git a/engines/ags/engine/gfx/ali_3d_scummvm.cpp b/engines/ags/engine/gfx/ali_3d_scummvm.cpp
index 5887c61ca5..e58cd789bc 100644
--- a/engines/ags/engine/gfx/ali_3d_scummvm.cpp
+++ b/engines/ags/engine/gfx/ali_3d_scummvm.cpp
@@ -162,8 +162,8 @@ void ScummVMRendererGraphicsDriver::ReleaseDisplayMode() {
ClearDrawLists();
}
-bool ScummVMRendererGraphicsDriver::SetNativeSize(const Size &src_size) {
- OnSetNativeSize(src_size);
+bool ScummVMRendererGraphicsDriver::SetNativeResolution(const GraphicResolution &native_res) {
+ OnSetNativeRes(native_res);
CreateVirtualScreen();
return !_srcRect.IsEmpty();
}
diff --git a/engines/ags/engine/gfx/ali_3d_scummvm.h b/engines/ags/engine/gfx/ali_3d_scummvm.h
index 8a5200668f..13ac002439 100644
--- a/engines/ags/engine/gfx/ali_3d_scummvm.h
+++ b/engines/ags/engine/gfx/ali_3d_scummvm.h
@@ -178,7 +178,7 @@ public:
void SetTintMethod(TintMethod method) override;
bool SetDisplayMode(const DisplayMode &mode) override;
void UpdateDeviceScreen(const Size &screen_sz) override;
- bool SetNativeSize(const Size &src_size) override;
+ bool SetNativeResolution(const GraphicResolution &native_res) override;
bool SetRenderFrame(const Rect &dst_rect) override;
bool IsModeSupported(const DisplayMode &mode) override;
int GetDisplayDepthForNativeDepth(int native_color_depth) const override;
diff --git a/engines/ags/engine/gfx/gfx_defines.h b/engines/ags/engine/gfx/gfx_defines.h
index 7f609eb0f0..17bbe98857 100644
--- a/engines/ags/engine/gfx/gfx_defines.h
+++ b/engines/ags/engine/gfx/gfx_defines.h
@@ -24,6 +24,7 @@
#define AGS_ENGINE_GFX_GFX_DEFINES_H
#include "ags/shared/core/types.h"
+#include "ags/shared/util/geometry.h"
namespace AGS3 {
namespace AGS {
@@ -38,21 +39,19 @@ enum GlobalFlipType {
};
// GraphicResolution struct determines image size and color depth
-struct GraphicResolution {
- int32_t Width;
- int32_t Height;
- int32_t ColorDepth;
+struct GraphicResolution : Size {
+ int32_t ColorDepth; // color depth in bits per pixel
GraphicResolution()
- : Width(0)
- , Height(0)
- , ColorDepth(0) {
+ : ColorDepth(0) {
}
- GraphicResolution(int32_t width, int32_t height, int32_t color_depth) {
- Width = width;
- Height = height;
- ColorDepth = color_depth;
+ GraphicResolution(int32_t width, int32_t height, int32_t color_depth)
+ : Size(width, height), ColorDepth(color_depth) {
+ }
+
+ GraphicResolution(Size size, int32_t color_depth)
+ : Size(size), ColorDepth(color_depth) {
}
inline bool IsValid() const {
diff --git a/engines/ags/engine/gfx/gfx_driver_base.cpp b/engines/ags/engine/gfx/gfx_driver_base.cpp
index c6e28a2456..bd03ee0ce6 100644
--- a/engines/ags/engine/gfx/gfx_driver_base.cpp
+++ b/engines/ags/engine/gfx/gfx_driver_base.cpp
@@ -103,12 +103,13 @@ void GraphicsDriverBase::OnScalingChanged() {
_scaling.Init(_srcRect.GetSize(), _dstRect);
}
-void GraphicsDriverBase::OnSetNativeSize(const Size &src_size) {
- _srcRect = RectWH(0, 0, src_size.Width, src_size.Height);
+void GraphicsDriverBase::OnSetNativeRes(const GraphicResolution &native_res) {
+ _srcRect = RectWH(0, 0, native_res.Width, native_res.Height);
+ _srcColorDepth = native_res.ColorDepth;
OnScalingChanged();
// Adjust default sprite batch making it comply to native size
- _spriteBatchDesc[0].Viewport = RectWH(src_size);
+ _spriteBatchDesc[0].Viewport = RectWH(native_res);
InitSpriteBatch(_actSpriteBatch, _spriteBatchDesc[_actSpriteBatch]);
}
diff --git a/engines/ags/engine/gfx/gfx_driver_base.h b/engines/ags/engine/gfx/gfx_driver_base.h
index 4cc6eb6dba..7ce09dd1c1 100644
--- a/engines/ags/engine/gfx/gfx_driver_base.h
+++ b/engines/ags/engine/gfx/gfx_driver_base.h
@@ -132,7 +132,7 @@ protected:
// Called after new mode was successfully initialized
virtual void OnModeSet(const DisplayMode &mode);
// Called when the new native size is set
- virtual void OnSetNativeSize(const Size &src_size);
+ virtual void OnSetNativeRes(const GraphicResolution &native_res);
// Called before display mode is going to be released
virtual void OnModeReleased();
// Called when new render frame is set
@@ -148,6 +148,7 @@ protected:
DisplayMode _mode; // display mode settings
Rect _srcRect; // rendering source rect
+ int _srcColorDepth; // rendering source color depth (in bits per pixel)
Rect _dstRect; // rendering destination rect
Rect _filterRect; // filter scaling destination rect (before final scaling)
PlaneScaling _scaling; // native -> render dest coordinate transformation
diff --git a/engines/ags/engine/gfx/graphics_driver.h b/engines/ags/engine/gfx/graphics_driver.h
index 5758883185..d6c8564e9c 100644
--- a/engines/ags/engine/gfx/graphics_driver.h
+++ b/engines/ags/engine/gfx/graphics_driver.h
@@ -107,7 +107,7 @@ public:
// Gets if a graphics mode was initialized
virtual bool IsModeSet() const = 0;
// Set the size of the native image size
- virtual bool SetNativeSize(const Size &src_size) = 0;
+ virtual bool SetNativeResolution(const GraphicResolution &native_res) = 0;
virtual bool IsNativeSizeValid() const = 0;
// Set game render frame and translation
virtual bool SetRenderFrame(const Rect &dst_rect) = 0;
diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp
index e5fa1c899b..27c1f26417 100644
--- a/engines/ags/engine/main/engine.cpp
+++ b/engines/ags/engine/main/engine.cpp
@@ -1237,7 +1237,8 @@ bool engine_try_set_gfxmode_any(const ScreenSetup &setup) {
engine_shutdown_gfxmode();
const Size init_desktop = get_desktop_size();
- if (!graphics_mode_init_any(_GP(game).GetGameRes(), setup, ColorDepthOption(_GP(game).GetColorDepth())))
+ if (!graphics_mode_init_any(GraphicResolution(_GP(game).GetGameRes(), _GP(game).color_depth * 8),
+ setup, ColorDepthOption(_GP(game).GetColorDepth())))
return false;
engine_post_gfxmode_setup(init_desktop);
diff --git a/engines/ags/engine/main/graphics_mode.cpp b/engines/ags/engine/main/graphics_mode.cpp
index 1f3b62fff6..17dc5dee2a 100644
--- a/engines/ags/engine/main/graphics_mode.cpp
+++ b/engines/ags/engine/main/graphics_mode.cpp
@@ -303,18 +303,18 @@ bool try_init_compatible_mode(const DisplayMode &dm, const bool match_device_rat
}
// Try to find and initialize compatible display mode as close to given setup as possible
-bool try_init_mode_using_setup(const Size &game_size, const DisplayModeSetup &dm_setup,
- const int col_depth, const GameFrameSetup &frame_setup,
- const GfxFilterSetup &filter_setup) {
+bool try_init_mode_using_setup(const GraphicResolution &game_res, const DisplayModeSetup &dm_setup,
+ const int col_depth, const GameFrameSetup &frame_setup,
+ const GfxFilterSetup &filter_setup) {
// We determine the requested size of the screen using setup options
- const Size screen_size = precalc_screen_size(game_size, dm_setup, frame_setup);
+ const Size screen_size = precalc_screen_size(game_res, dm_setup, frame_setup);
DisplayMode dm(GraphicResolution(screen_size.Width, screen_size.Height, col_depth),
- dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync);
+ dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync);
if (!try_init_compatible_mode(dm, dm_setup.ScreenSize.SizeDef == kScreenDef_Explicit ? false : dm_setup.ScreenSize.MatchDeviceRatio))
return false;
// Set up native size and render frame
- if (!graphics_mode_set_native_size(game_size) || !graphics_mode_set_render_frame(frame_setup))
+ if (!graphics_mode_set_native_res(game_res) || !graphics_mode_set_render_frame(frame_setup))
return false;
// Set up graphics filter
@@ -352,17 +352,19 @@ void log_out_driver_modes(const int color_depth) {
// Create requested graphics driver and try to find and initialize compatible display mode as close to user setup as possible;
// if the given setup fails, gets default setup for the opposite type of mode (fullscreen/windowed) and tries that instead.
-bool create_gfx_driver_and_init_mode_any(const String &gfx_driver_id, const Size &game_size, const DisplayModeSetup &dm_setup,
- const ColorDepthOption &color_depth, const GameFrameSetup &frame_setup, const GfxFilterSetup &filter_setup) {
+bool create_gfx_driver_and_init_mode_any(const String &gfx_driver_id,
+ const GraphicResolution &game_res,
+ const DisplayModeSetup &dm_setup, const ColorDepthOption &color_depth,
+ const GameFrameSetup &frame_setup, const GfxFilterSetup &filter_setup) {
if (!graphics_mode_create_renderer(gfx_driver_id))
return false;
const int use_col_depth =
- color_depth.Forced ? color_depth.Bits : _G(gfxDriver)->GetDisplayDepthForNativeDepth(color_depth.Bits);
+ color_depth.Forced ? color_depth.Bits : _G(gfxDriver)->GetDisplayDepthForNativeDepth(color_depth.Bits);
// Log out supported driver modes
log_out_driver_modes(use_col_depth);
- bool result = try_init_mode_using_setup(game_size, dm_setup, use_col_depth, frame_setup, filter_setup);
+ bool result = try_init_mode_using_setup(game_res, dm_setup, use_col_depth, frame_setup, filter_setup);
// Try windowed mode if fullscreen failed, and vice versa
if (!result && _G(editor_debugging_enabled) == 0) {
// we need to clone from initial config, because not every parameter is set by graphics_mode_get_defaults()
@@ -370,30 +372,30 @@ bool create_gfx_driver_and_init_mode_any(const String &gfx_driver_id, const Size
dm_setup_alt.Windowed = !dm_setup.Windowed;
GameFrameSetup frame_setup_alt;
graphics_mode_get_defaults(dm_setup_alt.Windowed, dm_setup_alt.ScreenSize, frame_setup_alt);
- result = try_init_mode_using_setup(game_size, dm_setup_alt, use_col_depth, frame_setup_alt, filter_setup);
+ result = try_init_mode_using_setup(game_res, dm_setup_alt, use_col_depth, frame_setup_alt, filter_setup);
}
return result;
}
bool simple_create_gfx_driver_and_init_mode(const String &gfx_driver_id,
- const Size &game_size,
- const DisplayModeSetup &dm_setup,
- const ColorDepthOption &color_depth,
- const GameFrameSetup &frame_setup,
- const GfxFilterSetup &filter_setup) {
+ const GraphicResolution &game_res,
+ const DisplayModeSetup &dm_setup,
+ const ColorDepthOption &color_depth,
+ const GameFrameSetup &frame_setup,
+ const GfxFilterSetup &filter_setup) {
if (!graphics_mode_create_renderer(gfx_driver_id)) {
return false;
}
const int col_depth = _G(gfxDriver)->GetDisplayDepthForNativeDepth(color_depth.Bits);
- DisplayMode dm(GraphicResolution(game_size.Width, game_size.Height, col_depth),
- dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync);
+ DisplayMode dm(GraphicResolution(game_res.Width, game_res.Height, col_depth),
+ dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync);
if (!graphics_mode_set_dm(dm)) {
return false;
}
- if (!graphics_mode_set_native_size(game_size)) {
+ if (!graphics_mode_set_native_res(dm)) {
return false;
}
if (!graphics_mode_set_render_frame(frame_setup)) {
@@ -406,7 +408,6 @@ bool simple_create_gfx_driver_and_init_mode(const String &gfx_driver_id,
return true;
}
-
void display_gfx_mode_error(const Size &game_size, const ScreenSetup &setup, const int color_depth) {
_G(proper_exit) = 1;
@@ -427,7 +428,7 @@ void display_gfx_mode_error(const Size &game_size, const ScreenSetup &setup, con
main_error.GetCStr(), _G(platform)->GetGraphicsTroubleshootingText());
}
-bool graphics_mode_init_any(const Size game_size, const ScreenSetup &setup, const ColorDepthOption &color_depth) {
+bool graphics_mode_init_any(const GraphicResolution &game_res, const ScreenSetup &setup, const ColorDepthOption &color_depth) {
// Log out display information
Size device_size;
if (sys_get_desktop_resolution(device_size.Width, device_size.Height) == 0)
@@ -468,7 +469,7 @@ bool graphics_mode_init_any(const Size game_size, const ScreenSetup &setup, cons
#else
create_gfx_driver_and_init_mode_any
#endif
- (*sit, game_size, setup.DisplayMode, color_depth, gameframe, setup.Filter);
+ (*sit, game_res, setup.DisplayMode, color_depth, gameframe, setup.Filter);
if (result)
break;
@@ -476,7 +477,7 @@ bool graphics_mode_init_any(const Size game_size, const ScreenSetup &setup, cons
}
// If all possibilities failed, display error message and quit
if (!result) {
- display_gfx_mode_error(game_size, setup, color_depth.Bits);
+ display_gfx_mode_error(game_res, setup, color_depth.Bits);
return false;
}
return true;
@@ -554,10 +555,10 @@ bool graphics_mode_update_render_frame() {
return true;
}
-bool graphics_mode_set_native_size(const Size &native_size) {
- if (!_G(gfxDriver) || native_size.IsNull())
+bool graphics_mode_set_native_res(const GraphicResolution &native_res) {
+ if (!_G(gfxDriver) || !native_res.IsValid())
return false;
- if (!_G(gfxDriver)->SetNativeSize(native_size))
+ if (!_G(gfxDriver)->SetNativeResolution(native_res))
return false;
// if render frame translation was already set, then update it with new native size
if (_G(gfxDriver)->IsRenderFrameValid())
diff --git a/engines/ags/engine/main/graphics_mode.h b/engines/ags/engine/main/graphics_mode.h
index 0cd6a45a5e..025157672e 100644
--- a/engines/ags/engine/main/graphics_mode.h
+++ b/engines/ags/engine/main/graphics_mode.h
@@ -31,6 +31,7 @@
namespace AGS3 {
using AGS::Shared::String;
+using AGS::Engine::GraphicResolution;
using AGS::Engine::DisplayMode;
Size get_desktop_size();
@@ -131,7 +132,7 @@ struct ActiveDisplaySetting {
// Initializes any possible gfx mode, using user config as a recommendation;
// may try all available renderers and modes before succeeding (or failing)
-bool graphics_mode_init_any(const Size game_size, const ScreenSetup &setup, const ColorDepthOption &color_depth);
+bool graphics_mode_init_any(const GraphicResolution &game_res, const ScreenSetup &setup, const ColorDepthOption &color_depth);
// Return last saved display mode of the given kind
ActiveDisplaySetting graphics_mode_get_last_setting(bool windowed);
// Creates graphics driver of given id
@@ -142,7 +143,7 @@ bool graphics_mode_set_dm_any(const Size &game_size, const DisplayModeSetup &dm_
// Set the display mode with given parameters
bool graphics_mode_set_dm(const AGS::Engine::DisplayMode &dm);
// Set the native image size
-bool graphics_mode_set_native_size(const Size &native_size);
+bool graphics_mode_set_native_res(const GraphicResolution &native_res);
// Get current render frame setup
GameFrameSetup graphics_mode_get_render_frame();
// Set the render frame position inside the window
Commit: 4bcaeb6609501ccc245f9137ce00bda3144142b8
https://github.com/scummvm/scummvm/commit/4bcaeb6609501ccc245f9137ce00bda3144142b8
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:09-07:00
Commit Message:
AGS: Use native color depth when creating vscreen and fading
>From upstream 28a882eefad283e20397d787a934ec9bd0efc8b7
Changed paths:
engines/ags/engine/gfx/ali_3d_scummvm.cpp
diff --git a/engines/ags/engine/gfx/ali_3d_scummvm.cpp b/engines/ags/engine/gfx/ali_3d_scummvm.cpp
index e58cd789bc..cfd02ed948 100644
--- a/engines/ags/engine/gfx/ali_3d_scummvm.cpp
+++ b/engines/ags/engine/gfx/ali_3d_scummvm.cpp
@@ -139,7 +139,7 @@ void ScummVMRendererGraphicsDriver::CreateVirtualScreen() {
// Initialize virtual screen; size is equal to native resolution
const int vscreen_w = _srcRect.GetWidth();
const int vscreen_h = _srcRect.GetHeight();
- _origVirtualScreen.reset(new Bitmap(vscreen_w, vscreen_h));
+ _origVirtualScreen.reset(new Bitmap(vscreen_w, vscreen_h, _srcColorDepth));
virtualScreen = _origVirtualScreen.get();
_stageVirtualScreen = virtualScreen;
@@ -263,7 +263,7 @@ void ScummVMRendererGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBa
}
// No surface prepared and has transformation other than offset
else if (!batch.Surface || batch.IsVirtualScreen || batch.Surface->GetWidth() != src_w || batch.Surface->GetHeight() != src_h) {
- batch.Surface.reset(new Bitmap(src_w, src_h));
+ batch.Surface.reset(new Bitmap(src_w, src_h, _srcColorDepth));
batch.Opaque = false;
batch.IsVirtualScreen = false;
}
@@ -287,7 +287,7 @@ void ScummVMRendererGraphicsDriver::SetScreenTint(int red, int green, int blue)
_tint_red = red;
_tint_green = green;
_tint_blue = blue;
- if (((_tint_red > 0) || (_tint_green > 0) || (_tint_blue > 0)) && (_mode.ColorDepth > 8)) {
+ if (((_tint_red > 0) || (_tint_green > 0) || (_tint_blue > 0)) && (_srcColorDepth > 8)) {
_spriteBatches[_actSpriteBatch].List.push_back(ALDrawListEntry((ALSoftwareBitmap *)0x1, 0, 0));
}
}
@@ -526,9 +526,9 @@ Bitmap *ScummVMRendererGraphicsDriver::GetStageBackBuffer(bool /*mark_dirty*/) {
bool ScummVMRendererGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) {
(void)at_native_res; // software driver always renders at native resolution at the moment
// software filter is taught to copy to any size
- if (destination->GetColorDepth() != _mode.ColorDepth) {
+ if (destination->GetColorDepth() != _srcColorDepth) {
if (want_fmt)
- *want_fmt = GraphicResolution(destination->GetWidth(), destination->GetHeight(), _mode.ColorDepth);
+ *want_fmt = GraphicResolution(destination->GetWidth(), destination->GetHeight(), _srcColorDepth);
return false;
}
@@ -659,7 +659,7 @@ void ScummVMRendererGraphicsDriver::__fade_out_range(int speed, int from, int to
}
void ScummVMRendererGraphicsDriver::FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) {
- if (_mode.ColorDepth > 8) {
+ if (_srcColorDepth > 8) {
highcolor_fade_out(virtualScreen, _drawPostScreenCallback, 0, 0, speed * 4, targetColourRed, targetColourGreen, targetColourBlue);
} else {
__fade_out_range(speed, 0, 255, targetColourRed, targetColourGreen, targetColourBlue);
@@ -671,7 +671,7 @@ void ScummVMRendererGraphicsDriver::FadeIn(int speed, PALETTE p, int targetColou
_drawScreenCallback();
RenderToBackBuffer();
}
- if (_mode.ColorDepth > 8) {
+ if (_srcColorDepth > 8) {
highcolor_fade_in(virtualScreen, _drawPostScreenCallback, 0, 0, speed * 4, targetColourRed, targetColourGreen, targetColourBlue);
} else {
initialize_fade_256(targetColourRed, targetColourGreen, targetColourBlue);
Commit: d86792075c56c04f8641e24db10856cf18a28cac
https://github.com/scummvm/scummvm/commit/d86792075c56c04f8641e24db10856cf18a28cac
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:09-07:00
Commit Message:
AGS: Fixed some old games crashing because of empty views
>From upstream 116e6d928eb335740d4c1801b4cb25fc5ba48905
Changed paths:
engines/ags/engine/ac/character_info_engine.cpp
diff --git a/engines/ags/engine/ac/character_info_engine.cpp b/engines/ags/engine/ac/character_info_engine.cpp
index 560f334a3f..d17e129f51 100644
--- a/engines/ags/engine/ac/character_info_engine.cpp
+++ b/engines/ags/engine/ac/character_info_engine.cpp
@@ -82,8 +82,13 @@ void CharacterInfo::UpdateMoveAndAnim(int &char_index, CharacterExtras *chex, in
for (loop = 0;
(loop < _G(views)[view].numLoops) && (_G(views)[view].loops[loop].numFrames == 0); ++loop) {
}
- if (loop == _G(views)[view].numLoops)
- quitprintf("!Character %s is assigned view %d that has no frames!", name, view);
+ if (loop == _G(views)[view].numLoops) {
+ // view has no frames?!
+ // amazingly enough there are old games that allow this to happen...
+ if (_G(loaded_game_file_version) >= kGameVersion_300)
+ quitprintf("!Character %s is assigned view %d that has no frames!", name, view);
+ loop = 0;
+ }
}
int doing_nothing = 1;
Commit: 9e50e3268ed42cad9071cb91fc69f6e2e7540d4b
https://github.com/scummvm/scummvm/commit/9e50e3268ed42cad9071cb91fc69f6e2e7540d4b
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:10-07:00
Commit Message:
AGS: Moved RoomAreaMask enum and GetMask functions to RoomStruct
>From upstream 0903ec301f25f69b8bb931db2e27e0e3bfce3afe
Changed paths:
engines/ags/shared/game/room_struct.cpp
engines/ags/shared/game/room_struct.h
diff --git a/engines/ags/shared/game/room_struct.cpp b/engines/ags/shared/game/room_struct.cpp
index ce3794e93d..2a6b824929 100644
--- a/engines/ags/shared/game/room_struct.cpp
+++ b/engines/ags/shared/game/room_struct.cpp
@@ -191,6 +191,27 @@ void RoomStruct::SetResolution(RoomResolutionType type) {
_resolution = type;
}
+Bitmap *RoomStruct::GetMask(RoomAreaMask mask) const {
+ switch (mask) {
+ case kRoomAreaHotspot: return HotspotMask.get();
+ case kRoomAreaWalkBehind: return WalkBehindMask.get();
+ case kRoomAreaWalkable: return WalkAreaMask.get();
+ case kRoomAreaRegion: return RegionMask.get();
+ }
+ return nullptr;
+}
+
+float RoomStruct::GetMaskScale(RoomAreaMask mask) const {
+ switch (mask) {
+ case kRoomAreaWalkBehind: return 1.f; // walk-behinds always 1:1 with room size
+ case kRoomAreaHotspot:
+ case kRoomAreaWalkable:
+ case kRoomAreaRegion:
+ return 1.f / MaskResolution;
+ }
+ return 0.f;
+}
+
bool RoomStruct::HasRegionLightLevel(int id) const {
if (id >= 0 && id < MAX_ROOM_REGIONS)
return Regions[id].Tint == 0;
diff --git a/engines/ags/shared/game/room_struct.h b/engines/ags/shared/game/room_struct.h
index 862b795d8f..d338aca78e 100644
--- a/engines/ags/shared/game/room_struct.h
+++ b/engines/ags/shared/game/room_struct.h
@@ -64,6 +64,15 @@ typedef std::shared_ptr<ccScript> PScript;
// later, when more engine source is put in AGS namespace and
// refactored.
+// Room's area mask type
+enum RoomAreaMask {
+ kRoomAreaNone = 0,
+ kRoomAreaHotspot,
+ kRoomAreaWalkBehind,
+ kRoomAreaWalkable,
+ kRoomAreaRegion
+};
+
// Room's audio volume modifier
enum RoomVolumeMod {
kRoomVolumeQuietest = -3,
@@ -280,6 +289,11 @@ public:
// Set legacy resolution type
void SetResolution(RoomResolutionType type);
+ // Gets bitmap of particular mask layer
+ Bitmap *GetMask(RoomAreaMask mask) const;
+ // Gets mask's scale relative to the room's background size
+ float GetMaskScale(RoomAreaMask mask) const;
+
// TODO: see later whether it may be more convenient to move these to the Region class instead.
// Gets if the given region has light level set
bool HasRegionLightLevel(int id) const;
Commit: c8f827197cba330b9b35be91d7082cbc73ef7785
https://github.com/scummvm/scummvm/commit/c8f827197cba330b9b35be91d7082cbc73ef7785
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:10-07:00
Commit Message:
AGS: Implemented getting DrawingSurface for room masks
>From upstream 087fe51893cc4b61dcfeb84fe72555349b56c411
Changed paths:
engines/ags/engine/ac/dynobj/script_drawing_surface.cpp
engines/ags/engine/ac/dynobj/script_drawing_surface.h
engines/ags/engine/ac/global_api.cpp
engines/ags/engine/ac/hotspot.cpp
engines/ags/engine/ac/region.cpp
engines/ags/engine/ac/room.cpp
engines/ags/engine/ac/room.h
diff --git a/engines/ags/engine/ac/dynobj/script_drawing_surface.cpp b/engines/ags/engine/ac/dynobj/script_drawing_surface.cpp
index f4cfa2b9cd..8d71a593f1 100644
--- a/engines/ags/engine/ac/dynobj/script_drawing_surface.cpp
+++ b/engines/ags/engine/ac/dynobj/script_drawing_surface.cpp
@@ -45,9 +45,9 @@ Bitmap *ScriptDrawingSurface::GetBitmapSurface() {
return _G(dynamicallyCreatedSurfaces)[dynamicSurfaceNumber];
else if (linkedBitmapOnly != nullptr)
return linkedBitmapOnly;
- else
- quit("!DrawingSurface: attempted to use surface after Release was called");
-
+ else if (roomMaskType > kRoomAreaNone)
+ return _GP(thisroom).GetMask(roomMaskType);
+ quit("!DrawingSurface: attempted to use surface after Release was called");
return nullptr;
}
@@ -77,7 +77,12 @@ const char *ScriptDrawingSurface::GetType() {
int ScriptDrawingSurface::Serialize(const char *address, char *buffer, int bufsize) {
StartSerialize(buffer);
- SerializeInt(roomBackgroundNumber);
+ // pack mask type in the last byte of a negative integer
+ // note: (-1) is reserved for "unused", for backward compatibility
+ if (roomMaskType > 0)
+ SerializeInt(0xFFFFFF00 | roomMaskType);
+ else
+ SerializeInt(roomBackgroundNumber);
SerializeInt(dynamicSpriteNumber);
SerializeInt(dynamicSurfaceNumber);
SerializeInt(currentColour);
@@ -91,7 +96,12 @@ int ScriptDrawingSurface::Serialize(const char *address, char *buffer, int bufsi
void ScriptDrawingSurface::Unserialize(int index, const char *serializedData, int dataSize) {
StartUnserialize(serializedData, dataSize);
- roomBackgroundNumber = UnserializeInt();
+ int room_ds = UnserializeInt();
+ if (room_ds >= 0)
+ roomBackgroundNumber = room_ds;
+ // negative value may contain a mask type
+ else if ((room_ds & 0xFF) != 0xFF)
+ roomMaskType = (RoomAreaMask)(room_ds & 0xFF);
dynamicSpriteNumber = UnserializeInt();
dynamicSurfaceNumber = UnserializeInt();
currentColour = UnserializeInt();
@@ -105,6 +115,7 @@ void ScriptDrawingSurface::Unserialize(int index, const char *serializedData, in
ScriptDrawingSurface::ScriptDrawingSurface() {
roomBackgroundNumber = -1;
+ roomMaskType = kRoomAreaNone;
dynamicSpriteNumber = -1;
dynamicSurfaceNumber = -1;
isLinkedBitmapOnly = false;
diff --git a/engines/ags/engine/ac/dynobj/script_drawing_surface.h b/engines/ags/engine/ac/dynobj/script_drawing_surface.h
index 0d0317095e..432571fea9 100644
--- a/engines/ags/engine/ac/dynobj/script_drawing_surface.h
+++ b/engines/ags/engine/ac/dynobj/script_drawing_surface.h
@@ -24,6 +24,7 @@
#define AGS_ENGINE_AC_DYNOBJ_SCRIPT_DRAWING_SURFACE_H
#include "ags/engine/ac/dynobj/cc_ags_dynamic_object.h"
+#include "ags/shared/game/room_struct.h"
namespace AGS3 {
@@ -34,7 +35,10 @@ class Bitmap;
} // namespace AGS
struct ScriptDrawingSurface final : AGSCCDynamicObject {
+ // These numbers and types are used to determine the source of this drawing surface;
+ // only one of them can be valid for this surface.
int roomBackgroundNumber;
+ RoomAreaMask roomMaskType;
int dynamicSpriteNumber;
int dynamicSurfaceNumber;
bool isLinkedBitmapOnly;
diff --git a/engines/ags/engine/ac/global_api.cpp b/engines/ags/engine/ac/global_api.cpp
index 81437c619e..ad66a73e44 100644
--- a/engines/ags/engine/ac/global_api.cpp
+++ b/engines/ags/engine/ac/global_api.cpp
@@ -718,6 +718,16 @@ RuntimeScriptValue Sc_GetWalkableAreaAtScreen(const RuntimeScriptValue *params,
API_SCALL_INT_PINT2(GetWalkableAreaAtScreen);
}
+RuntimeScriptValue Sc_GetDrawingSurfaceForWalkableArea(const RuntimeScriptValue *params, int32_t param_count) {
+ ScriptDrawingSurface *ret_obj = Room_GetDrawingSurfaceForMask(kRoomAreaWalkable);
+ return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj);
+}
+
+RuntimeScriptValue Sc_GetDrawingSurfaceForWalkbehind(const RuntimeScriptValue *params, int32_t param_count) {
+ ScriptDrawingSurface *ret_obj = Room_GetDrawingSurfaceForMask(kRoomAreaWalkBehind);
+ return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj);
+}
+
// void (int amnt)
RuntimeScriptValue Sc_GiveScore(const RuntimeScriptValue *params, int32_t param_count) {
API_SCALL_VOID_PINT(GiveScore);
@@ -2008,6 +2018,8 @@ void RegisterGlobalAPI() {
ccAddExternalStaticFunction("GetWalkableAreaAtRoom", Sc_GetWalkableAreaAtRoom);
ccAddExternalStaticFunction("GetWalkableAreaAt", Sc_GetWalkableAreaAtScreen);
ccAddExternalStaticFunction("GetWalkableAreaAtScreen", Sc_GetWalkableAreaAtScreen);
+ ccAddExternalStaticFunction("GetDrawingSurfaceForWalkableArea", Sc_GetDrawingSurfaceForWalkableArea);
+ ccAddExternalStaticFunction("GetDrawingSurfaceForWalkbehind", Sc_GetDrawingSurfaceForWalkbehind);
ccAddExternalStaticFunction("GiveScore", Sc_GiveScore);
ccAddExternalStaticFunction("HasPlayerBeenInRoom", Sc_HasPlayerBeenInRoom);
ccAddExternalStaticFunction("HideMouseCursor", Sc_HideMouseCursor);
diff --git a/engines/ags/engine/ac/hotspot.cpp b/engines/ags/engine/ac/hotspot.cpp
index e45ed105f0..4af2238bd0 100644
--- a/engines/ags/engine/ac/hotspot.cpp
+++ b/engines/ags/engine/ac/hotspot.cpp
@@ -154,6 +154,11 @@ RuntimeScriptValue Sc_GetHotspotAtScreen(const RuntimeScriptValue *params, int32
API_SCALL_OBJ_PINT2(ScriptHotspot, _GP(ccDynamicHotspot), GetHotspotAtScreen);
}
+RuntimeScriptValue Sc_Hotspot_GetDrawingSurface(const RuntimeScriptValue *params, int32_t param_count) {
+ ScriptDrawingSurface *ret_obj = Room_GetDrawingSurfaceForMask(kRoomAreaHotspot);
+ return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj);
+}
+
// void (ScriptHotspot *hss, char *buffer)
RuntimeScriptValue Sc_Hotspot_GetName(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_VOID_POBJ(ScriptHotspot, Hotspot_GetName, char);
@@ -226,6 +231,7 @@ RuntimeScriptValue Sc_Hotspot_GetWalkToY(void *self, const RuntimeScriptValue *p
void RegisterHotspotAPI() {
ccAddExternalStaticFunction("Hotspot::GetAtRoomXY^2", Sc_GetHotspotAtRoom);
ccAddExternalStaticFunction("Hotspot::GetAtScreenXY^2", Sc_GetHotspotAtScreen);
+ ccAddExternalStaticFunction("Hotspot::GetDrawingSurface", Sc_Hotspot_GetDrawingSurface);
ccAddExternalObjectFunction("Hotspot::GetName^1", Sc_Hotspot_GetName);
ccAddExternalObjectFunction("Hotspot::GetProperty^1", Sc_Hotspot_GetProperty);
ccAddExternalObjectFunction("Hotspot::GetPropertyText^2", Sc_Hotspot_GetPropertyText);
diff --git a/engines/ags/engine/ac/region.cpp b/engines/ags/engine/ac/region.cpp
index fa37c4f514..d24c6c70c4 100644
--- a/engines/ags/engine/ac/region.cpp
+++ b/engines/ags/engine/ac/region.cpp
@@ -25,8 +25,10 @@
#include "ags/shared/ac/game_setup_struct.h"
#include "ags/engine/ac/game_state.h"
#include "ags/engine/ac/global_region.h"
+#include "ags/engine/ac/room.h"
#include "ags/engine/ac/room_status.h"
#include "ags/engine/ac/dynobj/cc_region.h"
+#include "ags/engine/ac/dynobj/script_drawing_surface.h"
#include "ags/shared/game/room_struct.h"
#include "ags/engine/script/runtime_script_value.h"
#include "ags/shared/debugging/out.h"
@@ -141,6 +143,11 @@ RuntimeScriptValue Sc_GetRegionAtScreen(const RuntimeScriptValue *params, int32_
API_SCALL_OBJ_PINT2(ScriptRegion, _GP(ccDynamicRegion), GetRegionAtScreen);
}
+RuntimeScriptValue Sc_Region_GetDrawingSurface(const RuntimeScriptValue *params, int32_t param_count) {
+ ScriptDrawingSurface *ret_obj = Room_GetDrawingSurfaceForMask(kRoomAreaRegion);
+ return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj);
+}
+
RuntimeScriptValue Sc_Region_Tint(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_VOID_PINT5(ScriptRegion, Region_Tint);
}
@@ -210,10 +217,10 @@ RuntimeScriptValue Sc_Region_GetTintLuminance(void *self, const RuntimeScriptVal
}
-
void RegisterRegionAPI() {
ccAddExternalStaticFunction("Region::GetAtRoomXY^2", Sc_GetRegionAtRoom);
ccAddExternalStaticFunction("Region::GetAtScreenXY^2", Sc_GetRegionAtScreen);
+ ccAddExternalStaticFunction("Region::GetDrawingSurface", Sc_Region_GetDrawingSurface);
ccAddExternalObjectFunction("Region::Tint^4", Sc_Region_TintNoLum);
ccAddExternalObjectFunction("Region::Tint^5", Sc_Region_Tint);
ccAddExternalObjectFunction("Region::RunInteraction^1", Sc_Region_RunInteraction);
diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp
index 8725c36686..0f2010621e 100644
--- a/engines/ags/engine/ac/room.cpp
+++ b/engines/ags/engine/ac/room.cpp
@@ -103,6 +103,14 @@ ScriptDrawingSurface *Room_GetDrawingSurfaceForBackground(int backgroundNumber)
return surface;
}
+ScriptDrawingSurface *Room_GetDrawingSurfaceForMask(RoomAreaMask mask) {
+ if (_G(displayed_room) < 0)
+ quit("!Room_GetDrawingSurfaceForMask: no room is currently loaded");
+ ScriptDrawingSurface *surface = new ScriptDrawingSurface();
+ surface->roomMaskType = mask;
+ ccRegisterManagedObject(surface, surface);
+ return surface;
+}
int Room_GetObjectCount() {
return _G(croom)->numobj;
diff --git a/engines/ags/engine/ac/room.h b/engines/ags/engine/ac/room.h
index cef464acd0..93ae03db41 100644
--- a/engines/ags/engine/ac/room.h
+++ b/engines/ags/engine/ac/room.h
@@ -31,6 +31,7 @@
namespace AGS3 {
ScriptDrawingSurface *Room_GetDrawingSurfaceForBackground(int backgroundNumber);
+ScriptDrawingSurface *Room_GetDrawingSurfaceForMask(RoomAreaMask mask);
int Room_GetObjectCount();
int Room_GetWidth();
int Room_GetHeight();
Commit: 770541024e9c21c52a5dffabaefed03c104155ac
https://github.com/scummvm/scummvm/commit/770541024e9c21c52a5dffabaefed03c104155ac
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:10-07:00
Commit Message:
AGS: Reworked tests ensuring always valid room area IDs are returned
>From upstream df2729f49b9561678dd0a97d81da59e125d56af3
Changed paths:
engines/ags/engine/ac/global_hotspot.cpp
engines/ags/engine/ac/global_hotspot.h
engines/ags/engine/ac/global_region.cpp
engines/ags/engine/ac/global_region.h
engines/ags/engine/ac/global_walkable_area.cpp
engines/ags/engine/ac/global_walkable_area.h
engines/ags/engine/ac/hotspot.cpp
engines/ags/engine/ac/hotspot.h
engines/ags/engine/ac/region.cpp
diff --git a/engines/ags/engine/ac/global_hotspot.cpp b/engines/ags/engine/ac/global_hotspot.cpp
index 5836ffa696..661025a915 100644
--- a/engines/ags/engine/ac/global_hotspot.cpp
+++ b/engines/ags/engine/ac/global_hotspot.cpp
@@ -84,12 +84,8 @@ int GetHotspotPointY(int hotspot) {
int GetHotspotIDAtScreen(int scrx, int scry) {
VpPoint vpt = _GP(play).ScreenToRoomDivDown(scrx, scry);
- if (vpt.second < 0)
- return 0;
- Point pt = vpt.first;
- if ((pt.X >= _GP(thisroom).Width) | (pt.X < 0) | (pt.Y < 0) | (pt.Y >= _GP(thisroom).Height))
- return 0;
- return get_hotspot_at(pt.X, pt.Y);
+ if (vpt.second < 0) return 0;
+ return get_hotspot_at(vpt.first.X, vpt.first.Y);
}
void GetHotspotName(int hotspot, char *buffer) {
diff --git a/engines/ags/engine/ac/global_hotspot.h b/engines/ags/engine/ac/global_hotspot.h
index 207a152cb5..b4b800b758 100644
--- a/engines/ags/engine/ac/global_hotspot.h
+++ b/engines/ags/engine/ac/global_hotspot.h
@@ -29,6 +29,8 @@ void DisableHotspot(int hsnum);
void EnableHotspot(int hsnum);
int GetHotspotPointX(int hotspot);
int GetHotspotPointY(int hotspot);
+// Gets hotspot ID at the given screen coordinates;
+// if hotspot is disabled or non-existing, returns 0 (no area)
int GetHotspotIDAtScreen(int xxx, int yyy);
void GetHotspotName(int hotspot, char *buffer);
void RunHotspotInteraction(int hotspothere, int mood);
diff --git a/engines/ags/engine/ac/global_region.cpp b/engines/ags/engine/ac/global_region.cpp
index 0f6a4d5312..d074af8ae8 100644
--- a/engines/ags/engine/ac/global_region.cpp
+++ b/engines/ags/engine/ac/global_region.cpp
@@ -56,15 +56,8 @@ int GetRegionIDAtRoom(int xxx, int yyy) {
}
int hsthere = _GP(thisroom).RegionMask->GetPixel(xxx, yyy);
- if (hsthere < 0)
- hsthere = 0;
-
- if (hsthere >= MAX_ROOM_REGIONS) {
- quitprintf("!An invalid pixel was found on the room region mask (colour %d, location: %d, %d)", hsthere, xxx, yyy);
- }
-
- if (_G(croom)->region_enabled[hsthere] == 0)
- return 0;
+ if (hsthere <= 0 || hsthere >= MAX_ROOM_REGIONS) return 0;
+ if (_G(croom)->region_enabled[hsthere] == 0) return 0;
return hsthere;
}
diff --git a/engines/ags/engine/ac/global_region.h b/engines/ags/engine/ac/global_region.h
index f10fc9bcd3..93fec2cb0c 100644
--- a/engines/ags/engine/ac/global_region.h
+++ b/engines/ags/engine/ac/global_region.h
@@ -25,6 +25,8 @@
namespace AGS3 {
+// Gets region ID at the given room coordinates;
+// if region is disabled or non-existing, returns 0 (no area)
int GetRegionIDAtRoom(int xxx, int yyy);
void SetAreaLightLevel(int area, int brightness);
void SetRegionTint(int area, int red, int green, int blue, int amount, int luminance = 100);
diff --git a/engines/ags/engine/ac/global_walkable_area.cpp b/engines/ags/engine/ac/global_walkable_area.cpp
index 6687eb9795..de53ca25f3 100644
--- a/engines/ags/engine/ac/global_walkable_area.cpp
+++ b/engines/ags/engine/ac/global_walkable_area.cpp
@@ -89,12 +89,10 @@ int GetWalkableAreaAtScreen(int x, int y) {
}
int GetWalkableAreaAtRoom(int x, int y) {
- if ((x >= _GP(thisroom).Width) | (x < 0) | (y < 0) | (y >= _GP(thisroom).Height))
- return 0;
- int result = get_walkable_area_pixel(x, y);
- if (result <= 0)
- return 0;
- return result;
+ int area = get_walkable_area_pixel(x, y);
+ // IMPORTANT: disabled walkable areas are actually erased completely from the mask;
+ // see: RemoveWalkableArea() and RestoreWalkableArea().
+ return area >= 0 && area < (MAX_WALK_AREAS + 1) ? area : 0;
}
} // namespace AGS3
diff --git a/engines/ags/engine/ac/global_walkable_area.h b/engines/ags/engine/ac/global_walkable_area.h
index 121a419335..fa2ae00229 100644
--- a/engines/ags/engine/ac/global_walkable_area.h
+++ b/engines/ags/engine/ac/global_walkable_area.h
@@ -29,9 +29,11 @@ int GetScalingAt(int x, int y);
void SetAreaScaling(int area, int min, int max);
void RemoveWalkableArea(int areanum);
void RestoreWalkableArea(int areanum);
-// Gets walkable area at the given room coordinates
+// Gets walkable area at the given room coordinates;
+// if area is disabled or non-existing, returns 0 (no area)
int GetWalkableAreaAtRoom(int x, int y);
// Gets walkable area at the given screen coordinates
+// if area is disabled or non-existing, returns 0 (no area)
int GetWalkableAreaAtScreen(int x, int y);
} // namespace AGS3
diff --git a/engines/ags/engine/ac/hotspot.cpp b/engines/ags/engine/ac/hotspot.cpp
index 4af2238bd0..fcef8b7208 100644
--- a/engines/ags/engine/ac/hotspot.cpp
+++ b/engines/ags/engine/ac/hotspot.cpp
@@ -71,23 +71,11 @@ int Hotspot_GetWalkToY(ScriptHotspot *hss) {
}
ScriptHotspot *GetHotspotAtScreen(int xx, int yy) {
- int hsnum = GetHotspotIDAtScreen(xx, yy);
- ScriptHotspot *ret_hotspot;
- if (hsnum <= 0)
- ret_hotspot = &_G(scrHotspot)[0];
- else
- ret_hotspot = &_G(scrHotspot)[hsnum];
- return ret_hotspot;
+ return &_G(scrHotspot)[GetHotspotIDAtScreen(xx, yy)];
}
ScriptHotspot *GetHotspotAtRoom(int x, int y) {
- int hsnum = get_hotspot_at(x, y);
- ScriptHotspot *ret_hotspot;
- if (hsnum <= 0)
- ret_hotspot = &_G(scrHotspot)[0];
- else
- ret_hotspot = &_G(scrHotspot)[hsnum];
- return ret_hotspot;
+ return &_G(scrHotspot)[get_hotspot_at(x, y)];
}
void Hotspot_GetName(ScriptHotspot *hss, char *buffer) {
@@ -134,7 +122,7 @@ bool Hotspot_SetTextProperty(ScriptHotspot *hss, const char *property, const cha
int get_hotspot_at(int xpp, int ypp) {
int onhs = _GP(thisroom).HotspotMask->GetPixel(room_to_mask_coord(xpp), room_to_mask_coord(ypp));
- if (onhs < 0) return 0;
+ if (onhs <= 0 || onhs >= MAX_ROOM_HOTSPOTS) return 0;
if (_G(croom)->hotspot_enabled[onhs] == 0) return 0;
return onhs;
}
diff --git a/engines/ags/engine/ac/hotspot.h b/engines/ags/engine/ac/hotspot.h
index b9a0067d71..3ab97662d0 100644
--- a/engines/ags/engine/ac/hotspot.h
+++ b/engines/ags/engine/ac/hotspot.h
@@ -43,7 +43,8 @@ int Hotspot_GetProperty(ScriptHotspot *hss, const char *property);
void Hotspot_GetPropertyText(ScriptHotspot *hss, const char *property, char *bufer);
const char *Hotspot_GetTextProperty(ScriptHotspot *hss, const char *property);
-// Gets hotspot ID at the given room coordinates
+// Gets hotspot ID at the given room coordinates;
+// if hotspot is disabled or non-existing, returns 0 (no area)
int get_hotspot_at(int xpp, int ypp);
} // namespace AGS3
diff --git a/engines/ags/engine/ac/region.cpp b/engines/ags/engine/ac/region.cpp
index d24c6c70c4..a79f133e74 100644
--- a/engines/ags/engine/ac/region.cpp
+++ b/engines/ags/engine/ac/region.cpp
@@ -41,10 +41,7 @@ namespace AGS3 {
using namespace AGS::Shared;
ScriptRegion *GetRegionAtRoom(int xx, int yy) {
- int hsnum = GetRegionIDAtRoom(xx, yy);
- if (hsnum < 0)
- hsnum = 0;
- return &_G(scrRegion)[hsnum];
+ return &_G(scrRegion)[GetRegionIDAtRoom(xx, yy)];
}
ScriptRegion *GetRegionAtScreen(int x, int y) {
Commit: ae6479ffeecf9fa21b66547e87f44132219580a1
https://github.com/scummvm/scummvm/commit/ae6479ffeecf9fa21b66547e87f44132219580a1
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:10-07:00
Commit Message:
AGS: Recache walkbehinds after the mask was drawn upon
>From upstream 1d10e3776a52b538916166215f239d39e32e4d32
Changed paths:
engines/ags/engine/ac/drawing_surface.cpp
diff --git a/engines/ags/engine/ac/drawing_surface.cpp b/engines/ags/engine/ac/drawing_surface.cpp
index 33ab8ff735..8d082528f9 100644
--- a/engines/ags/engine/ac/drawing_surface.cpp
+++ b/engines/ags/engine/ac/drawing_surface.cpp
@@ -33,6 +33,7 @@
#include "ags/engine/ac/room_object.h"
#include "ags/engine/ac/room_status.h"
#include "ags/engine/ac/string.h"
+#include "ags/engine/ac/walk_behind.h"
#include "ags/engine/debugging/debug_log.h"
#include "ags/shared/font/fonts.h"
#include "ags/shared/gui/gui_main.h"
@@ -64,6 +65,12 @@ void DrawingSurface_Release(ScriptDrawingSurface *sds) {
sds->roomBackgroundNumber = -1;
}
+ if (sds->roomMaskType > kRoomAreaNone) {
+ if (sds->roomMaskType == kRoomAreaWalkBehind) {
+ recache_walk_behinds();
+ }
+ sds->roomMaskType = kRoomAreaNone;
+ }
if (sds->dynamicSpriteNumber >= 0) {
if (sds->modified) {
game_sprite_updated(sds->dynamicSpriteNumber);
Commit: a9afcf230bd4f60e461e692efae8345957db104b
https://github.com/scummvm/scummvm/commit/a9afcf230bd4f60e461e692efae8345957db104b
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:10-07:00
Commit Message:
AGS: Class FindFile, working as a file iterator with a name pattern
>From upstream c0d4f6587d1c3428fe891aa477550d42fdcd49da
Changed paths:
A engines/ags/lib/std/regex.h
engines/ags/lib/std/std.cpp
engines/ags/shared/util/directory.cpp
engines/ags/shared/util/directory.h
engines/ags/shared/util/string_utils.cpp
engines/ags/shared/util/string_utils.h
diff --git a/engines/ags/lib/std/regex.h b/engines/ags/lib/std/regex.h
new file mode 100644
index 0000000000..174d635566
--- /dev/null
+++ b/engines/ags/lib/std/regex.h
@@ -0,0 +1,44 @@
+/* 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.
+ *
+ */
+
+#ifndef AGS_STD_REGEX_H
+#define AGS_STD_REGEX_H
+
+#include "common/str.h"
+#include "common/textconsole.h"
+
+namespace AGS3 {
+namespace std {
+
+struct regex {
+public:
+ regex(const char *) {}
+};
+
+inline Common::String regex_replace(const char *wildcard, const regex &esc, const char *fmt) {
+ error("TODO: Implement if engine needs it");
+}
+
+} // namespace std
+} // namespace AGS3
+
+#endif
diff --git a/engines/ags/lib/std/std.cpp b/engines/ags/lib/std/std.cpp
index 4a737d3cbe..379b010b5e 100644
--- a/engines/ags/lib/std/std.cpp
+++ b/engines/ags/lib/std/std.cpp
@@ -34,6 +34,7 @@
#include "ags/lib/std/memory.h"
#include "ags/lib/std/mutex.h"
#include "ags/lib/std/queue.h"
+#include "ags/lib/std/regex.h"
#include "ags/lib/std/set.h"
#include "ags/lib/std/thread.h"
#include "ags/lib/std/type_traits.h"
diff --git a/engines/ags/shared/util/directory.cpp b/engines/ags/shared/util/directory.cpp
index 2b0dccfd04..ef22e5ff83 100644
--- a/engines/ags/shared/util/directory.cpp
+++ b/engines/ags/shared/util/directory.cpp
@@ -22,7 +22,9 @@
#include "common/config-manager.h"
#include "common/fs.h"
+#include "ags/lib/std/regex.h"
#include "ags/shared/core/platform.h"
+#include "ags/shared/util/string_utils.h"
#include "ags/shared/util/directory.h"
#include "ags/shared/util/path.h"
#include "ags/shared/util/stdio_compat.h"
@@ -112,6 +114,40 @@ bool GetFiles(const String &dir_path, std::vector<String> &files) {
} // namespace Directory
+FindFile::FindFile(const FindFile &ff) {
+ _files = ff._files;
+ _index = ff._index;
+}
+
+FindFile::~FindFile() {
+ Close();
+}
+
+FindFile FindFile::Open(const String &path, const String &wildcard, bool do_file, bool do_dir) {
+ FindFile ff;
+ ff._folder = Common::FSNode(path);
+
+ Common::FSNode::ListMode mode = Common::FSNode::kListAll;
+ if (do_file && !do_dir)
+ mode = Common::FSNode::kListFilesOnly;
+ else if (!do_file && do_dir)
+ mode = Common::FSNode::kListDirectoriesOnly;
+
+ warning("TODO: Wildcard not yet supported - %s", wildcard.GetCStr());
+
+ ff._folder.getChildren(ff._files, mode);
+ return ff;
+}
+
+void FindFile::Close() {
+ _index = 0;
+}
+
+bool FindFile::Next() {
+ ++_index;
+ return _index < (int)_files.size();
+}
+
} // namespace Shared
} // namespace AGS
} // namespace AGS3
diff --git a/engines/ags/shared/util/directory.h b/engines/ags/shared/util/directory.h
index 80df2f0d16..916b393c0a 100644
--- a/engines/ags/shared/util/directory.h
+++ b/engines/ags/shared/util/directory.h
@@ -29,6 +29,8 @@
#ifndef AGS_SHARED_UTIL_DIRECTORY_H
#define AGS_SHARED_UTIL_DIRECTORY_H
+#include "common/fs.h"
+#include "ags/lib/std/memory.h"
#include "ags/shared/core/platform.h"
#include "ags/shared/util/string.h"
@@ -57,6 +59,36 @@ bool GetFiles(const String &dir_path, std::vector<String> &files);
} // namespace Directory
+class FindFile {
+private:
+ Common::FSNode _folder;
+ Common::FSList _files;
+ int _index = 0;
+
+private:
+ static FindFile Open(const String &path, const String &wildcard,
+ bool do_file, bool do_dir);
+
+public:
+ FindFile() {}
+ FindFile(const FindFile &ff);
+ ~FindFile();
+ static FindFile OpenFiles(const String &path, const String &wildcard = "*") {
+ return Open(path, wildcard, true, false);
+ }
+ static FindFile OpenDirs(const String &path, const String &wildcard = "*") {
+ return Open(path, wildcard, false, true);
+ }
+ bool AtEnd() const {
+ return (_index >= (int)_files.size());
+ }
+ String Current() const {
+ return AtEnd() ? String() : String(_files[_index].getName().c_str());
+ }
+ void Close();
+ bool Next();
+};
+
} // namespace Shared
} // namespace AGS
} // namespace AGS3
diff --git a/engines/ags/shared/util/string_utils.cpp b/engines/ags/shared/util/string_utils.cpp
index e304a1ed4a..5f5bb9155f 100644
--- a/engines/ags/shared/util/string_utils.cpp
+++ b/engines/ags/shared/util/string_utils.cpp
@@ -20,9 +20,10 @@
*
*/
+#include "ags/shared/util/string_utils.h"
#include "ags/shared/core/platform.h"
+#include "ags/lib/std/regex.h"
#include "ags/shared/util/math.h"
-#include "ags/shared/util/string_utils.h"
#include "ags/shared/util/stream.h"
#include "ags/globals.h"
@@ -95,6 +96,18 @@ String StrUtil::Unescape(const String &s) {
return dst;
}
+String StrUtil::WildcardToRegex(const String &wildcard) {
+ // https://stackoverflow.com/questions/40195412/c11-regex-search-for-exact-string-escape
+ // matches any characters that need to be escaped in RegEx
+ std::regex esc{ R"([-[\]{}()*+?.,\^$|#\s])" };
+ Common::String sanitized = std::regex_replace(wildcard.GetCStr(), esc, R"(\$&)");
+ // convert (now escaped) wildcard "\\*" and "\\?" into ".*" and "." respectively
+ String pattern(sanitized.c_str());
+ pattern.Replace("\\*", ".*");
+ pattern.Replace("\\?", ".");
+ return pattern;
+}
+
String StrUtil::ReadString(Stream *in) {
size_t len = in->ReadInt32();
if (len > 0)
diff --git a/engines/ags/shared/util/string_utils.h b/engines/ags/shared/util/string_utils.h
index f90d88bc5c..09ee7b2396 100644
--- a/engines/ags/shared/util/string_utils.h
+++ b/engines/ags/shared/util/string_utils.h
@@ -60,6 +60,8 @@ ConversionError StringToInt(const String &s, int &val, int def_val);
// A simple unescape string implementation, unescapes '\\x' into '\x'.
String Unescape(const String &s);
+// Converts a classic wildcard search pattern into C++11 compatible regex pattern
+String WildcardToRegex(const String &wildcard);
// Serialize and unserialize unterminated string prefixed with 32-bit length;
// length is presented as 32-bit integer integer
Commit: cb73fd2f2a3b212986b879a1f76cf077c3dde800
https://github.com/scummvm/scummvm/commit/cb73fd2f2a3b212986b879a1f76cf077c3dde800
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:10-07:00
Commit Message:
AGS: Class FindFileRecursive, for iterating over nested subdirs
>From upstream 4c1d6244a9b9f50d1646163768bdc9e96cf064f8
Changed paths:
engines/ags/shared/util/directory.cpp
engines/ags/shared/util/directory.h
engines/ags/shared/util/path.cpp
engines/ags/shared/util/path.h
diff --git a/engines/ags/shared/util/directory.cpp b/engines/ags/shared/util/directory.cpp
index ef22e5ff83..f16aecdec1 100644
--- a/engines/ags/shared/util/directory.cpp
+++ b/engines/ags/shared/util/directory.cpp
@@ -148,6 +148,86 @@ bool FindFile::Next() {
return _index < (int)_files.size();
}
+FindFileRecursive::~FindFileRecursive() {
+ Close();
+}
+
+FindFileRecursive FindFileRecursive::Open(const String &path, const String &wildcard, size_t max_level) {
+ FindFile fdir = FindFile::OpenDirs(path);
+ FindFile ffile = FindFile::OpenFiles(path, wildcard);
+ if (ffile.AtEnd() && fdir.AtEnd())
+ return FindFileRecursive(); // return invalid object
+ FindFileRecursive ff;
+ ff._fdir = std::move(fdir);
+ ff._ffile = std::move(ffile);
+ // Try get the first matching entry
+ if (ff._ffile.AtEnd() && !ff.Next())
+ return FindFileRecursive(); // return invalid object
+ ff._maxLevel = max_level;
+ ff._fullDir = path;
+ ff._curFile = ff._ffile.Current();
+ return ff; // success
+}
+
+void FindFileRecursive::Close() {
+ while (_fdirs.size())
+ _fdirs.pop();
+ _fdir.Close();
+ _ffile.Close();
+}
+
+bool FindFileRecursive::Next() {
+ // Look up for the next file in the current dir
+ if (_ffile.Next()) {
+ Path::ConcatPaths(_curFile, _curDir, _ffile.Current());
+ return true;
+ }
+ // No more files? Find a directory that still has
+ while (_ffile.AtEnd()) {
+ // first make sure there are unchecked subdirs left in current dir
+ while (_fdir.AtEnd()) { // if not, go up, until found any, or hit the top
+ if (!PopDir())
+ return false; // no more directories
+ }
+
+ // Found an unchecked subdirectory/ies, try opening one
+ while (!PushDir(_fdir.Current()) && !_fdir.AtEnd())
+ _fdir.Next();
+ }
+ Path::ConcatPaths(_curFile, _curDir, _ffile.Current());
+ return true; // success
+}
+
+bool FindFileRecursive::PushDir(const String &sub) {
+ if (_maxLevel != -1 && (int)_fdirs.size() == _maxLevel)
+ return false; // no more nesting allowed
+
+ String path = Path::ConcatPaths(_fullDir, sub);
+ FindFile fdir = FindFile::OpenDirs(path);
+ FindFile ffile = FindFile::OpenFiles(path);
+ if (ffile.AtEnd() && fdir.AtEnd())
+ return false; // dir is empty, or error
+ _fdirs.push(std::move(_fdir)); // save previous dir iterator
+ _fdir = std::move(fdir);
+ _ffile = std::move(ffile);
+ _fullDir = path;
+ _curDir = Path::ConcatPaths(_curDir, sub);
+ return true;
+}
+
+bool FindFileRecursive::PopDir() {
+ if (_fdirs.size() == 0)
+ return false; // no more parent levels
+ // restore parent level
+ _fdir = std::move(_fdirs.top());
+ _fdirs.pop();
+ _fullDir = Path::GetParent(_fullDir);
+ _curDir = Path::GetParent(_curDir);
+ // advance dir iterator that we just recovered
+ _fdir.Next();
+ return true;
+}
+
} // namespace Shared
} // namespace AGS
} // namespace AGS3
diff --git a/engines/ags/shared/util/directory.h b/engines/ags/shared/util/directory.h
index 916b393c0a..e78c719d90 100644
--- a/engines/ags/shared/util/directory.h
+++ b/engines/ags/shared/util/directory.h
@@ -30,6 +30,7 @@
#define AGS_SHARED_UTIL_DIRECTORY_H
#include "common/fs.h"
+#include "common/stack.h"
#include "ags/lib/std/memory.h"
#include "ags/shared/core/platform.h"
#include "ags/shared/util/string.h"
@@ -89,6 +90,36 @@ public:
bool Next();
};
+class FindFileRecursive {
+public:
+ FindFileRecursive() {}
+ ~FindFileRecursive();
+
+ static FindFileRecursive Open(const String &path, const String &wildcard = "*",
+ size_t max_level = -1);
+ // TODO: directory mode, like in FindFile
+ bool AtEnd() const {
+ return _ffile.AtEnd();
+ }
+ String Current() const {
+ return _curFile;
+ }
+ void Close();
+ bool Next();
+
+private:
+ bool PushDir(const String &sub);
+ bool PopDir();
+
+ Common::Stack<FindFile> _fdirs;
+ FindFile _fdir; // current find dir iterator
+ FindFile _ffile; // current find file iterator
+ int _maxLevel = -1; // max nesting level, -1 for unrestricted
+ String _fullDir; // full directory path
+ String _curDir; // current dir path, relative to the base path
+ String _curFile; // current file path with parent dirs
+};
+
} // namespace Shared
} // namespace AGS
} // namespace AGS3
diff --git a/engines/ags/shared/util/path.cpp b/engines/ags/shared/util/path.cpp
index b19ca3ecd6..8aeee66fdc 100644
--- a/engines/ags/shared/util/path.cpp
+++ b/engines/ags/shared/util/path.cpp
@@ -225,6 +225,17 @@ String ConcatPaths(const String &parent, const String &child) {
return path;
}
+String ConcatPaths(String &buf, const String &parent, const String &child) {
+ if (parent.IsEmpty())
+ buf = child;
+ else if (child.IsEmpty())
+ buf = parent;
+ else
+ buf.Format("%s/%s", parent.GetCStr(), child.GetCStr());
+ FixupPath(buf);
+ return buf;
+}
+
String MakePath(const String &parent, const String &filename) {
String path = String::FromFormat("%s/%s", parent.GetCStr(), filename.GetCStr());
FixupPath(path);
diff --git a/engines/ags/shared/util/path.h b/engines/ags/shared/util/path.h
index 44c99dee11..1f25e6fa76 100644
--- a/engines/ags/shared/util/path.h
+++ b/engines/ags/shared/util/path.h
@@ -53,6 +53,9 @@ bool IsFile(const String &filename);
bool IsFileOrDir(const String &filename);
// Returns parent directory of the given path;
// returns "." (current dir) if the path does not contain a parent segment
+String GetParent(const String &path);
+// Returns parent directory of the given path;
+// returns "." (current dir) if the path does not contain a parent segment
String GetFilename(const String &path);
// Returns file's extension; file may be a fully qualified path too
String GetFileExtension(const String &path);
@@ -89,6 +92,7 @@ String MakeAbsolutePath(const String &path);
String MakeRelativePath(const String &base, const String &path);
// Concatenates parent and relative paths
String ConcatPaths(const String &parent, const String &child);
+String ConcatPaths(String &buf, const String &parent, const String &child);
// Creates path by combining directory, file name and extension
String MakePath(const String &parent, const String &filename, const String &ext);
// Splits path into components, divided by path separator
Commit: c56b82b5f6716ca3c9e68dc3747582401e669394
https://github.com/scummvm/scummvm/commit/c56b82b5f6716ca3c9e68dc3747582401e669394
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:10-07:00
Commit Message:
AGS: Codestyle members of DataExtParser
>From upstream b88b83385d7d4f5180f5741d2ce31b8547bbf156
Changed paths:
engines/ags/shared/game/tra_file.cpp
engines/ags/shared/util/data_ext.cpp
engines/ags/shared/util/data_ext.h
diff --git a/engines/ags/shared/game/tra_file.cpp b/engines/ags/shared/game/tra_file.cpp
index fe42175685..f833a78f63 100644
--- a/engines/ags/shared/game/tra_file.cpp
+++ b/engines/ags/shared/game/tra_file.cpp
@@ -132,7 +132,7 @@ public:
HError err = FindOne(kTraFblk_GameID);
if (!err)
return err;
- return ReadTraBlock(_tra, _in, kTraFblk_GameID, "", _block_len);
+ return ReadTraBlock(_tra, _in, kTraFblk_GameID, "", _blockLen);
}
private:
diff --git a/engines/ags/shared/util/data_ext.cpp b/engines/ags/shared/util/data_ext.cpp
index 4d6044bd0b..a6e7cad72c 100644
--- a/engines/ags/shared/util/data_ext.cpp
+++ b/engines/ags/shared/util/data_ext.cpp
@@ -48,44 +48,44 @@ HError DataExtParser::OpenBlock() {
// and -1 indicates end of the block list.
// - 16 bytes - string ID of an extension (if numeric ID is 0).
// - 4 or 8 bytes - length of extension data, in bytes.
- _block_id = ((_flags & kDataExt_NumID32) != 0) ?
+ _blockID = ((_flags & kDataExt_NumID32) != 0) ?
_in->ReadInt32() :
_in->ReadInt8();
- if (_block_id < 0)
+ if (_blockID < 0)
return HError::None(); // end of list
if (_in->EOS())
return new DataExtError(kDataExtErr_UnexpectedEOF);
- if (_block_id > 0) { // old-style block identified by a numeric id
- _block_len = ((_flags & kDataExt_File64) != 0) ? _in->ReadInt64() : _in->ReadInt32();
- _ext_id = GetOldBlockName(_block_id);
+ if (_blockID > 0) { // old-style block identified by a numeric id
+ _blockLen = ((_flags & kDataExt_File64) != 0) ? _in->ReadInt64() : _in->ReadInt32();
+ _extID = GetOldBlockName(_blockID);
} else { // new style block identified by a string id
- _ext_id = String::FromStreamCount(_in, 16);
- _block_len = _in->ReadInt64();
+ _extID = String::FromStreamCount(_in, 16);
+ _blockLen = _in->ReadInt64();
}
- _block_start = _in->GetPosition();
+ _blockStart = _in->GetPosition();
return HError::None();
}
void DataExtParser::SkipBlock() {
- if (_block_id >= 0)
- _in->Seek(_block_len);
+ if (_blockID >= 0)
+ _in->Seek(_blockLen);
}
HError DataExtParser::PostAssert() {
const soff_t cur_pos = _in->GetPosition();
- const soff_t block_end = _block_start + _block_len;
+ const soff_t block_end = _blockStart + _blockLen;
if (cur_pos > block_end) {
String err = String::FromFormat("Block: '%s', expected to end at offset: %lld, finished reading at %lld.",
- _ext_id.GetCStr(), block_end, cur_pos);
- if (cur_pos <= block_end + GetOverLeeway(_block_id))
+ _extID.GetCStr(), block_end, cur_pos);
+ if (cur_pos <= block_end + GetOverLeeway(_blockID))
Debug::Printf(kDbgMsg_Warn, err);
else
return new DataExtError(kDataExtErr_BlockDataOverlapping, err);
} else if (cur_pos < block_end) {
Debug::Printf(kDbgMsg_Warn, "WARNING: data blocks nonsequential, block '%s' expected to end at %lld, finished reading at %lld",
- _ext_id.GetCStr(), block_end, cur_pos);
+ _extID.GetCStr(), block_end, cur_pos);
_in->Seek(block_end, Shared::kSeekBegin);
}
return HError::None();
@@ -96,9 +96,9 @@ HError DataExtParser::FindOne(int id) {
HError err = HError::None();
for (err = OpenBlock(); err && !AtEnd(); err = OpenBlock()) {
- if (id == _block_id)
+ if (id == _blockID)
return HError::None();
- _in->Seek(_block_len); // skip it
+ _in->Seek(_blockLen); // skip it
}
if (!err)
return err;
@@ -111,7 +111,7 @@ HError DataExtReader::Read() {
for (err = OpenBlock(); err && !AtEnd() && read_next; err = OpenBlock()) {
// Call the reader function to read current block's data
read_next = true;
- err = ReadBlock(_block_id, _ext_id, _block_len, read_next);
+ err = ReadBlock(_blockID, _extID, _blockLen, read_next);
if (!err)
return err;
// Test that we did not read too much or too little
diff --git a/engines/ags/shared/util/data_ext.h b/engines/ags/shared/util/data_ext.h
index 5db288558f..7901a7c4e5 100644
--- a/engines/ags/shared/util/data_ext.h
+++ b/engines/ags/shared/util/data_ext.h
@@ -111,7 +111,7 @@ public:
}
// Tells if the end of the block list was reached
inline bool AtEnd() const {
- return _block_id < 0;
+ return _blockID < 0;
}
// Tries to opens a next standard block from the stream,
// fills in identifier and length on success
@@ -128,10 +128,10 @@ protected:
Stream *_in = nullptr;
int _flags = 0;
- int _block_id = -1;
- String _ext_id;
- soff_t _block_start = 0;
- soff_t _block_len = 0;
+ int _blockID = -1;
+ String _extID;
+ soff_t _blockStart = 0;
+ soff_t _blockLen = 0;
};
// DataExtReader is a virtual base class of a block list reader; provides
Commit: 47fe5901d5e8b962a5b88a74b7f24ae082684a42
https://github.com/scummvm/scummvm/commit/47fe5901d5e8b962a5b88a74b7f24ae082684a42
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:11-07:00
Commit Message:
AGS: Removed unused old code
>From upstream 495c35538e8e3db878853833ca817217b9ca1b34
Changed paths:
R engines/ags/shared/util/misc.cpp
R engines/ags/shared/util/misc.h
engines/ags/module.mk
diff --git a/engines/ags/module.mk b/engines/ags/module.mk
index 55c1513067..5fdbd157e5 100644
--- a/engines/ags/module.mk
+++ b/engines/ags/module.mk
@@ -81,7 +81,6 @@ MODULE_OBJS = \
shared/util/ini_file.o \
shared/util/ini_util.o \
shared/util/lzw.o \
- shared/util/misc.o \
shared/util/memory_stream.o \
shared/util/multi_file_lib.o \
shared/util/path.o \
diff --git a/engines/ags/shared/util/misc.cpp b/engines/ags/shared/util/misc.cpp
deleted file mode 100644
index a1e1a97ec2..0000000000
--- a/engines/ags/shared/util/misc.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-/* 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.
- *
- */
-
-/*
- Copyright (c) 2003, Shawn R. Walker
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of Shawn R. Walker nor names of contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "ags/shared/core/platform.h"
-#include "ags/lib/allegro.h" // file path functions
-#include "ags/shared/util/file.h"
-#include "ags/shared/util/stream.h"
-
-namespace AGS3 {
-
-using namespace AGS::Shared;
-
-//
-// TODO: rewrite all this in a cleaner way perhaps, and move to our file or path utilities unit
-//
-
-#if !defined(AGS_CASE_SENSITIVE_FILESYSTEM)
-/* File Name Concatenator basically on Windows / DOS */
-char *ci_find_file(const char *dir_name, const char *file_name) {
- char *diamond = NULL;
-
- if (dir_name == NULL && file_name == NULL)
- return NULL;
-
- if (dir_name == NULL) {
- diamond = (char *)malloc(strlen(file_name) + 3);
- strcpy(diamond, file_name);
- } else {
- diamond = (char *)malloc(strlen(dir_name) + strlen(file_name) + 2);
- append_filename(diamond, dir_name, file_name, strlen(dir_name) + strlen(file_name) + 2);
- }
- fix_filename_case(diamond);
- fix_filename_slashes(diamond);
- return diamond;
-}
-
-#else
-/* Case Sensitive File Find - only used on UNIX platforms */
-char *ci_find_file(const char *dir_name, const char *file_name) {
- struct stat statbuf;
- struct dirent *entry = nullptr;
- DIR *rough = nullptr;
- char *diamond = nullptr;
- char *directory = nullptr;
- char *filename = nullptr;
-
- if (dir_name == nullptr && file_name == nullptr)
- return nullptr;
-
- if (dir_name != nullptr) {
- directory = (char *)malloc(strlen(dir_name) + 1);
- strcpy(directory, dir_name);
-
- fix_filename_case(directory);
- fix_filename_slashes(directory);
- }
-
- if (file_name != nullptr) {
- filename = (char *)malloc(strlen(file_name) + 1);
- strcpy(filename, file_name);
-
- fix_filename_case(filename);
- fix_filename_slashes(filename);
- }
-
- // the ".." check here prevents file system traversal -
- // since only in this fast-path it's possible a potentially evil
- // script could try to break out of the directories it's restricted
- // to, whereas the latter chdir/opendir approach checks file by file
- // in the directory. it's theoretically possible a valid filename
- // could contain "..", but in that case it will just fallback to the
- // slower method later on and succeed.
- if (filename && !strstr(filename, "..")) {
- char buf[1024];
- if (!directory && filename[0] == '/')
- snprintf(buf, sizeof buf, "%s", filename);
- else
- snprintf(buf, sizeof buf, "%s/%s", directory ? directory : ".", filename);
-
- if (lstat(buf, &statbuf) == 0 &&
- (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode))) {
- diamond = strdup(buf); goto out;
- }
- }
-
- if (directory == nullptr) {
- char *match = nullptr;
- int match_len = 0;
- int dir_len = 0;
-
- match = get_filename(filename);
- if (match == nullptr)
- goto out;
-
- match_len = strlen(match);
- dir_len = (match - filename);
-
- if (dir_len == 0) {
- directory = (char *)malloc(2);
- strcpy(directory, ".");
- } else {
- directory = (char *)malloc(dir_len + 1);
- strncpy(directory, file_name, dir_len);
- directory[dir_len] = '\0';
- }
-
- filename = (char *)malloc(match_len + 1);
- strncpy(filename, match, match_len);
- filename[match_len] = '\0';
- }
-
- if ((rough = opendir(directory)) == nullptr) {
- fprintf(stderr, "ci_find_file: cannot open directory: %s\n", directory);
- goto out;
- }
-
- while ((entry = readdir(rough)) != nullptr) {
- if (strcasecmp(filename, entry->d_name) == 0) {
- if (lstat(entry->d_name, &statbuf) == 0 &&
- (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode))) {
-#if AGS_PLATFORM_DEBUG
- fprintf(stderr, "ci_find_file: Looked for %s in rough %s, found diamond %s.\n", filename, directory, entry->d_name);
-#endif // AGS_PLATFORM_DEBUG
- diamond = (char *)malloc(strlen(directory) + strlen(entry->d_name) + 2);
- append_filename(diamond, directory, entry->d_name, strlen(directory) + strlen(entry->d_name) + 2);
- break;
- }
- }
- }
- closedir(rough);
-
-out:;
- if (directory) free(directory);
- if (filename) free(filename);
-
- return diamond;
-}
-#endif
-
-/* Case Insensitive fopen */
-Stream *ci_fopen(const char *file_name, FileOpenMode open_mode, FileWorkMode work_mode) {
-#if !defined (AGS_CASE_SENSITIVE_FILESYSTEM)
- return File::OpenFile(file_name, open_mode, work_mode);
-#else
- Stream *fs = nullptr;
- char *fullpath = ci_find_file(nullptr, (char *)file_name);
-
- /* If I didn't find a file, this could be writing a new file,
- so use whatever file_name they passed */
- if (fullpath == nullptr) {
- fs = File::OpenFile(file_name, open_mode, work_mode);
- } else {
- fs = File::OpenFile(fullpath, open_mode, work_mode);
- free(fullpath);
- }
-
- return fs;
-#endif
-}
-
-} // namespace AGS3
diff --git a/engines/ags/shared/util/misc.h b/engines/ags/shared/util/misc.h
deleted file mode 100644
index 7ce980ec44..0000000000
--- a/engines/ags/shared/util/misc.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* 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.
- *
- */
-
-/*
- Copyright (c) 2003, Shawn R. Walker
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of Shawn R. Walker nor names of contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __MISC_H
-#define __MISC_H
-
-#include "ags/shared/util/file.h" // TODO: extract filestream mode constants
-
-namespace AGS3 {
-
-namespace AGS {
-namespace Shared {
-class Stream;
-}
-}
-using namespace AGS; // FIXME later
-
-// Case-insensitive file lookup functions. On case-insensitive systems
-// (like MS Windows) they simply return given file, but on case-sensitive
-// systems (like Linux) they search the directory for files with matching
-// names in different character case.
-// They are used as a system-independent way to open a file when its name
-// case can be ignored.
-Shared::Stream *ci_fopen(const char *file_name,
- Shared::FileOpenMode open_mode = Shared::kFile_Open,
- Shared::FileWorkMode work_mode = Shared::kFile_Read);
-// TODO: return String object
-char *ci_find_file(const char *dir_name, const char *file_name);
-
-} // namespace AGS3
-
-#endif
Commit: 79defb2f0fc9653d115444990169bbe36fd877e7
https://github.com/scummvm/scummvm/commit/79defb2f0fc9653d115444990169bbe36fd877e7
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:11-07:00
Commit Message:
AGS: Updated upstream sync point comment
Changed paths:
engines/ags/ags.h
diff --git a/engines/ags/ags.h b/engines/ags/ags.h
index 146de292c1..4dfdc15e85 100644
--- a/engines/ags/ags.h
+++ b/engines/ags/ags.h
@@ -50,8 +50,8 @@ namespace AGS {
* @brief Engine to run Adventure Game Studio games.
*/
-/* Synced up to upstream: 3.6.0.5
- * 4bb97d6d318fdd1a8d2e86e0b8b0457bd5f939d0
+/* Synced up to upstream: 3.6.0.6
+ * ff6c964fc649a97c65374f69379773bf50754a6a
*/
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 200
Commit: 5ad9352f8ee3f82759b263a3bf07e006305cec81
https://github.com/scummvm/scummvm/commit/5ad9352f8ee3f82759b263a3bf07e006305cec81
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-07-31T14:34:11-07:00
Commit Message:
AGS: Re-add accidentally removed Object::get_Solid export
Changed paths:
engines/ags/engine/ac/object.cpp
diff --git a/engines/ags/engine/ac/object.cpp b/engines/ags/engine/ac/object.cpp
index a15cc5ddf1..90b9cf0de8 100644
--- a/engines/ags/engine/ac/object.cpp
+++ b/engines/ags/engine/ac/object.cpp
@@ -906,6 +906,7 @@ void RegisterObjectAPI() {
ccAddExternalObjectFunction("Object::get_Name", Sc_Object_GetName_New);
ccAddExternalObjectFunction("Object::get_Scaling", Sc_Object_GetScaling);
ccAddExternalObjectFunction("Object::set_Scaling", Sc_Object_SetScaling);
+ ccAddExternalObjectFunction("Object::get_Solid", Sc_Object_GetSolid);
ccAddExternalObjectFunction("Object::set_Solid", Sc_Object_SetSolid);
ccAddExternalObjectFunction("Object::get_Transparency", Sc_Object_GetTransparency);
ccAddExternalObjectFunction("Object::set_Transparency", Sc_Object_SetTransparency);
More information about the Scummvm-git-logs
mailing list