• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!
  • 2026 staff recruitment is open! Check it out and consider applying!

TFC - The Forgotten Client - partially downgraded to 7.4

Gover

Well-Known Member
Joined
Sep 3, 2009
Messages
129
Reaction score
67
Hello,
This is a thread connected with:

I start some fixing on great client release created by sayianking.

The goal is to make a client fully compabitle with 772 tfs engine (maybe with leaked also) with features from 7.4 client (the one's I know).

You should of course limit some functions in options to make it more 7.4 (there is light slider).

anyway, here is change log from today:
Rendering Bugfixes
-engine.cpp — LoadPicture(): Fixed pixel format for Tibia.pic — client was reading 4 bytes (RGBA) instead of 3 (RGB), causing the entire GUI to render scrambled
-protocol.cpp — getProtocolVersion() / getClientVersion(): Both were returning the override flag value (1) instead of the actual protocol version (772), causing "Protocol mismatched" on login
-surfaceDirect3D11.cpp — loadSprite() / loadSpriteMask(): Pixel copy loop was iterating texture->m_height (atlas size) instead of 32 (sprite size), causing an access violation crash when switching to D3D11
-surfaceOpengl.cpp, surfaceOpenglCore.cpp, surfaceOpengles.cpp, surfaceOpengles2.cpp — isSupported(): GL_ATI_meminfo returns 4 values but code only allocated int vram (4 bytes) — fixed to int vram[4], resolving a stack corruption crash on OpenGL renderers

Version Configuration
-const.h: Set CLIENT_OVVERIDE_VERSION = 1, CLIENT_OVERRIDE_PROTOCOL_VERSION = 772, CLIENT_OVERRIDE_FILE_VERSION = 772
-game.cpp — clientChangeVersion(): Added GAME_FEATURE_EXTENDED_SPRITES for version 772 to support .dat/.spr files with more than 65535 sprites
-gui_const.h: Replaced configure button icon with scrollbar down arrow; removed broken bottom-left/right panel border sprites


UI — Hotkeys Window
-Hotkeys.cpp: Full rewrite — new "Hotkey Options" window with F1–F12 / Shift+F1–F12 / Ctrl+F1–F12 slots, text input field, "Send automatically" checkbox, live list update on typing, auto-focus on text field after row selection, white/grey color per row based on sendAuto state
-engine.cpp — bindHotkeyAction(): New function to assign text to a hotkey slot
-engine.cpp — CLIENT_HOTKEY_ACTION handler: Implemented — sends text automatically or pastes it into chat input
-engine.h: Added bindHotkeyAction() declaration
GUI_Window.h
+ GUI_Window.cpp: Added lockActiveElement(bool) and m_lockActive — permanently locks focus on the text field after a hotkey row is selected

UI — Inventory / Soul
-Inventory.cpp
— GUI_Icons::render(): New 2D grid layout (max 6 icons, patterns: 1 / 2 / 2+1 / 2+2 / 3+2 / 3+3), anchored to absolute screen position
Inventory.cpp
— GUI_Icons::onMouseMove(): Rewritten hover tooltips to match the new 2D layout
Inventory.cpp
— inventory panel: Removed Soul background, labels and old status bar strip; status icons moved into the Soul area; panel height reduced accordingly
SkillsWindow.cpp
: Removed "Soul Points" row from the stats list and its update handler


UI — Panel Window Resize
GUI_PanelWindow.cpp
— setRect(): Children are no longer moved when only y1 changes (resize from top) — movement only happens on drag
GUI_PanelWindow.cpp
— render(): Panel background anchored to absolute screen position via setClipRect + y=0; removed resizer graphic
GUI_Panel.cpp
— checkPanels(): setRect() is now only called when position actually changed
GUI_Panel.cpp
— render(): Free-space background anchored via setClipRect
Chat.cpp
— render(): Chat background anchored to absolute screen position via setClipRect + y=0 — background tiles no longer shift during resize

Graphics Engines
surfaceSoftware.cpp — drawBackground(): Fixed pixel copy to account for window surface pitch

Automap Path
main.cpp: g_mapPath changed from AppData\TheForgottenClient\Automap\ to the directory next to the .exe — makes it easy to distribute a pre-filled minimap with the client


If you want to use extended sprites then extend below in game.cpp (enableGameFeature(GAME_FEATURE_EXTENDED_SPRITES):
void Game::clientChangeVersion(Uint32 clientVersion, Uint32 fileVersion)
{
m_gameFeatures.reset();
enableGameFeature(GAME_FEATURE_UPDATE_TILE);
if(clientVersion >= 770)
{
enableGameFeature(GAME_FEATURE_XTEA);
enableGameFeature(GAME_FEATURE_RSA1024);
enableGameFeature(GAME_FEATURE_MESSAGE_STATEMENT);
enableGameFeature(GAME_FEATURE_LOOKTYPE_U16);
//enableGameFeature(GAME_FEATURE_EXTENDED_SPRITES); // Extended .dat/.spr (U32 sprite IDs)
}

This is how client looks like:
1778880281007.webp

It feels really responsive. But how it would handle a big war on a screen? i do not know.

Source and compiled client in attachment. With stock 772 sprites and pic from 2006.
Regards,
Gover
 

Attachments

Last edited:
New updates - I think it is the last update pack. The rest of the features works fine. If someone engage with testing this version - then I can provide new fixes here.

New changelog from yesterday till today:

1. Hotkeys — Arrow Key Navigation
Files:
Hotkeys.cpp, GUI_Element.h, GUI_ListBox.h, GUI_Window.cpp

-Added virtual bool wantsArrowKeys() to GUI_Element base class (returns false by default)
-Overridden in GUI_ListBox to return true
-GUI_Window::onKeyDown now forwards UP/DOWN to the first child that wantsArrowKeys() when the active element doesn't handle them
-Hotkeys window opens with focus on the listbox — pressing UP or DOWN immediately selects F1 (row 0) from unselected state
-After first row selection, focus locks to the textbox; subsequent arrow presses are forwarded back to the listbox

2. Server Log — Toggle Option
Files: engine.h, engine.cpp, Chat.h, Chat.cpp, GeneralOptions.cpp

-New option m_serverLogInDefault (default: true = Server Log visible) in Engine
-Saved/loaded as ServerLogInDefault in config.cfg
-New method Chat::setServerLogVisible(bool) — when false: silently removes the Server Log channel from the panel (no server packet sent), switches view to Default if Server Log was active, enables workAsServerLog on Default channel so server messages appear there instead; when true: re-opens the Server Log channel and disables the mirror
-New checkbox "Server Log Enabled" added to General Options window (window height extended from 444px to 477px, EventID 1014)
-Change applies immediately when clicking OK — no reconnect needed

3. Soul Points Tooltip — Removed
Files:
Inventory.cpp

-Removed INVENTORY_SOUL_DESCRIPTION and INVENTORY_SOUL_EVENTID defines (dead code)
-Both GUI_StaticImage instances for the status background area (minimized and maximized inventory) now pass an empty string as tooltip — no tooltip appears when hovering over the background

4. Skills Window — Soul Points Dead Code Cleanup
Files:
SkillsWindow.cpp

-Removed SKILLS_SOUL_TITLE and SKILLS_SOUL_EVENTID defines
-Removed the dead case SKILLS_SOUL_EVENTID handler from the skills event switch

5. Panel Window Drag — Ghost Image Fix
Files:
GUI_PanelWindow.cpp

-During drag, the original slot of the dragged window was rendered with a DARKGREY texture (drawPictureRepeat) — this caused a "ghost/multiplied" artifact at the source position
Replaced with fillRectangle(0, 0, 0, 255) — the slot is now filled with a clean black rectangle, matching original Tibia client behavior

6. Hotkeys — Key Repeat Support
Files: engine.cpp

-Removed event.key.repeat == 0 guard from the CLIENT_HOTKEY_ACTION handler
-Holding a hotkey now repeatedly fires the action using the OS key-repeat mechanism (SDL SDL_KEYDOWN with repeat > 0) — same timing as holding any regular key: instant first trigger, ~500ms delay, then rapid repeat

7. Double-Click on Character List — Auto Login
Files: CharacterList.cpp

-Double-clicking a character in the list now triggers login immediately, equivalent to pressing OK or Enter
-Uses the existing GUI_ListBox double-click mechanism (~select negative value)

8. Double-Click on Panel Window Title Bar — Minimize/Maximize
Files: GUI_PanelWindow.h, GUI_PanelWindow.cpp

-Double-clicking the title bar of any panel window (Skills, Battle, VIP, containers, etc.) toggles minimize/maximize
-Works in both expanded and minimized states
-Uses a 400ms double-click window; simulates a click on the minimize button (child ID 1000, consistent across all panel windows)

9. Panel Window Drag — Bottom Gap Fix
Files: GUI_PanelWindow.cpp

-Reduced the black placeholder rectangle height by 2px (m_nRect.y2 - 2) to eliminate the thin black gap that appeared between windows during drag

10. Panel Window Corner Artifacts — Fixed on Login
Files: engine.h, engine.cpp

-On login, any previously open panel windows (Skills, Battle, VIP, Party) are silently closed and reopened after the first rendered frame (~32ms total)
-This forces the renderer to correctly initialize corner sprites, eliminating the bright pixel artifacts that appeared in window corners immediately after login
-Completely invisible to the player

11. Creature Name Formatting — Removed ucwords
Files: util.cpp

-UTIL_formatCreatureName() now returns the name unchanged instead of applying ucwords capitalization
-Names are displayed exactly as received from the server — "GM" stays "GM", "GM Retro" stays "GM Retro"

12. Chat — Ctrl+C and Ctrl+A Support
Files: Chat.cpp

-Ctrl+A: always routes to the chat console (selects all text in chat history)
-Ctrl+C / Ctrl+X: routes to the chat console when it has a selection (copies/cuts selected history text); otherwise routes to the text input box as before

13. Double-Click on Character in VIP List — Auto open new chat
Files: VipWindow.cpp/h
 
Last edited:
I think the version attached below should contain all changelog above. But im not sure. All further versions contain features compatible only with my engine - so further I can release further patches to the issues which you guys point here on forum.
 

Attachments

Back
Top