00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00020
00021
00022
00023 #include "swf.h"
00024
00025 #ifdef RCSID
00026 static char *rcsid = "$Id: button.cc,v 1.1.1.1 2002/01/25 22:14:58 kergoth Exp $";
00027 #endif
00028
00029 #define PRINT 0
00030
00031
00032
00033 Button::Button(long id, int level) : Character(ButtonType, id)
00034 {
00035 defLevel = level;
00036 actionRecords = 0;
00037 buttonRecords = 0;
00038 conditionList = 0;
00039 reset();
00040 isMenu = 0;
00041 sound[0] = sound[1] = sound[2] = sound[3] = 0;
00042 }
00043
00044
00045
00046 Button::~Button()
00047 {
00048 if (actionRecords) {
00049 ActionRecord *ar,*del;
00050 for(ar = actionRecords; ar;) {
00051 del = ar;
00052 ar = ar->next;
00053 delete del;
00054 }
00055 }
00056 if (buttonRecords) {
00057 ButtonRecord *br,*del;
00058 for(br = buttonRecords; br;) {
00059 del = br;
00060 br = br->next;
00061 if (del->cxform)
00062 delete del->cxform;
00063 delete del;
00064 }
00065 }
00066 if (conditionList) {
00067 Condition *cond,*del;
00068 for(cond = conditionList; cond;) {
00069 ActionRecord *ar,*d;
00070
00071 for(ar = cond->actions; ar;) {
00072 d = ar;
00073 ar = ar->next;
00074 delete d;
00075 }
00076
00077 del = cond;
00078 cond = cond->next;
00079 delete del;
00080 }
00081 }
00082 }
00083
00084 ButtonRecord *
00085 Button::getButtonRecords()
00086 {
00087 return buttonRecords;
00088 }
00089
00090 ActionRecord *
00091 Button::getActionRecords()
00092 {
00093 return actionRecords;
00094 }
00095
00096 Sound **
00097 Button::getSounds()
00098 {
00099 return sound;
00100 }
00101
00102 Condition *
00103 Button::getConditionList()
00104 {
00105 return conditionList;
00106 }
00107
00108 void
00109 Button::setButtonSound(Sound *s, int state)
00110 {
00111 if (state >=0 && state < 4) {
00112 sound[state] = s;
00113 }
00114 }
00115
00116 void
00117 Button::setButtonMenu(int menu)
00118 {
00119 isMenu = menu;
00120 }
00121
00122 void
00123 Button::addButtonRecord( ButtonRecord *br )
00124 {
00125 #if 0
00126
00127 ButtonRecord **l;
00128
00129
00130 l=&buttonRecords;
00131 while (*l != NULL && (*l)->layer < br->layer) l = &(*l)->next;
00132 br->next = *l;
00133 *l = br;
00134 #else
00135 br->next = 0;
00136
00137 if (buttonRecords == 0) {
00138 buttonRecords = br;
00139 } else {
00140 ButtonRecord *current;
00141
00142 for(current = buttonRecords; current->next; current = current->next);
00143
00144 current->next = br;
00145 }
00146 #endif
00147 }
00148
00149 void
00150 Button::addCondition( long transition )
00151 {
00152 Condition *condition;
00153
00154 condition = new Condition;
00155 if (condition == NULL) return;
00156
00157 condition->transition = transition;
00158 condition->next = conditionList;
00159
00160
00161 condition->actions = actionRecords;
00162 actionRecords = 0;
00163
00164 conditionList = condition;
00165 }
00166
00167 void
00168 Button::addActionRecord( ActionRecord *ar )
00169 {
00170 ar->next = 0;
00171
00172 if (actionRecords == 0) {
00173 actionRecords = ar;
00174 } else {
00175 ActionRecord *current;
00176
00177 for(current = actionRecords; current->next; current = current->next);
00178
00179 current->next = ar;
00180 }
00181 }
00182
00183 void
00184 Button::getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func)
00185 {
00186 ButtonRecord *br;
00187
00188 for (br = buttonRecords; br; br = br->next)
00189 {
00190 if ((br->state & stateHitTest) && br->character ) {
00191 Matrix mat;
00192
00193 mat = (*matrix) * br->buttonMatrix;
00194 br->character->getRegion(gd, &mat, id, scan_line_func);
00195 }
00196 }
00197 }
00198
00199 int
00200 Button::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ButtonState renderState)
00201 {
00202 ButtonRecord *br;
00203 int sprite = 0;
00204 Cxform *cxf = 0;
00205
00206 #if PRINT==2
00207 printf("Rendering Button %d for State(s) ", getTagId());
00208 #endif
00209 for (br = buttonRecords; br; br = br->next)
00210 {
00211 if ((br->state & renderState) && br->character != NULL) {
00212 Matrix mat;
00213
00214 #if PRINT==2
00215 printf("%d ", br->state);
00216 #endif
00217 mat = (*matrix) * br->buttonMatrix;
00218
00219 if (cxform) {
00220 cxf = cxform;
00221 } else if (br->cxform) {
00222 cxf = br->cxform;
00223 }
00224
00225 if (br->character->execute(gd, &mat, cxf)) {
00226 sprite = 1;
00227 }
00228 }
00229 }
00230 #if PRINT==2
00231 printf("\n");
00232 #endif
00233 return sprite;
00234 }
00235
00236 ActionRecord *
00237 Button::getActionFromTransition(ButtonState cur, ButtonState old)
00238 {
00239 Condition *cond;
00240 long mask;
00241
00242 if (old == cur) return NULL;
00243
00244
00245 mask = 0;
00246 if (old == stateUp && cur == stateOver)
00247 mask |= 0x001;
00248 else if (old == stateOver && cur == stateUp)
00249 mask |= 0x002;
00250 else if (old == stateOver && cur == stateDown)
00251 mask |= 0x004;
00252 else if (old == stateDown && cur == stateOver)
00253 mask |= 0x008;
00254
00255 if (!isMenu) {
00256
00257 if (old == stateDown && cur == stateUp)
00258 mask = 0x010;
00259 else if (old == stateUp && cur == stateDown)
00260 mask = 0x020;
00261
00262 } else {
00263
00264 if (old == stateUp && cur == stateDown)
00265 mask = 0x080;
00266 else if (old == stateDown && cur == stateUp)
00267 mask = 0x100;
00268 }
00269
00270 for (cond = conditionList; cond; cond = cond->next) {
00271 if (cond->transition & mask) {
00272 return cond->actions;
00273 }
00274 }
00275 return 0;
00276 }
00277
00278 void
00279 Button::getBoundingBox(Rect *bbox, DisplayListEntry *e)
00280 {
00281 ButtonRecord *br;
00282
00283 bbox->reset();
00284 for (br = buttonRecords; br; br = br->next)
00285 {
00286 if (br->state & e->renderState) {
00287 if (br->character) {
00288 Rect bb;
00289
00290 bb.reset();
00291 br->character->getBoundingBox(&bb,e);
00292 transformBoundingBox(bbox, &br->buttonMatrix, &bb, 0);
00293 }
00294 }
00295 }
00296 }
00297
00298
00299
00300 Character *
00301 Button::getRenderCharacter(ButtonState state)
00302 {
00303 ButtonRecord *br;
00304
00305 for (br = buttonRecords; br; br = br->next)
00306 {
00307 if (br->state & state) {
00308 return br->character;
00309 }
00310 }
00311 return 0;
00312 }
00313
00314 void
00315 Button::updateButtonState(DisplayListEntry *e)
00316 {
00317 ButtonRecord *br;
00318
00319 e->buttonCharacter = 0;
00320 for (br = buttonRecords; br; br = br->next)
00321 {
00322 if (br->state & e->renderState) {
00323 e->buttonCharacter = br->character;
00324 e->buttonMatrix = br->buttonMatrix;
00325 return;
00326 }
00327 }
00328 }