1+ /* Task Module based on ./src/task.c from
2+ https://github.com/jiangzhengwenjz/katam/ */
13#if PORTABLE
24// TEMP
35#include <assert.h>
1315static void TaskMainDummy1 (void );
1416static void TaskMainDummy2 (void );
1517static void TaskMainDummy3 (void );
16- static void IwramFree (void * );
1718static struct Task * TaskGetNextSlot (void );
1819
1920u32 TasksInit (void )
@@ -25,6 +26,10 @@ u32 TasksInit(void)
2526 gNextTask = NULL ;
2627 gNumTasks = 0 ;
2728
29+ #if (ENGINE == ENGINE_3 )
30+ gNextTaskToCheckForDestruction = NULL ;
31+ #endif
32+
2833#ifndef BUG_FIX
2934 // 0x4 * MAX_TASK_NUM = 0x200, but that would assume gTasks is an array of pointers
3035 DmaFill32 (3 , 0 , gTasks , 0x200 );
@@ -114,7 +119,7 @@ struct Task *TaskCreate(TaskMain taskMain, u16 structSize, u16 priority, u16 fla
114119 task -> dtor = taskDestructor ;
115120 task -> priority = priority ;
116121 task -> flags = flags ;
117- #if ( GAME == GAME_SA2 )
122+ #if USE_SA2_TASK_SYSTEM
118123 task -> unk15 = 0 ;
119124 task -> unk16 = 0 ;
120125 task -> unk18 = 0 ;
@@ -165,6 +170,14 @@ void TaskDestroy(struct Task *task)
165170 gNextTask = TASK_NEXT (task );
166171 }
167172
173+ #if (ENGINE == ENGINE_3 )
174+ // can only happen in (implicitly) recursive TaskDestroy calls (from
175+ // task->dtor) in TasksDestroyInPriorityRange
176+ if (task == gNextTaskToCheckForDestruction ) {
177+ gNextTaskToCheckForDestruction = (struct Task * )(task -> next + IWRAM_START );
178+ }
179+ #endif
180+
168181 prev = TASK_PTR (task -> prev );
169182 next = TASK_PTR (task -> next );
170183 ((struct Task * )prev )-> next = next ;
@@ -203,17 +216,8 @@ void TasksExec(void)
203216 while (TASK_IS_NOT_NULL (gCurTask )) {
204217 gNextTask = (struct Task * )TASK_PTR (gCurTask -> next );
205218
206- if (!(gCurTask -> flags & 1 )) {
207- #ifdef BUG_FIX
208- if (gCurTask -> main == NULL )
209- #if ENABLE_TASK_LOGGING
210- printf ("WARNING: Pointer of Task '%s' is NULL.\n" , gCurTask -> name );
211- #else
212- ;
213- #endif
214- else
215- #endif
216- gCurTask -> main ();
219+ if (!(gCurTask -> flags & TASK_INACTIVE )) {
220+ gCurTask -> main ();
217221 }
218222
219223 gCurTask = gNextTask ;
@@ -346,7 +350,7 @@ void IwramFree(void *p)
346350}
347351
348352/* The function is probably for cleaning up the IWRAM nodes, but it's not working. */
349- static void UNUSED sa2__sub_80028DC (void )
353+ static void UNUSED SA2_LABEL ( sub_80028DC ) (void )
350354{
351355 struct IwramNode * cur = (struct IwramNode * )& gIwramHeap [0 ];
352356 s32 curStateBackup ;
@@ -405,6 +409,7 @@ static struct Task *TaskGetNextSlot(void)
405409 }
406410}
407411
412+ #if ((GAME == GAME_SA1 ) || (GAME == GAME_SA2 ))
408413void TasksDestroyInPriorityRange (u16 lbound , u16 rbound )
409414{
410415 struct Task * cur = gTaskPtrs [0 ];
@@ -436,6 +441,40 @@ void TasksDestroyInPriorityRange(u16 lbound, u16 rbound)
436441 cur = (struct Task * )TASK_PTR (curOffset );
437442 }
438443}
444+ #else
445+ void TasksDestroyInPriorityRange (u16 lbound , u16 rbound )
446+ {
447+ struct Task * cur = gTaskPtrs [0 ];
448+ TaskPtr curOffset = (TaskPtr )(TaskPtr32 )cur ;
449+ #ifndef NONMATCHING
450+ asm("" ::: "r5" );
451+ #endif
452+ while (curOffset != 0 ) {
453+ if (cur -> priority >= lbound ) {
454+ lbound = 0 ;
455+ while (cur -> priority < rbound ) {
456+ gNextTaskToCheckForDestruction = (struct Task * )(cur -> next + (IWRAM_START ));
457+ if (cur != gTaskPtrs [0 ] && cur != gTaskPtrs [1 ]) {
458+ TaskDestroy (cur );
459+ }
460+ cur = gNextTaskToCheckForDestruction ;
461+
462+ if (TASK_IS_NULL (cur )) {
463+ break ;
464+ }
465+ ++ cur ;
466+ -- cur ;
467+ gNextTaskToCheckForDestruction += 0 ;
468+ }
469+ gNextTaskToCheckForDestruction = (void * )(TaskPtr32 )lbound ; // NULL
470+ return ;
471+ }
472+ curOffset = cur -> next ;
473+ cur = (struct Task * )(curOffset + IWRAM_START );
474+ }
475+ gNextTaskToCheckForDestruction = NULL ;
476+ }
477+ #endif
439478
440479#if (GAME == GAME_SA3 )
441480static s32 IwramActiveNodeTotalSize (void )
0 commit comments