129 lines
3.9 KiB
Go
129 lines
3.9 KiB
Go
package imgui
|
|
|
|
import (
|
|
"mxl-player/internal/sdl"
|
|
"unsafe"
|
|
|
|
cimgui "github.com/AllenDang/cimgui-go/imgui"
|
|
)
|
|
|
|
const (
|
|
sdlKModShift uint16 = 0x0001 | 0x0002
|
|
sdlKModCtrl uint16 = 0x0040 | 0x0080
|
|
sdlKModAlt uint16 = 0x0100 | 0x0200
|
|
sdlKModGUI uint16 = 0x0400 | 0x0800
|
|
)
|
|
|
|
// SDL3 event (128 byte raw buffer) -> imgui
|
|
func (c *Context) ProcessEvent(event *[128]byte) {
|
|
eventType := *(*uint32)(unsafe.Pointer(&event[0]))
|
|
|
|
// CommonEvent (16 bytes: type uint32 + reserved uint32 + timestamp uint64)
|
|
switch eventType {
|
|
case sdl.EventKeyDown, sdl.EventKeyUp:
|
|
scancode := *(*uint32)(unsafe.Pointer(&event[24]))
|
|
modifiers := *(*uint16)(unsafe.Pointer(&event[32]))
|
|
down := eventType == sdl.EventKeyDown
|
|
c.addKeyModifiers(modifiers)
|
|
key := sdlScancodeToImGuiKey(scancode)
|
|
if key >= 0 {
|
|
c.io.AddKeyEvent(key, down)
|
|
}
|
|
// MouseMotionEvent: +16 windowID(4), +20 which(4), +24 state(4), +28 x(float32), +32 y(float32)
|
|
case sdl.EventMouseMotion:
|
|
x := *(*float32)(unsafe.Pointer(&event[28]))
|
|
y := *(*float32)(unsafe.Pointer(&event[32]))
|
|
c.io.AddMousePosEvent(x, y)
|
|
// MouseButtonEvent: +16 windowID(4), +20 which(4), +24 button(1), +25 down(bool)
|
|
case sdl.EventMouseButtonDown, sdl.EventMouseButtonUp:
|
|
button := *(*uint8)(unsafe.Pointer(&event[24]))
|
|
down := eventType == sdl.EventMouseButtonDown
|
|
c.io.AddMouseButtonEvent(int32(button-1), down)
|
|
// MouseWheelEvent: +16 windowID(4), +20 which(4), +24 x(float32), +28 y(float32)
|
|
case sdl.EventMouseWheel:
|
|
x := *(*float32)(unsafe.Pointer(&event[24]))
|
|
y := *(*float32)(unsafe.Pointer(&event[28]))
|
|
c.io.AddMouseWheelEvent(x, y)
|
|
// TextInputEvent: +16 windowID(4), +20 text(*char pointer, 8 bytes on 64-bit)
|
|
case sdl.EventTextInput:
|
|
// text pointer is at offset 24, 8 bytes (pointer)
|
|
ptr := *(*uintptr)(unsafe.Pointer(&event[24]))
|
|
if ptr != 0 {
|
|
text := cstr(ptr)
|
|
c.io.AddInputCharactersUTF8(text)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
func (c *Context) addKeyModifiers(modifiers uint16) {
|
|
c.io.AddKeyEvent(cimgui.ModCtrl, modifiers&sdlKModCtrl != 0)
|
|
c.io.AddKeyEvent(cimgui.ModShift, modifiers&sdlKModShift != 0)
|
|
c.io.AddKeyEvent(cimgui.ModAlt, modifiers&sdlKModAlt != 0)
|
|
c.io.AddKeyEvent(cimgui.ModSuper, modifiers&sdlKModGUI != 0)
|
|
}
|
|
|
|
func sdlScancodeToImGuiKey(scancode uint32) cimgui.Key {
|
|
switch scancode {
|
|
case 40: // SDL_SCANCODE_RETURN
|
|
return cimgui.KeyEnter
|
|
case 42: // SDL_SCANCODE_BACKSPACE
|
|
return cimgui.KeyBackspace
|
|
case 41: // SDL_SCANCODE_ESCAPE
|
|
return cimgui.KeyEscape
|
|
case 43: // SDL_SCANCODE_TAB
|
|
return cimgui.KeyTab
|
|
case 44: // SDL_SCANCODE_SPACE
|
|
return cimgui.KeySpace
|
|
case 80: // SDL_SCANCODE_LEFT
|
|
return cimgui.KeyLeftArrow
|
|
case 79: // SDL_SCANCODE_RIGHT
|
|
return cimgui.KeyRightArrow
|
|
case 82: // SDL_SCANCODE_UP
|
|
return cimgui.KeyUpArrow
|
|
case 81: // SDL_SCANCODE_DOWN
|
|
return cimgui.KeyDownArrow
|
|
case 225: // SDL_SCANCODE_LSHIFT
|
|
return cimgui.KeyLeftShift
|
|
case 229: // SDL_SCANCODE_RSHIFT
|
|
return cimgui.KeyRightShift
|
|
case 224: // SDL_SCANCODE_LCTRL
|
|
return cimgui.KeyLeftCtrl
|
|
case 228: // SDL_SCANCODE_RCTRL
|
|
return cimgui.KeyRightCtrl
|
|
case 226: // SDL_SCANCODE_LALT
|
|
return cimgui.KeyLeftAlt
|
|
case 230: // SDL_SCANCODE_RALT
|
|
return cimgui.KeyRightAlt
|
|
case 227: // SDL_SCANCODE_LGUI
|
|
return cimgui.KeyLeftSuper
|
|
case 231: // SDL_SCANCODE_RGUI
|
|
return cimgui.KeyRightSuper
|
|
default:
|
|
// Letters A-Z: scancodes 4-29 map to ImGui KeyA-KeyZ
|
|
if scancode >= 4 && scancode <= 29 {
|
|
return cimgui.Key(int(cimgui.KeyA) + int(scancode-4))
|
|
}
|
|
// Numbers 0-9: scancodes 30-39
|
|
if scancode >= 30 && scancode <= 39 {
|
|
return cimgui.Key(int(cimgui.Key0) + int(scancode-30))
|
|
}
|
|
return -1
|
|
}
|
|
}
|
|
|
|
// cstr reads a NUL-terminated C string at p.
|
|
// TODO: same func used in Vulkan
|
|
// Maybe i should create something like "package common"
|
|
// for funcs like this
|
|
func cstr(p uintptr) string {
|
|
if p == 0 {
|
|
return ""
|
|
}
|
|
var n int
|
|
for *(*byte)(unsafe.Pointer(p + uintptr(n))) != 0 {
|
|
n++
|
|
}
|
|
return string(unsafe.Slice((*byte)(unsafe.Pointer(p)), n))
|
|
}
|