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
00229 void reflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00230
00231 void reflexReflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00232
00233 void implReflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00234
00235 bool reflexExists(const char type, int partitions = TRIGGER_ALL_PARTITIONS) ;
00236
00237 void suppress(const char type, int partitions);
00238 void allow(const char type, int partitions);
00239
00241 void otherwise(PacketHandler pfunc, int partitions = TRIGGER_BRAIN, bool allowBroken = false) ;
00242
00243 void empty(PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool allowBroken = false) ;
00244
00245 void triggerUp() ;
00246
00254 bool inHandler() ;
00255
00256 u8 source() ;
00257
00258 u8 getFlags(const char type) ;
00259
00275 void trigger(u8 * packet, u8 face) ;
00276
00277 SFBReactor() ;
00278
00287 bool canTrigger() ;
00288
00289 private:
00290
00291 void setSpecial(const u8 offset, u8 flags, GRL grl, int partitions) ;
00292
00293 bool fireTrigger(u8 * packet, PacketHandler ph, u8 face) ;
00294
00295 int positionInPartition(const u8 partition, const u8 type) ;
00296
00297 GRL findInPartitions(const u8 type, int flags) ;
00298
00299
00300 SFBGRLMasterTable masterTable;
00301 SFBDispatchEntry entries[MAX_REACTORS];
00302 PacketHandler casualTable[MAX_CASUAL_REFLEXES];
00303 u16 partitionStarts[PARTITION_COUNT];
00304 u8 casualTableInUse;
00305
00306 u8 triggerSources[MAX_NESTED_TRIGGERS];
00307 TRIGGER_SET_TYPE triggerUpFlags;
00308 s8 topTrigger;
00309
00310 friend void reflex(const char type, PacketHandler ph, int flags);
00311 };
00312
00316 void reflex(const char type, PacketHandler ph, int flags = SFBReactor::TRIGGER_SPINE);
00317
00321 extern SFBReactor Body;
00322
00337 class SFBBrainReflex {
00338 public:
00339 void reflex(const char type, PacketHandler ph) {
00340 ::reflex(type, ph, SFBReactor::TRIGGER_BRAIN);
00341 }
00342 };
00343 extern SFBBrainReflex Brain;
00344
00359 class SFBSpineReflex {
00360 public:
00373 void reflex(const char type, PacketHandler ph) {
00374 ::reflex(type, ph, SFBReactor::TRIGGER_SPINE);
00375 }
00376 };
00377 extern SFBSpineReflex Spine;
00378
00379 #endif
00380