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