[Scummvm-git-logs] scummvm master -> 2fd6e9b3d3f56c33e23a7434b6319130de9cdc76

mgerhardy noreply at scummvm.org
Mon Oct 14 17:57:12 UTC 2024


This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
690555928d TWINE: added frame time visualisation for the imgui debugger
9d1abc02ff TWINE: use push/popid for showing multiple palettes to prevent an id clash
d9efa04b4f TWINE: fixed FrameMarker values for fps
d89f925155 TWINE: renamed to match original sources
2fd6e9b3d3 TWINE: LBA: Game and Main Menu Palette Issue after intro video (Regression)


Commit: 690555928d635d0f90079d900241a113ec123f74
    https://github.com/scummvm/scummvm/commit/690555928d635d0f90079d900241a113ec123f74
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2024-10-14T19:56:29+02:00

Commit Message:
TWINE: added frame time visualisation for the imgui debugger

Changed paths:
  A engines/twine/debugger/ringbuffer.h
    engines/twine/debugger/debug_state.cpp
    engines/twine/debugger/debug_state.h
    engines/twine/debugger/debugtools.cpp
    engines/twine/twine.cpp


diff --git a/engines/twine/debugger/debug_state.cpp b/engines/twine/debugger/debug_state.cpp
index e425864bc83..65dc46bfb7d 100644
--- a/engines/twine/debugger/debug_state.cpp
+++ b/engines/twine/debugger/debug_state.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "twine/debugger/debug_state.h"
+#include "common/util.h"
 #include "twine/menu/interface.h"
 #include "twine/menu/menu.h"
 #include "twine/renderer/redraw.h"
@@ -214,6 +215,13 @@ bool DebugState::displayZones() {
 	return state;
 }
 
+void DebugState::addFrameData(uint32 frameTime, int32 waitMillis, uint32 maxDelay) {
+	if (!_frameDataRecording) {
+		return;
+	}
+	_frameData.emplace_back(frameTime, waitMillis, maxDelay);
+}
+
 void DebugState::renderDebugView() {
 	if (_showingZones) {
 		displayZones();
diff --git a/engines/twine/debugger/debug_state.h b/engines/twine/debugger/debug_state.h
index 5d17ea525f1..4b1187157b0 100644
--- a/engines/twine/debugger/debug_state.h
+++ b/engines/twine/debugger/debug_state.h
@@ -22,8 +22,10 @@
 #ifndef TWINE_DEBUG_SCENE_H
 #define TWINE_DEBUG_SCENE_H
 
+#include "common/array.h"
 #include "common/rect.h"
 #include "common/scummsys.h"
+#include "twine/debugger/ringbuffer.h"
 #include "twine/shared.h"
 #include <cstdarg>
 
@@ -91,6 +93,8 @@ public:
 	bool _sceneFlagsWindow = false;
 	bool _paletteWindow = false;
 	bool _loggerWindow = false;
+	bool _frameTimeWindow = false;
+	bool _frameDataRecording = true;
 
 	bool _useFreeCamera = false;
 	bool _disableGridRendering = false;
@@ -99,6 +103,16 @@ public:
 	void renderDebugView();
 	void drawClip(const Common::Rect &rect);
 
+	struct FrameData {
+		uint32 frameTime;
+		int32 waitMillis;
+		uint32 maxDelay;
+	};
+	using FrameDataBuffer = RingBuffer<FrameData, 256>;
+	FrameDataBuffer _frameData;
+
+	void addFrameData(uint32 frameTime, int32 waitMillis, uint32 maxDelay);
+
 	void update();
 };
 
diff --git a/engines/twine/debugger/debugtools.cpp b/engines/twine/debugger/debugtools.cpp
index 1eda11b6190..001685f34cb 100644
--- a/engines/twine/debugger/debugtools.cpp
+++ b/engines/twine/debugger/debugtools.cpp
@@ -221,6 +221,29 @@ static void paletteWindow(TwinEEngine *engine) {
 	ImGui::End();
 }
 
+static float WaitTime(void *data, int i) {
+	TwinE::DebugState::FrameDataBuffer &buffer = *(TwinE::DebugState::FrameDataBuffer *)data;
+	return (float)buffer[i].waitMillis;
+}
+
+static float FrameTime(void *data, int i) {
+	TwinE::DebugState::FrameDataBuffer &buffer = *(TwinE::DebugState::FrameDataBuffer *)data;
+	return (float)buffer[i].frameTime;
+}
+
+static void frameTimeWindow(TwinEEngine *engine) {
+	if (!engine->_debugState->_frameTimeWindow) {
+		return;
+	}
+
+	if (ImGui::Begin("Frame time", &engine->_debugState->_frameTimeWindow)) {
+		ImGui::Checkbox("Record", &engine->_debugState->_frameDataRecording);
+		ImGui::PlotHistogram("Wait time", WaitTime, &engine->_debugState->_frameData, (int)engine->_debugState->_frameData.size(), 0, "Wait time in millis", -100.0f, 100.0f, ImVec2(0, 80));
+		ImGui::PlotHistogram("Frame time", FrameTime, &engine->_debugState->_frameData, (int)engine->_debugState->_frameData.size(), 0, "Frame time in millis", -100.0f, 100.0f, ImVec2(0, 80));
+	}
+	ImGui::End();
+}
+
 static void sceneFlagsWindow(TwinEEngine *engine) {
 	if (!engine->_debugState->_sceneFlagsWindow) {
 		return;
@@ -786,6 +809,9 @@ static void debuggerMenu(TwinEEngine *engine) {
 		if (ImGui::MenuItem("Actor details")) {
 			engine->_debugState->_actorDetailsWindow = true;
 		}
+		if (ImGui::MenuItem("Frame time")) {
+			engine->_debugState->_frameTimeWindow = true;
+		}
 
 		ImGui::SeparatorText("Actions");
 
@@ -870,9 +896,9 @@ void onImGuiRender() {
 	gameFlagsWindow(engine);
 	paletteWindow(engine);
 	sceneFlagsWindow(engine);
+	frameTimeWindow(engine);
 	_logger->draw("Logger", &engine->_debugState->_loggerWindow);
 
-
 	if (engine->_debugState->_openPopup) {
 		ImGui::OpenPopup(engine->_debugState->_openPopup);
 		engine->_debugState->_openPopup = nullptr;
diff --git a/engines/twine/debugger/ringbuffer.h b/engines/twine/debugger/ringbuffer.h
new file mode 100644
index 00000000000..0b1aef4b83e
--- /dev/null
+++ b/engines/twine/debugger/ringbuffer.h
@@ -0,0 +1,212 @@
+/**
+ * @file
+ */
+
+#pragma once
+
+#include "common/util.h"
+#include <stddef.h>
+
+namespace TwinE {
+
+/**
+ * @brief Non allocating buffer class holds a maximum of given entries and allows an endless insert
+ * by overrinding previous elements in the buffer
+ */
+template<typename TYPE, size_t SIZE = 64u>
+class RingBuffer {
+protected:
+	size_t _size = 0u;
+	size_t _front = 0u;
+	size_t _back = SIZE - 1;
+	TYPE _buffer[SIZE]{};
+
+public:
+	using value_type = TYPE;
+
+	class iterator {
+	private:
+		RingBuffer *_ringBuffer;
+		size_t _idx;
+
+	public:
+		iterator(RingBuffer *ringBuffer, size_t idx) : _ringBuffer(ringBuffer), _idx(idx) {
+		}
+
+		inline const TYPE &operator*() const {
+			return _ringBuffer->_buffer[_idx % _ringBuffer->capacity()];
+		}
+
+		inline TYPE &operator*() {
+			return _ringBuffer->_buffer[_idx % _ringBuffer->capacity()];
+		}
+
+		inline const TYPE &operator()() const {
+			return _ringBuffer->_buffer[_idx % _ringBuffer->capacity()];
+		}
+
+		inline TYPE &operator()() {
+			return _ringBuffer->_buffer[_idx % _ringBuffer->capacity()];
+		}
+
+		iterator &operator++() {
+			++_idx;
+			return *this;
+		}
+
+		inline bool operator!=(const iterator &rhs) const {
+			return _ringBuffer != rhs._ringBuffer || _idx != rhs._idx;
+		}
+
+		inline bool operator==(const iterator &rhs) const {
+			return _ringBuffer == rhs._ringBuffer && _idx == rhs._idx;
+		}
+
+		inline const TYPE *operator->() const {
+			return &_ringBuffer->_buffer[_idx % _ringBuffer->capacity()];
+		}
+	};
+
+	iterator begin() {
+		return iterator(this, _front);
+	}
+
+	iterator end() {
+		return iterator(this, _front + _size);
+	}
+
+	iterator begin() const {
+		return iterator(const_cast<RingBuffer *>(this), _front);
+	}
+
+	iterator end() const {
+		return iterator(const_cast<RingBuffer *>(this), _front + _size);
+	}
+
+	inline size_t size() const {
+		return _size;
+	}
+
+	constexpr size_t capacity() const {
+		return SIZE;
+	}
+
+	inline bool empty() const {
+		return _size == 0;
+	}
+
+	/**
+	 * @brief Access to the first element in the buffer
+	 * @note This is not the same as accessing the index 0 element
+	 */
+	const TYPE &front() const {
+		return _buffer[_front];
+	}
+
+	/**
+	 * @brief Access to the first element in the buffer
+	 * @note This is not the same as accessing the index 0 element
+	 */
+	TYPE &front() {
+		return _buffer[_front];
+	}
+
+	/**
+	 * @brief Access to the last element in the buffer
+	 * @note This is not the same as accessing the index @c size-1 element
+	 */
+	const TYPE &back() const {
+		return _buffer[_back];
+	}
+
+	/**
+	 * @brief Access to the last element in the buffer
+	 * @note This is not the same as accessing the index @c size-1 element
+	 */
+	TYPE &back() {
+		return _buffer[_back];
+	}
+
+	/**
+	 * @brief Clears the whole ring buffer
+	 * @note Does not call any destructors - they are called when the buffer itself gets destroyed
+	 */
+	void clear() {
+		_front = 0u;
+		_back = SIZE - 1u;
+		_size = 0u;
+	}
+
+	/**
+	 * @brief Pushes an element to the end of the buffer
+	 */
+	void push_back(const TYPE &x) {
+		_back = (_back + 1u) % SIZE;
+		if (_size == SIZE) {
+			_front = (_front + 1u) % SIZE;
+		} else {
+			++_size;
+		}
+		_buffer[_back] = x;
+	}
+
+	/**
+	 * @brief Pushes an elements to the end of the buffer
+	 * @note Performs a move operation
+	 */
+	template<typename... _Args>
+	void emplace_back(_Args &&...args) {
+		_back = (_back + 1u) % SIZE;
+		if (_size == SIZE) {
+			_front = (_front + 1u) % SIZE;
+		} else {
+			++_size;
+		}
+		_buffer[_back] = Common::move(TYPE{Common::forward<_Args>(args)...});
+	}
+
+	/**
+	 * @brief Removes element from the beginning of the buffer
+	 */
+	void pop() {
+		if (_size == 0) {
+			return;
+		}
+		--_size;
+		_front = (_front + 1u) % SIZE;
+	}
+
+	/**
+	 * @brief Erase the given amount of elements from the end of the buffer
+	 */
+	void erase_back(const size_t n) {
+		if (n >= _size) {
+			clear();
+			return;
+		}
+		_size -= n;
+		_back = (_front + _size - 1u) % SIZE;
+	}
+
+	/**
+	 * @brief Erase the given amount of elements from the beginning of the buffer
+	 */
+	void erase_front(const size_t n) {
+		if (n >= _size) {
+			clear();
+			return;
+		}
+		_front = (_front + n) % SIZE;
+		_size -= n;
+	}
+
+	inline TYPE &operator[](size_t i) {
+		return _buffer[(_front + i) % SIZE];
+	}
+
+	inline const TYPE &operator[](size_t i) const {
+		return _buffer[(_front + i) % SIZE];
+	}
+};
+
+} // namespace TwinE
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 1c37b7e1347..c77886b0b44 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -101,12 +101,13 @@ FrameMarker::~FrameMarker() {
 	const uint32 end = g_system->getMillis();
 	const uint32 frameTime = end - _start;
 	const uint32 maxDelay = 1000 / _fps;
-	if (frameTime > maxDelay) {
+	const int32 waitMillis = (int32)maxDelay - (int32)frameTime;
+	_engine->_debugState->addFrameData(frameTime, waitMillis, maxDelay);
+	if (waitMillis < 0) {
 		debug(5, "Frame took longer than the max allowed time: %u (max is %u)", frameTime, maxDelay);
 		return;
 	}
-	const uint32 waitMillis = maxDelay - frameTime;
-	g_system->delayMillis(waitMillis);
+	g_system->delayMillis((uint)waitMillis);
 }
 
 TwineScreen::TwineScreen(TwinEEngine *engine) : _engine(engine) {


Commit: 9d1abc02ff37550844763dab310e47a24b50a699
    https://github.com/scummvm/scummvm/commit/9d1abc02ff37550844763dab310e47a24b50a699
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2024-10-14T19:56:29+02:00

Commit Message:
TWINE: use push/popid for showing multiple palettes to prevent an id clash

Changed paths:
    engines/twine/debugger/debugtools.cpp


diff --git a/engines/twine/debugger/debugtools.cpp b/engines/twine/debugger/debugtools.cpp
index 001685f34cb..427e095487e 100644
--- a/engines/twine/debugger/debugtools.cpp
+++ b/engines/twine/debugger/debugtools.cpp
@@ -210,13 +210,19 @@ static void paletteWindow(TwinEEngine *engine) {
 
 		ImGui::SeparatorText("Front buffer palette");
 		const Graphics::Palette &frontBufferPalette = engine->_frontVideoBuffer.getPalette();
+		ImGui::PushID("frontBufferPalette");
 		ImGuiEx::Palette(frontBufferPalette);
+		ImGui::PopID();
 
 		ImGui::SeparatorText("PalettePCX");
+		ImGui::PushID("palettePcx");
 		ImGuiEx::Palette(engine->_screens->_palettePcx);
+		ImGui::PopID();
 
 		ImGui::SeparatorText("Palette");
+		ImGui::PushID("ptrPal");
 		ImGuiEx::Palette(engine->_screens->_ptrPal);
+		ImGui::PopID();
 	}
 	ImGui::End();
 }


Commit: d9efa04b4f5f82ed20315ce889f20fd1ff4d2835
    https://github.com/scummvm/scummvm/commit/d9efa04b4f5f82ed20315ce889f20fd1ff4d2835
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2024-10-14T19:56:29+02:00

Commit Message:
TWINE: fixed FrameMarker values for fps

Changed paths:
    engines/twine/renderer/screens.cpp


diff --git a/engines/twine/renderer/screens.cpp b/engines/twine/renderer/screens.cpp
index 0b3920ef60f..15e7e4be839 100644
--- a/engines/twine/renderer/screens.cpp
+++ b/engines/twine/renderer/screens.cpp
@@ -192,7 +192,7 @@ void Screens::fadeToBlack(const Graphics::Palette &ptrpal) {
 	}
 
 	for (int32 n = 100; n >= 0; n -= 2) {
-		FrameMarker frame(_engine, DEFAULT_HZ); // VSync()
+		FrameMarker frame(_engine, 66); // VSync()
 		fadePal(0, 0, 0, ptrpal, n);
 	}
 
@@ -203,7 +203,7 @@ void Screens::whiteFade() {
 	Graphics::Palette workpal{NUMOFCOLORS};
 
 	for (int32 n = 0; n <= 255; n++) {
-		FrameMarker frame(_engine, DEFAULT_HZ); // VSync()
+		FrameMarker frame(_engine, 66); // VSync()
 		for (int i = 0; i < NUMOFCOLORS; i++) {
 			workpal.set(i, n, n, n);
 		}
@@ -215,14 +215,14 @@ void Screens::whiteFade() {
 
 void Screens::fadeWhiteToPal(const Graphics::Palette &ptrpal) {
 	for (int32 n = 0; n <= 100; ++n) {
-		FrameMarker frame(_engine, DEFAULT_HZ); // VSync()
+		FrameMarker frame(_engine, 66); // VSync()
 		fadePal(255, 255, 255, ptrpal, n);
 	}
 }
 
 void Screens::fadeToPal(const Graphics::Palette &ptrpal) {
 	for (int32 i = 0; i <= 100; i += 3) {
-		FrameMarker frame(_engine, DEFAULT_HZ); // VSync()
+		FrameMarker frame(_engine, 66); // VSync()
 		fadePal(0, 0, 0, ptrpal, i);
 	}
 
@@ -243,7 +243,7 @@ void Screens::fadePalToPal(const Graphics::Palette &ptrpal, const Graphics::Pale
 	Graphics::Palette workpal{NUMOFCOLORS};
 
 	for (int m = 0; m < 100; ++m) {
-		FrameMarker frame(_engine, DEFAULT_HZ); // VSync()
+		FrameMarker frame(_engine, 66); // VSync()
 		for (int32 i = 0; i < NUMOFCOLORS; i++) {
 			byte r1, g1, b1;
 			ptrpal.get(i, r1, g1, b1);
@@ -264,14 +264,14 @@ void Screens::fadePalToPal(const Graphics::Palette &ptrpal, const Graphics::Pale
 
 void Screens::fadeToRed(const Graphics::Palette &ptrpal) {
 	for (int32 i = 100; i >= 0; i -= 2) {
-		FrameMarker frame(_engine, DEFAULT_HZ);
+		FrameMarker frame(_engine, 66); // VSync()
 		fadePal(255, 0, 0, ptrpal, i);
 	}
 }
 
 void Screens::fadeRedToPal(const Graphics::Palette &ptrpal) {
 	for (int32 i = 0; i <= 100; i += 2) {
-		FrameMarker frame(_engine, DEFAULT_HZ);
+		FrameMarker frame(_engine, 66); // VSync()
 		fadePal(255, 0, 0, ptrpal, i);
 	}
 }


Commit: d89f9251553c830a4d993654d015e045b5077f44
    https://github.com/scummvm/scummvm/commit/d89f9251553c830a4d993654d015e045b5077f44
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2024-10-14T19:56:29+02:00

Commit Message:
TWINE: renamed to match original sources

Changed paths:
    engines/twine/menu/menuoptions.cpp
    engines/twine/twine.cpp
    engines/twine/twine.h


diff --git a/engines/twine/menu/menuoptions.cpp b/engines/twine/menu/menuoptions.cpp
index fe070afacf8..159f87610f8 100644
--- a/engines/twine/menu/menuoptions.cpp
+++ b/engines/twine/menu/menuoptions.cpp
@@ -106,7 +106,7 @@ void MenuOptions::showCredits() {
 	_engine->_scene->_newCube = LBA1SceneId::Credits_List_Sequence;
 
 	flagCredits = true;
-	_engine->gameEngineLoop();
+	_engine->mainLoop();
 	_engine->_scene->stopRunningGame();
 	flagCredits = false;
 
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index c77886b0b44..6e9471f571b 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -376,7 +376,7 @@ Common::Error TwinEEngine::run() {
 			_state = EngineState::GameLoop;
 			break;
 		case EngineState::GameLoop:
-			if (gameEngineLoop()) {
+			if (mainLoop()) {
 				_menuOptions->showCredits();
 				_menuOptions->showEndSequence();
 			}
@@ -1222,7 +1222,7 @@ bool TwinEEngine::runGameEngine() { // mainLoopInteration
 	return false;
 }
 
-bool TwinEEngine::gameEngineLoop() {
+bool TwinEEngine::mainLoop() {
 	_redraw->_firstTime = true;
 	_screens->_flagFade = true;
 	_movements->initRealValue(LBAAngles::ANGLE_0, -LBAAngles::ANGLE_90, LBAAngles::ANGLE_1, &_realFalling);
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index 46d05e76642..5de3c3ed387 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -370,7 +370,7 @@ public:
 	 * Game engine main loop
 	 * @return true if we want to show credit sequence
 	 */
-	bool gameEngineLoop();
+	bool mainLoop();
 
 	/**
 	 * Deplay certain seconds till proceed - Can also Skip this delay


Commit: 2fd6e9b3d3f56c33e23a7434b6319130de9cdc76
    https://github.com/scummvm/scummvm/commit/2fd6e9b3d3f56c33e23a7434b6319130de9cdc76
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2024-10-14T19:56:29+02:00

Commit Message:
TWINE: LBA: Game and Main Menu Palette Issue after intro video (Regression)

see bug #15402 (https://bugs.scummvm.org/ticket/15402)

Changed paths:
    engines/twine/renderer/screens.cpp


diff --git a/engines/twine/renderer/screens.cpp b/engines/twine/renderer/screens.cpp
index 15e7e4be839..fda4305dca7 100644
--- a/engines/twine/renderer/screens.cpp
+++ b/engines/twine/renderer/screens.cpp
@@ -232,9 +232,9 @@ void Screens::fadeToPal(const Graphics::Palette &ptrpal) {
 }
 
 void Screens::setBlackPal() {
-	_ptrPal.clear();
+	Graphics::Palette workPal(NUMOFCOLORS);
 
-	_engine->setPalette(_ptrPal);
+	_engine->setPalette(workPal);
 
 	_flagBlackPal = true;
 }




More information about the Scummvm-git-logs mailing list