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
00037 typedef void (*PacketHandler)(u8 * packet) ;
00038
00039 typedef void (*DispatchHandler)(u8 * packet, u8 face);
00040
00055 struct GRL {
00056 u8 tableIndex;
00057 u8 entryIndex;
00058 };
00059 extern bool isNone(GRL g) ;
00060 extern GRL makeGRL(u8 table, u8 entry) ;
00061 extern void initGRL(GRL & g, u8 table = 0, u8 entry = 0) ;
00062
00067 #define MAX_GRL_TABLES 7
00068
00072 struct SFBGRLMasterTable {
00073 const PacketHandler *(tables[MAX_GRL_TABLES]);
00074 u8 lengths[MAX_GRL_TABLES];
00075 u8 inUse;
00076
00077 SFBGRLMasterTable() ;
00078 u8 addTable(const PacketHandler * table, int length) ;
00079
00080 GRL find(PacketHandler ph) ;
00081
00082 PacketHandler find(GRL index) ;
00083 };
00084
00085 #define MAX_REACTORS 200
00086
00090 struct SFBDispatchEntry {
00091 SFBDispatchEntry() ;
00092 GRL grl;
00093 u8 type;
00094 u8 flags;
00095 };
00100 #define MAX_CASUAL_REFLEXES 10
00101
00102 #define TRIGGER_SET_TYPE s16
00103 #define MAX_NESTED_TRIGGERS (sizeof(TRIGGER_SET_TYPE)*8)
00104
00109 class SFBReactor {
00110
00111
00112 enum {
00113 END_PARTITION=BRAIN+1,
00114 PARTITION_COUNT
00115 };
00116 int nextPartition(int partition) ;
00117
00118 int partitionLength(const u8 partition) ;
00119 bool inPartition(const u8 partition, const u8 type);
00120 void openUp(const u8 inPartition, const u8 atPosition);
00121 void addToPartition(const u8 partition, const u8 type, GRL grl, u8 flags);
00122
00123 GRL addToCasual(PacketHandler ph) ;
00124
00125 GRL findOrAdd(PacketHandler ph) ;
00126
00127 public:
00128
00129 enum {
00130 TRIGGER_IF_BROKEN = 0x01,
00131 TRIGGER_EMPTY = 0x02,
00132 TRIGGER_SUPPRESSED = 0x04,
00133 TRIGGER_RESERVED3 = 0x08,
00134 TRIGGER_RESERVED4 = 0x10,
00135 TRIGGER_RESERVED5 = 0x20,
00136 TRIGGER_RESERVED6 = 0x40,
00137 TRIGGER_RESERVED7 = 0x80,
00139
00140
00141 TRIGGER_FIRST_PARTITION = 0x100,
00142 TRIGGER_NORTH = TRIGGER_FIRST_PARTITION<<NORTH,
00143 TRIGGER_SOUTH = TRIGGER_FIRST_PARTITION<<SOUTH,
00144 TRIGGER_EAST = TRIGGER_FIRST_PARTITION<<EAST,
00145 TRIGGER_WEST = TRIGGER_FIRST_PARTITION<<WEST,
00146 TRIGGER_SPINE = TRIGGER_FIRST_PARTITION<<SPINE,
00147 TRIGGER_MEMORY = TRIGGER_FIRST_PARTITION<<WMEM,
00148 TRIGGER_BRAIN = TRIGGER_FIRST_PARTITION<<BRAIN,
00150 TRIGGER_ALL_PARTITIONS =
00151 TRIGGER_NORTH|TRIGGER_SOUTH|TRIGGER_EAST|TRIGGER_WEST|TRIGGER_SPINE|TRIGGER_MEMORY|TRIGGER_BRAIN
00152 };
00153
00154 void reset() ;
00155
00156 int faceToFlag(const u32 face) ;
00157
00205 u8 reflexes(const PacketHandler * table, int length) ;
00206
00233 void reflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00234
00235 void reflexReflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00236
00237 void implReflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00238
00239 bool reflexExists(const char type, int partitions = TRIGGER_ALL_PARTITIONS) ;
00240
00241 void suppress(const char type, int partitions);
00242 void allow(const char type, int partitions);
00243
00245 void otherwise(PacketHandler pfunc, int partitions = TRIGGER_BRAIN, bool allowBroken = false) ;
00246
00247 void empty(PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool allowBroken = false) ;
00248
00249 void triggerUp() ;
00250
00258 bool inHandler() ;
00259
00260 u8 source() ;
00261
00262 u8 getFlags(const char type) ;
00263
00279 void trigger(u8 * packet, u8 face) ;
00280
00281 SFBReactor() ;
00282
00291 bool canTrigger() ;
00292
00293 private:
00294
00295 void setSpecial(const u8 offset, u8 flags, GRL grl, int partitions) ;
00296
00297 bool fireTrigger(u8 * packet, PacketHandler ph, u8 face) ;
00298
00299 int positionInPartition(const u8 partition, const u8 type) ;
00300
00301 GRL findInPartitions(const u8 type, int flags) ;
00302
00303
00304 SFBGRLMasterTable masterTable;
00305 SFBDispatchEntry entries[MAX_REACTORS];
00306 PacketHandler casualTable[MAX_CASUAL_REFLEXES];
00307 u16 partitionStarts[PARTITION_COUNT];
00308 u8 casualTableInUse;
00309
00310 u8 triggerSources[MAX_NESTED_TRIGGERS];
00311 TRIGGER_SET_TYPE triggerUpFlags;
00312 s8 topTrigger;
00313
00314 friend void reflex(const char type, PacketHandler ph, int flags);
00315 };
00316
00320 void reflex(const char type, PacketHandler ph, int flags = SFBReactor::TRIGGER_SPINE);
00321
00325 extern SFBReactor Body;
00326
00341 class SFBBrainReflex {
00342 public:
00343 void reflex(const char type, PacketHandler ph) {
00344 ::reflex(type, ph, SFBReactor::TRIGGER_BRAIN);
00345 }
00346 };
00350 extern SFBBrainReflex Brain;
00351
00366 class SFBSpineReflex {
00367 public:
00380 void reflex(const char type, PacketHandler ph) {
00381 ::reflex(type, ph, SFBReactor::TRIGGER_SPINE);
00382 }
00383 };
00387 extern SFBSpineReflex Spine;
00388
00389 #endif
00390