123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- /* GCSx
- ** EVENT.CPP
- **
- ** Our custom event queue to allow preempting SDL's event queue
- */
- /*****************************************************************************
- ** Copyright (C) 2003-2006 Janson
- **
- ** This program is free software; you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation; either version 2 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program; if not, write to the Free Software
- ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
- #include "all.h"
- // We need enough events to handle changing every layer of a scene
- // at once, with room to spare; game event queue doesn't need as
- // much room but we keep it safe
- #define MAX_EVENTS 128
- SDL_Event eventQueue[MAX_EVENTS];
- int eventHead = 0;
- int eventTail = 0;
- SDL_Event gameEventQueue[MAX_EVENTS];
- int gameEventHead = 0;
- int gameEventTail = 0;
- void insertEvent(const SDL_Event* customEvent) { start_func
- int tail = (eventTail + 1) % MAX_EVENTS;
- // If we're full, drop the event
- // This should never occur in normal usage, and
- // even if it does should be harmless as these are
- // only CLOSE, FOCUS, and OBJCHANGE events
- if (tail == eventHead) {
- /* SDL_OBJECTCHANGE events no longer use the queue
- **
- if (customEvent->type == SDL_OBJECTCHANGE) {
- delete (ObjChange*)customEvent->user.data1;
- }
- **
- */
- return;
- }
-
- eventQueue[eventTail] = *customEvent;
- eventTail = tail;
- }
- void preemptEvent(const SDL_Event* customEvent) { start_func
- int head = (eventHead + MAX_EVENTS - 1) % MAX_EVENTS;
- // If we're full, drop the event
- // This should never occur in normal usage, and
- // even if it does should be harmless as these are
- // only CLOSE, FOCUS, and OBJCHANGE events
- if (head == eventTail) {
- /* SDL_OBJECTCHANGE events no longer use the queue
- **
- if (customEvent->type == SDL_OBJECTCHANGE) {
- delete (ObjChange*)customEvent->user.data1;
- }
- **
- */
- return;
- }
-
- eventHead = head;
- eventQueue[eventHead] = *customEvent;
- }
- /* SDL_OBJECTCHANGE events no longer use the queue
- **
- void combinatoryEvent(const SDL_Event* customEvent) { start_func
- // Right now, we only know how to combine SDL_OBJCHANGE events
- assert(customEvent->type == SDL_OBJECTCHANGE);
- // Scan all existing events
- for (int pos = eventHead; pos != eventTail; pos = (pos + 1) % MAX_EVENTS) {
- // Matching type and code
- if ((eventQueue[pos].type == customEvent->type) &&
- (eventQueue[pos].user.code == customEvent->user.code)) {
- // We only support one type of combination right now
- if ((customEvent->user.code & (OBJMOD_TILE | OBJMOD_COLL)) &&
- (customEvent->user.code & OBJ_TILESET)) {
- // (for now, these must be SDL_OBJCHANGE events)
- const ObjChange* obj1 = (ObjChange*)customEvent->user.data1;
- ObjChange* obj2 = (ObjChange*)eventQueue[pos].user.data1;
-
- // Replace old event with min/max of combined events
- if (obj1->info1 < obj2->info1) obj2->info1 = obj1->info1;
- if (obj1->info2 > obj2->info2) obj2->info2 = obj1->info2;
-
- // Delete old event details
- delete obj1;
- return;
- }
- }
- }
-
- // No combination made
- preemptEvent(customEvent);
- }
- **
- */
- int eventsWaiting() { start_func
- if (eventTail == eventHead) return 0;
- return 1;
- }
- int grabEvent(SDL_Event* store) { start_func
- if (eventTail == eventHead) {
- if (SDL_PollEvent(store)) return 1;
- return 0;
- }
- *store = eventQueue[eventHead];
- eventHead = (eventHead + 1) % MAX_EVENTS;
- return 1;
- }
- void cleanEvents(const void* window) { start_func
- for (int pos = eventHead; pos != eventTail; pos = (pos + 1) % MAX_EVENTS) {
- if (eventQueue[pos].user.data1 == window) eventQueue[pos].type = SDL_NOEVENT;
- }
- }
- void clearEvents() { start_func
- /* SDL_OBJECTCHANGE events no longer use the queue
- **
- // Clear our events only
- while (eventTail != eventHead) {
- if (eventQueue[eventHead].type == SDL_OBJECTCHANGE) {
- delete (ObjChange*)eventQueue[eventHead].user.data1;
- }
- eventHead = (eventHead + 1) % MAX_EVENTS;
- }
- **
- */
- eventTail = eventHead;
- gameEventTail = gameEventHead;
- }
- void storeEventGame(const SDL_Event* event) { start_func
- int tail = (gameEventTail + 1) % MAX_EVENTS;
- // If we're full, drop the event
- if (tail == gameEventHead) return;
- gameEventQueue[gameEventTail] = *event;
- gameEventTail = tail;
- }
- int grabEventGame(SDL_Event* store) { start_func
- if (gameEventTail == gameEventHead) return 0;
- *store = gameEventQueue[gameEventHead];
- gameEventHead = (gameEventHead + 1) % MAX_EVENTS;
- return 1;
- }
|