mirror of
https://github.com/brues-code/ClassicAPI.git
synced 2026-11-14 23:20:44 +00:00
Retail's ScrollingMessageFrame SetScrollOffset, GetScrollOffset, GetMaxScrollRange, ScrollByAmount, SetInsertMode / GetInsertMode with the SCROLLING_MESSAGE_FRAME_INSERT_MODE_* globals, and AddOnDisplayRefreshedCallback, which ScrollUtil's InitScrollingMessageFrameWithScrollBar calls. The offset is the engine's own: SetScrollFromBottom's body (0x00788700) is 4.3.4's SetScrollOffset step for step, and GetCurrentScroll is GetScrollOffset under retail's name. The setters clamp to 0..GetNumMessages()-1 first, as retail does; the engine wraps. 1.12's layout stacks lines bottom-up only, so the insert mode is BOTTOM and SetInsertMode raises an error for anything else. The callbacks run after the frame's own update (0x00788460, OnUpdate then the fader), where retail's OnPostUpdate runs them, for a frame the line layout, AddMessage or ScrollByAmount marked. The layout hook moves out of Text::InlineTexture into ScrollingMessageFrame::Layout, which owns it and fans out to both.
42 lines
1.5 KiB
C++
42 lines
1.5 KiB
C++
// This file is part of ClassicAPI.
|
|
//
|
|
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
|
// of the GNU General Public License as published by the Free Software Foundation, either
|
|
// version 3 of the License, or (at your option) any later version.
|
|
//
|
|
// ClassicAPI 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
|
|
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
#include "scrollingmessageframe/Layout.h"
|
|
|
|
#include "Game.h"
|
|
#include "Offsets.h"
|
|
|
|
namespace ScrollingMessageFrame::Layout {
|
|
|
|
namespace {
|
|
|
|
AutoSubscribe *g_head = nullptr;
|
|
|
|
using Layout_t = void(__fastcall *)(void *smf, void *edx, int newestRecord);
|
|
Layout_t g_origLayout = nullptr;
|
|
|
|
void __fastcall Layout_h(void *smf, void *edx, int newestRecord) {
|
|
g_origLayout(smf, edx, newestRecord);
|
|
for (const AutoSubscribe *s = g_head; s != nullptr; s = s->next)
|
|
s->fn(smf);
|
|
}
|
|
|
|
const Game::HookAutoRegister _hook{Offsets::FUN_SMF_DISPLAY_REFRESH, reinterpret_cast<void *>(&Layout_h),
|
|
reinterpret_cast<void **>(&g_origLayout)};
|
|
|
|
} // namespace
|
|
|
|
AutoSubscribe::AutoSubscribe(Listener fn) : fn(fn), next(g_head) { g_head = this; }
|
|
|
|
} // namespace ScrollingMessageFrame::Layout
|