diff --git a/src/d_main.cpp b/src/d_main.cpp index ba1de1bd22..a0456d6a06 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -287,6 +287,9 @@ void D_ProcessEvents (void) continue; // console ate the event if (M_Responder (ev)) continue; // menu ate the event + // check events + if (E_Responder(ev)) // [ZZ] ZScript ate the event + continue; G_Responder (ev); } } diff --git a/src/events.cpp b/src/events.cpp index 141db3fdff..f04fdaa004 100755 --- a/src/events.cpp +++ b/src/events.cpp @@ -15,13 +15,15 @@ bool E_RegisterHandler(DStaticEventHandler* handler) return false; if (E_CheckHandler(handler)) return false; + + handler->OnRegister(); // link into normal list // update: link at specific position based on order. DStaticEventHandler* before = nullptr; for (DStaticEventHandler* existinghandler = E_FirstEventHandler; existinghandler; existinghandler = existinghandler->next) { - if (existinghandler->GetOrder() > handler->GetOrder()) + if (existinghandler->Order > handler->Order) { before = existinghandler; break; @@ -71,6 +73,9 @@ bool E_UnregisterHandler(DStaticEventHandler* handler) return false; if (!E_CheckHandler(handler)) return false; + + handler->OnUnregister(); + // link out of normal list if (handler->prev) handler->prev->next = handler->next; @@ -197,8 +202,6 @@ void E_InitStaticHandlers(bool map) if (map) // don't initialize map handlers if restoring from savegame. { - Printf("Initializing map handlers\n"); - // delete old handlers if any. for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next) { @@ -213,7 +216,6 @@ void E_InitStaticHandlers(bool map) PClass* type = PClass::FindClass(typestring); if (!type || E_IsStaticType(type)) // don't init the really global stuff here. continue; - Printf("global -> %s\n", typestring.GetChars()); E_InitStaticHandler(type, typestring, false); } @@ -221,7 +223,6 @@ void E_InitStaticHandlers(bool map) { FString typestring = level.info->EventHandlers[i]; PClass* type = PClass::FindClass(typestring); - Printf("level -> %s\n", typestring.GetChars()); E_InitStaticHandler(type, typestring, true); } } @@ -370,6 +371,45 @@ void E_PlayerDisconnected(int num) handler->PlayerDisconnected(num); } +bool E_Responder(event_t* ev) +{ + if (ev->type == EV_GUI_Event) + { + // iterate handlers back to front by order, and give them this event. + for (DStaticEventHandler* handler = E_LastEventHandler; handler; handler = handler->prev) + { + if (handler->IsUiProcessor && handler->UiProcess(ev)) + return true; // event was processed + } + } + else + { + // not sure if we want to handle device changes, but whatevs. + for (DStaticEventHandler* handler = E_LastEventHandler; handler; handler = handler->prev) + { + if (!handler->IsUiProcessor && handler->InputProcess(ev)) + return true; // event was processed + } + } + + return false; +} + +bool E_CheckUiProcessors() +{ + for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next) + { + if (handler->IsUiProcessor) + { + //Printf("E_CheckUiProcessors = true\n"); + return true; + } + } + + //Printf("E_CheckUiProcessors = false\n"); + return false; +} + // normal event loopers (non-special, argument-less) DEFINE_EVENT_LOOPER(RenderFrame) DEFINE_EVENT_LOOPER(WorldLightning) @@ -382,6 +422,11 @@ IMPLEMENT_CLASS(DBaseEvent, false, false) IMPLEMENT_CLASS(DRenderEvent, false, false) IMPLEMENT_CLASS(DWorldEvent, false, false) IMPLEMENT_CLASS(DPlayerEvent, false, false) +IMPLEMENT_CLASS(DUiEvent, false, false) +IMPLEMENT_CLASS(DInputEvent, false, false) + +DEFINE_FIELD_X(StaticEventHandler, DStaticEventHandler, Order); +DEFINE_FIELD_X(StaticEventHandler, DStaticEventHandler, IsUiProcessor); DEFINE_FIELD_X(RenderEvent, DRenderEvent, ViewPos); DEFINE_FIELD_X(RenderEvent, DRenderEvent, ViewAngle); @@ -403,6 +448,22 @@ DEFINE_FIELD_X(WorldEvent, DWorldEvent, DamageAngle); DEFINE_FIELD_X(PlayerEvent, DPlayerEvent, PlayerNumber); DEFINE_FIELD_X(PlayerEvent, DPlayerEvent, IsReturn); +DEFINE_FIELD_X(UiEvent, DUiEvent, Type); +DEFINE_FIELD_X(UiEvent, DUiEvent, KeyString); +DEFINE_FIELD_X(UiEvent, DUiEvent, KeyChar); +DEFINE_FIELD_X(UiEvent, DUiEvent, MouseX); +DEFINE_FIELD_X(UiEvent, DUiEvent, MouseY); +DEFINE_FIELD_X(UiEvent, DUiEvent, IsShift); +DEFINE_FIELD_X(UiEvent, DUiEvent, IsAlt); +DEFINE_FIELD_X(UiEvent, DUiEvent, IsCtrl); + +DEFINE_FIELD_X(InputEvent, DInputEvent, Type); +DEFINE_FIELD_X(InputEvent, DInputEvent, KeyScan); +DEFINE_FIELD_X(InputEvent, DInputEvent, KeyString); +DEFINE_FIELD_X(InputEvent, DInputEvent, KeyChar); +DEFINE_FIELD_X(InputEvent, DInputEvent, MouseX); +DEFINE_FIELD_X(InputEvent, DInputEvent, MouseY); + DEFINE_ACTION_FUNCTION(DEventHandler, Create) { PARAM_PROLOGUE; @@ -515,6 +576,9 @@ DEFINE_ACTION_FUNCTION(DStaticEventHandler, Unregister) return 0; \ } +DEFINE_EMPTY_HANDLER(DStaticEventHandler, OnRegister) +DEFINE_EMPTY_HANDLER(DStaticEventHandler, OnUnregister) + DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLoaded) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldUnloaded) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingSpawned) @@ -532,11 +596,8 @@ DEFINE_EMPTY_HANDLER(DStaticEventHandler, PlayerRespawned) DEFINE_EMPTY_HANDLER(DStaticEventHandler, PlayerDied) DEFINE_EMPTY_HANDLER(DStaticEventHandler, PlayerDisconnected) -DEFINE_ACTION_FUNCTION(DStaticEventHandler, GetOrder) -{ - PARAM_SELF_PROLOGUE(DStaticEventHandler); - ACTION_RETURN_INT(0); -} +DEFINE_EMPTY_HANDLER(DStaticEventHandler, UiProcess); +DEFINE_EMPTY_HANDLER(DStaticEventHandler, InputProcess); // =========================================== // @@ -544,6 +605,30 @@ DEFINE_ACTION_FUNCTION(DStaticEventHandler, GetOrder) // // =========================================== +void DStaticEventHandler::OnRegister() +{ + IFVIRTUAL(DStaticEventHandler, OnRegister) + { + // don't create excessive DObjects if not going to be processed anyway + if (func == DStaticEventHandler_OnRegister_VMPtr) + return; + VMValue params[1] = { (DStaticEventHandler*)this }; + GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); + } +} + +void DStaticEventHandler::OnUnregister() +{ + IFVIRTUAL(DStaticEventHandler, OnUnregister) + { + // don't create excessive DObjects if not going to be processed anyway + if (func == DStaticEventHandler_OnUnregister_VMPtr) + return; + VMValue params[1] = { (DStaticEventHandler*)this }; + GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); + } +} + static DWorldEvent* E_SetupWorldEvent() { static DWorldEvent* e = nullptr; @@ -780,28 +865,125 @@ void DStaticEventHandler::PlayerDisconnected(int num) } } +static DUiEvent* E_SetupUiEvent() +{ + static DUiEvent* e = nullptr; + if (!e) e = (DUiEvent*)RUNTIME_CLASS(DUiEvent)->CreateNew(); + e->Type = EV_GUI_None; + e->IsShift = false; + e->IsAlt = false; + e->IsCtrl = false; + e->MouseX = e->MouseY = 0; + e->KeyChar = 0; + e->KeyString = ""; + return e; +} + +bool DStaticEventHandler::UiProcess(event_t* ev) +{ + IFVIRTUAL(DStaticEventHandler, UiProcess) + { + // don't create excessive DObjects if not going to be processed anyway + if (func == DStaticEventHandler_UiProcess_VMPtr) + return false; + DUiEvent* e = E_SetupUiEvent(); + + // + e->Type = (EGUIEvent)ev->subtype; + // we don't want the modders to remember what weird fields mean what for what events. + switch (e->Type) + { + case EV_GUI_None: + break; + case EV_GUI_KeyDown: + case EV_GUI_KeyRepeat: + case EV_GUI_KeyUp: + e->KeyChar = ev->data1; + e->KeyString.Format("%c", e->KeyChar); + e->IsShift = !!(ev->data3 & GKM_SHIFT); + e->IsAlt = !!(ev->data3 & GKM_ALT); + e->IsCtrl = !!(ev->data3 & GKM_CTRL); + break; + case EV_GUI_Char: + e->KeyChar = ev->data1; + e->KeyString.Format("%c", e->KeyChar); + e->IsAlt = !!ev->data2; // only true for Win32, not sure about SDL + break; + default: // mouse event + // note: SDL input doesn't seem to provide these at all + e->MouseX = ev->x; + e->MouseY = ev->y; + e->IsShift = !!(ev->data3 & GKM_SHIFT); + e->IsAlt = !!(ev->data3 & GKM_ALT); + e->IsCtrl = !!(ev->data3 & GKM_CTRL); + break; + } + + int processed; + VMReturn results[1] = { &processed }; + VMValue params[2] = { (DStaticEventHandler*)this, e }; + GlobalVMStack.Call(func, params, 2, results, 1, nullptr); + return !!processed; + } + + return false; +} + +static DInputEvent* E_SetupInputEvent() +{ + static DInputEvent* e = nullptr; + if (!e) e = (DInputEvent*)RUNTIME_CLASS(DInputEvent)->CreateNew(); + e->Type = EV_None; + e->KeyScan = 0; + e->KeyChar = 0; + e->KeyString = ""; + e->MouseX = e->MouseY = 0; + return e; +} + +bool DStaticEventHandler::InputProcess(event_t* ev) +{ + IFVIRTUAL(DStaticEventHandler, InputProcess) + { + // don't create excessive DObjects if not going to be processed anyway + if (func == DStaticEventHandler_InputProcess_VMPtr) + return false; + DInputEvent* e = E_SetupInputEvent(); + + // + e->Type = (EGenericEvent)ev->type; + // we don't want the modders to remember what weird fields mean what for what events. + switch (e->Type) + { + case EV_None: + break; + case EV_KeyDown: + case EV_KeyUp: + e->KeyScan = ev->data1; + e->KeyChar = ev->data2; + e->KeyString.Format("%c", e->KeyChar); + break; + case EV_Mouse: + e->MouseX = ev->x; + e->MouseY = ev->y; + break; + default: + break; // EV_DeviceChange = wat? + } + + int processed; + VMReturn results[1] = { &processed }; + VMValue params[2] = { (DStaticEventHandler*)this, e }; + GlobalVMStack.Call(func, params, 2, results, 1, nullptr); + return !!processed; + } + + return false; +} + // void DStaticEventHandler::OnDestroy() { E_UnregisterHandler(this); Super::OnDestroy(); } - -// -int DStaticEventHandler::GetOrder() -{ - // if we have cached order, return it. - // otherwise call VM. - if (haveorder) - return order; - - IFVIRTUAL(DStaticEventHandler, GetOrder) - { - VMReturn results[1] = { &order }; - VMValue params[1] = { (DStaticEventHandler*)this }; - GlobalVMStack.Call(func, params, 1, results, 1, nullptr); - haveorder = true; - } - - return order; -} \ No newline at end of file diff --git a/src/events.h b/src/events.h index 05bda85c7e..7658d5f912 100755 --- a/src/events.h +++ b/src/events.h @@ -3,6 +3,8 @@ #include "dobject.h" #include "serializer.h" +#include "d_event.h" +#include "d_gui.h" class DStaticEventHandler; @@ -49,6 +51,11 @@ void E_PlayerRespawned(int num); void E_PlayerDied(int num); // this executes when a player leaves the game void E_PlayerDisconnected(int num); +// this executes on events. +bool E_Responder(event_t* ev); // splits events into InputProcess and UiProcess + +// check if there is anything that should receive GUI events +bool E_CheckUiProcessors(); // serialization stuff void E_SerializeEvents(FSerializer& arc); @@ -67,17 +74,17 @@ public: { prev = 0; next = 0; - order = 0; - haveorder = false; + Order = 0; + IsUiProcessor = false; } DStaticEventHandler* prev; DStaticEventHandler* next; virtual bool IsStatic() { return true; } - // order is cached to avoid calling the VM for sorting too much - int order; - bool haveorder; + // + int Order; + bool IsUiProcessor; // serialization handler. let's keep it here so that I don't get lost in serialized/not serialized fields void Serialize(FSerializer& arc) override @@ -91,34 +98,42 @@ public: { Printf("DStaticEventHandler::Serialize: store object %s\n", GetClass()->TypeName.GetChars()); } - /* do nothing */ + + arc("Order", Order); + arc("IsUiProcessor", IsUiProcessor); } // destroy handler. this unlinks EventHandler from the list automatically. void OnDestroy() override; // - virtual void WorldLoaded(); - virtual void WorldUnloaded(); - virtual void WorldThingSpawned(AActor*); - virtual void WorldThingDied(AActor*, AActor*); - virtual void WorldThingRevived(AActor*); - virtual void WorldThingDamaged(AActor*, AActor*, AActor*, int, FName, int, DAngle); - virtual void WorldThingDestroyed(AActor*); - virtual void WorldLightning(); - virtual void WorldTick(); + void OnRegister(); // you can set order and IsUi here. + void OnUnregister(); // - virtual void RenderFrame(); + void WorldLoaded(); + void WorldUnloaded(); + void WorldThingSpawned(AActor*); + void WorldThingDied(AActor*, AActor*); + void WorldThingRevived(AActor*); + void WorldThingDamaged(AActor*, AActor*, AActor*, int, FName, int, DAngle); + void WorldThingDestroyed(AActor*); + void WorldLightning(); + void WorldTick(); // - virtual void PlayerEntered(int num, bool fromhub); - virtual void PlayerRespawned(int num); - virtual void PlayerDied(int num); - virtual void PlayerDisconnected(int num); + void RenderFrame(); - // gets the order of this item. - int GetOrder(); + // + void PlayerEntered(int num, bool fromhub); + void PlayerRespawned(int num); + void PlayerDied(int num); + void PlayerDisconnected(int num); + + // + // return true if handled. + virtual bool InputProcess(event_t* ev); + virtual bool UiProcess(event_t* ev); }; class DEventHandler : public DStaticEventHandler { @@ -213,4 +228,47 @@ public: } }; +class DUiEvent : public DBaseEvent +{ + DECLARE_CLASS(DUiEvent, DBaseEvent) +public: + // this essentially translates event_t UI events to ZScript. + EGUIEvent Type; + // for keys/chars/whatever + FString KeyString; + int KeyChar; + // for mouse + int MouseX; + int MouseY; + // global (?) + bool IsShift; + bool IsCtrl; + bool IsAlt; + + DUiEvent() + { + Type = EV_GUI_None; + } +}; + +class DInputEvent : public DBaseEvent +{ + DECLARE_CLASS(DInputEvent, DBaseEvent) +public: + // this translates regular event_t events to ZScript (not UI, UI events are sent via DUiEvent and only if requested!) + EGenericEvent Type; + // for keys + int KeyScan; + FString KeyString; + int KeyChar; + // for mouse + int MouseX; + int MouseY; + + DInputEvent() + { + Type = EV_None; + } +}; + #endif \ No newline at end of file diff --git a/src/posix/cocoa/i_input.mm b/src/posix/cocoa/i_input.mm index 7032806158..7b5faa80ea 100644 --- a/src/posix/cocoa/i_input.mm +++ b/src/posix/cocoa/i_input.mm @@ -47,6 +47,7 @@ #include "doomdef.h" #include "doomstat.h" #include "v_video.h" +#include "events.h" #undef Class @@ -94,6 +95,10 @@ void CheckGUICapture() ? (c_down == ConsoleState || c_falling == ConsoleState || chatmodeon) : (MENU_On == menuactive || MENU_OnNoPause == menuactive); + // [ZZ] check active event handlers that want the UI processing + if (!wantCapture && E_CheckUiProcessors()) + wantCapture = true; + if (wantCapture != GUICapture) { GUICapture = wantCapture; diff --git a/src/posix/sdl/i_input.cpp b/src/posix/sdl/i_input.cpp index 372b234461..1d47dd6e0c 100644 --- a/src/posix/sdl/i_input.cpp +++ b/src/posix/sdl/i_input.cpp @@ -17,6 +17,7 @@ #include "dikeys.h" #include "templates.h" #include "s_sound.h" +#include "events.h" static void I_CheckGUICapture (); static void I_CheckNativeMouse (); @@ -154,6 +155,10 @@ static void I_CheckGUICapture () wantCapt = (menuactive == MENU_On || menuactive == MENU_OnNoPause); } + // [ZZ] check active event handlers that want the UI processing + if (!wantCapt && E_CheckUiProcessors()) + wantCapt = true; + if (wantCapt != GUICapture) { GUICapture = wantCapt; diff --git a/src/win32/i_input.cpp b/src/win32/i_input.cpp index 1e63903927..0788e94156 100644 --- a/src/win32/i_input.cpp +++ b/src/win32/i_input.cpp @@ -101,6 +101,7 @@ #include "d_event.h" #include "v_text.h" #include "version.h" +#include "events.h" // Prototypes and declarations. #include "rawinput.h" @@ -187,6 +188,10 @@ static void I_CheckGUICapture () wantCapt = (menuactive == MENU_On || menuactive == MENU_OnNoPause); } + // [ZZ] check active event handlers that want the UI processing + if (!wantCapt && E_CheckUiProcessors()) + wantCapt = true; + if (wantCapt != GUICapture) { GUICapture = wantCapt; diff --git a/wadsrc/static/zscript/events.txt b/wadsrc/static/zscript/events.txt index e6b826554e..bbbe065341 100755 --- a/wadsrc/static/zscript/events.txt +++ b/wadsrc/static/zscript/events.txt @@ -37,6 +37,241 @@ class PlayerEvent : BaseEvent native native readonly bool IsReturn; } +class UiEvent : BaseEvent native +{ + // d_gui.h + enum EGUIEvent + { + Type_None, + Type_KeyDown, + Type_KeyRepeat, + Type_KeyUp, + Type_Char, + Type_FirstMouseEvent, // ? + Type_MouseMove, + Type_LButtonDown, + Type_LButtonUp, + Type_LButtonClick, + Type_MButtonDown, + Type_MButtonUp, + Type_MButtonClick, + Type_RButtonDown, + Type_RButtonUp, + Type_RButtonClick, + Type_WheelUp, + Type_WheelDown, + Type_WheelRight, // ??? + Type_WheelLeft, // ??? + Type_BackButtonDown, // ??? + Type_BackButtonUp, // ??? + Type_FwdButtonDown, // ??? + Type_FwdButtonUp, // ??? + Type_LastMouseEvent + } + + // for KeyDown, KeyRepeat, KeyUp + enum ESpecialGUIKeys + { + Key_PgDn = 1, + Key_PgUp = 2, + Key_Home = 3, + Key_End = 4, + Key_Left = 5, + Key_Right = 6, + Key_Alert = 7, // ASCII bell + Key_Backspace = 8, // ASCII + Key_Tab = 9, // ASCII + Key_LineFeed = 10, // ASCII + Key_Down = 10, + Key_VTab = 11, // ASCII + Key_Up = 11, + Key_FormFeed = 12, // ASCII + Key_Return = 13, // ASCII + Key_F1 = 14, + Key_F2 = 15, + Key_F3 = 16, + Key_F4 = 17, + Key_F5 = 18, + Key_F6 = 19, + Key_F7 = 20, + Key_F8 = 21, + Key_F9 = 22, + Key_F10 = 23, + Key_F11 = 24, + Key_F12 = 25, + Key_Del = 26, + Key_Escape = 27, // ASCII + Key_Free1 = 28, + Key_Free2 = 29, + Key_Back = 30, // browser back key + Key_CEscape = 31 // color escape + } + + // + native readonly EGUIEvent Type; + // + native readonly String KeyString; + native readonly int KeyChar; + // + native readonly int MouseX; + native readonly int MouseY; + // + /* // this can't be exposed yet: SDL driver doesn't set these at all + native readonly bool IsShift; + native readonly bool IsCtrl; + native readonly bool IsAlt; + */ +} + +class InputEvent : BaseEvent native +{ + enum EGenericEvent + { + Type_None, + Type_KeyDown, + Type_KeyUp, + Type_Mouse, + Type_GUI, // unused, kept for completeness + Type_DeviceChange + } + + // ew. + enum EDoomInputKeys + { + Key_Pause = 0xc5, // DIK_PAUSE + Key_RightArrow = 0xcd, // DIK_RIGHT + Key_LeftArrow = 0xcb, // DIK_LEFT + Key_UpArrow = 0xc8, // DIK_UP + Key_DownArrow = 0xd0, // DIK_DOWN + Key_Escape = 0x01, // DIK_ESCAPE + Key_Enter = 0x1c, // DIK_RETURN + Key_Space = 0x39, // DIK_SPACE + Key_Tab = 0x0f, // DIK_TAB + Key_F1 = 0x3b, // DIK_F1 + Key_F2 = 0x3c, // DIK_F2 + Key_F3 = 0x3d, // DIK_F3 + Key_F4 = 0x3e, // DIK_F4 + Key_F5 = 0x3f, // DIK_F5 + Key_F6 = 0x40, // DIK_F6 + Key_F7 = 0x41, // DIK_F7 + Key_F8 = 0x42, // DIK_F8 + Key_F9 = 0x43, // DIK_F9 + Key_F10 = 0x44, // DIK_F10 + Key_F11 = 0x57, // DIK_F11 + Key_F12 = 0x58, // DIK_F12 + Key_Grave = 0x29, // DIK_GRAVE + + Key_Backspace = 0x0e, // DIK_BACK + + Key_Equals = 0x0d, // DIK_EQUALS + Key_Minus = 0x0c, // DIK_MINUS + + Key_LShift = 0x2A, // DIK_LSHIFT + Key_LCtrl = 0x1d, // DIK_LCONTROL + Key_LAlt = 0x38, // DIK_LMENU + + Key_RShift = Key_LSHIFT, + Key_RCtrl = Key_LCTRL, + Key_RAlt = Key_LALT, + + Key_Ins = 0xd2, // DIK_INSERT + Key_Del = 0xd3, // DIK_DELETE + Key_End = 0xcf, // DIK_END + Key_Home = 0xc7, // DIK_HOME + Key_PgUp = 0xc9, // DIK_PRIOR + Key_PgDn = 0xd1, // DIK_NEXT + + Key_Mouse1 = 0x100, + Key_Mouse2 = 0x101, + Key_Mouse3 = 0x102, + Key_Mouse4 = 0x103, + Key_Mouse5 = 0x104, + Key_Mouse6 = 0x105, + Key_Mouse7 = 0x106, + Key_Mouse8 = 0x107, + + Key_FirstJoyButton = 0x108, + Key_Joy1 = (Key_FirstJoyButton+0), + Key_Joy2 = (Key_FirstJoyButton+1), + Key_Joy3 = (Key_FirstJoyButton+2), + Key_Joy4 = (Key_FirstJoyButton+3), + Key_Joy5 = (Key_FirstJoyButton+4), + Key_Joy6 = (Key_FirstJoyButton+5), + Key_Joy7 = (Key_FirstJoyButton+6), + Key_Joy8 = (Key_FirstJoyButton+7), + Key_LastJoyButton = 0x187, + Key_JoyPOV1_Up = 0x188, + Key_JoyPOV1_Right = 0x189, + Key_JoyPOV1_Down = 0x18a, + Key_JoyPOV1_Left = 0x18b, + Key_JoyPOV2_Up = 0x18c, + Key_JoyPOV3_Up = 0x190, + Key_JoyPOV4_Up = 0x194, + + Key_MWheelUp = 0x198, + Key_MWheelDown = 0x199, + Key_MWheelRight = 0x19A, + Key_MWheelLeft = 0x19B, + + Key_JoyAxis1Plus = 0x19C, + Key_JoyAxis1Minus = 0x19D, + Key_JoyAxis2Plus = 0x19E, + Key_JoyAxis2Minus = 0x19F, + Key_JoyAxis3Plus = 0x1A0, + Key_JoyAxis3Minus = 0x1A1, + Key_JoyAxis4Plus = 0x1A2, + Key_JoyAxis4Minus = 0x1A3, + Key_JoyAxis5Plus = 0x1A4, + Key_JoyAxis5Minus = 0x1A5, + Key_JoyAxis6Plus = 0x1A6, + Key_JoyAxis6Minus = 0x1A7, + Key_JoyAxis7Plus = 0x1A8, + Key_JoyAxis7Minus = 0x1A9, + Key_JoyAxis8Plus = 0x1AA, + Key_JoyAxis8Minus = 0x1AB, + Num_JoyAxisButtons = 8, + + Key_Pad_LThumb_Right = 0x1AC, + Key_Pad_LThumb_Left = 0x1AD, + Key_Pad_LThumb_Down = 0x1AE, + Key_Pad_LThumb_Up = 0x1AF, + + Key_Pad_RThumb_Right = 0x1B0, + Key_Pad_RThumb_Left = 0x1B1, + Key_Pad_RThumb_Down = 0x1B2, + Key_Pad_RThumb_Up = 0x1B3, + + Key_Pad_DPad_Up = 0x1B4, + Key_Pad_DPad_Down = 0x1B5, + Key_Pad_DPad_Left = 0x1B6, + Key_Pad_DPad_Right = 0x1B7, + Key_Pad_Start = 0x1B8, + Key_Pad_Back = 0x1B9, + Key_Pad_LThumb = 0x1BA, + Key_Pad_RThumb = 0x1BB, + Key_Pad_LShoulder = 0x1BC, + Key_Pad_RShoulder = 0x1BD, + Key_Pad_LTrigger = 0x1BE, + Key_Pad_RTrigger = 0x1BF, + Key_Pad_A = 0x1C0, + Key_Pad_B = 0x1C1, + Key_Pad_X = 0x1C2, + Key_Pad_Y = 0x1C3, + + Num_Keys = 0x1C4 + } + + // + native readonly EGenericEvent Type; + // + native readonly int KeyScan; // as in EDoomInputKeys enum + native readonly String KeyString; + native readonly int KeyChar; // ASCII char (if any) + // + native readonly int MouseX; + native readonly int MouseY; +} + class StaticEventHandler : Object native { // static event handlers CAN register other static event handlers. @@ -47,6 +282,11 @@ class StaticEventHandler : Object native protected static native bool Register(StaticEventHandler handler); protected static native bool Unregister(StaticEventHandler handler); + + // these are called when the handler gets registered or unregistered + // you can set Order/IsUiProcessor here. + virtual native void OnRegister(); + virtual native void OnUnregister(); // actual handlers are here virtual native void WorldLoaded(WorldEvent e); @@ -68,10 +308,16 @@ class StaticEventHandler : Object native virtual native void PlayerDied(PlayerEvent e); virtual native void PlayerDisconnected(PlayerEvent e); - // this function should return a value that will be queried on Register() to decide the relative order of this handler to every other. + // + virtual native bool UiProcess(UiEvent e); + virtual native bool InputProcess(InputEvent e); + + // this value will be queried on Register() to decide the relative order of this handler to every other. // this is most useful in UI systems. // default is 0. - virtual native int GetOrder(); + native int Order; + // this value will be queried on user input to decide whether to send UiProcess to this handler. + native bool IsUiProcessor; } class EventHandler : StaticEventHandler native