00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00028 #ifndef SFBREACTOR_H_
00029 #define SFBREACTOR_H_
00030
00031 #include "SFBTypes.h"
00032 #include "SFBAssert.h"
00033
00034 typedef void (*PacketHandler)(u8 * packet) ;
00035
00036 typedef void (*DispatchHandler)(u8 * packet, u8 face);
00037
00052 struct GRL {
00053 u8 tableIndex;
00054 u8 entryIndex;
00055 };
00056 extern bool isNone(GRL g) ;
00057 extern GRL makeGRL(u8 table, u8 entry) ;
00058 extern void initGRL(GRL & g, u8 table = 0, u8 entry = 0) ;
00059
00064 #define MAX_GRL_TABLES 7
00065
00069 struct SFBGRLMasterTable {
00070 const PacketHandler *(tables[MAX_GRL_TABLES]);
00071 u8 lengths[MAX_GRL_TABLES];
00072 u8 inUse;
00073
00074 SFBGRLMasterTable() ;
00075 u8 addTable(const PacketHandler * table, int length) ;
00076
00077 GRL find(PacketHandler ph) ;
00078
00079 PacketHandler find(GRL index) ;
00080 };
00081
00082 #define MAX_REACTORS 200
00083
00087 struct SFBDispatchEntry {
00088 SFBDispatchEntry() ;
00089 GRL grl;
00090 u8 type;
00091 u8 flags;
00092 };
00097 #define MAX_CASUAL_REFLEXES 10
00098
00099 #define TRIGGER_SET_TYPE s16
00100 #define MAX_NESTED_TRIGGERS (sizeof(TRIGGER_SET_TYPE)*8)
00101
00106 class SFBReactor {
00107
00108
00109 enum {
00110 END_PARTITION=BRAIN+1,
00111 PARTITION_COUNT
00112 };
00113 int nextPartition(int partition) ;
00114
00115 int partitionLength(const u8 partition) ;
00116 bool inPartition(const u8 partition, const u8 type);
00117 void openUp(const u8 inPartition, const u8 atPosition);
00118 void addToPartition(const u8 partition, const u8 type, GRL grl, u8 flags);
00119
00120 GRL addToCasual(PacketHandler ph) ;
00121
00122 GRL findOrAdd(PacketHandler ph) ;
00123
00124 public:
00125
00126 enum {
00127 TRIGGER_IF_BROKEN = 0x01,
00128 TRIGGER_EMPTY = 0x02,
00129 TRIGGER_SUPPRESSED = 0x04,
00130 TRIGGER_RESERVED3 = 0x08,
00131 TRIGGER_RESERVED4 = 0x10,
00132 TRIGGER_RESERVED5 = 0x20,
00133 TRIGGER_RESERVED6 = 0x40,
00134 TRIGGER_RESERVED7 = 0x80,
00136
00137
00138 TRIGGER_FIRST_PARTITION = 0x100,
00139 TRIGGER_NORTH = TRIGGER_FIRST_PARTITION<<NORTH,
00140 TRIGGER_SOUTH = TRIGGER_FIRST_PARTITION<<SOUTH,
00141 TRIGGER_EAST = TRIGGER_FIRST_PARTITION<<EAST,
00142 TRIGGER_WEST = TRIGGER_FIRST_PARTITION<<WEST,
00143 TRIGGER_SPINE = TRIGGER_FIRST_PARTITION<<SPINE,
00144 TRIGGER_MEMORY = TRIGGER_FIRST_PARTITION<<WMEM,
00145 TRIGGER_BRAIN = TRIGGER_FIRST_PARTITION<<BRAIN,
00147 TRIGGER_ALL_PARTITIONS =
00148 TRIGGER_NORTH|TRIGGER_SOUTH|TRIGGER_EAST|TRIGGER_WEST|TRIGGER_SPINE|TRIGGER_MEMORY|TRIGGER_BRAIN
00149 };
00150
00151 void reset() ;
00152
00153 int faceToFlag(const u32 face) ;
00154
00201 u8 reflexes(const PacketHandler * table, int length) ;
00202
00203 void reflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00204
00205 void reflexReflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00206
00207 void implReflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00208
00209 bool reflexExists(const char type, int partitions = TRIGGER_ALL_PARTITIONS) ;
00210
00211 void suppress(const char type, int partitions);
00212 void allow(const char type, int partitions);
00213
00215 void otherwise(PacketHandler pfunc, int partitions = TRIGGER_BRAIN, bool allowBroken = false) ;
00216
00217 void empty(PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool allowBroken = false) ;
00218
00219 void triggerUp() ;
00220
00228 bool inHandler() ;
00229
00230 u8 source() ;
00231
00232 u8 getFlags(const char type) ;
00233
00234 void trigger(u8 * packet, u8 face) ;
00235
00236 SFBReactor() ;
00237
00238 bool canTrigger() ;
00239
00240 private:
00241
00242 void setSpecial(const u8 offset, u8 flags, GRL grl, int partitions) ;
00243
00244 bool fireTrigger(u8 * packet, PacketHandler ph, u8 face) ;
00245
00246 int positionInPartition(const u8 partition, const u8 type) ;
00247
00248 GRL findInPartitions(const u8 type, int flags) ;
00249
00250
00251 SFBGRLMasterTable masterTable;
00252 SFBDispatchEntry entries[MAX_REACTORS];
00253 PacketHandler casualTable[MAX_CASUAL_REFLEXES];
00254 u16 partitionStarts[PARTITION_COUNT];
00255 u8 casualTableInUse;
00256
00257 u8 triggerSources[MAX_NESTED_TRIGGERS];
00258 TRIGGER_SET_TYPE triggerUpFlags;
00259 s8 topTrigger;
00260
00261 friend void reflex(const char type, PacketHandler ph, int flags);
00262 };
00263
00264 void reflex(const char type, PacketHandler ph, int flags = SFBReactor::TRIGGER_SPINE);
00265
00266 extern SFBReactor Body;
00267
00282 class SFBBrainReflex {
00283 public:
00284 void reflex(const char type, PacketHandler ph) {
00285 ::reflex(type, ph, SFBReactor::TRIGGER_BRAIN);
00286 }
00287 };
00288 extern SFBBrainReflex Brain;
00289
00304 class SFBSpineReflex {
00305 public:
00318 void reflex(const char type, PacketHandler ph) {
00319 ::reflex(type, ph, SFBReactor::TRIGGER_SPINE);
00320 }
00321 };
00322 extern SFBSpineReflex Spine;
00323
00324 #endif
00325