Open PalasX opened 4 weeks ago
This one is tricky because you have to write code in a location where it doesn't fit. The Ephinea DLL does this by simply writing the code within the DLL itself, and patching the source location to call that code. For an online (server) patch, you could call malloc(), write the code there, and patch the callsite to call the new code, similar to what Ephinea does. (They also take advantage of the ability to use global variables in their DLL's address space, which you don't necessarily have to do.) If you're patching the executable file statically, you would have to create a new code section or find unused space in an existing code section, write your code there, and patch the callsite in the existing code section to call code in your new section.
Creating a draw distance patch would probably be a lot of work, not because doing the above is hard (though it is tricky), but because it sounds like Sodaboy's patch above only applies to floor items. It could be that many different object types have many different draw distance functions, in which case we'd have to find and patch them all. I haven't done research on this personally, but I wouldn't be surprised if this is the case.
If you were to go the server-patch route, an adaptation of Sodaboy's patch might look something like this. (This won't work on newserv as-is because the x86 assembler doesn't support the float opcodes yet, but that may change soon.)
entry_ptr:
reloc0:
.offsetof start
start:
# Call write_call_to_code(patch_code, sizeof(patch_code), 0x005C5267, 8)
push 8 # Callsite size
push 0x005C5267 # Callsite address
# Hack: the x86 assembler doesn't yet support label deltas in arguments, so
# we instead put the label delta in memory, use call to get its address, then
# read the value from there and push it on the stack.
call get_code_size
.deltaof patch_code, patch_code_end
get_code_size:
pop eax # eax = address of .offsetof above
push dword [eax] # Push value from .offsetof above
# Hack (again): use the call opcode to push the address of patch_code to the
# stack, for the first argument to write_call_to_code
call patch_code_end
patch_code:
# This is the code that gets copied (permanently) to allocated memory.
# First, execute the opcode that was replaced with a call to this function.
mov edx, [esp + 0x18]
# Next, push 2.0 to the st register stack (without reading it from memory)
fld1 # Push 1.0
fld1 # Push 1.0
faddp # st0 = 1.0 + 1.0
# Load the original draw distance (this is the other opcode that was replaced
# by the call to this function)
fld [esp + 0x14]
# Multiply the original draw distance by 2.0
fmulp st1
ret
patch_code_end:
call write_call_to_code
ret
write_call_to_code:
.include WriteCallToCode-59NL
Is your feature request related to a problem? Please describe. Not related to any specific problem
Describe the solution you'd like Possible to implement ASM draw distance patch for either a set float value or integer multiplier to be used with the run time client patches for BB? Idealy for all objects (floor items/meseta, boxes/crates, monsters, teleporters, switches, doors, etc.)
Game version(s) (choose one or more of the following): BB
Additional context I have this snippet of conversation from Sodaboy that i ALMOST grasp the concept of, but could never do anything with. Even with the blueburst patch project compiled and working my my copy of the client, im still drastically lost. I think the example he provided is only for floor items/meseta anyway.
Internet Wayback machine has my back on this one: https://web.archive.org/web/20221210014611/https://www.pioneer2.net/community/threads/increasing-draw-distance-in-psobb-exe-12513.24387/#post-191868
If this is totally infeasible, or out of scope, or just way more work than it's worth, that's cool too! Never hurts to ask :) Thanks again!