-
Notifications
You must be signed in to change notification settings - Fork 64
Expand file tree
/
Copy pathtask.h
More file actions
149 lines (117 loc) · 4.79 KB
/
Copy pathtask.h
File metadata and controls
149 lines (117 loc) · 4.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#ifndef GUARD_TASK_H
#define GUARD_TASK_H
#include "global.h"
struct Task_;
typedef void (*TaskMain)(void);
typedef void (*TaskDestructor)(struct Task_ *);
// The task system uses the GBA's unique memory layout to halve the size of pointers.
// Other platforms need to have the same logical behavior, but done differently.
#if PLATFORM_GBA
typedef u16 TaskPtr;
// Mainly used to silence (void* -> u16) warnings
typedef u32 TaskPtr32;
#define TASK_PTR(taskRef) (IWRAM_START + (taskRef))
#define TASK_IS_NULL(taskp) ((taskp) == (void *)IWRAM_START)
typedef u16 IwramData;
#define CLEAR_TASK_MEMORY_ON_DESTROY FALSE
#else
typedef struct Task_ *TaskPtr;
typedef TaskPtr TaskPtr32;
#define TASK_PTR(taskRef) (taskRef)
#define TASK_IS_NULL(task) ((task) == NULL)
typedef void *IwramData;
#if !DEBUG && !TAS_TESTING
#define ENABLE_TASK_LOGGING !TRUE
#else
#define ENABLE_TASK_LOGGING TRUE
#endif // !DEBUG && !TAS_TESTING
#define CLEAR_TASK_MEMORY_ON_DESTROY TRUE
#endif // PLATFORM_GBA
#define TASK_IS_NOT_NULL(taskp) !TASK_IS_NULL(taskp)
#define MAX_TASK_NUM 128
#define TASK_INACTIVE 0x0001
#define TASK_DESTROY_DISABLED 0x0002
#define TASK_x0004 0x0004
#define TASK_USE_EWRAM 0x0010
// NOTE(Jace):
// Used for uses of unk14, unk15, unk16 and unk18, which might have been debug data.
#define USE_SA2_TASK_SYSTEM (GAME == GAME_SA2)
typedef struct Task_ {
/* 0x00 */ TaskPtr parent;
/* 0x02 */ TaskPtr prev;
/* 0x04 */ TaskPtr next;
/* 0x06 */ IwramData data;
#if PORTABLE
u32 dataSize;
#endif // PORTABLE
/* 0x08 */ TaskMain main;
/* 0x0C */ TaskDestructor dtor;
/* 0x10 */ u16 priority; // priority?
/* 0x12 */ u16 flags; // 0x1 = active
// 0x2 = ???
// 0x10 = use ewram for struct
#if USE_SA2_TASK_SYSTEM
/* 0x14 */ u8 unk14;
/* 0x15 */ u8 unk15;
/* 0x16 */ u16 unk16;
/* 0x18 */ u16 unk18;
#endif // USE_SA2_TASK_SYSTEM
#if ENABLE_TASK_LOGGING
const char *name;
#endif
} Task;
#if PLATFORM_GBA
typedef u16 IwramNodePtr;
typedef u32 IwramNodePtr32;
#else
struct IwramNode;
typedef struct IwramNode *IwramNodePtr;
typedef IwramNodePtr IwramNodePtr32;
#endif // PLATFORM_GBA
#define IWRAM_PTR(ptr) TASK_PTR(ptr)
struct IwramNode {
IwramNodePtr next;
s16 state;
u8 ALIGNED(sizeof(void *)) space[0];
};
#define TASK_DATA(taskp) (void *)TASK_PTR((taskp)->data)
#define TASK_PARENT(taskp) (Task *)TASK_PTR((taskp)->parent)
#define TASK_NEXT(taskp) (Task *)TASK_PTR((taskp)->next)
#define TasksDestroyAll() TasksDestroyInPriorityRange(0, 0xFFFF)
#define TASK_HEAP_SIZE ((0x881) * sizeof(uintptr_t))
// NOTE: DO NOT USE, unless ABSOLUTELY necessary for matching!!!
#define TASK_GET_MEMBER(_taskType, _task, _memberType, _memberName) \
*(_memberType *)((unsigned char *)TASK_DATA(_task) + offsetof(_taskType, _memberName))
#define TASK_SET_MEMBER(_taskType, _task, _memberType, _memberName, _value) \
TASK_GET_MEMBER(_taskType, _task, _memberType, _memberName) = (_value);
extern Task gTasks[MAX_TASK_NUM];
extern Task gEmptyTask;
extern Task *gTaskPtrs[MAX_TASK_NUM];
extern s32 gNumTasks;
#if (ENGINE == ENGINE_3)
extern Task *gNextTaskToCheckForDestruction;
#endif
extern Task *gNextTask;
extern Task *gCurTask;
extern u8 gIwramHeap[TASK_HEAP_SIZE];
u32 TasksInit(void);
void TasksExec(void);
#if ENABLE_TASK_LOGGING
#include <stdio.h>
Task *TaskCreate(TaskMain taskMain, u16 structSize, u16 priority, u16 flags, TaskDestructor taskDestructor, const char *name);
// The printout is split so we can still read the input, even if TaskCreate crashes.
#define TaskCreate(taskMain, structSize, priority, flags, taskDestructor) \
({ \
printf("New '%s' (0x%X, %p) ", #taskMain, (u32)structSize, taskMain); \
Task *tt = TaskCreate(taskMain, structSize, priority, flags, taskDestructor, #taskMain); \
printf("at %p\n", tt); \
tt; \
})
#else
Task *TaskCreate(TaskMain taskMain, u16 structSize, u16 priority, u16 flags, TaskDestructor taskDestructor);
#endif // ENABLE_TASK_LOGGING
void TaskDestroy(Task *);
void *IwramMalloc(u16);
void IwramFree(void *p);
void TasksDestroyInPriorityRange(u16, u16);
#endif // GUARD_TASK_H