View source: Task Queue System (revision 625)
Jump to navigation
Jump to search
2021-12-31T21:34:48Z · LemonHaze · Download source
=Task memory structure=
{| class="wikitable"
|-
! Position !! Length !! Type !! Description
|-
| 0x00 || 0x08 || uint64_t* || Callback function pointer
|-
| 0x08 || 0x04 || char* || Task type/name token
|-
| 0x0C || 0x01 || uint8_t || Unknown value
|-
| 0x0D || 0x01 || uint8_t || Unknown value
|-
| 0x10 || 0x08 || uint64_t* || Next task pointer
|-
| 0x18 || 0x08 || uint64_t* || Some task pointer
|-
| 0x20 || 0x08 || uint64_t* || Current task pointer (at the moment of creation)
|-
| 0x28 || 0x08 || uint64_t* || Some task pointer
|-
| 0x30 || 0x08 || uint64_t* || Some task pointer
|-
| 0x38 || 0x08 || uint64_t* || Some task pointer
|-
| 0x40 || 0x08 || uint64_t* || Some task pointer
|-
| 0x48 || 0x08 || uint64_t* || Unknown pointer
|-
| 0x50 || 0x08 || uint64_t* || Unknown pointer
|-
| 0x58 || 0x08 || uint64_t* || Unknown pointer
|-
| 0x60 || 0x08 || uint64_t* || Unknown pointer
|-
| 0x68 || 0x08 || uint64_t* || Callback function parameter struct pointer
|}
=Task queue=
Task Queue Pointer Offset: 0x1481FFA50 (v1.07)<br>
At the start an ROOT task is created.<br>
When the ROOT task was created the Queue gets filled with NONE task's which do nothing.<br>
At initialization each task has the next task in order as their next task specified inside 0x18.<br>
The last task however points to 0x142A88530 (v1.07) as their next task.<br>
The ROOT task points to the first task as it's next task.<br>
=Enqueue task=
==Enqueue task without TASK data allocation==
To enqueue an task without TASK data allocation the subroutine 0x14049D890 (v1.07) needs to be called.
<sub>
EnqueueTask(void* callbackFunction, uint8_t nextFunctionIndex, uint8_t a3, uint32_t taskToken)
</sub>
==Enqueue task with TASK data allocation==
To enqueue an task with TASK data allocation the subroutine 0x14049DA10 (v1.07) needs to be called.<br>
<sub>
EnqueueTaskWithData(void* callbackFunction, uint8_t nextFunctionIndex, uint8_t a3, uint32_t dataSize, uint32_t taskToken, char* debugTaskName)
</sub>
=Task creation=
During the enqueue process the task will be created with the given callback function.<br>
The callback function parameter, which is optional, is an pointer to an struct than can have any shape or size the callback function needs.<br>
This parameter struct will be allocated inside the USE/fREe storage.
=Task execution=
The main loop iterates through the task queue and calls the callback function with the optional parameter.<br>
When the callback function returns the next task pointer is read from the current task and moved into the task queue address pointer.
<syntaxhighlight lang="C++" line>
void Shenmue::Main(int argc, void *argv) {
// initialize
if ( Shenmue::Initialization(argc, argv) )
{
HLib_Task * taskPtr = nullptr;
// loop all tasks
for ( taskPtr = HLib::CurrentTask; ; HLib::CurrentTask = taskPtr )
{
// execute task function
taskPtr->taskCallbackFnPtr(taskPtr->task_data);
// select next task
taskPtr = HLib::CurrentTask->next_task;
}
}
}
</syntaxhighlight>
=Task cleanup (Destruction)=
A task controls how long it lives in its own callback function.<br>
When a task wants to be destroyed it calls the subroutine 0x14049D660 (v1.07) during its own callback.<br>
Tasks can also be destroyed if a pointer can be retrieved for it, like this:
<syntaxhighlight lang="C++" line>
HLib_Task * TASK = HLib::EnqueueTaskWithoutParameter(HLTaskFunc_CharacterHandler_Callback, a1, 4ui64, 'RAHC');
if ( !TASK )
goto COULD_NOT_ENQUEUE_TASK;
if ( TASK->task_data )
goto TASK_DATA_ALREADY_EXISTS;
task_memory = HLib::AllocHeapMemBlock(272i64, 'KSAT');
if ( task_memory )
*((int *)task_memory + 0x7) |= 0x10u;
TASK->task_data = task_memory;
if ( !task_memory )
{
TASK_DATA_ALREADY_EXISTS:
TASK->initTaskFnPtr = 0i64;
TASK->taskCallbackFnPtr = HLib::DestroyCurrentTask;
TASK->taskPtr08 = 0i64;
COULD_NOT_ENQUEUE_TASK:
TASK = 0i64;
}
</syntaxhighlight>
=Task parameter=
When a task gets enqueued with a parameter it will need to find some "fREe" storage in the USE/fREe storage.<br>
==Storage entry==
{| class="wikitable"
|-
! Position !! Length !! Type !! Description
|-
| 0x00 || 0x04 || string || Task token (TASK)
|-
| 0x10 || 0x08 || uint64_t* || Unknown pointer
|-
| 0x18 || 0x08 || uint64_t* || Unknown pointer
|-
| 0x20 || 0x04 || string || USE/fREe token
|-
| 0x40 || 0x?? || ? || Storage data
|}