Browse Source

Joystick, Keyboard and some display functions with some benchmarks. Results are not too bad.

Beoran 12 năm trước cách đây
mục cha
commit
aa086a8027
5 tập tin đã thay đổi với 867 bổ sung4 xóa
  1. 3 4
      src/algo/al/al.go
  2. 114 0
      src/algo/al/al_test.go
  3. 304 0
      src/algo/al/aldisplay.go
  4. 217 0
      src/algo/al/aljoystick.go
  5. 229 0
      src/algo/al/alkeyboard.go

+ 3 - 4
src/algo/al/al.go

@@ -391,7 +391,6 @@ func (self *Event) IsUser() bool {
 	return EVENT_TYPE_IS_USER(t)
 }
 
-type Display C.ALLEGRO_DISPLAY
 
 // Returns the display that has emitted the event. Will return nil if 
 // this is not a display event.
@@ -399,7 +398,7 @@ func (self *Event) DisplayDisplay() *Display {
 	if !(self.IsDisplay()) {
 		return nil
 	}
-	return (*Display)(C.algo_event_display(self.toC()).source)
+	return wrapDisplayRaw(C.algo_event_display(self.toC()).source)
 }
 
 // Returns the X position of the display event. Will return garbage 
@@ -466,7 +465,7 @@ func (self *Event) KeyboardDisplay() *Display {
 	if !(self.IsKeyboard()) {
 		return nil
 	}
-	return (*Display)(C.algo_event_keyboard(self.toC()).display)
+	return wrapDisplayRaw(C.algo_event_keyboard(self.toC()).display)
 }
 
 // Returns the keycode of the keyboard event. Returns garbage 
@@ -559,7 +558,7 @@ func (self *Event) MouseDisplay() *Display {
 	if !(self.IsMouse()) {
 		return nil
 	}
-	return (*Display)(C.algo_event_mouse(self.toC()).display)
+	return wrapDisplayRaw(C.algo_event_mouse(self.toC()).display)
 }
 
 // Returns the error of the timer event. Returns garbage 

+ 114 - 0
src/algo/al/al_test.go

@@ -7,6 +7,9 @@ import "runtime"
 
 // some parameters
 const expected_version = 83887873
+const SCREEN_W         = 640 
+const SCREEN_H         = 480
+const TEST_FULLSCREEN  = false
 
 func TestGetAllegroVersion(t *testing.T) {
 	version := GetAllegroVersion()
@@ -96,3 +99,114 @@ func TestInhibitScreensaver(t *testing.T) {
 		t.Errorf("InhibitScreensaver failed: %v", ok)
 	}
 }
+
+
+
+// Test joystick functions, works better with a joystick plugged in ;)
+func TestJoystick(t *testing.T) {
+  InstallSystem()
+  defer UninstallSystem()
+  InstallJoystick()
+  defer UninstallJoystick()
+  num := GetNumJoysticks()
+  t.Logf("Found %d joysticks\n", num)
+  for index :=0 ; index < num ; index ++ {
+    js      := GetJoystick(index)
+    jsname  := js.GetName()
+    sticks  := js.GetNumSticks()
+    buttons := js.GetNumButtons()
+    t.Logf("Joystick %s (nr %d) has %d sticks and %d buttons:\n", 
+            jsname, index, sticks, buttons)
+    for sdex  := 0 ; sdex < sticks ; sdex++ {
+      axes    := js.GetNumAxes(sdex)
+      sname   := js.GetStickName(sdex)
+      sfname  := js.GetStickFlagsName(sdex)
+      t.Logf("Stick %s (nr %d, %s) has %d axes: ", sname, sdex, sfname, axes)
+      for adex :=0 ; adex < axes ; adex++ {
+        aname  := js.GetAxisName(sdex, adex)
+        t.Logf("%s (nr %d) ",aname, adex)
+      }
+    }
+    t.Logf("\nButtons :")
+    for bdex := 0 ; bdex < buttons; bdex++ {
+      bname := js.GetButtonName(bdex);
+        t.Logf("%s (nr %d) ",bname, bdex)
+    }
+    t.Logf("\n")
+  }
+}
+
+// Makesa display for testing, using the test's setting above 
+func makeDisplay() (*Display) {
+  flags := 0
+  // Use full screen mode if needed.
+  if TEST_FULLSCREEN  { 
+    flags = FULLSCREEN | GENERATE_EXPOSE_EVENTS;
+  } 
+  SetNewDisplayFlags(flags)
+  // Create a window to display things on: 640x480 pixels.
+  display := CreateDisplay(SCREEN_W, SCREEN_H)  
+  return display
+}
+
+// Test basic display functions 
+func TestBasicDisplay(t *testing.T) {
+  InstallSystem()
+  defer UninstallSystem()  
+  display := makeDisplay()
+  if display == nil {
+    t.Error("Error creating display.")
+  }
+  /*
+  if !display.Resize(SCREEN_W, SCREEN_H) {
+    t.Error("Resize of display failed.")
+  }
+  */
+  blue   := CreateColor(0.0, 0.0, 1.0, 1.0)
+  yellow := CreateColor(1.0, 1.0, 0.0, 1.0)
+  ClearToColor(blue)
+  DrawPixel(20.0, 10.0, yellow)  
+  FlipDisplay()
+  ClearToColor(yellow)
+  DrawPixel(20.0, 10.0, blue)
+  FlipDisplay()
+  display.Destroy() 
+}
+
+// Benchmark basic display function ClearToColor
+func BenchmarkClearToColor(b *testing.B) {
+    b.StopTimer()
+    InstallSystem()
+    defer UninstallSystem()  
+    display := makeDisplay()
+    blue    := CreateColor(0.0, 0.0, 1.0, 1.0)
+    if display == nil {
+      b.Fatal("Error creating display. Cannot benchmark it.")
+    }
+    b.StartTimer()
+    for i := 0; i < b.N; i++ {
+        ClearToColor(blue)
+        FlipDisplay()
+    }    
+    display.Destroy()
+}
+
+// Benchmark basic display function FlipDisplay
+func BenchmarkFlipDisplay(b *testing.B) {
+    b.StopTimer()
+    InstallSystem()
+    defer UninstallSystem()  
+    display := makeDisplay()
+    if display == nil {
+      b.Fatal("Error creating display. Cannot benchmark it.")
+    }
+    b.StartTimer()
+    for i := 0; i < b.N; i++ {
+        FlipDisplay()
+    }
+    display.Destroy()
+}
+
+
+
+

+ 304 - 0
src/algo/al/aldisplay.go

@@ -0,0 +1,304 @@
+package al
+
+/*
+#include <stdlib.h>
+#include <allegro5/allegro.h>
+#include "helpers.h"
+*/
+import "C"
+
+import "runtime"
+
+// Usful regexp for KATE:  ALLEGRO_([A-Z0-9_]+)(.*) -> \1 = C.ALLEGRO_\1
+
+// Display functions.
+
+// Possible bit combinations for the flags parameter of CreateDisplay.
+const (
+   WINDOWED = C.ALLEGRO_WINDOWED
+   FULLSCREEN = C.ALLEGRO_FULLSCREEN
+   OPENGL = C.ALLEGRO_OPENGL
+   DIRECT3D_INTERNAL = C.ALLEGRO_DIRECT3D_INTERNAL
+   RESIZABLE = C.ALLEGRO_RESIZABLE
+   FRAMELESS = C.ALLEGRO_FRAMELESS
+   NOFRAME = C.ALLEGRO_NOFRAME
+   GENERATE_EXPOSE_EVENTS = C.ALLEGRO_GENERATE_EXPOSE_EVENTS
+   OPENGL_3_0 = C.ALLEGRO_OPENGL_3_0
+   OPENGL_FORWARD_COMPATIBLE = C.ALLEGRO_OPENGL_FORWARD_COMPATIBLE
+   FULLSCREEN_WINDOW = C.ALLEGRO_FULLSCREEN_WINDOW
+   MINIMIZED = C.ALLEGRO_MINIMIZED
+)
+
+/* Possible parameters for SetDisplayOption. */
+const (
+   RED_SIZE = C.ALLEGRO_RED_SIZE
+   GREEN_SIZE = C.ALLEGRO_GREEN_SIZE
+   BLUE_SIZE = C.ALLEGRO_BLUE_SIZE
+   ALPHA_SIZE = C.ALLEGRO_ALPHA_SIZE
+   RED_SHIFT = C.ALLEGRO_RED_SHIFT
+   GREEN_SHIFT = C.ALLEGRO_GREEN_SHIFT
+   BLUE_SHIFT = C.ALLEGRO_BLUE_SHIFT
+   ALPHA_SHIFT = C.ALLEGRO_ALPHA_SHIFT
+   ACC_RED_SIZE = C.ALLEGRO_ACC_RED_SIZE
+   ACC_GREEN_SIZE = C.ALLEGRO_ACC_GREEN_SIZE
+   ACC_BLUE_SIZE = C.ALLEGRO_ACC_BLUE_SIZE
+   ACC_ALPHA_SIZE = C.ALLEGRO_ACC_ALPHA_SIZE
+   STEREO = C.ALLEGRO_STEREO
+   AUX_BUFFERS = C.ALLEGRO_AUX_BUFFERS
+   COLOR_SIZE = C.ALLEGRO_COLOR_SIZE
+   DEPTH_SIZE = C.ALLEGRO_DEPTH_SIZE
+   STENCIL_SIZE = C.ALLEGRO_STENCIL_SIZE
+   SAMPLE_BUFFERS = C.ALLEGRO_SAMPLE_BUFFERS
+   SAMPLES = C.ALLEGRO_SAMPLES
+   RENDER_METHOD = C.ALLEGRO_RENDER_METHOD
+   FLOAT_COLOR = C.ALLEGRO_FLOAT_COLOR
+   FLOAT_DEPTH = C.ALLEGRO_FLOAT_DEPTH
+   SINGLE_BUFFER = C.ALLEGRO_SINGLE_BUFFER
+   SWAP_METHOD = C.ALLEGRO_SWAP_METHOD
+   COMPATIBLE_DISPLAY = C.ALLEGRO_COMPATIBLE_DISPLAY
+   UPDATE_DISPLAY_REGION = C.ALLEGRO_UPDATE_DISPLAY_REGION
+   VSYNC = C.ALLEGRO_VSYNC
+   MAX_BITMAP_SIZE = C.ALLEGRO_MAX_BITMAP_SIZE
+   SUPPORT_NPOT_BITMAP = C.ALLEGRO_SUPPORT_NPOT_BITMAP
+   CAN_DRAW_INTO_BITMAP = C.ALLEGRO_CAN_DRAW_INTO_BITMAP
+   SUPPORT_SEPARATE_ALPHA = C.ALLEGRO_SUPPORT_SEPARATE_ALPHA
+   DISPLAY_OPTIONS_COUNT = C.ALLEGRO_DISPLAY_OPTIONS_COUNT
+)
+
+// Constants thatdetermine if a setting is required or not.
+const (
+   DONTCARE = C.ALLEGRO_DONTCARE
+   REQUIRE = C.ALLEGRO_REQUIRE
+   SUGGEST = C.ALLEGRO_SUGGEST
+)
+
+// Display orientations
+const (
+   DISPLAY_ORIENTATION_0_DEGREES = C.ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES
+   DISPLAY_ORIENTATION_90_DEGREES = C.ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES
+   DISPLAY_ORIENTATION_180_DEGREES = C.ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES
+   DISPLAY_ORIENTATION_270_DEGREES = C.ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES
+   DISPLAY_ORIENTATION_FACE_UP = C.ALLEGRO_DISPLAY_ORIENTATION_FACE_UP
+   DISPLAY_ORIENTATION_FACE_DOWN = C.ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN
+)
+
+// Type that wraps a Display (a main window)
+type Display struct {
+  handle * C.ALLEGRO_DISPLAY
+}
+
+// Destroys a display. Use this only when really needed!
+func (self * Display) Destroy() {
+  if(self.handle != nil) {
+    C.al_destroy_display(self.handle)
+  }
+  self.handle = nil
+}
+
+// Wraps a C Allegro display in a Display. Sets no finalizer.
+func wrapDisplayRaw(handle * C.ALLEGRO_DISPLAY) * Display {
+  if handle == nil { return nil } 
+  return &Display{handle}
+}
+
+// Wraps a C Allegro display in a Display. Sets a finalizer that calls Destroy
+func wrapDisplay(handle * C.ALLEGRO_DISPLAY) * Display {
+  self := wrapDisplayRaw(handle)
+  if self != nil {
+    runtime.SetFinalizer(self, func (me * Display) { me.Destroy() })
+  }
+  return self
+}
+
+
+// Display mode info.
+type DisplayMode C.ALLEGRO_DISPLAY_MODE 
+
+// Returns the width of the display mode self.
+func (self * DisplayMode) Width() int {
+  return int(self.width)
+}
+
+// Returns the height of the display mode self.
+func (self * DisplayMode) Height() int {
+  return int(self.height)
+}
+
+// Returns the format of the display mode self.
+func (self * DisplayMode) Format() int {
+  return int(self.format)
+}
+
+// Returns the refresh rate of the display mode self.
+func (self * DisplayMode) RefreshRate() int {
+  return int(self.refresh_rate)
+}
+
+// Monitor info
+type MonitorInfo C.ALLEGRO_MONITOR_INFO
+
+// Returns the X1 of the monitor info self.
+func (self * MonitorInfo) X1() int {
+  return int(self.x1)
+}
+
+// Returns the Y1 of the monitor info self.
+func (self * MonitorInfo) Y1() int {
+  return int(self.y1)
+}
+
+// Returns the X2 of the monitor info self.
+func (self * MonitorInfo) X2() int {
+  return int(self.x2)
+}
+
+// Returns the Y2 of the monitor info self.
+func (self * MonitorInfo) Y2() int {
+  return int(self.y2)
+}
+
+
+const (
+   DEFAULT_DISPLAY_ADAPTER = C.ALLEGRO_DEFAULT_DISPLAY_ADAPTER
+)
+
+// Sets the flags that a display created by CreateDisplay will get after
+// this function was called.
+func SetNewDisplayFlags(flags int) {
+  C.al_set_new_display_flags(C.int(flags))
+}
+
+// Creates a new dosplay with the given size. Influenced by SetNewDisplayFlags.
+func CreateDisplay(width, height int) (*Display) {
+  return wrapDisplay(C.al_create_display(C.int(width), C.int(height)))
+}
+
+// Resizes the display.
+func (self * Display) Resize(width, height int) bool {
+  return bool(C.al_resize_display(self.handle, C.int(width), C.int(height)))
+}
+
+// Updates the display to the physical scree no any changes become visible
+func FlipDisplay() {
+  C.al_flip_display()
+}
+
+// Same as FlipDisplay, for mere consistency
+func (self * Display) Flip() {
+  C.al_flip_display()
+}
+
+
+// Color type
+type Color C.ALLEGRO_COLOR
+
+// Convert to C
+func (self Color) toC() C.ALLEGRO_COLOR {
+  return C.ALLEGRO_COLOR(self)
+}
+
+
+// Creates a new color 
+func CreateColor(r, g, b, a float32) Color {
+  return Color{C.float(r),C.float(g),C.float(b),C.float(a)}
+}
+
+// Returns the R component of the color self.
+func (self Color) R() float32 {
+  return float32(self.r)
+}
+
+// Returns the G component of the color self.
+func (self Color) G() float32 {
+  return float32(self.g)
+}
+
+// Returns the B component of the color self.
+func (self Color) B() float32 {
+  return float32(self.b)
+}
+
+// Returns the A component of the color self.
+func (self Color) A() float32 {
+  return float32(self.a)
+}
+
+// Fills the current active display with a color
+func ClearToColor(color Color) {
+  C.al_clear_to_color(color.toC());
+}
+
+// Draws a pixel on the active display at the given location 
+// with the given color
+func DrawPixel(x, y float32, color Color) {
+  C.al_draw_pixel(C.float(x), C.float(y), C.ALLEGRO_COLOR(color))
+}
+
+
+/*
+AL_FUNC(void, al_set_new_display_refresh_rate, (int refresh_rate));
+AL_FUNC(void, al_set_new_display_flags, (int flags));
+AL_FUNC(int,  al_get_new_display_refresh_rate, (void));
+AL_FUNC(int,  al_get_new_display_flags, (void));
+
+AL_FUNC(int, al_get_display_width,  (ALLEGRO_DISPLAY *display));
+AL_FUNC(int, al_get_display_height, (ALLEGRO_DISPLAY *display));
+AL_FUNC(int, al_get_display_format, (ALLEGRO_DISPLAY *display));
+AL_FUNC(int, al_get_display_refresh_rate, (ALLEGRO_DISPLAY *display));
+AL_FUNC(int, al_get_display_flags,  (ALLEGRO_DISPLAY *display));
+AL_FUNC(bool, al_set_display_flag, (ALLEGRO_DISPLAY *display, int flag, bool onoff));
+AL_FUNC(bool, al_toggle_display_flag, (ALLEGRO_DISPLAY *display, int flag, bool onoff));
+
+AL_FUNC(ALLEGRO_DISPLAY*, al_create_display, (int w, int h));
+AL_FUNC(void,             al_destroy_display, (ALLEGRO_DISPLAY *display));
+AL_FUNC(ALLEGRO_DISPLAY*, al_get_current_display, (void));
+AL_FUNC(void,            al_set_target_bitmap, (ALLEGRO_BITMAP *bitmap));
+AL_FUNC(void,            al_set_target_backbuffer, (ALLEGRO_DISPLAY *display));
+AL_FUNC(ALLEGRO_BITMAP*, al_get_backbuffer,    (ALLEGRO_DISPLAY *display));
+AL_FUNC(ALLEGRO_BITMAP*, al_get_target_bitmap, (void));
+
+AL_FUNC(bool, al_acknowledge_resize, (ALLEGRO_DISPLAY *display));
+AL_FUNC(bool, al_resize_display,     (ALLEGRO_DISPLAY *display, int width, int height));
+AL_FUNC(void, al_flip_display,       (void));
+AL_FUNC(void, al_update_display_region, (int x, int y, int width, int height));
+AL_FUNC(bool, al_is_compatible_bitmap, (ALLEGRO_BITMAP *bitmap));
+
+AL_FUNC(int, al_get_num_display_modes, (void));
+AL_FUNC(ALLEGRO_DISPLAY_MODE*, al_get_display_mode, (int index,
+        ALLEGRO_DISPLAY_MODE *mode));
+
+AL_FUNC(bool, al_wait_for_vsync, (void));
+
+AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_display_event_source, (ALLEGRO_DISPLAY *display));
+
+
+AL_FUNC(void, al_clear_to_color, (ALLEGRO_COLOR color));
+AL_FUNC(void, al_draw_pixel, (float x, float y, ALLEGRO_COLOR color));
+
+AL_FUNC(void, al_set_display_icon, (ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *icon));
+
+
+AL_FUNC(int, al_get_num_video_adapters, (void));
+AL_FUNC(bool, al_get_monitor_info, (int adapter, ALLEGRO_MONITOR_INFO *info));
+AL_FUNC(int, al_get_new_display_adapter, (void));
+AL_FUNC(void, al_set_new_display_adapter, (int adapter));
+AL_FUNC(void, al_set_new_window_position, (int x, int y));
+AL_FUNC(void, al_get_new_window_position, (int *x, int *y));
+AL_FUNC(void, al_set_window_position, (ALLEGRO_DISPLAY *display, int x, int y));
+AL_FUNC(void, al_get_window_position, (ALLEGRO_DISPLAY *display, int *x, int *y));
+
+AL_FUNC(void, al_set_window_title, (ALLEGRO_DISPLAY *display, const char *title));
+
+
+AL_FUNC(void, al_set_new_display_option, (int option, int value, int importance));
+AL_FUNC(int, al_get_new_display_option, (int option, int *importance));
+AL_FUNC(void, al_reset_new_display_options, (void));
+AL_FUNC(int, al_get_display_option, (ALLEGRO_DISPLAY *display, int option));
+
+
+AL_FUNC(void, al_hold_bitmap_drawing, (bool hold));
+AL_FUNC(bool, al_is_bitmap_drawing_held, (void));
+
+*/
+
+

+ 217 - 0
src/algo/al/aljoystick.go

@@ -0,0 +1,217 @@
+package al
+
+/*
+#include <stdlib.h>
+#include <allegro5/allegro.h>
+#include "helpers.h"
+*/
+import "C"
+
+import "runtime"
+
+// Usful regexp for KATE:  ALLEGRO_([A-Z0-9_]+)(.*) -> \1 = C.ALLEGRO_\1
+
+// Joystick functionality.
+
+type Joystick struct { 
+  handle * C.ALLEGRO_JOYSTICK
+}
+
+// Destroyst he joystick. According to the Allegro documentation, this 
+// does nothing.
+func (self * Joystick) Destroy() {
+  // Some problems is this is enabled so make sure this does nothing...
+  // C.al_release_joystick(self.handle)
+}
+
+// Wraps a C joystick handler into the Go Joystick wrapper.
+func wrapJoystickRaw(handle * C.ALLEGRO_JOYSTICK) (*Joystick) {
+  if handle == nil { return nil }
+  return &Joystick{handle}
+}
+
+// Wraps a C joystick handler into the Go Joystick wrapper.
+// Also sets a finalizer that calls joystick.Destroy().
+func wrapJoystick(handle * C.ALLEGRO_JOYSTICK) (*Joystick) {
+  self := wrapJoystickRaw(handle)
+  if self != nil {
+    runtime.SetFinalizer(self, func(me * Joystick) { me.Destroy() } )
+  }
+  return self
+}
+
+// Struct that holds the state of the joystick.
+type JoystickState C.ALLEGRO_JOYSTICK_STATE
+
+// Converts a wrapped joystick state to a C joystick state.
+func (self * JoystickState) toC()  *C.ALLEGRO_JOYSTICK_STATE {
+  return (*C.ALLEGRO_JOYSTICK_STATE)(self)
+}
+
+// Gets the state of the axis for the given stick on the joystick.
+// returns 0.0 if the stick or axis are out of range. May return
+// garbage for nonexisting sticks and axes.
+func (self * JoystickState) GetStickAxis(stick, axis int) float32 {
+  if (stick >= int(C._AL_MAX_JOYSTICK_STICKS)) { return 0.0 }
+  if (axis >= int(C._AL_MAX_JOYSTICK_AXES))    { return 0.0 }
+  if (axis  < 0) { return 0.0 }
+  if (stick < 0) { return 0.0 }
+  return float32(self.stick[C.int(stick)].axis[C.int(axis)])
+}
+
+// Gerts the state of the button with the given index on the joystick.
+// Will return -1 if the button is out of range.
+func (self * JoystickState) GetButton(button int) int {
+  if (button >= int(C._AL_MAX_JOYSTICK_BUTTONS)) { return -1 }
+  if (button < 0) { return -1 }
+  return int(self.button[C.int(button)])
+}
+
+
+// Joystick flags that determine the type of the joystick.
+const (
+  JOYFLAG_DIGITAL  = C.ALLEGRO_JOYFLAG_DIGITAL
+  JOYFLAG_ANALOGUE = C.ALLEGRO_JOYFLAG_ANALOGUE 
+)
+
+
+// Installs the Allegro Joystick module.
+func InstallJoystick() bool {
+  return bool(C.al_install_joystick())
+}
+
+// Uninstalls the Allegro Joystick module.
+func UninstallJoystick() {
+  C.al_uninstall_joystick()
+}
+
+// Returns true if the Allegro joystick module ws instaled, false if not.
+func IsJoystickInstalled() bool {
+  return bool(C.al_is_joystick_installed())
+}
+
+// Returns the amount of joysticks detected.
+func GetNumJoysticks() int {
+  return int(C.al_get_num_joysticks())
+}
+
+// Returns the joyn'th joystick, or nil if no such stick exists. 
+func GetJoystick(joyn int) (*Joystick) {
+  return wrapJoystick(C.al_get_joystick(C.int(joyn)))
+}
+
+
+// Joystick properties.
+
+// Returns true if the joystick self is active, false if not.
+func (self * Joystick) IsActive() bool {
+  return bool(C.al_get_joystick_active(self.handle))
+}
+
+// Returns the name of the joystick self.
+func (self * Joystick) GetName() string {
+  return gostr(C.al_get_joystick_name(self.handle))
+}
+
+// Returns the amount of sticks the joystick self has.
+func (self * Joystick) GetNumSticks() int {
+  return int(C.al_get_joystick_num_sticks(self.handle))
+}
+
+// Returns the joystick flags for the numbered stick on the joystick self.
+func (self * Joystick) GetStickFlags(stick int) int {
+  return int(C.al_get_joystick_stick_flags(self.handle, C.int(stick)))
+}
+
+// Returns true if the numbered stick on joystick self is digital, false if not.
+// Note that theoretically, a stick could be both digital and analog...
+func (self * Joystick) IsStickDigital(stick int) bool {
+  return (JOYFLAG_DIGITAL &  self.GetStickFlags(stick)) == JOYFLAG_DIGITAL
+}
+
+// Returns true if the numbered stick on joystick self is analog, false if not
+// Note that theoretically, a stick could be both digital and analog...
+func (self * Joystick) IsStickAnalog(stick int) bool {
+  return (JOYFLAG_ANALOGUE &  self.GetStickFlags(stick)) == JOYFLAG_ANALOGUE
+}
+
+// Returns a string that describes the joystick flags for the numbered stick 
+// on the joystick self. Will return "Analog" for an analog joystick, 
+// "Digital" for a digital joystick, "Hybrid" fo one that's both and 
+// "None" for one that's neither
+func (self * Joystick) GetStickFlagsName(stick int) string {
+  if self.IsStickAnalog(stick) {
+    if self.IsStickDigital(stick) { 
+      return "Hybrid"
+    } else { 
+      return "Analog"
+    }
+  } 
+  if self.IsStickDigital(stick) {
+    return "Digital"
+  } 
+  return "None"
+}
+
+
+// Returns the name of the stick on the joystick self.
+func (self * Joystick) GetStickName(stick int) string {
+  return gostr(C.al_get_joystick_stick_name(self.handle, C.int(stick)))
+}
+
+
+// Returns the amount of axes for the stick on the joystick self.
+func (self * Joystick) GetNumAxes(stick int) int {
+  return int(C.al_get_joystick_num_axes(self.handle, C.int(stick)))
+}
+
+// Returns the name of the axis for the stick on the joystick self.
+func (self * Joystick) GetAxisName(stick, axis int) string {
+  return gostr(C.al_get_joystick_axis_name(self.handle, C.int(stick), C.int(axis)))
+}
+
+// Returns the amount of buttons on the joystick self.
+func (self * Joystick) GetNumButtons() int {
+  return int(C.al_get_joystick_num_buttons(self.handle))
+}
+
+// Returns the name of the button on the joystick self.
+func (self * Joystick) GetButtonName(button int) string {
+  return gostr(C.al_get_joystick_button_name(self.handle, C.int(button)))
+}
+
+// Gets the state of the joystick
+func (self * Joystick) GetState() (* JoystickState) {
+  state := &JoystickState{}
+  C.al_get_joystick_state(self.handle, state.toC())
+  return state
+}
+
+
+/*
+AL_FUNC(bool,           al_install_joystick,    (void));
+AL_FUNC(void,           al_uninstall_joystick,  (void));
+AL_FUNC(bool,           al_is_joystick_installed, (void));
+AL_FUNC(bool,           al_reconfigure_joysticks, (void));
+
+AL_FUNC(int,            al_get_num_joysticks,   (void));
+AL_FUNC(ALLEGRO_JOYSTICK *, al_get_joystick,    (int joyn));
+AL_FUNC(void,           al_release_joystick,    (ALLEGRO_JOYSTICK *));
+AL_FUNC(bool,           al_get_joystick_active, (ALLEGRO_JOYSTICK *));
+AL_FUNC(const char*,    al_get_joystick_name,   (ALLEGRO_JOYSTICK *));
+
+AL_FUNC(int,            al_get_joystick_num_sticks, (ALLEGRO_JOYSTICK *));
+AL_FUNC(int, al_get_joystick_stick_flags, (ALLEGRO_JOYSTICK *, int stick)); 
+
+AL_FUNC(const char*,    al_get_joystick_stick_name, (ALLEGRO_JOYSTICK *, int stick));
+
+AL_FUNC(int,            al_get_joystick_num_axes,   (ALLEGRO_JOYSTICK *, int stick));
+AL_FUNC(const char*,    al_get_joystick_axis_name,  (ALLEGRO_JOYSTICK *, int stick, int axis));
+
+AL_FUNC(int,            al_get_joystick_num_buttons,  (ALLEGRO_JOYSTICK *));
+AL_FUNC(const char*,    al_get_joystick_button_name,  (ALLEGRO_JOYSTICK *, int buttonn));
+
+AL_FUNC(void,           al_get_joystick_state,  (ALLEGRO_JOYSTICK *, ALLEGRO_JOYSTICK_STATE *ret_state));
+
+AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_joystick_event_source, (void));
+*/

+ 229 - 0
src/algo/al/alkeyboard.go

@@ -0,0 +1,229 @@
+package al
+
+/*
+#include <stdlib.h>
+#include <allegro5/allegro.h>
+#include "helpers.h"
+*/
+import "C"
+
+// Usful regexp for KATE:  ALLEGRO_([A-Z0-9_]+)(.*) -> \1 = C.ALLEGRO_\1
+
+
+// Keyboard functionality.
+
+// Checks if the Allegro keyboard module is installed or not.
+func IsKeyboardInstalled() bool {
+  return bool(C.al_is_keyboard_installed())
+}
+
+// Installs the Allegro keyboard module.
+func InstallKeyboard() bool {
+  return bool(C.al_install_keyboard())
+}
+
+// Uninstalls the Allegro keyboard module.
+func UninstallKeyboard() {
+  C.al_uninstall_keyboard()
+}
+
+// Gets the name of te given keucode as a string.
+func KeycodeToName(keycode int) string {
+  return gostr(C.al_keycode_to_name(C.int(keycode)))
+}
+
+// KeyboardState isn't very interesting for now, so don't wrap it
+// and let KeyDown work as a global function
+
+// Gets the state of a given keyboard key by keycode. True is down, false is up.
+func KeyDown(keycode int) bool {
+  state := &C.ALLEGRO_KEYBOARD_STATE{}
+  C.al_get_keyboard_state(state)
+  return bool(C.al_key_down(state, C.int(keycode)))
+}
+
+// Sets the state of the leds on the keyboard.
+func SetKeyboardLeds(leds int) bool {
+  return bool(C.al_set_keyboard_leds(C.int(leds)))
+}
+
+// Returns the Keyboard event source that can be registered to an EventQueue
+// with RegisterEventSource.
+func GetKeyboardEventSource() * EventSource {
+  return (*EventSource)(C.al_get_keyboard_event_source())
+}
+
+
+// Keyboard constants
+const (
+	KEY_A = C.ALLEGRO_KEY_A
+	KEY_B = C.ALLEGRO_KEY_B
+	KEY_C = C.ALLEGRO_KEY_C
+	KEY_D = C.ALLEGRO_KEY_D
+	KEY_E = C.ALLEGRO_KEY_E
+	KEY_F = C.ALLEGRO_KEY_F
+	KEY_G = C.ALLEGRO_KEY_G
+	KEY_H = C.ALLEGRO_KEY_H
+	KEY_I = C.ALLEGRO_KEY_I
+	KEY_J = C.ALLEGRO_KEY_J
+	KEY_K = C.ALLEGRO_KEY_K
+	KEY_L = C.ALLEGRO_KEY_L
+	KEY_M = C.ALLEGRO_KEY_M
+	KEY_N = C.ALLEGRO_KEY_N
+	KEY_O = C.ALLEGRO_KEY_O
+	KEY_P = C.ALLEGRO_KEY_P
+	KEY_Q = C.ALLEGRO_KEY_Q
+	KEY_R = C.ALLEGRO_KEY_R
+	KEY_S = C.ALLEGRO_KEY_S
+	KEY_T = C.ALLEGRO_KEY_T
+	KEY_U = C.ALLEGRO_KEY_U
+	KEY_V = C.ALLEGRO_KEY_V
+	KEY_W = C.ALLEGRO_KEY_W
+	KEY_X = C.ALLEGRO_KEY_X
+	KEY_Y = C.ALLEGRO_KEY_Y
+	KEY_Z = C.ALLEGRO_KEY_Z
+
+	KEY_0 = C.ALLEGRO_KEY_0
+	KEY_1 = C.ALLEGRO_KEY_1
+	KEY_2 = C.ALLEGRO_KEY_2
+	KEY_3 = C.ALLEGRO_KEY_3
+	KEY_4 = C.ALLEGRO_KEY_4
+	KEY_5 = C.ALLEGRO_KEY_5
+	KEY_6 = C.ALLEGRO_KEY_6
+	KEY_7 = C.ALLEGRO_KEY_7
+	KEY_8 = C.ALLEGRO_KEY_8
+	KEY_9 = C.ALLEGRO_KEY_9
+
+	KEY_PAD_0 = C.ALLEGRO_KEY_PAD_0
+	KEY_PAD_1 = C.ALLEGRO_KEY_PAD_1
+	KEY_PAD_2 = C.ALLEGRO_KEY_PAD_2
+	KEY_PAD_3 = C.ALLEGRO_KEY_PAD_3
+	KEY_PAD_4 = C.ALLEGRO_KEY_PAD_4
+	KEY_PAD_5 = C.ALLEGRO_KEY_PAD_5
+	KEY_PAD_6 = C.ALLEGRO_KEY_PAD_6
+	KEY_PAD_7 = C.ALLEGRO_KEY_PAD_7
+	KEY_PAD_8 = C.ALLEGRO_KEY_PAD_8
+	KEY_PAD_9 = C.ALLEGRO_KEY_PAD_9
+
+	KEY_F1  = C.ALLEGRO_KEY_F1
+	KEY_F2  = C.ALLEGRO_KEY_F2
+	KEY_F3  = C.ALLEGRO_KEY_F3
+	KEY_F4  = C.ALLEGRO_KEY_F4
+	KEY_F5  = C.ALLEGRO_KEY_F5
+	KEY_F6  = C.ALLEGRO_KEY_F6
+	KEY_F7  = C.ALLEGRO_KEY_F7
+	KEY_F8  = C.ALLEGRO_KEY_F8
+	KEY_F9  = C.ALLEGRO_KEY_F9
+	KEY_F10 = C.ALLEGRO_KEY_F10
+	KEY_F11 = C.ALLEGRO_KEY_F11
+	KEY_F12 = C.ALLEGRO_KEY_F12
+
+	KEY_ESCAPE     = C.ALLEGRO_KEY_ESCAPE
+	KEY_TILDE      = C.ALLEGRO_KEY_TILDE
+	KEY_MINUS      = C.ALLEGRO_KEY_MINUS
+	KEY_EQUALS     = C.ALLEGRO_KEY_EQUALS
+	KEY_BACKSPACE  = C.ALLEGRO_KEY_BACKSPACE
+	KEY_TAB        = C.ALLEGRO_KEY_TAB
+	KEY_OPENBRACE  = C.ALLEGRO_KEY_OPENBRACE
+	KEY_CLOSEBRACE = C.ALLEGRO_KEY_CLOSEBRACE
+	KEY_ENTER      = C.ALLEGRO_KEY_ENTER
+	KEY_SEMICOLON  = C.ALLEGRO_KEY_SEMICOLON
+	KEY_QUOTE      = C.ALLEGRO_KEY_QUOTE
+	KEY_BACKSLASH  = C.ALLEGRO_KEY_BACKSLASH
+	KEY_BACKSLASH2 = C.ALLEGRO_KEY_BACKSLASH2
+	KEY_COMMA      = C.ALLEGRO_KEY_COMMA
+	KEY_FULLSTOP   = C.ALLEGRO_KEY_FULLSTOP
+	KEY_SLASH      = C.ALLEGRO_KEY_SLASH
+	KEY_SPACE      = C.ALLEGRO_KEY_SPACE
+
+	KEY_INSERT = C.ALLEGRO_KEY_INSERT
+	KEY_DELETE = C.ALLEGRO_KEY_DELETE
+	KEY_HOME   = C.ALLEGRO_KEY_HOME
+	KEY_END    = C.ALLEGRO_KEY_END
+	KEY_PGUP   = C.ALLEGRO_KEY_PGUP
+	KEY_PGDN   = C.ALLEGRO_KEY_PGDN
+	KEY_LEFT   = C.ALLEGRO_KEY_LEFT
+	KEY_RIGHT  = C.ALLEGRO_KEY_RIGHT
+	KEY_UP     = C.ALLEGRO_KEY_UP
+	KEY_DOWN   = C.ALLEGRO_KEY_DOWN
+
+	KEY_PAD_SLASH    = C.ALLEGRO_KEY_PAD_SLASH
+	KEY_PAD_ASTERISK = C.ALLEGRO_KEY_PAD_ASTERISK
+	KEY_PAD_MINUS    = C.ALLEGRO_KEY_PAD_MINUS
+	KEY_PAD_PLUS     = C.ALLEGRO_KEY_PAD_PLUS
+	KEY_PAD_DELETE   = C.ALLEGRO_KEY_PAD_DELETE
+	KEY_PAD_ENTER    = C.ALLEGRO_KEY_PAD_ENTER
+
+	KEY_PRINTSCREEN = C.ALLEGRO_KEY_PRINTSCREEN
+	KEY_PAUSE       = C.ALLEGRO_KEY_PAUSE
+
+	KEY_ABNT_C1    = C.ALLEGRO_KEY_ABNT_C1
+	KEY_YEN        = C.ALLEGRO_KEY_YEN
+	KEY_KANA       = C.ALLEGRO_KEY_KANA
+	KEY_CONVERT    = C.ALLEGRO_KEY_CONVERT
+	KEY_NOCONVERT  = C.ALLEGRO_KEY_NOCONVERT
+	KEY_AT         = C.ALLEGRO_KEY_AT
+	KEY_CIRCUMFLEX = C.ALLEGRO_KEY_CIRCUMFLEX
+	KEY_COLON2     = C.ALLEGRO_KEY_COLON2
+	KEY_KANJI      = C.ALLEGRO_KEY_KANJI
+
+	KEY_PAD_EQUALS = C.ALLEGRO_KEY_PAD_EQUALS
+	KEY_BACKQUOTE  = C.ALLEGRO_KEY_BACKQUOTE
+	KEY_SEMICOLON2 = C.ALLEGRO_KEY_SEMICOLON2
+	KEY_COMMAND    = C.ALLEGRO_KEY_COMMAND
+	KEY_UNKNOWN    = C.ALLEGRO_KEY_UNKNOWN
+
+	/* All codes up to before KEY_MODIFIERS = C.ALLEGRO_KEY_MODIFIERS
+	 * assignedas additional unknown keys, like various multimedia
+	 * and application keys keyboards may have.
+	 */
+
+	KEY_MODIFIERS = C.ALLEGRO_KEY_MODIFIERS
+
+	KEY_LSHIFT     = C.ALLEGRO_KEY_LSHIFT
+	KEY_RSHIFT     = C.ALLEGRO_KEY_RSHIFT
+	KEY_LCTRL      = C.ALLEGRO_KEY_LCTRL
+	KEY_RCTRL      = C.ALLEGRO_KEY_RCTRL
+	KEY_ALT        = C.ALLEGRO_KEY_ALT
+	KEY_ALTGR      = C.ALLEGRO_KEY_ALTGR
+	KEY_LWIN       = C.ALLEGRO_KEY_LWIN
+	KEY_RWIN       = C.ALLEGRO_KEY_RWIN
+	KEY_MENU       = C.ALLEGRO_KEY_MENU
+	KEY_SCROLLLOCK = C.ALLEGRO_KEY_SCROLLLOCK
+	KEY_NUMLOCK    = C.ALLEGRO_KEY_NUMLOCK
+	KEY_CAPSLOCK   = C.ALLEGRO_KEY_CAPSLOCK
+
+	KEY_MAX = C.ALLEGRO_KEY_MAX
+)
+
+// Keyboard modifier constants
+const (
+	KEYMOD_SHIFT      = C.ALLEGRO_KEYMOD_SHIFT
+	KEYMOD_CTRL       = C.ALLEGRO_KEYMOD_CTRL
+	KEYMOD_ALT        = C.ALLEGRO_KEYMOD_ALT
+	KEYMOD_LWIN       = C.ALLEGRO_KEYMOD_LWIN
+	KEYMOD_RWIN       = C.ALLEGRO_KEYMOD_RWIN
+	KEYMOD_MENU       = C.ALLEGRO_KEYMOD_MENU
+	KEYMOD_ALTGR      = C.ALLEGRO_KEYMOD_ALTGR
+	KEYMOD_COMMAND    = C.ALLEGRO_KEYMOD_COMMAND
+	KEYMOD_SCROLLLOCK = C.ALLEGRO_KEYMOD_SCROLLLOCK
+	KEYMOD_NUMLOCK    = C.ALLEGRO_KEYMOD_NUMLOCK
+	KEYMOD_CAPSLOCK   = C.ALLEGRO_KEYMOD_CAPSLOCK
+	KEYMOD_INALTSEQ   = C.ALLEGRO_KEYMOD_INALTSEQ
+	KEYMOD_ACCENT1    = C.ALLEGRO_KEYMOD_ACCENT1
+	KEYMOD_ACCENT2    = C.ALLEGRO_KEYMOD_ACCENT2
+	KEYMOD_ACCENT3    = C.ALLEGRO_KEYMOD_ACCENT3
+	KEYMOD_ACCENT4    = C.ALLEGRO_KEYMOD_ACCENT4
+)
+
+
+
+
+
+
+
+
+
+
+
+