EVENT.CPP 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. //*****************************************************************************
  19. //
  20. // EVENT.CPP
  21. //
  22. // History:
  23. // 02/09/95 BH Started this module
  24. //
  25. //*****************************************************************************
  26. //
  27. // FUNCTIONALITY
  28. //
  29. // The basic function of this module is to monitor the movement of the display
  30. // area in order to determine whether any events associated with the
  31. // background map should be triggered. If so, the routines which the
  32. // aplication has associated with those events will be called.
  33. //
  34. // WHAT ARE EVENTS?
  35. //
  36. // Basically, events are attached to the background maps by the artists. Each
  37. // event consists of an x and y coordinate and a type, which is simply a
  38. // number from 0 to 254 (255 is an end-of-list marker). What each of
  39. // those types "means" is up to the application.
  40. //
  41. // There are two basic types of events: those that are "triggered" when they
  42. // get withing a certain distance of the display area, and those that are
  43. // used as markers, which the application will explicitly look for at some
  44. // point.
  45. //
  46. // For example, one event may be used to indicate the player's starting
  47. // position on the map. Another event may be used to indicate each of the
  48. // many places where a mutant penguin should appear. Another may be used
  49. // to trigger a special feature, such as turning on color cycling. Finally,
  50. // an event can be used to simply mark a position, such as where sea-level is
  51. // located.
  52. //
  53. //*****************************************************************************
  54. #include <stdafx.h>
  55. #include "System.h"
  56. #include "event.h"
  57. #include "univ.h"
  58. extern CUniverse g_GameUniverse;
  59. //*****************************************************************************
  60. // Event Handlers (function pointers)
  61. //*****************************************************************************
  62. static void* event_handlers[] =
  63. {
  64. event_undefined, // 0
  65. event_undefined, // 1
  66. event_undefined, // 2
  67. event_undefined, // 3
  68. event_undefined, // 4
  69. event_undefined, // 5
  70. event_undefined, // 6
  71. event_undefined, // 7
  72. event_undefined, // 8
  73. event_undefined, // 9
  74. event_undefined, // 10
  75. };
  76. //*****************************************************************************
  77. // Declair static members
  78. //*****************************************************************************
  79. EVENT* CEvent::m_pEventList;
  80. short CEvent::m_aIndexList[EVENT_MAX_COORD/EVENT_SPACING];
  81. CList CEvent::m_IgnoreList;
  82. //*****************************************************************************
  83. //
  84. // Constructor
  85. //
  86. //*****************************************************************************
  87. CEvent::CEvent()
  88. {
  89. }
  90. //*****************************************************************************
  91. //
  92. // Destructor
  93. //
  94. //*****************************************************************************
  95. CEvent::~CEvent()
  96. {
  97. }
  98. //*****************************************************************************
  99. //
  100. // Reset
  101. //
  102. // Description:
  103. // Reset everything in this module.
  104. //
  105. // The ignore list is cleared, and the default range for triggerable
  106. // event types is set.
  107. //
  108. // Input:
  109. // none
  110. //
  111. // Uses:
  112. // m_sEventTriggerMin/Max m_sEventConstMin/Max
  113. // m_IgnoreList
  114. //
  115. // Output:
  116. // none
  117. //
  118. // Return:
  119. // none
  120. //
  121. //*****************************************************************************
  122. void CEvent::Reset()
  123. {
  124. while (m_IgnoreList.Remove()); // Remove all items from the list
  125. m_sEventTriggerMin = 0; // Set default trigger ranges
  126. m_sEventConstMin = 0;
  127. m_sEventTriggerMax = 255;
  128. m_sEventConstMax = 255;
  129. m_sOrientation = HORIZONTAL; // Set default orientation
  130. }
  131. //*****************************************************************************
  132. //
  133. // SelectSet
  134. //
  135. // Description:
  136. // Selects a set of event data as the current set and builds an index
  137. // table which enables fast searching of events for the level.
  138. //
  139. // Input:
  140. //
  141. // Uses:
  142. //
  143. // Output:
  144. //
  145. // Return:
  146. //
  147. //*****************************************************************************
  148. short CEvent::SelectSet(short sEventSet)
  149. {
  150. // from the univ data - somewhere, get the event data
  151. // and create memory for the event data then point to it.
  152. // of if Univ creates the memory, just get the pointer.
  153. m_pEventData = g_GameUniverse.GetEvents();
  154. return SUCCESS;
  155. }
  156. //*****************************************************************************
  157. //
  158. // TriggerInit
  159. //
  160. // Description:
  161. // This routine triggers all events within the trigger area. This area
  162. // is based around the display area.
  163. //
  164. // Input:
  165. // sDispX = x coordinate of display area's upper left corner
  166. // sDispY = y coordinate of display area's upper left corner
  167. //
  168. // Uses:
  169. //
  170. // Output:
  171. // none
  172. //
  173. // Return:
  174. // none
  175. //
  176. //*****************************************************************************
  177. void CEvent::TriggerInit(short sDispX, short sDispY)
  178. {
  179. // Save the display position
  180. m_sDispOldX = sDispX;
  181. m_sDispOldY = sDispY;
  182. // Determine boundries of trigger area. Then scan the area and trigger
  183. // all events found within it.
  184. m_sScanYFrom = max(0, sDispY - EVENT_TRIGGER_TOP);
  185. m_sScanYTo = sDispY + GRIP_DISPLAY_H + EVENT_TRIGGER_BOTTOM;
  186. m_sScanXFrom = max(0, sDispX - EVENT_TRIGGER_LEFT);
  187. m_sScanXTo = sDispX + GRIP_DISPLAY_W + EVENT_TRIGGER_RIGHT;
  188. // Set to trigger from all directions
  189. m_sEventDir = EVENT_LEFT + EVENT_RIGHT + EVENT_UP + EVENT_DOWN;
  190. // Trigger all events in area
  191. Scan();
  192. }
  193. //*****************************************************************************
  194. //
  195. // Trigger
  196. //
  197. // Description:
  198. // Trigger any events which are "unconvered" by virtue of the display
  199. // area having moved.
  200. //
  201. // First, we check the orientation and split the process into
  202. // left/right movement and up/down movement. Next, we determine which
  203. // edge (left/right or top/bottom) is the leading edge. Then we
  204. // calculate the coordinates of the tirgger area by adding onto that
  205. // edge's coordinates the appropriate trigger offset. We do this for
  206. // both the previous and new position of the edge, and any event which
  207. // fall between those two values, inclusive, are triggered.
  208. //
  209. // Note that in order to avoid multiple-triggers of the same event,
  210. // we have to make sure that the new trigger area does not overlap the
  211. // previous trigger area. For example, when moving right, we don't
  212. // really want to go from the old right edge to the new right edge,
  213. // because if we do that same thing each time, then we'll be checking
  214. // a particular coordinate again on the next move. The solution for going
  215. // right is to go from the old right edge PLUS 1 to the new right edge.
  216. // This avoids the overlap. A similar thing is done for each of the edges.
  217. //
  218. // This routine also calls DecrementTimers to go through the ignore list
  219. //
  220. // Input:
  221. // sDispX = x coordinate of the display area's upper left corner
  222. // sDispY = y coordinate of the display area's upper left corner
  223. //
  224. // Uses:
  225. //
  226. // Output:
  227. // none
  228. //
  229. // Return:
  230. //
  231. //*****************************************************************************
  232. short CEvent::Trigger(short sDispX, short sDispY)
  233. {
  234. // Decrement timers no matter what happens
  235. DecrementTimers();
  236. // Check for direction of movement
  237. enum Direction
  238. {
  239. UP, DOWN, LEFT, RIGHT, DOWN_RIGHT, DOWN_LEFT, UP_RIGHT, UP_LEFT, NONE
  240. };
  241. Direction eDir;
  242. if (sDispX != m_sDispOldX && sDispY != m_sDispOldY)
  243. { //diagonal movement
  244. if (sDispY > m_sDispOldY)
  245. { // down
  246. if (sDispX > m_sDispOldX)
  247. eDir = DOWN_RIGHT;
  248. else
  249. eDir = DOWN_LEFT;
  250. }
  251. else
  252. { // up
  253. if (sDispX > m_sDispOldX)
  254. eDir = UP_RIGHT;
  255. else
  256. eDir = UP_LEFT;
  257. }
  258. }
  259. else
  260. { // one direction only
  261. if (sDispY != m_sDispOldY)
  262. { // up/down motion
  263. if (sDispY > m_sDispOldY)
  264. eDir = DOWN;
  265. else
  266. eDir = UP;
  267. }
  268. else
  269. { // left/right motion
  270. if (sDispX > m_sDispOldX)
  271. eDir = RIGHT;
  272. else
  273. eDir = LEFT;
  274. }
  275. }
  276. switch (eDir)
  277. {
  278. case UP:
  279. m_sEventDir = EVENT_UP;
  280. From_Top(sDispY);
  281. To_Top(m_sDispOldY);
  282. From_Left(m_sDispOldX);
  283. To_Right(m_sDispOldX);
  284. Scan();
  285. break;
  286. case DOWN:
  287. m_sEventDir = EVENT_DOWN;
  288. From_Bottom(m_sDispOldY);
  289. To_Bottom(sDispY);
  290. From_Left(m_sDispOldX);
  291. To_Right(m_sDispOldX);
  292. Scan();
  293. break;
  294. case RIGHT:
  295. m_sEventDir = EVENT_RIGHT;
  296. From_Right(m_sDispOldX);
  297. To_Right(sDispX);
  298. From_Top(m_sDispOldY);
  299. To_Bottom(m_sDispOldY);
  300. Scan();
  301. break;
  302. case LEFT:
  303. m_sEventDir = EVENT_LEFT;
  304. From_Left(sDispX);
  305. To_Left(m_sDispOldX);
  306. From_Top(m_sDispOldY);
  307. To_Bottom(m_sDispOldY);
  308. Scan();
  309. break;
  310. case DOWN_RIGHT:
  311. m_sEventDir = EVENT_DOWN + EVENT_RIGHT;
  312. // Area 1
  313. From_Bottom(m_sDispOldY);
  314. To_Bottom(m_sDispOldY);
  315. From_Left(sDispX);
  316. To_Right(sDispX);
  317. Scan();
  318. // Area 2
  319. From_Right(m_sDispOldX);
  320. To_Right(m_sDispOldX);
  321. From_Top(sDispY);
  322. To_Bottom(m_sDispOldY);
  323. Scan();
  324. break;
  325. case DOWN_LEFT:
  326. m_sEventDir = EVENT_DOWN + EVENT_LEFT;
  327. // Area 1
  328. From_Bottom(m_sDispOldY);
  329. To_Bottom(sDispY);
  330. From_Left(sDispX);
  331. To_Right(sDispX);
  332. Scan();
  333. // Area 2
  334. From_Left(sDispX);
  335. To_Left(m_sDispOldX);
  336. From_Top(sDispY);
  337. To_Bottom(m_sDispOldY);
  338. Scan();
  339. break;
  340. case UP_RIGHT:
  341. m_sEventDir = EVENT_UP + EVENT_RIGHT;
  342. // Area 1
  343. From_Top(sDispY);
  344. To_Top(m_sDispOldY);
  345. From_Left(sDispX);
  346. To_Right(sDispX);
  347. Scan();
  348. // Area 2
  349. From_Right(m_sDispOldX);
  350. To_Right(sDispX);
  351. From_Top(m_sDispOldY);
  352. To_Bottom(sDispY);
  353. Scan();
  354. break;
  355. case UP_LEFT:
  356. m_sEventDir = EVENT_UP + EVENT_LEFT;
  357. // Area 1
  358. From_Top(sDispY);
  359. To_Top(m_sDispOldY);
  360. From_Left(sDispX);
  361. To_Right(sDispX);
  362. Scan();
  363. // Area 2
  364. From_Left(sDispX);
  365. To_Left(m_sDispOldX);
  366. From_Top(m_sDispOldY);
  367. To_Bottom(sDispY);
  368. Scan();
  369. break;
  370. case NONE:
  371. break;
  372. }
  373. // Save display position for next time
  374. m_sDispOldX = sDispX;
  375. m_sDispOldY = sDispY;
  376. return SUCCESS; //or perhaps some other value
  377. }
  378. //*****************************************************************************
  379. //
  380. // Ignore
  381. //
  382. // Description:
  383. // Add the specified id into the "ignore" list. As long as the id
  384. // is left in the ignore list, the event associated with it will not
  385. // be triggered.
  386. //
  387. // A "handle" is returned by this routine, and the application must use
  388. // this "handle" when calling Unignore().
  389. //
  390. // As a special feature, an event id of $ffff will be ignored (meaning
  391. // it won't be added to the list). This may be helpful in those
  392. // situations where the application is already calling this routine but
  393. // sometimes doesn't ahve a valid event id to send to it. It can
  394. // basically create a "dummy" event id by using $ffff .
  395. //
  396. // NOTE: This routine does not check to see if the id being added to
  397. // this list is already on the list. Therefore, the application can
  398. // add an id more than once if it so desires. Of course, each of those
  399. // id's would need to be removed from the list in order for the event
  400. // to be triggered again.
  401. //
  402. // Input:
  403. // sEventID = unique id (as passed to event handler by this module, or
  404. // $ffff if inserting a "dummy" value)
  405. // sEventTimer = MUST BE $FFFF OR $FFFE (EVENT_PERMANENT OR EVENT_TEMPORARY)
  406. //
  407. // Uses:
  408. //
  409. // Output:
  410. //
  411. // Return:
  412. // CEvent* pointer to the event - "handle"
  413. //
  414. //*****************************************************************************
  415. void CEvent::Ignore(EVENT* pEvent)
  416. {
  417. m_IgnoreList.Add((LISTNODE) pEvent);
  418. }
  419. //*****************************************************************************
  420. //
  421. // Unignore
  422. //
  423. // Description:
  424. //
  425. // Input:
  426. //
  427. // Uses:
  428. //
  429. // Output:
  430. //
  431. // Return:
  432. // none
  433. //
  434. //*****************************************************************************
  435. void CEvent::Unignore(EVENT* pEvent)
  436. {
  437. m_IgnoreList.Remove((LISTNODE) pEvent);
  438. }
  439. //*****************************************************************************
  440. //
  441. // Search
  442. //
  443. // Description:
  444. // Search for a particular event type in the current set's event list.
  445. // If found, all of the relevant data about that event is returned
  446. //
  447. // Input:
  448. // sEventType = type of event to search for.
  449. //
  450. // Uses:
  451. // m_pEventData array
  452. //
  453. // Output:
  454. // none
  455. //
  456. // Return:
  457. // EVENT* pEvent which serves as its ID. In addition the structure
  458. // contains x, y, type, status, and timer.
  459. //
  460. //*****************************************************************************
  461. EVENT* CEvent::Search(short sEventNum)
  462. {
  463. short s = 0;
  464. while (m_pEventData[s].sType != sEventNum && m_pEventData[s].sType >= 0)
  465. s++;
  466. if (m_pEventData[s].sType < 0)
  467. return NULL;
  468. else
  469. return &(m_pEventData[s]);
  470. }
  471. //*****************************************************************************
  472. //
  473. // SearchNext
  474. //
  475. // Description:
  476. // Similar to Search, but finds the next event of the same type given
  477. // a pointer to the event. For example, if you wanted to find all of
  478. // the events of type $02, you would call Search(2) to get a pointer to
  479. // the first event of that type in the level. If you wanted to find the
  480. // next occurance of event type $02, you would call SearchNext(pEvent)
  481. // where pEvent is the pointer to the event type $02 that was returned from
  482. // the Search() function.
  483. //
  484. // Input:
  485. // pEvent = pointer to
  486. //
  487. // Uses:
  488. // m_pEventData array
  489. //
  490. // Output:
  491. // none
  492. //
  493. // Return:
  494. // EVENT* pEvent
  495. //
  496. //*****************************************************************************
  497. EVENT* CEvent::SearchNext(EVENT* pEvent)
  498. {
  499. short s = 0;
  500. while (m_pEventData[s].sType != pEvent->sType &&
  501. m_pEventData[s].sType >= 0 &&
  502. &(m_pEventData[s]) == pEvent
  503. )
  504. s++;
  505. if (m_pEventData[s].sType < 0)
  506. return NULL;
  507. else
  508. return &(m_pEventData[s]);
  509. }
  510. //*****************************************************************************
  511. //
  512. // CreateIndexes
  513. //
  514. // Description:
  515. // Create table of index values for current set of event data.
  516. //
  517. // The index table contains indexes into the event data. It's purpose
  518. // is to speed up searches through the event data by giving us a
  519. // starting position within the event data which is near (or at) the
  520. // event data we are looking for.
  521. //
  522. // The tables are indexed using the coordinate divided by 16 and return
  523. // the index of the first event whose coordinate is equal to or greater
  524. // than the coordinate AND'ed with $fff0.
  525. //
  526. // Algorithm
  527. //
  528. // coord = 0;
  529. // event = 0;
  530. // index = 0;
  531. //
  532. // do
  533. // {
  534. // while (array[event] < coord)
  535. // event = event + 1;
  536. // event_index[index] = event;
  537. // index = index + 1;
  538. //
  539. // coord = coord + EVENT_SPACING
  540. // }
  541. // while (coord < EVENT_INDEX_MAX);
  542. //
  543. // Input:
  544. // sOrientation = orientation of section, vertical or horizontal
  545. //
  546. // Uses:
  547. // pEventData
  548. //
  549. // Output:
  550. // m_pIndexList;
  551. //
  552. // Return:
  553. // none
  554. //
  555. //*****************************************************************************
  556. void CEvent::CreateIndexes(short sOrientation)
  557. {
  558. short sCoord = 0;
  559. short sEvent = 0;
  560. short sIndex = 0;
  561. if (sOrientation == HORIZONTAL)
  562. {
  563. do
  564. {
  565. while (m_pEventData[sEvent].sX < sCoord)
  566. sEvent++;
  567. m_aIndexList[sIndex++] = sEvent;
  568. sCoord += EVENT_SPACING;
  569. } while (sCoord < EVENT_INDEX_MAX);
  570. }
  571. else // VERTICAL
  572. {
  573. do
  574. {
  575. while (m_pEventData[sEvent].sY < sCoord)
  576. sEvent++;
  577. m_aIndexList[sIndex++] = sEvent;
  578. sCoord += EVENT_SPACING;
  579. } while (sCoord < EVENT_INDEX_MAX);
  580. }
  581. }
  582. //*****************************************************************************
  583. //
  584. // Scan
  585. //
  586. // Description:
  587. // Scan for events in the specified range.
  588. //
  589. // This routine doesn't know whether it is searching for x or y
  590. // coordinates. The m_sEventScanFrom and m_sEventScanTo variables are
  591. // simply set to the start and end of the range to scan through.
  592. //
  593. // We need to find all events which are defined by the 4 corners,
  594. // m_sScanXFrom, m_sScanXTo, m_sScanYFrom, m_sScanYTo inclusive.
  595. //
  596. // To find out where in the list to start, we look into a table of indexes
  597. // which has been conveniently constructed ahead of time. We index this
  598. // table with m_sScanFrom divided by 16, and the result is the index to the
  599. // first event whose coordinate is equal to or greater than m_sEventScanFrom
  600. // AND'ed with $fff0.
  601. //
  602. // Starting with that index, we go through the events looking for coordinates
  603. // that are between m_sScanFrom and m_sScanTo, inclusive. Note that
  604. // we don't have to do a separate check for the end of the event array because
  605. // the end is marked by an $ffff, which will always be greater than the range
  606. // we're looking for, and will thus end the scan.
  607. //
  608. // For every event in the range, we call its event handler (see CallHandler
  609. // for more information.)
  610. //
  611. // Input:
  612. // sOrientation = HORIZONTAL or VERTICAL
  613. //
  614. // Uses:
  615. // m_sScanXFrom
  616. // m_sScanXTo
  617. // m_sScanYFrom
  618. // m_sScanYTo
  619. // m_pEventData
  620. //
  621. // Output:
  622. //
  623. // Return:
  624. //
  625. //*****************************************************************************
  626. short CEvent::Scan()
  627. {
  628. short s;
  629. short sEventIndex;
  630. if (m_sOrientation == VERTICAL)
  631. { // Vertical - aIndexList is sorted on Y
  632. s = m_sScanYFrom / EVENT_SPACING;
  633. sEventIndex = m_aIndexList[s];
  634. while (m_pEventData[sEventIndex].sY < m_sScanYTo)
  635. {
  636. if (m_pEventData[sEventIndex].sY > m_sScanYFrom)
  637. {
  638. if (m_pEventData[sEventIndex].sX > m_sScanXFrom &&
  639. m_pEventData[sEventIndex].sX <= m_sScanXTo)
  640. CallHandler(sEventIndex); // Trigger event
  641. }
  642. sEventIndex++;
  643. }
  644. }
  645. else
  646. { // Horizontal - aIndexList is sorted on X
  647. s = m_sScanXFrom / EVENT_SPACING;
  648. sEventIndex = m_aIndexList[s];
  649. while (m_pEventData[sEventIndex].sX < m_sScanXTo)
  650. {
  651. if (m_pEventData[sEventIndex].sX > m_sScanXFrom)
  652. {
  653. if (m_pEventData[sEventIndex].sY > m_sScanYFrom &&
  654. m_pEventData[sEventIndex].sY <= m_sScanYTo)
  655. CallHandler(sEventIndex); // Trigger event
  656. }
  657. sEventIndex++;
  658. }
  659. }
  660. return SUCCESS; //or perhaps some other value
  661. }
  662. //*****************************************************************************
  663. //
  664. // CallHandler
  665. //
  666. // Description:
  667. // Call an event's handler, but only if:
  668. // 1. The event type is within the application-definable
  669. // "triggerable range"
  670. // 2. The event's unique id is not on the "ignore" list
  671. // 3. The display has moved in a direction which agrees with that
  672. // defined by the event status.
  673. //
  674. // We are passed only the index into the event data. We must first
  675. // get all of the events data and put it into the member variables
  676. // which are then used by the event handler. Along the way, we
  677. // generate the event's unique id.
  678. //
  679. // We check the unique id against the list of id's to be ignored, and
  680. // if we find the id, then we ignore it.
  681. //
  682. // If we don't find the id, then we call the event's handler by getting
  683. // its address from the list in which the application has inserted all
  684. // of the event handler addresses. We do a simulated indirect call to
  685. // the routine, and it returns to us here when it's done.
  686. //
  687. // Input:
  688. // sEventIndex = index into event array
  689. //
  690. // Uses:
  691. //
  692. // Output:
  693. //
  694. // Return:
  695. //
  696. //*****************************************************************************
  697. short CEvent::CallHandler(short sEventIndex)
  698. {
  699. //-----------------------------------------------------------------------------
  700. // Get event's data
  701. //
  702. // Check if event's type is within "triggerable" range. The minimum is
  703. // the lowset triggerable event type and the maximum is the highest event
  704. // type PLUS 1!
  705. //-----------------------------------------------------------------------------
  706. if ((m_pEventData[sEventIndex].sType < m_sEventConstMin ||
  707. m_pEventData[sEventIndex].sType > m_sEventConstMax) &&
  708. (m_pEventData[sEventIndex].sType < m_sEventTriggerMin ||
  709. m_pEventData[sEventIndex].sType > m_sEventTriggerMax))
  710. return EVENT_NOT_IN_RANGE;
  711. //-----------------------------------------------------------------------------
  712. // Check if event's id appears in ignore list. If it does, check the timer.
  713. // If the timer is negative, the event is still active, so ignore it.
  714. // If the timer is zero, unignore the event and retrigger it.
  715. // If the timer is positive, ignore the event. (Event_Trigger does the
  716. // decrementing).
  717. //-----------------------------------------------------------------------------
  718. EVENT* pEvent = (EVENT*) m_IgnoreList.GetHead();
  719. BOOL bFound = FALSE;
  720. while (pEvent != NULL && !bFound)
  721. {
  722. if (pEvent == &(m_pEventData[sEventIndex]))
  723. bFound = TRUE;
  724. else
  725. pEvent = (EVENT*) m_IgnoreList.GetNext();
  726. }
  727. if (bFound && pEvent->sIgnoreTimer != 0)
  728. return EVENT_ON_IGNORE_LIST;
  729. //-----------------------------------------------------------------------------
  730. // Check whether the display has moved in a direction which agrees with that
  731. // defined by the event status.
  732. //
  733. // NOTE: As long as the direction of scrolling overlaps with the direction
  734. // defined by m_sEventDir, the event should be triggered. For example, if
  735. // m_sEventDir has EVENT_RIGHT bit set and the display has moved diagonally
  736. // right and up, the event should be triggered.
  737. //
  738. // If there are no directional flags set for this event then assume it can
  739. // be triggered by any direction. If directional flags are set, then see if
  740. // any of those directions match the scroll direction. If either of these
  741. // is true, then trigger this event.
  742. //
  743. // The event handler function pointers are stored in the table event_handler
  744. // at the top of this file.
  745. //------------------------------------------------------------------------------
  746. // if ((pEvent->sFlags & m_sEventDir) || !(pEvent->sFlags & EVENT_DIR_MASK))
  747. // (event_handlers[pEvent->sType])();
  748. return SUCCESS;
  749. }
  750. //*****************************************************************************
  751. //
  752. // DecrementTimers
  753. //
  754. // Description:
  755. // Decrement all timers in the Ignore list. The "real" timers are those
  756. // with positive values. -1 (EVENT_PERMANENT) or -2 (EVENT_TEMPORARY)
  757. // are flags only.
  758. //
  759. // Input:
  760. // none
  761. //
  762. // Uses:
  763. // m_IgnoreList and the list of EVENTS that it contains as nodes
  764. // Decrements m_IgnoreList->pEvent->sTimer
  765. //
  766. // Output:
  767. // none
  768. //
  769. // Return:
  770. // none
  771. //
  772. //*****************************************************************************
  773. void CEvent::DecrementTimers()
  774. {
  775. EVENT* pEvent = (EVENT*) m_IgnoreList.GetHead();
  776. while (pEvent)
  777. {
  778. if (pEvent->sTimer > 0)
  779. pEvent->sTimer++;
  780. pEvent = (EVENT*) m_IgnoreList.GetNext();
  781. }
  782. }
  783. //*****************************************************************************
  784. //
  785. // event_undefined
  786. //
  787. // Description:
  788. // Place holder function that is placed in the event handler table for
  789. // event numbers which have no assigned function.
  790. //
  791. //*****************************************************************************
  792. void event_undefined()
  793. {
  794. }
  795. //*****************************************************************************
  796. // EOF
  797. //*****************************************************************************