Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions EEex/copy/EEex_scripts/EEex_Assembly.lua
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ function EEex_IsMaskUnset(original, isUnsetMask)
return EEex_BAnd(original, isUnsetMask) == 0x0
end

-- The classic bit trick for "exactly one bit set" is:
-- mask the bits you care about, then check that ``x & (x-1) == 0``
-- (which clears the lowest set bit — if the result is zero, there was only one bit set to begin with)

function EEex_IsExactlyOneBitSet(original, isSetMask)
local masked = EEex_BAnd(original, isSetMask)
return masked ~= 0 and EEex_BAnd(masked, masked - 1) == 0
end

function EEex_IsAtMostOneBitSet(original, isSetMask)
local masked = EEex_BAnd(original, isSetMask)
return EEex_BAnd(masked, masked - 1) == 0
end

function EEex_SetBit(original, toSetIndex)
return EEex_BOr(original, EEex_LShift(0x1, toSetIndex))
end
Expand Down Expand Up @@ -103,6 +117,86 @@ function EEex_UnsetMask(original, toUnsetmask)
return EEex_BAnd(original, EEex_BNot(toUnsetmask))
end

-- Combines two byte components into an unsigned 16-bit word.
-- Each component accepts both signed [-128, 127] and unsigned [0, 255] values.
-- Negative inputs are treated as two's complement and normalized before packing:
-- e.g. -1 → 0xFF (255), -128 → 0x80 (128)
-- Always returns an unsigned value in [0, 65535].
function EEex_PackWord(lowByte, highByte)
if type(lowByte) ~= "number" then EEex_Error("lowByte must be a number") end
if type(highByte) ~= "number" then EEex_Error("highByte must be a number") end
lowByte = math.floor(lowByte)
highByte = math.floor(highByte)
-- Accept both signed and unsigned ranges
if lowByte < -128 or lowByte > 0xFF then EEex_Error("lowByte out-of-bounds (expected [-128, 255])") end
if highByte < -128 or highByte > 0xFF then EEex_Error("highByte out-of-bounds (expected [-128, 255])") end
-- Normalize signed two's complement: -1 → 255, -128 → 128
if lowByte < 0 then lowByte = lowByte + 0x100 end
if highByte < 0 then highByte = highByte + 0x100 end
return lowByte + highByte * 0x100
end

-- Splits a 16-bit word into its low and high byte components.
-- The optional `signed` parameter (default: false) controls how the returned
-- bytes are interpreted:
-- signed=false → both bytes are unsigned [0, 255]
-- signed=true → both bytes use signed two's complement [-128, 127]
-- e.g. 0xFF → -1, 0x80 → -128
-- Input always accepts the full unsigned range [0, 65535].
function EEex_UnpackWord(word, signed)
if type(word) ~= "number" then EEex_Error("word must be a number") end
word = math.floor(word)
if word < 0 or word > 0xFFFF then EEex_Error("word out-of-bounds (expected [0, 65535])") end
local lowByte = word % 0x100
local highByte = math.floor(word / 0x100)
if signed then
-- Reinterpret as signed: values above 0x7F wrap to negative
if lowByte > 0x7F then lowByte = lowByte - 0x100 end
if highByte > 0x7F then highByte = highByte - 0x100 end
end
return lowByte, highByte
end

-- Combines two 16-bit word components into an unsigned 32-bit dword.
-- Each component accepts both signed [-32768, 32767] and unsigned [0, 65535] values.
-- Negative inputs are treated as two's complement and normalized before packing:
-- e.g. -1 → 0xFFFF (65535), -32768 → 0x8000 (32768)
-- Always returns an unsigned value in [0, 4294967295].
function EEex_PackDWord(lowWord, highWord)
if type(lowWord) ~= "number" then EEex_Error("lowWord must be a number") end
if type(highWord) ~= "number" then EEex_Error("highWord must be a number") end
lowWord = math.floor(lowWord)
highWord = math.floor(highWord)
-- Accept both signed and unsigned ranges
if lowWord < -32768 or lowWord > 0xFFFF then EEex_Error("lowWord out-of-bounds (expected [-32768, 65535])") end
if highWord < -32768 or highWord > 0xFFFF then EEex_Error("highWord out-of-bounds (expected [-32768, 65535])") end
-- Normalize signed two's complement: -1 → 65535, -32768 → 32768
if lowWord < 0 then lowWord = lowWord + 0x10000 end
if highWord < 0 then highWord = highWord + 0x10000 end
return lowWord + highWord * 0x10000
end

-- Splits a 32-bit dword into its low and high 16-bit word components.
-- The optional `signed` parameter (default: false) controls how the returned
-- words are interpreted:
-- signed=false → both words are unsigned [0, 65535]
-- signed=true → both words use signed two's complement [-32768, 32767]
-- e.g. 0xFFFF → -1, 0x8000 → -32768
-- Input always accepts the full unsigned range [0, 4294967295].
function EEex_UnpackDWord(dword, signed)
if type(dword) ~= "number" then EEex_Error("dword must be a number") end
dword = math.floor(dword)
if dword < 0 or dword > 0xFFFFFFFF then EEex_Error("dword out-of-bounds (expected [0, 4294967295])") end
local lowWord = dword % 0x10000
local highWord = math.floor(dword / 0x10000)
if signed then
-- Reinterpret as signed: values above 0x7FFF wrap to negative
if lowWord > 0x7FFF then lowWord = lowWord - 0x10000 end
if highWord > 0x7FFF then highWord = highWord - 0x10000 end
end
return lowWord, highWord
end

-------------------
-- Debug Utility --
-------------------
Expand Down
2 changes: 2 additions & 0 deletions EEex/copy/EEex_scripts/EEex_EarlyMain.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@
EEex_DoFile("EEex_Assembly_Patch")
-- Replaces the statically compiled, in-exe Lua version with LuaLibrary.
EEex_DoFile("EEex_ReplaceLua")
-- Build the verified module trust chain using the now-active external Lua runtime.
EEex_DoFile("EEex_LuaModule")
end)()
78 changes: 78 additions & 0 deletions EEex/copy/EEex_scripts/EEex_GameObject.lua
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,45 @@ function EEex_GameObject_IsSpriteID(objectID, allowDead)
return EEex_GameObject_IsSprite(EEex_GameObject_Get(objectID), allowDead)
end

-- @bubb_doc { EEex_GameObject_GetEA / instance_name=getEA }
--
-- @summary: Returns the given ``object``'s EA.
--
-- @self { object / usertype=CGameObject }: The object whose EA is being fetched.
--
-- @return { type=number }: See summary.

function EEex_GameObject_GetEA(object)
return object.m_typeAI.m_EnemyAlly
end
CGameObject.getEA = EEex_GameObject_GetEA

-- @bubb_doc { EEex_GameObject_GetGeneral / instance_name=getGeneral }
--
-- @summary: Returns the given ``object``'s general.
--
-- @self { object / usertype=CGameObject }: The object whose general is being fetched.
--
-- @return { type=number }: See summary.

function EEex_GameObject_GetGeneral(object)
return object.m_typeAI.m_General
end
CGameObject.getGeneral = EEex_GameObject_GetGeneral

-- @bubb_doc { EEex_GameObject_GetRace / instance_name=getRace }
--
-- @summary: Returns the given ``object``'s race.
--
-- @self { object / usertype=CGameObject }: The object whose race is being fetched.
--
-- @return { type=number }: See summary.

function EEex_GameObject_GetRace(object)
return object.m_typeAI.m_Race
end
CGameObject.getRace = EEex_GameObject_GetRace

-- @bubb_doc { EEex_GameObject_GetClass / instance_name=getClass }
--
-- @summary: Returns the given ``object``'s class.
Expand All @@ -272,6 +311,45 @@ function EEex_GameObject_GetClass(object)
end
CGameObject.getClass = EEex_GameObject_GetClass

-- @bubb_doc { EEex_GameObject_GetSpecifics / instance_name=getSpecifics }
--
-- @summary: Returns the given ``object``'s specifics.
--
-- @self { object / usertype=CGameObject }: The object whose specifics is being fetched.
--
-- @return { type=number }: See summary.

function EEex_GameObject_GetSpecifics(object)
return object.m_typeAI.m_Specifics
end
CGameObject.getSpecifics = EEex_GameObject_GetSpecifics

-- @bubb_doc { EEex_GameObject_GetGender / instance_name=getGender }
--
-- @summary: Returns the given ``object``'s gender.
--
-- @self { object / usertype=CGameObject }: The object whose gender is being fetched.
--
-- @return { type=number }: See summary.

function EEex_GameObject_GetGender(object)
return object.m_typeAI.m_Gender
end
CGameObject.getGender = EEex_GameObject_GetGender

-- @bubb_doc { EEex_GameObject_GetAlignment / instance_name=getAlignment }
--
-- @summary: Returns the given ``object``'s alignment.
--
-- @self { object / usertype=CGameObject }: The object whose alignment is being fetched.
--
-- @return { type=number }: See summary.

function EEex_GameObject_GetAlignment(object)
return object.m_typeAI.m_Alignment
end
CGameObject.getAlignment = EEex_GameObject_GetAlignment

------------------------------
-- Game Object Manipulation --
------------------------------
Expand Down
Loading