About HUD edit
-
-
FriendlyFire wrote:
All the HUD is model-based, but you’re very limited in what you can move around or change because buttons won’t be moved. HUDShift can move some bits, but you won’t get the ability to move every single button.You won’t be able to do that curved UI effect.
I definitely had a control over navmap’s plane. This is seems to be the same. But i did in memory, may be now really just enough to re-model hud’s 3db: rotate/scale in 3dsmax and export(without reset xform), just a theory. As for controls, same approach? And a little bit of hacks for positions as mentioned. And to take care about mouse calculations in case fl performs its in flattened 2d (fatality lol).
-
I have no clue how to rotate text. May be need to choose another renderer’s proc(DALib.dll), but better check its released source(if has not been changed). Whatever float I change in Label(i don’t remember the name) struct it neither scales nor rotates. Finally those buttons are “montage” very specific, you need to load them as true-3db and render them by proper proc to be able to adjust 3d positions with keeping original “montage” behavior(long story).
Danger next. I swa fwtow implemented circle-menu by mouse-wheel, idk whether it’s overlay or native so leaving tldr obsolete test code to those who’d like to try to do custom controls(i keep hopes for a hud framework ). The only rule is any 3db file must have a proper VMeshLibrary node (as fl beta’s ones). If it doesn’t exist Freelancer looks into interface-generic.vms.
var CustomXYZ : array [0..2] of Single = (-0.21,-0.37,0); CustomBND : array [0..2] of Single = (0.014,0.014,0); Custom3DB : PAnsiChar = 'HUD_custom.3db'; CustomTXT : PAnsiChar = 'CustomExperimental'; CustomBTN : Pointer; const //actually there're some bits, however freelancer often uses "test al,al jnz" so nobody cares UI_CONTROL_VISIBLE = $0B; UI_CONTROL_INVISIBLE = $08; //Constructing (Hook somewhere in one of hud creation procs like sub_4DA930 ("Status HUD" related)) push 0 push 0 push $5FF //name?/hint? resid(?) push 0 push 0 push 1 push 0 lea edx,CustomBND push edx push 0 lea eax,CustomXYZ push eax push 0 push $5CED30 //"ui_select_item" push 0 push Custom3DB push CustomTXT mov ecx,esi //parent??? keep in mind we're in sub_4DA930,todo: check what is esi call sub_5A0C90 //"ButtonControl" mov [CustomBTN],eax mov byte ptr [eax+$6C],UI_CONTROL_VISIBLE //Rendering (Hook 0x4E793D with JMP in sub_4E7890(in-space hud renderer?)) mov esi,[CustomBTN] mov eax,[esi] mov ecx,esi call dword ptr [eax+$08] mov edx,[esi] mov ecx,esi call dword ptr [edx+$34] //origin code included mov eax,[edi] mov ecx,edi pop edi pop esi jmp dword ptr [eax+$9C] //Clicking (Hook 0x59D212 with JMP in sub_59D140 (global hud click loop?)) mov edx,[eax] lea ecx,[esp+$10] push ecx mov ecx,eax cmp [CustomBTN],ecx jne @@default //your action... push $59D220 ret @@default: call dword ptr [edx+$4C] mov bl,al push $59D220 ret
Simple parallel in-game stuff rendering (3db/cmp), however need to sort the code out first one day. It might not work. There’re a lot of Renderers and methods.
var Model : T3db; //Initializing lea ecx,Model call sub_420D40 mov ecx,$3F800000 mov [edx+$20],ecx mov [edx+$1C],ecx mov [edx+$18],ecx mov [edx+$14],ecx mov [edx+$24],ecx mov [edx],$5D2EFC mov [edx+$10],$FFFFFFFF //Loading push 1 push 0 push FileName lea ecx,Model call sub_59EC80 //Rendering lea edx,Model mov edx,[edx+$04] //$FFFFFFFF = not loaded, won't be rendered mov eax,ds:?Renderer@DALib@@3PAUIRenderer2@@A ; IRenderer2 * DALib::Renderer mov eax,[eax] mov ecx,[eax] push 0 push 0 push $300 //? push $3F800000 //? push edx push esi //Parent?/Handle? push eax call dword ptr [ecx+$1C] //Freeing lea ecx,Model //mov? call sub_59EEE0 lea ecx,Model //mov? call sub_59EF20
Types:
{ 3db bounds ? } P3dbData = ^T3dbData; T3dbData = record //80 bytes tbl1 : Pointer; //engbase.dll off_66295D0 sqzx : Single; u1 : Single; u2 : Single; u3 : Single; sqzy : Single; u4 : Single; u5 : Single; u6 : Single; u7 : Single; posx : Single; posy : Single; posz : Single; u8 : Single; u9 : Single; u10 : Single; u11 : Single; u12 : Single; u13 : UINT; u14 : UINT; //0x88000000 ? end; P3dbInfo = ^T3dbInfo; T3dbInfo = record // 64 bytes u1 : UINT; //0x180A0000 ? filename : PAnsiChar; u3 : UINT; u4 : UINT; hash : UINT; //filepath hash (like "Interface\NeuroNet\...\file.3db") u5 : UINT; //reference/created count ? (probability ~90% lol just bcoz debugged & saw) u6 : array [0..7] of UINT; u7 : UINT; u8 : UINT; //0x88000000 ? end; P3dbRec = ^T3dbRec; T3dbRec = record //248 bytes u1 : UINT; //2 _3dbdata : P3dbData; //critical _3dbinfo : P3dbInfo; u2 : array [0..6] of Single; p2 : Pointer; u3 : array [0..41] of Single; u5 : UINT; //1 u6 : array [0..5] of Single; u7 : array [0..1] of Byte; end; P3db = ^T3db; T3db = record //40 bytes tbl1 : Pointer; //freelancer.exe off_5D2EFC -> sub_48DD20 (freememory or something) _3dbrec : P3dbRec; //$FFFFFFFF -> not present u1 : UINT; //0 u2 : UINT; //0 u3 : UINT; //$FFFFFFFF -> not present ? u4 : Single; u5 : Single; u6 : Single; u7 : Single; u8 : Single; end;
The site got rid of me while I was writing and i see it’s possible to post without logging in again, but i could not daamn
-
Zyos, it’ll be need to be coded anyway(what controls should do). Not me I think, someone else.
Now, crashing(3db). Someone gets a float value rather than a pointer at it. At least it’s working in navmap rendering proc(i cut the code out there).
Buttons are fine, created in “Status HUD” context, left one activates cruise, right one turns off lights(except for docking ones), vice versa. On minimizing hud both disappears for a moment. Nothing updates on loading games, leaving bases, changing ships etc. Just a concept.
-
oO Exellent! Finally Arts coming to reality
Shoot screen from inside cockpit please!
-
HeIIoween, http://i.imgur.com/xhuX9Rp.jpg
Forgotten to mention I don’t how to free a control yet. #MemoryLeak
-
Psst, wanna navmap?
Concept proof. Just calling [edx+$34] which probably means Draw for any control so almost nothing to discuss. I’ve used here button for navstars and static for others. Total the end.
Had to make almost hundred recompilation because everything inside is completely relative. Radiation sign click change stars Z axis, but ones fly towards the center of the screen. Different model sizes did put another problem to match stuff on the screen etc and so on. DALib either Engine/RenderComp/x86math should have some helpers for handling that kind of stuff, but they’re all dword ptr +0xblahblah. For now, only hardcoding.
-
Experimental reference .
IHud = interface ['{45F1E847-B5D0-421E-8E51-E45A3B64A648}'] procedure Draw(const Sender:IControl);stdcall; procedure Update(const Sender:IControl);stdcall; procedure Execute(const Sender:IControl);stdcall; procedure Terminate(const Sender:IControl);stdcall; end;
Low-level and simple. IControl is a simple pointer(class reference, parent at +0x04, next control on same level at +0x08, first child at +0x0C, name (ANSI) at +0x18 and its length at +0x14 etc.)
Draw - sender is one of topmost controls. Its usually contain a traverser for drawing childs and its possible by its visibility to detect when to hide new hud(cinematic cameras/planet/base). Small list:
HUD_ContactList, HUD_Core, HUD_CruiseProgress, HUD_DamageIndicator, HUD_Maneuvers, HUD_Status,HUD_Target, HUD_Waypoint, NN_MainButton, NN_Pause
Update - sender is one of topmost controls. Originally depends on +0x6C first bit which chooses between call dword ptr [this+0x2C] and call dword ptr [this+0x30]. Looks like a background work.
Execute - sender is button/text. OnClick event. For text click must be +0x35C byte/bit set.
Terminate - sender is any control. Freelancer handles everything automatically and destroys all new /child controls once parent destructor has been executed(closing NavMap, Inventory and others). Better check all new stuff for matching and reset all class.
In dacom.ini first must be HudFacility. It exports:
function _IHudFacility:IHudFacility;stdcall;
The interface hooks code and simply calls methods in the manner “for i to count”.
IHudFacility = interface ['{F99B8A4F-99F7-4DA6-91EC-74DD3286464A}'] function AddHud(const Hud:IHud):Boolean;stdcall; end;
HudTest implements the useless window with keeping in mind original hardcoded behavior, but escape drops cruise anyway.(idk how to make hotkeys). Manhattan Planet must be selected only. Animation not, but flashing text speed seems to be relying on fps lol.
I know unit is in delphi, bad, but leave news if somebody will decide to attack freelancer so all could use a shared lib for multihud support. No need to multiply implementations, need the only single one.This may serve as a reference.
Blackjack & animation
But status makes its flicker on minimizing -
Delithor wrote:
I hope this was not given up. I have absolutely no idea how to edit anything other than simple stuff. What you are/were doing is amazing. Is it possible to get the angled windows you have in a few pictures?I might complete most regarding hud, but it’s all about priorities, they control me, even when FL stays #1 for me. Curved elements were never completed, but did attach anyway.
Yeah, I’m living out of the time, 8 months is like 8 days for me
-
its looking pretty good so far
-
The fact is it can’t be completed anyway in standard edit-some-values-in-memory approach. Need a custom drawing directly through Direct3D to get curved text and then implement fixed screen interaction.
(Or A-Z a-z 3db letters with a good amount 3d math to build and place lines of text)
Eventually, we would just end with no-hud hack and drawing everything by ourselves. Sugar dream.
-
Don’t how 'bout you, but i’ve made FINAL breaking change. And the change is removed “Facility” suffix, so it is now just Hud.dll that exports _IHud void.
To be consistent i’ve recompilied HudStatus/HudTarget/HudWeapongGroups that are used in Adv Hud Mod. And included HudShip.dll to activate/deactivate cloak/lights. The currently shipped hud.ini (that should be placed in EXE) contains settings and descriptions for HudShip (thus customizable a little).
And rewrting pascal units as well (do not treat classes as pascal’s ones, those are abstract, pure pointer from the game). Thus any method exposed in IDE from TObject are ILLEGAL to use. Will going to redo MultiUniverse in plain pascal from now, with much better readbility and better sections/lists/columns/rows names & defines so everything should become much easier to read and configurate.