2019-12-19 06:08:52 +00:00
|
|
|
package allg5
|
|
|
|
|
|
|
|
/*
|
|
|
|
#define ALLEGRO_KCM_AUDIO_SRC
|
|
|
|
|
|
|
|
#include <allegro5/allegro.h>
|
|
|
|
#include <allegro5/allegro_audio.h>
|
|
|
|
|
|
|
|
#define USER_EVENT_TYPE ALLEGRO_GET_EVENT_TYPE('u', 's', 'e', 'r')
|
|
|
|
|
|
|
|
void init_user_event(ALLEGRO_EVENT* e)
|
|
|
|
{
|
|
|
|
e->user.type = USER_EVENT_TYPE;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
import "C"
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"unsafe"
|
|
|
|
)
|
|
|
|
|
|
|
|
type EventQueue struct {
|
2020-02-20 17:08:01 +00:00
|
|
|
queue *C.ALLEGRO_EVENT_QUEUE
|
|
|
|
displays map[*C.ALLEGRO_DISPLAY]*Display
|
2019-12-19 06:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type Event interface {
|
|
|
|
Stamp() float64
|
|
|
|
}
|
|
|
|
|
|
|
|
type EventBase struct {
|
|
|
|
stamp float64
|
|
|
|
}
|
|
|
|
|
|
|
|
func (eb EventBase) Stamp() float64 {
|
|
|
|
return eb.stamp
|
|
|
|
}
|
|
|
|
|
|
|
|
type DisplayCloseEvent struct {
|
2020-02-20 17:08:01 +00:00
|
|
|
DisplayEvent
|
2019-12-19 06:08:52 +00:00
|
|
|
}
|
|
|
|
|
2020-02-20 17:08:01 +00:00
|
|
|
type DisplayConnectedEvent struct {
|
|
|
|
DisplayEvent
|
|
|
|
}
|
|
|
|
|
|
|
|
type DisplayDisconnectedEvent struct {
|
|
|
|
DisplayEvent
|
|
|
|
}
|
|
|
|
|
|
|
|
type DisplayEvent struct {
|
2019-12-19 06:08:52 +00:00
|
|
|
EventBase
|
2020-02-20 17:08:01 +00:00
|
|
|
Display *Display
|
2019-12-19 06:08:52 +00:00
|
|
|
}
|
|
|
|
|
2020-02-20 17:08:01 +00:00
|
|
|
type DisplayFoundEvent struct {
|
|
|
|
DisplayEvent
|
|
|
|
}
|
|
|
|
|
|
|
|
type DisplayHaltDrawingEvent struct {
|
|
|
|
DisplayEvent
|
|
|
|
}
|
|
|
|
|
|
|
|
type DisplayLostEvent struct {
|
|
|
|
DisplayEvent
|
|
|
|
}
|
2019-12-19 06:08:52 +00:00
|
|
|
type DisplayOrientation int
|
|
|
|
|
|
|
|
const (
|
|
|
|
DisplayOrientation0Degrees DisplayOrientation = iota
|
|
|
|
DisplayOrientation90Degrees
|
|
|
|
DisplayOrientation180Degrees
|
|
|
|
DisplayOrientation270Degrees
|
|
|
|
DisplayOrientationFaceUp
|
|
|
|
DisplayOrientationFaceDown
|
|
|
|
)
|
|
|
|
|
|
|
|
func toDisplayOrientation(o C.int) DisplayOrientation {
|
|
|
|
switch o {
|
|
|
|
case C.ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES:
|
|
|
|
return DisplayOrientation0Degrees
|
|
|
|
case C.ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES:
|
|
|
|
return DisplayOrientation90Degrees
|
|
|
|
case C.ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES:
|
|
|
|
return DisplayOrientation180Degrees
|
|
|
|
case C.ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES:
|
|
|
|
return DisplayOrientation270Degrees
|
|
|
|
case C.ALLEGRO_DISPLAY_ORIENTATION_FACE_UP:
|
|
|
|
return DisplayOrientationFaceUp
|
|
|
|
case C.ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN:
|
|
|
|
return DisplayOrientationFaceDown
|
|
|
|
default:
|
|
|
|
panic("not supported")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type DisplayOrientationEvent struct {
|
2020-02-20 17:08:01 +00:00
|
|
|
DisplayEvent
|
2019-12-19 06:08:52 +00:00
|
|
|
Orientation DisplayOrientation
|
|
|
|
}
|
|
|
|
|
2020-02-20 17:08:01 +00:00
|
|
|
type DisplayResizeEvent struct {
|
|
|
|
DisplayEvent
|
|
|
|
X, Y int
|
|
|
|
Width int
|
|
|
|
Height int
|
|
|
|
}
|
|
|
|
|
|
|
|
type DisplayResumeDrawingEvent struct {
|
|
|
|
DisplayEvent
|
|
|
|
}
|
|
|
|
|
|
|
|
type DisplaySwitchInEvent struct {
|
|
|
|
DisplayEvent
|
|
|
|
}
|
|
|
|
|
|
|
|
type DisplaySwitchOutEvent struct {
|
|
|
|
DisplayEvent
|
|
|
|
}
|
|
|
|
|
2019-12-19 06:08:52 +00:00
|
|
|
type KeyEvent struct {
|
|
|
|
EventBase
|
|
|
|
KeyCode Key
|
|
|
|
Display *Display
|
|
|
|
}
|
|
|
|
|
|
|
|
type KeyCharEvent struct {
|
|
|
|
KeyEvent
|
|
|
|
UnicodeCharacter rune
|
|
|
|
Modifiers KeyMod
|
|
|
|
Repeat bool
|
|
|
|
}
|
|
|
|
|
|
|
|
type KeyDownEvent struct {
|
|
|
|
KeyEvent
|
|
|
|
}
|
|
|
|
|
|
|
|
type KeyUpEvent struct {
|
|
|
|
KeyEvent
|
|
|
|
}
|
|
|
|
|
|
|
|
type MouseButtonDownEvent struct {
|
|
|
|
MouseEvent
|
|
|
|
Button MouseButton
|
|
|
|
Pressure float32
|
|
|
|
}
|
|
|
|
|
|
|
|
type MouseButtonUpEvent struct {
|
|
|
|
MouseEvent
|
|
|
|
Button MouseButton
|
|
|
|
Pressure float32
|
|
|
|
}
|
|
|
|
|
|
|
|
type MouseEnterEvent struct {
|
|
|
|
MouseEvent
|
|
|
|
}
|
|
|
|
|
|
|
|
type MouseEvent struct {
|
|
|
|
EventBase
|
|
|
|
X, Y int
|
|
|
|
Z, W int
|
|
|
|
Display *Display
|
|
|
|
}
|
2020-02-20 17:08:01 +00:00
|
|
|
|
2019-12-19 06:08:52 +00:00
|
|
|
type MouseLeaveEvent struct {
|
|
|
|
MouseEvent
|
|
|
|
}
|
|
|
|
|
|
|
|
type MouseMoveEvent struct {
|
|
|
|
MouseEvent
|
|
|
|
DeltaX, DeltaY int
|
|
|
|
DeltaZ, DeltaW int
|
|
|
|
Pressure float32
|
|
|
|
}
|
|
|
|
|
|
|
|
type RecorderFragmentEvent struct {
|
|
|
|
EventBase
|
|
|
|
Buffer unsafe.Pointer
|
|
|
|
Samples int
|
|
|
|
}
|
|
|
|
|
|
|
|
type UserEvent struct {
|
|
|
|
EventBase
|
|
|
|
}
|
|
|
|
|
|
|
|
type UserEventSource struct {
|
|
|
|
source *C.ALLEGRO_EVENT_SOURCE
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewEventQueue() (*EventQueue, error) {
|
|
|
|
q := C.al_create_event_queue()
|
|
|
|
if q == nil {
|
|
|
|
return nil, errors.New("unable to create event queue")
|
|
|
|
}
|
2020-02-20 17:08:01 +00:00
|
|
|
return &EventQueue{q, map[*C.ALLEGRO_DISPLAY]*Display{}}, nil
|
2019-12-19 06:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (eq *EventQueue) register(source *C.ALLEGRO_EVENT_SOURCE) {
|
|
|
|
C.al_register_event_source(eq.queue, source)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (eq *EventQueue) RegisterDisplay(d *Display) {
|
|
|
|
eq.register(C.al_get_display_event_source(d.display))
|
2020-02-20 17:08:01 +00:00
|
|
|
eq.displays[d.display] = d
|
2019-12-19 06:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (eq *EventQueue) RegisterMouse() {
|
|
|
|
eq.register(C.al_get_mouse_event_source())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (eq *EventQueue) RegisterKeyboard() {
|
|
|
|
eq.register(C.al_get_keyboard_event_source())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (eq *EventQueue) RegisterRecorder(rec *Recorder) {
|
|
|
|
eq.register(C.al_get_audio_recorder_event_source(rec.recorder))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (eq *EventQueue) RegisterUserEvents(source *UserEventSource) {
|
|
|
|
eq.register(source.source)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (eq *EventQueue) mapEvent(e *C.ALLEGRO_EVENT) Event {
|
|
|
|
any := (*C.ALLEGRO_ANY_EVENT)(unsafe.Pointer(e))
|
|
|
|
eb := EventBase{float64(any.timestamp)}
|
|
|
|
switch any._type {
|
|
|
|
case C.ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT:
|
|
|
|
recorder := (*C.ALLEGRO_AUDIO_RECORDER_EVENT)(unsafe.Pointer(e))
|
|
|
|
return &RecorderFragmentEvent{eb, unsafe.Pointer(recorder.buffer), int(recorder.samples)}
|
2020-02-20 17:08:01 +00:00
|
|
|
case C.ALLEGRO_EVENT_DISPLAY_CONNECTED:
|
|
|
|
display := (*C.ALLEGRO_DISPLAY_EVENT)(unsafe.Pointer(e))
|
|
|
|
return &DisplayConnectedEvent{DisplayEvent{eb, eq.displays[display.source]}}
|
2019-12-19 06:08:52 +00:00
|
|
|
case C.ALLEGRO_EVENT_DISPLAY_CLOSE:
|
2020-02-20 17:08:01 +00:00
|
|
|
display := (*C.ALLEGRO_DISPLAY_EVENT)(unsafe.Pointer(e))
|
|
|
|
return &DisplayCloseEvent{DisplayEvent{eb, eq.displays[display.source]}}
|
|
|
|
case C.ALLEGRO_EVENT_DISPLAY_DISCONNECTED:
|
|
|
|
display := (*C.ALLEGRO_DISPLAY_EVENT)(unsafe.Pointer(e))
|
|
|
|
return &DisplayDisconnectedEvent{DisplayEvent{eb, eq.displays[display.source]}}
|
|
|
|
case C.ALLEGRO_EVENT_DISPLAY_FOUND:
|
|
|
|
display := (*C.ALLEGRO_DISPLAY_EVENT)(unsafe.Pointer(e))
|
|
|
|
return &DisplayFoundEvent{DisplayEvent{eb, eq.displays[display.source]}}
|
|
|
|
case C.ALLEGRO_EVENT_DISPLAY_HALT_DRAWING:
|
|
|
|
display := (*C.ALLEGRO_DISPLAY_EVENT)(unsafe.Pointer(e))
|
|
|
|
return &DisplayHaltDrawingEvent{DisplayEvent{eb, eq.displays[display.source]}}
|
|
|
|
case C.ALLEGRO_EVENT_DISPLAY_LOST:
|
|
|
|
display := (*C.ALLEGRO_DISPLAY_EVENT)(unsafe.Pointer(e))
|
|
|
|
return &DisplayLostEvent{DisplayEvent{eb, eq.displays[display.source]}}
|
2019-12-19 06:08:52 +00:00
|
|
|
case C.ALLEGRO_EVENT_DISPLAY_ORIENTATION:
|
|
|
|
display := (*C.ALLEGRO_DISPLAY_EVENT)(unsafe.Pointer(e))
|
2020-02-20 17:08:01 +00:00
|
|
|
return &DisplayOrientationEvent{DisplayEvent{eb, eq.displays[display.source]}, toDisplayOrientation(display.orientation)}
|
2019-12-19 06:08:52 +00:00
|
|
|
case C.ALLEGRO_EVENT_DISPLAY_RESIZE:
|
|
|
|
display := (*C.ALLEGRO_DISPLAY_EVENT)(unsafe.Pointer(e))
|
|
|
|
C.al_acknowledge_resize(display.source)
|
2020-02-20 17:08:01 +00:00
|
|
|
return &DisplayResizeEvent{DisplayEvent{eb, eq.displays[display.source]}, int(display.x), int(display.y), int(display.width), int(display.height)}
|
|
|
|
case C.ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING:
|
|
|
|
display := (*C.ALLEGRO_DISPLAY_EVENT)(unsafe.Pointer(e))
|
|
|
|
return &DisplayResumeDrawingEvent{DisplayEvent{eb, eq.displays[display.source]}}
|
|
|
|
case C.ALLEGRO_EVENT_DISPLAY_SWITCH_IN:
|
|
|
|
display := (*C.ALLEGRO_DISPLAY_EVENT)(unsafe.Pointer(e))
|
|
|
|
return &DisplaySwitchInEvent{DisplayEvent{eb, eq.displays[display.source]}}
|
|
|
|
case C.ALLEGRO_EVENT_DISPLAY_SWITCH_OUT:
|
|
|
|
display := (*C.ALLEGRO_DISPLAY_EVENT)(unsafe.Pointer(e))
|
|
|
|
return &DisplaySwitchOutEvent{DisplayEvent{eb, eq.displays[display.source]}}
|
2019-12-19 06:08:52 +00:00
|
|
|
case C.ALLEGRO_EVENT_MOUSE_AXES:
|
|
|
|
mouse := (*C.ALLEGRO_MOUSE_EVENT)(unsafe.Pointer(e))
|
2020-12-25 18:43:21 +00:00
|
|
|
return &MouseMoveEvent{MouseEvent{eb, int(mouse.x), int(mouse.y), int(mouse.z), int(mouse.w), eq.displays[mouse.display]}, int(mouse.dx), int(mouse.dy), int(mouse.dz), int(mouse.dw), float32(mouse.pressure)}
|
2019-12-19 06:08:52 +00:00
|
|
|
case C.ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
|
|
|
|
mouse := (*C.ALLEGRO_MOUSE_EVENT)(unsafe.Pointer(e))
|
2020-12-25 18:43:21 +00:00
|
|
|
return &MouseButtonDownEvent{MouseEvent{eb, int(mouse.x), int(mouse.y), int(mouse.z), int(mouse.w), eq.displays[mouse.display]}, MouseButton(mouse.button), float32(mouse.pressure)}
|
2019-12-19 06:08:52 +00:00
|
|
|
case C.ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY:
|
|
|
|
mouse := (*C.ALLEGRO_MOUSE_EVENT)(unsafe.Pointer(e))
|
2020-12-25 18:43:21 +00:00
|
|
|
return &MouseEnterEvent{MouseEvent{eb, int(mouse.x), int(mouse.y), int(mouse.z), int(mouse.w), eq.displays[mouse.display]}}
|
2019-12-19 06:08:52 +00:00
|
|
|
case C.ALLEGRO_EVENT_MOUSE_BUTTON_UP:
|
|
|
|
mouse := (*C.ALLEGRO_MOUSE_EVENT)(unsafe.Pointer(e))
|
|
|
|
return &MouseButtonUpEvent{MouseEvent{eb, int(mouse.x), int(mouse.y), int(mouse.z), int(mouse.w), nil}, MouseButton(mouse.button), float32(mouse.pressure)}
|
|
|
|
case C.ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY:
|
|
|
|
mouse := (*C.ALLEGRO_MOUSE_EVENT)(unsafe.Pointer(e))
|
|
|
|
return &MouseLeaveEvent{MouseEvent{eb, int(mouse.x), int(mouse.y), int(mouse.z), int(mouse.w), nil}}
|
|
|
|
case C.ALLEGRO_EVENT_KEY_DOWN:
|
|
|
|
key := (*C.ALLEGRO_KEYBOARD_EVENT)(unsafe.Pointer(e))
|
|
|
|
return &KeyDownEvent{KeyEvent{eb, Key(key.keycode), nil}}
|
|
|
|
case C.ALLEGRO_EVENT_KEY_UP:
|
|
|
|
key := (*C.ALLEGRO_KEYBOARD_EVENT)(unsafe.Pointer(e))
|
|
|
|
return &KeyUpEvent{KeyEvent{eb, Key(key.keycode), nil}}
|
|
|
|
case C.ALLEGRO_EVENT_KEY_CHAR:
|
|
|
|
key := (*C.ALLEGRO_KEYBOARD_EVENT)(unsafe.Pointer(e))
|
|
|
|
return &KeyCharEvent{KeyEvent{eb, Key(key.keycode), nil}, rune(key.unichar), KeyMod(key.modifiers), bool(key.repeat)}
|
|
|
|
case C.USER_EVENT_TYPE:
|
|
|
|
return &UserEvent{eb}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (eq *EventQueue) Get() Event {
|
|
|
|
var event C.ALLEGRO_EVENT
|
|
|
|
if !bool(C.al_get_next_event(eq.queue, &event)) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return eq.mapEvent(&event)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (eq *EventQueue) GetWait() Event {
|
|
|
|
var event C.ALLEGRO_EVENT
|
|
|
|
C.al_wait_for_event(eq.queue, &event)
|
|
|
|
return eq.mapEvent(&event)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (eq *EventQueue) Destroy() {
|
|
|
|
C.al_destroy_event_queue(eq.queue)
|
|
|
|
}
|
|
|
|
|
2020-12-25 18:43:21 +00:00
|
|
|
func (eq *EventQueue) unregister(source *C.ALLEGRO_EVENT_SOURCE) {
|
|
|
|
C.al_unregister_event_source(eq.queue, source)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (eq *EventQueue) UnregisterDisplay(d *Display) {
|
|
|
|
eq.unregister(C.al_get_display_event_source(d.display))
|
|
|
|
delete(eq.displays, d.display)
|
|
|
|
}
|
|
|
|
|
2019-12-19 06:08:52 +00:00
|
|
|
func NewUserEventSource() *UserEventSource {
|
|
|
|
s := (*C.ALLEGRO_EVENT_SOURCE)(C.malloc(C.sizeof_ALLEGRO_EVENT_SOURCE))
|
|
|
|
source := &UserEventSource{s}
|
|
|
|
C.al_init_user_event_source(s)
|
|
|
|
return source
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *UserEventSource) Destroy() {
|
|
|
|
C.al_destroy_user_event_source(s.source)
|
|
|
|
C.free(unsafe.Pointer(s.source))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *UserEventSource) EmitEvent() bool {
|
|
|
|
e := (*C.ALLEGRO_EVENT)(C.malloc(C.sizeof_ALLEGRO_EVENT))
|
|
|
|
C.init_user_event(e)
|
|
|
|
return bool(C.al_emit_user_event(s.source, e, nil))
|
|
|
|
}
|
2021-06-03 18:14:55 +00:00
|
|
|
|
|
|
|
func GetTime() float64 {
|
|
|
|
return float64(C.al_get_time())
|
|
|
|
}
|