@Dimis - nice work on the breakables, are you animating them or using physics? Can't remember if you have said. Looks good either way.
@Chris - phew! that's a lot of clocks. I thought I did a lot of benchmarking / logging...
I actually completed an overhaul of my timing/logging system last month adding more detailed info and making the output easier to work with.
@Dimis -
For timing, I mostly just check each update process as a whole, though there are a few processes where I break it down into more detailed subsections with their own timing, mostly in the UI stuff. If something is taking a long time, I'll break it down further as needed.
I get a log.csv file that looks something like this:
Timing is in milliseconds
(filtered and formatted version)
Timestamp Level Channel Log Timing
779730794 2 main End Update: getHardwareInput() 0
779730794 2 main End Update: debugPerformance() 0
779730794 2 main End Update: systemIntervals() 0
779730794 2 main End Update: arcs3d() 0
779730795 2 main End Update: aiControl() 0
779730795 2 main End Update: getPlayerInput() 0
779730795 2 main End Update: environment() 0
779730795 2 main End Update: characters() 1
779730796 2 main End Update: anim3d() 0
779730796 2 main End Update: updateAccessories() 0
779730796 2 main End Update: debugDisplay() 0
779730796 2 main End Update: 3pCamera() 1
779730798 2 ui End resolving element properties. 1
779730798 2 ui Begin render document 60 elements.
779730798 2 ui End render document. 0
779730798 2 main End Update: gui() 1
779730798 2 main End Update: getInputUI() 0
779730807 2 main End Update: AdvLighting() 8
779730807 2 main Main loop finished. 12
(raw version)
Timestamp,Level,Channel,Log,Timing
779730794,2,main,Begin Update: getHardwareInput()
779730794,2,main,End Update: getHardwareInput(),0
779730794,2,main,Begin Update: debugPerformance()
779730794,2,main,End Update: debugPerformance(),0
779730794,2,main,Begin Update: systemIntervals()
779730794,2,main,End Update: systemIntervals(),0
779730794,2,main,Begin Update: arcs3d()
779730794,2,main,End Update: arcs3d(),0
779730794,2,main,Begin Update: aiControl()
779730794,2,ai,Begin ai control update for character 1
779730794,2,ai,AI 1 is in combat with target: 0
779730794,2,ai,AI 1 is evaluating combat behaviors.
779730794,2,ai,AI 1 has requested input: 3 Applying.
779730794,2,ai,Begin ai control update for character 2
779730794,2,ai,AI 2 is passive.
779730794,2,ai,AI 2 has requested input: 0 Applying.
779730794,2,ai,Begin ai control update for character 3
779730795,2,ai,AI 3 is passive.
779730795,2,ai,AI 3 has requested input: 0 Applying.
779730795,2,ai,Begin ai control update for character 4
779730795,2,ai,AI 4 is passive.
779730795,2,ai,AI 4 has requested input: 0 Applying.
779730795,2,main,End Update: aiControl(),0
779730795,2,main,Begin Update: getPlayerInput()
779730795,2,main,End Update: getPlayerInput(),0
779730795,2,main,Begin Update: environment()
779730795,2,main,End Update: environment(),0
779730795,2,main,Begin Update: characters()
779730795,2,chars,Begin character update for character 0
779730795,2,chars,Begin character update for character 1
779730795,2,chars,Begin character update for character 2
779730795,2,chars,Begin character update for character 3
779730795,2,chars,Begin character update for character 4
779730795,2,main,End Update: characters(),1
779730795,2,main,Begin Update: anim3d()
779730795,2,anim3d,Begin animation update for object 11 active key: light-breeze-mid
779730795,2,anim3d,This object has not been processed. This key will process.
779730795,2,anim3d,Begin animation update for object 37 active key: single-light-breeze
779730795,2,anim3d,This object has not been processed. This key will process.
779730795,2,anim3d,Begin animation update for object 38 active key: single-light-breeze
779730795,2,anim3d,This object has not been processed. This key will process.
779730795,2,anim3d,Begin animation update for object 39 active key: grove-light-breeze
779730795,2,anim3d,This object has not been processed. This key will process.
779730795,2,anim3d,Begin animation update for object 40 active key: grove-light-breeze
779730795,2,anim3d,This object has not been processed. This key will process.
779730795,2,anim3d,Begin animation update for object 41 active key: grove-light-breeze
779730795,2,anim3d,This object has not been processed. This key will process.
779730795,2,anim3d,Begin animation update for object 42 active key: grove-light-breeze
779730795,2,anim3d,This object has not been processed. This key will process.
779730795,2,anim3d,Begin animation update for object 43 active key: grove-light-breeze
779730795,2,anim3d,This object has not been processed. This key will process.
779730795,2,anim3d,Begin animation update for object 44 active key: grove-light-breeze
779730795,2,anim3d,This object has not been processed. This key will process.
779730795,2,anim3d,Begin animation update for object 45 active key: grove-light-breeze
779730795,2,anim3d,This object has not been processed. This key will process.
779730795,2,anim3d,Begin animation update for object 46 active key: grove-light-breeze
779730795,2,anim3d,This object has not been processed. This key will process.
779730795,2,anim3d,Begin animation update for object 47 active key: grove-light-breeze
779730795,2,anim3d,This object has not been processed. This key will process.
779730795,2,anim3d,Begin animation update for object 48 active key: grove-light-breeze
779730796,2,anim3d,This object has not been processed. This key will process.
779730796,2,anim3d,Begin animation update for object 25 active key: 0000L0
779730796,2,anim3d,This object has not been processed. This key will process.
779730796,2,anim3d,Begin animation update for object 29 active key: 0000L0
779730796,2,anim3d,This object has not been processed. This key will process.
779730796,2,anim3d,Begin animation update for object 33 active key: 0000L0
779730796,2,anim3d,This object has not been processed. This key will process.
779730796,2,anim3d,Begin animation update for object 21 active key: 5110L
779730796,2,anim3d,This object has not been processed. This key will process.
779730796,2,anim3d,Animation loop - executing continue callback: _chars_isAbilityDistanceReached('1')
779730796,2,anim3d,Begin animation update for object 1 active key: 5440L-Dodge
779730796,2,anim3d,This object has not been processed. This key will process.
779730796,2,anim3d,Animation loop - executing continue callback: _chars_isAbilityDistanceReached('0')
779730796,2,anim3d,Begin animation update for object 1 active key: 5440O-Dodge
779730796,2,anim3d,This object has already been processed. Skip this key
779730796,2,anim3d,Begin animation update for object 1 active key: 4000L
779730796,2,anim3d,This object has already been processed. Skip this key
779730796,2,main,End Update: anim3d(),0
779730796,2,main,Begin Update: updateAccessories()
779730796,2,main,End Update: updateAccessories(),0
779730796,2,main,Begin Update: debugDisplay()
779730796,2,main,End Update: debugDisplay(),0
779730796,2,main,Begin Update: 3pCamera()
779730796,2,main,End Update: 3pCamera(),1
779730796,2,main,Begin Update: gui()
779730796,2,ui,Reset resolved element properties.
779730796,2,ui,Begin resolving element properties.
779730798,2,ui,End resolving element properties.,1
779730798,2,ui,Begin render document, 60 elements.
779730798,2,ui,End render document.,0
779730798,2,main,End Update: gui(),1
779730798,2,main,Begin Update: getInputUI()
779730798,2,main,End Update: getInputUI(),0
779730798,2,main,Begin Update: AdvLighting()
779730807,2,main,End Update: AdvLighting(),8
779730807,2,main,Main loop finished.,12
the cool thing about csv is that excel, openoffice or whathave you can open them natively and then you can manage the data with all the spreadsheet tools they provide.
The current code for my system.dba file is here:
It isn't directly usable without the rest of the framework, but may give you some additional ideas.
REMSTART
-------------------------------------------------------------------------------------
System Utility Module - $Revision: 126 $
-------------------------------------------------------------------------------------
Author: Josh Kirklin (Ortu)
-------------------------------------------------------------------------------------
Description:
Provides various debugging and performance monitoring processes.
*******************************************
Plugin Dependancies:
Matrix1Util_05.dll (IanM)
Matrix1Util_16.dll (IanM)
Matrix1Util_20.dll (IanM)
*******************************************
Classes:
Extends framework
Defines system
-------------------------------------------------------------------------------------
*******************************************
Provides Public Functions:
system_update_splashScreen(message as string)
- This will update the splash screen, dynamically fitting it to the screen and updating with the specified message.
- This should be called at the start of each module initialization to give a visual indication of loading progress.
system_log(level as byte, channel as string, content as string)
- This will write the specified content to ./debug/log.csv if it meets the level and channel filter configs contained within SYSTEM.
system_setInterval(callbackFunction as string, callbackParameters as string, maxTicks as integer, intervalRate as integer)
- This will add a new interval to the system_Intervals.
system_clearInterval(intervalID as integer)
- This will remove the specified interval from system_Intervals.
*******************************************
Provides Public Data:
SYSTEM as systemData
This global manages timing data and log configurations.
system_Intervals as intervalData
- This array holds interval data for the update handler to work with.
-------------------------------------------------------------------------------------
*******************************************
Provides Private Functions:
*******************************************
Provides Private Data:
-------------------------------------------------------------------------------------
*******************************************
Provides Automatic Update Handlers:
- These will be added to the automatic update queue, the settings for each may be configured in the function declarations below.
framework_update_debugPerformance()
- This will measure program performance metrics.
framework_update_debugDisplay()
- This will display debug info to the screen.
framework_update_performanceSleep()
- This will return some processing time back to the CPU. This will conserve battery life, CPU strain, and help the game play nice with other running applications.
framework_update_getHardwareInput()
- This will capture mouse and keyboard status for later use, as well as tracking previous status to compare against.
framework_update_systemIntervals()
- This will manage active intervals, executing callbacks as intervals are met.
*******************************************
Notes:
REMEND
init_system_module:
`Include Dependent Modules =======================================================================
`Types ===========================================================================================
type timingData
syncMark as dword
loopMark as dword
loopCountMark as dword
loopTime as integer
loopCount as integer
loopsPerSec as integer
msPerLoop as integer
updateMark as dword
endtype
type systemData
timing as timingData
logFile as byte
logLevel as byte `0 will write everything, 255 will write nothing :: 1 minute program flow: section 'bodies', 2 section 'labels', 3 WARNING, 4 ERROR, 5 something specific and usually temporary
logInclude as string `csv instr
endtype
type inputData
isDown as boolean
wasDown as boolean
endType
dim SYSTEM_KeyInput(115) as inputData
type mouseInputData
leftBtn as inputData
rightBtn as inputData
moveX as float
moveY as float
moveZ as float
endtype
type systemIntervalData
id as integer `identifier to reference against, independant of unstable array index
mark as integer `time of last tick
interval as integer `time between ticks in ms
ticks as integer `total ticks processed
maxTicks as integer `total ticks before stopping.
callback as string `function to call each tick
params as string `paramters passed to callback function.
endtype
dim system_Intervals() as systemIntervalData `TODO: make private?
type splashScreenData
img as integer
pasteX as integer
pasteY as integer
hasAlpha as boolean
endtype
dim _system_SplashScreenResource() as splashScreenData
`Globals =========================================================================================
GLOBAL SYSTEM as systemData
GLOBAL SYSTEM_MouseInput as mouseInputData
`Configure the debuggers, comment out to disable components ======================================
SYSTEM.logLevel = CL_LOG_LEVEL
SYSTEM.logInclude = "main,ai,abilities,anim3d,chars,combat,data,ui,world,xml"
`SYSTEM.logInclude = "main,ui"
SYSTEM.logFile = find free file()
if file exist("debug/log.csv") then delete file "debug/log.csv"
open to write SYSTEM.logFile, "debug/log.csv"
write string SYSTEM.logFile, "Timestamp,Level,Channel,Log,Timing"
`Set Update Callbacks ============================================================================
system_update_splashScreen("")
framework_update_debugDisplay()
framework_update_debugPerformance()
framework_update_systemIntervals()
framework_update_performanceSleep()
`Finish ==========================================================================================
GLOBAL SYSTEM_MODULE_LOADED = 1
system_log(2, "main", "End module load: system.")
return
`Functions ===========================================================================================
function framework_update_debugPerformance()
`Initialize Updates
if SYSTEM_MODULE_LOADED = 0
system_log(1, "main", "Adding debugPerformance() to update queue.")
array insert at bottom framework_UpdateList()
framework_UpdateList().ignorePause = TRUE
framework_UpdateList().ptr = get ptr to this function()
framework_UpdateList().mark = timer()
framework_UpdateList().cycle = 0
framework_UpdateList().priority = 1
else
system_log(2, "main", "Begin Update: debugPerformance()")
updateMark as double integer
updateMark = hitimer()
if hitimer() - SYSTEM.timing.loopCountMark > 1000
SYSTEM.timing.loopsPerSec = SYSTEM.timing.loopCount
SYSTEM.timing.msPerLoop = SYSTEM.timing.loopTime
SYSTEM.timing.loopCount = 0
SYSTEM.timing.loopCountMark = hitimer()
endif
system_log(2, "main", "End Update: debugPerformance()," + str$(hitimer() - updateMark))
endif
endfunction
function framework_update_performanceSleep()
`Initialize Updates
if SYSTEM_MODULE_LOADED = 0
system_log(1, "main", "Adding performanceSleep() to update queue.")
array insert at bottom framework_UpdateList()
framework_UpdateList().ignorePause = TRUE
framework_UpdateList().ptr = get ptr to this function()
framework_UpdateList().mark = timer()
framework_UpdateList().cycle = 0
framework_UpdateList().priority = 10
else
system_log(2, "main", "Begin Update: performanceSleep()")
updateMark as double integer
updateMark = hitimer()
nice sleep 10
system_log(2, "main", "End Update: performanceSleep()," + str$(hitimer() - updateMark))
endif
endfunction
function framework_update_getHardwareInput()
system_log(2, "main", "Begin Update: getHardwareInput()")
updateMark as double integer
updateMark = hitimer()
`get keyboard input
for i = 1 to 115
SYSTEM_KeyInput(i).wasDown = SYSTEM_KeyInput(i).isDown
SYSTEM_KeyInput(i).isDown = keystate(i)
next i
`get mouse input
SYSTEM_MouseInput.leftBtn.wasDown = SYSTEM_MouseInput.leftBtn.isDown
SYSTEM_MouseInput.leftBtn.isDown = 0
SYSTEM_MouseInput.rightBtn.wasDown = SYSTEM_MouseInput.rightBtn.isDown
SYSTEM_MouseInput.rightBtn.isDown = 0
tMouseClick = mouseclick()
if tMouseClick = 1 or tMouseClick = 3 then SYSTEM_MouseInput.leftBtn.isDown = 1
if tMouseClick = 2 or tMouseClick = 3 then SYSTEM_MouseInput.rightBtn.isDown = 1
SYSTEM_MouseInput.moveX = mouseMoveX()
SYSTEM_MouseInput.moveY = mouseMoveY()
SYSTEM_MouseInput.moveZ = mouseMoveZ()
system_log(2, "main", "End Update: getHardwareInput()," + str$(hitimer() - updateMark))
endfunction
function framework_update_systemIntervals()
if SYSTEM_MODULE_LOADED = 0
system_log(1, "main", "Adding systemIntervals() to update queue.")
array insert at bottom framework_UpdateList()
framework_UpdateList().ignorePause = FALSE
framework_UpdateList().ptr = get ptr to this function()
framework_UpdateList().mark = timer()
framework_UpdateList().cycle = 0
framework_UpdateList().priority = 1
else
system_log(2, "main", "Begin Update: systemIntervals()")
updateMark as double integer
updateMark = hitimer()
array index to top system_Intervals()
while array index valid(system_Intervals())
now = timer()
if now - (system_Intervals(i).mark + UI.status.pauseElapsed) >= system_Intervals(i).interval
system_Intervals(i).mark = now
call function name system_Intervals(i).callback, system_Intervals(i).params
if system_Intervals(i).maxTicks > -1
inc system_Intervals(i).ticks
if system_Intervals(i).ticks >= system_Intervals(i).maxTicks
array delete element system_Intervals()
else
next array index system_Intervals()
endif
else
next array index system_Intervals()
endif
else
next array index system_Intervals()
endif
endwhile
system_log(2, "main", "End Update: systemIntervals()," + str$(hitimer() - updateMark))
endif
endfunction
function system_setInterval(reqCallback as string, reqParams as string, reqTicks as integer, reqInterval as integer)
array insert at bottom system_Intervals()
system_Intervals().id = timer()
system_Intervals().mark = timer()
system_Intervals().interval = reqInterval
system_Intervals().ticks = 0
system_Intervals().maxTicks = reqTicks
system_Intervals().callback = reqCallback
system_Intervals().params = reqParams
tID = system_Intervals().id
endfunction tID
function system_clearInterval(reqID as integer)
for i = 0 to array count(system_Intervals())
if system_Intervals(i).id = reqID
array delete element system_Intervals(), i
exitfunction
endif
next i
endfunction
function framework_update_debugDisplay()
`Initialize Updates
if SYSTEM_MODULE_LOADED = 0
system_log(1, "main", "Adding debugDisplay() to update queue.")
array insert at bottom framework_UpdateList()
framework_UpdateList().ignorePause = TRUE
framework_UpdateList().ptr = get ptr to this function()
framework_UpdateList().mark = timer()
framework_UpdateList().cycle = 0
framework_UpdateList().priority = 4
else
system_log(2, "main", "Begin Update: debugDisplay()")
updateMark as double integer
updateMark = hitimer()
tPanel = gui_getElementById("stream-panel-left")
if gui_Elements(tPanel).style.display <> "none"
`left panel ----------------------------------------------------------------
`Performance
txt$ = "-Performance-" + NEWLINE
txt$ = txt$ + "FPS: " + str$(Screen FPS()) + NEWLINE
txt$ = txt$ + "LPS: " + str$(SYSTEM.timing.loopsPerSec) + NEWLINE
txt$ = txt$ + "ms/loop: " + str$(SYSTEM.timing.msPerLoop) + NEWLINE
txt$ = txt$ + "TMem: " + str$(system tmem available()) + NEWLINE
txt$ = txt$ + "SMem: " + str$(system smem available()) + NEWLINE
perform checklist for onscreen objects 0
txt$ = txt$ + "Objs: " + str$(checklist quantity()) + NEWLINE
txt$ = txt$ + "Tris: " + str$(statistic(1)) + NEWLINE
txt$ = txt$ + "Prim: " + str$(statistic(5)) + NEWLINE
`General
txt$ = txt$ + NEWLINE + "-General-" + NEWLINE
txt$ = txt$ + "My Pos: " + NEWLINE + str$(Chars(MY_CHAR).baseData.x, 2) + ", " + str$(Chars(MY_CHAR).baseData.y, 2) + ", " + str$(Chars(MY_CHAR).baseData.z, 2) + NEWLINE
txt$ = txt$ + "My Facing: " + math2d_getCompassHeading(Chars(MY_CHAR).baseData.facing) + " " + str$(Chars(MY_CHAR).baseData.facing, 2) + NEWLINE
txt$ = txt$ + "My Speed: " + str$(Chars(MY_CHAR).baseData.speed, 1) + NEWLINE
txt$ = txt$ + "Cam Pos: " + NEWLINE + str$(CAM.x, 2) + ", " + str$(CAM.y, 2) + ", " + str$(CAM.z, 2) + NEWLINE
txt$ = txt$ + "Cam T/P: " + str$(CAM.tilt, 2) + ", " + str$(CAM.pan, 2) + NEWLINE
txt$ = txt$ + "Cam Zoom: " + str$(CAM.zoom) + NEWLINE
txt$ = txt$ + "ToD: " + str$(WORLD.time, 2) + NEWLINE
`Handles
txt$ = txt$ + NEWLINE + "-Handles-" + NEWLINE
txt$ = txt$ + "Control Arc: " + str$(math3d_getActiveArc(Chars(MY_CHAR).baseData.obj)) + NEWLINE
txt$ = txt$ + "Animation Set: " + str$(Chars(MY_CHAR).handle.animationSetID) + NEWLINE
txt$ = txt$ + "Inventory List: " + str$(Chars(MY_CHAR).handle.inventoryListID) + NEWLINE
`UI
txt$ = txt$ + NEWLINE + "-UI-" + NEWLINE
txt$ = txt$ + "Key Mode: "+ UI.status.keyMode + NEWLINE
txt$ = txt$ + "Mouse Mode: " + UI.status.mouseMode + NEWLINE
txt$ = txt$ + "Mouse Pos: " + str$(mouseX()) + ", " + str$(mouseY()) + NEWLINE
`Interactable
txt$ = txt$ + NEWLINE + "-Interactable-" + NEWLINE
txt$ = txt$ + "Target Entity: "+ str$(WORLD.interactableTarget.entityID) + ": " + WORLD.interactableTarget.name + NEWLINE
`Action State
txt$ = txt$ + NEWLINE + "-Action State-" + NEWLINE
tState$ = str$(Chars(c).status.stance)
tState$ = tState$ + str$(Chars(c).status.action)
tState$ = tState$ + str$(Chars(c).status.locomotion)
tState$ = tState$ + str$(Chars(c).status.direction)
txt$ = txt$ + "Current State: " + tState$ + NEWLINE
txt$ = txt$ + "Current Anim: " + NEWLINE
tAnim = anim3d_getActiveAnimation(Chars(MY_CHAR).baseData.obj)
if tAnim > -1
txt$ = txt$ + _anim3d_ActiveAnimations(tAnim).key + NEWLINE
endif
txt$ = txt$ + NEWLINE
if Chars(MY_CHAR).combat.activeAttack.mode <> "none"
txt$ = txt$ + "Attacking: " + Chars(MY_CHAR).combat.activeAttack.mode + " " + Chars(MY_CHAR).combat.activeAttack.dir + NEWLINE
endif
if tPanel >= 0 then gui_Elements(tPanel).value = txt$
`right panel ----------------------------------------------------------------
txt$ = " HP: " + str$(Chars(MY_CHAR).phyStats.health) + NEWLINE
txt$ = txt$ + " SP: " + str$(Chars(MY_CHAR).phyStats.stamina) + NEWLINE + NEWLINE
remstart
txt$ = txt$ + "-Right Hand-" + NEWLINE
txt$ = txt$ + " attack range: " + str$(Chars(MY_CHAR).equipped.rHand.reach, 2) + NEWLINE
txt$ = txt$ + " recovery time: " + str$(Chars(MY_CHAR).equipped.rHand.baseRecovery, 2) + NEWLINE
txt$ = txt$ + " thrust damage: " + Chars(MY_CHAR).equipped.rHand.thrustAttack.damageType + NEWLINE
txt$ = txt$ + " thrust force: " + str$(Chars(MY_CHAR).equipped.rHand.thrustAttack.baseForce, 2) + NEWLINE
txt$ = txt$ + " swing damage: " + Chars(MY_CHAR).equipped.rHand.swingAttack.damageType + NEWLINE
txt$ = txt$ + " swing force: " + str$(Chars(MY_CHAR).equipped.rHand.swingAttack.baseForce, 2) + NEWLINE
txt$ = txt$ + " brace damage: " + Chars(MY_CHAR).equipped.rHand.braceAttack.damageType + NEWLINE
txt$ = txt$ + " brace force: " + str$(Chars(MY_CHAR).equipped.rHand.braceAttack.baseForce, 2) + NEWLINE
txt$ = txt$ + " range damage: " + Chars(MY_CHAR).equipped.rHand.rangeAttack.damageType + NEWLINE
txt$ = txt$ + " range force: " + str$(Chars(MY_CHAR).equipped.rHand.rangeAttack.baseForce, 2) + NEWLINE
REMEND
tPanel = gui_getElementById("stream-panel-right")
if tPanel >= 0
`DEBUG: attack range
if gui_Elements(tPanel).style.display = "inline"
for c = 0 to array count(Chars())
txt$ = txt$ + "-Right Hand-" + NEWLINE
txt$ = txt$ + " attack range: " + str$(Chars(c).equipped.rHand.reach, 2) + NEWLINE
txt$ = txt$ + " recovery time: " + str$(Chars(c).equipped.rHand.baseRecovery, 2) + NEWLINE
txt$ = txt$ + " thrust damage: " + Chars(c).equipped.rHand.thrustAttack.damageType + NEWLINE
txt$ = txt$ + " thrust force: " + str$(Chars(c).equipped.rHand.thrustAttack.baseForce, 2) + NEWLINE
txt$ = txt$ + " swing damage: " + Chars(c).equipped.rHand.swingAttack.damageType + NEWLINE
txt$ = txt$ + " swing force: " + str$(Chars(c).equipped.rHand.swingAttack.baseForce, 2) + NEWLINE
if Chars(c).status.stance >= CHAR_STATE.shieldGuard
x# = Chars(c).baseData.x + sin(Chars(c).baseData.facing) * Chars(c).equipped.rHand.reach
z# = Chars(c).baseData.z + cos(Chars(c).baseData.facing) * Chars(c).equipped.rHand.reach
d3d_line3D Chars(c).baseData.x, Chars(c).baseData.y + Chars(c).baseData.waist, Chars(c).baseData.z, x#, Chars(c).baseData.y + Chars(c).baseData.waist, z#, 0xfffffa5a, 0xfffffa5a, 1
targetAngle# = wrapvalue(360.0 - Chars(0).baseData.facing + atanfull(Chars(1).baseData.x - Chars(0).baseData.x, Chars(1).baseData.z - Chars(0).baseData.z))
txt$ = txt$ + "targetAng: " + str$(targetAngle#) + NEWLINE
`txt$ = txt$ + "in Attack Arc: " + str$(_combat_inOffensiveArc(1, 0)) + NEWLINE + NEWLINE
endif
next c
endif
gui_Elements(tPanel).value = txt$
endif
endif
system_log(2, "main", "End Update: debugDisplay()," + str$(hitimer() - updateMark))
endif
endfunction
function system_log(level as byte, channel as string, content as string)
`TODO: handle file size limits
if level >= SYSTEM.logLevel and file open(SYSTEM.logFile)
if instr(SYSTEM.logInclude, channel) > 0
write string SYSTEM.logFile, str$(timer()) + "," + str$(level) + "," + channel + "," + content
endif
endif
endfunction
function system_update_splashScreen(reqMsg as string)
if SYSTEM_MODULE_LOADED = 0
`background-fill
`TODO: ^
`banner / background-over
tImg = find free image()
load image "media/ui/background-title03b.jpg", tImg, 1
create bitmap 1, 1920, 1080
paste image tImg, 0, 0
create bitmap 2, SCREEN_WIDTH, SCREEN_HEIGHT
copy bitmap 1, 0, 0, 1920, 1080, 2, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT
get image tImg, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT
set current bitmap 0
delete bitmap 1
delete bitmap 2
tX = 0
tY = 0
tX2 = SCREEN_WIDTH
tY2 = SCREEN_HEIGHT
if SCREEN_WIDTH > 1920
tX = (SCREEN_WIDTH - 1920) / 2
tX2 = tX + 1920
endif
if SCREEN_HEIGHT > 1080
tY = (SCREEN_HEIGHT - 1080) / 2
tY2 = tY + 1080
endif
paste image tImg,tX,tY
array insert at bottom _system_SplashScreenResource()
_system_SplashScreenResource().img = tImg
_system_SplashScreenResource().pasteX = tX
_system_SplashScreenResource().pasteY = tY
_system_SplashScreenResource().hasAlpha = 0
`logo shadow
tImg = find free image()
load image "media/ui/background-title-shadow.png", tImg, 1
paste image tImg,tX,tY2 - 200, 1
array insert at bottom _system_SplashScreenResource()
_system_SplashScreenResource().img = tImg
_system_SplashScreenResource().pasteX = tX
_system_SplashScreenResource().pasteY = tY2 - 200
_system_SplashScreenResource().hasAlpha = 1
`logo
tImg = find free image()
load image "media/ui/logo-title.png", tImg, 1
paste image tImg,tX2 - 255,tY2 - 120, 1
array insert at bottom _system_SplashScreenResource()
_system_SplashScreenResource().img = tImg
_system_SplashScreenResource().pasteX = tX2 - 255
_system_SplashScreenResource().pasteY = tY2 - 120
_system_SplashScreenResource().hasAlpha = 1
d3d_startText
d3d_text 1, SCREEN_CENTER_X, (SCREEN_HEIGHT / 4 * 3), 1, "Loading..."
d3d_endText
sync
sync
else
array index to top _system_SplashScreenResource()
while array index valid(_system_SplashScreenResource())
paste image _system_SplashScreenResource().img, _system_SplashScreenResource().pasteX, _system_SplashScreenResource().pasteY, 1 `_system_SplashScreenResource().hasAlpha
next array index _system_SplashScreenResource()
endwhile
d3d_startText
d3d_text 1, SCREEN_CENTER_X, (SCREEN_HEIGHT / 4 * 3), 1, "Loading..."
d3d_text 2, SCREEN_CENTER_X + 35, ((SCREEN_HEIGHT / 4 * 3) - 5), 1, reqMsg
d3d_endText
sync
endif
endfunction
