Browse Source

Wrapping blender, bitmap and clipboard functions.

Beoran 6 years ago
parent
commit
e6cbd242e1
8 changed files with 281 additions and 23 deletions
  1. 34 0
      al/aid.go
  2. 18 5
      al/al.go
  3. 66 0
      al/bitmap.go
  4. 8 0
      al/bitmap_draw.go
  5. 93 0
      al/blender.go
  6. 36 18
      al/callbacks.go
  7. 2 0
      al/callbacks.h
  8. 24 0
      al/clipboard.go

+ 34 - 0
al/aid.go

@@ -112,6 +112,40 @@ func cui16(f int) C.uint16_t {
     return C.uint16_t(f)
 }
 
+//Converts an array of C strings to a slice of Go strings
+func GoStrings(argc C.int, argv **C.char) []string {
+    length := int(argc)
+    tmpslice := (*[1 << 30]*C.char)(unsafe.Pointer(argv))[:length:length]
+    gostrings := make([]string, length)
+    for i, s := range tmpslice {
+        gostrings[i] = C.GoString(s)
+    }
+    return gostrings
+}
+
+//Converts an array of go strings to an array of C strings and a length 
+func CStrings(args []string) (argc C.int, argv **C.char) {
+    length := len(args)
+    argv = (**C.char)(malloc(length * int(unsafe.Sizeof(*argv))))
+    tmpslice := (*[1 << 30]*C.char)(unsafe.Pointer(argv))[:length:length]
+    for i, s := range args {
+        tmpslice[i] = cstr(s)
+    }
+    return argc, argv
+}
+
+// frees the data allocated by Cstrings
+func CStringsFree(argc C.int, argv **C.char) {
+    length := int(argc)
+    tmpslice := (*[1 << 30]*C.char)(unsafe.Pointer(argv))[:length:length]
+    for _, s := range tmpslice {
+        cstrFree(s)
+    }
+    free(unsafe.Pointer(argv))
+}
+
+
+
 
 /* This is the usual boilerplate for wrapping C types through a handle
 

+ 18 - 5
al/al.go

@@ -8,6 +8,7 @@ package al
 #include <allegro5/allegro.h>
 #include <allegro5/events.h>
 #include "helpers.h"
+#include "callbacks.h"
 */
 import "C"
 
@@ -32,7 +33,7 @@ const (
     DATE_STR        =  C.ALLEGRO_DATE_STR
     VERSION_INT     =  ((VERSION << 24) | (SUB_VERSION << 16) |
                         (WIP_VERSION << 8) | RELEASE_NUMBER | UNSTABLE_BIT)
-)
+ )
 
 // Converts bool to Allegro's C.bool
 func b2cb(res bool) C.bool {
@@ -241,8 +242,13 @@ func InhibitScreensaver(inhibit bool) bool {
     return bool(C.al_inhibit_screensaver(C.bool(inhibit)))
 }
 
-/// XXX How to wrap this and is it needed????
-// AL_FUNC(int, al_run_main, (int argc, char **argv, int (*)(int, char **)));
+// Might be needed on OSX.
+func RunMain(args []string, callback RunMainCallback, data interface{}) int {
+    runMain.fn   = callback
+    runMain.data = data
+    argc, argv := CStrings(args) ; defer CStringsFree(argc, argv)
+    return int(C.al_run_main(argc, argv, (*[0]byte)(C.go_run_main_callback)))
+}
 
 /** Allegro has it's own string type. While it's nice, it's 
 not needed in Go, so I will just wrap the basic conversion functions. */
@@ -304,8 +310,8 @@ func USTRP(str *string) *USTR {
 
 // Allegro's timer functions 
 
-// Gets the time the app is running in seconds 
-func GetTime() float64 {
+// Gets the time since allegro was initialized in seconds 
+func Time() float64 {
     return float64(C.al_get_time())
 }
 
@@ -767,6 +773,13 @@ AL_FUNC(bool, al_wait_for_event_until, (ALLEGRO_EVENT_QUEUE *queue,
                                         ALLEGRO_TIMEOUT *timeout));
 */
 
+type Timeout = C.ALLEGRO_TIMEOUT
+
+func (tout * Timeout) Init(seconds float64) {
+    C.al_init_timeout(tout, C.double(seconds))
+}
+
+
 // Precise (?) Timer 
 type Timer struct {
     handle *C.ALLEGRO_TIMER

+ 66 - 0
al/bitmap.go

@@ -10,6 +10,7 @@ package al
 import "C"
 
 import "runtime"
+import "unsafe"
 
 // Type that wraps a Bitmap
 type Bitmap struct {
@@ -193,6 +194,20 @@ func (self *Bitmap) Parent() *Bitmap {
     return wrapBitmapRaw(C.al_get_parent_bitmap(self.handle))
 }
 
+// Gets the Returns the X position within the parent of a sub bitmap
+func (bmp *Bitmap) SubX() int {
+    return int(C.al_get_bitmap_x(bmp.handle))
+}
+// Gets the Returns the Y position within the parent of a sub bitmap
+func (bmp *Bitmap) SubY() int {
+    return int(C.al_get_bitmap_y(bmp.handle))
+}
+
+// Changes the parent, size and position of a sub bitmap 
+func (bmp *Bitmap) Reparent(parent * Bitmap, x, y, w, h int) {
+    C.al_reparent_bitmap(bmp.handle, parent.handle, C.int(x), C.int(y), C.int(w), C.int(h))
+}
+
 // Returns a raw clone of the bitmap, that will not be automatically 
 // destroyed.
 func (self *Bitmap) CloneRaw() *Bitmap {
@@ -215,3 +230,54 @@ func (self *Bitmap) Convert() {
 func ConvertMemoryBitmaps() {
     C.al_convert_memory_bitmaps()
 }
+
+const (
+    LOCK_READWRITE = C.ALLEGRO_LOCK_READWRITE
+    LOCK_READONLY  = C.ALLEGRO_LOCK_READONLY
+    LOCK_WRITEONLY = C.ALLEGRO_LOCK_WRITEONLY
+)
+
+type LockedRegion = C.ALLEGRO_LOCKED_REGION
+
+// TODO: Provide better access to the data member if needed
+func (lk * LockedRegion) dataPointer() unsafe.Pointer {
+    return unsafe.Pointer(lk.data)
+}
+
+func (lk * LockedRegion) Format() int {
+    return int(lk.format)
+}
+
+func (lk * LockedRegion) Pitch() int {
+    return int(lk.pitch)
+}
+
+func (lk * LockedRegion) PixelSize() int {
+    return int(lk.pixel_size)
+}
+
+func (bmp * Bitmap) Lock(format, flags int) *LockedRegion {
+    return (*LockedRegion)(C.al_lock_bitmap(bmp.handle, C.int(format), C.int(flags)))
+}
+
+func (bmp * Bitmap) LockRegion(x, y, width, height, format, flags int) *LockedRegion {
+    return (*LockedRegion)(C.al_lock_bitmap_region(bmp.handle, 
+    C.int(x), C.int(y), C.int(width), C.int(height), C.int(format), C.int(flags)))
+}
+
+func (bmp * Bitmap) LockBlocked(flags int) *LockedRegion {
+    return (*LockedRegion)(C.al_lock_bitmap_blocked(bmp.handle, C.int(flags)))
+}
+
+func (bmp * Bitmap) LockRegionBlocked(x, y, width, height, flags int) *LockedRegion {
+    return (*LockedRegion)(C.al_lock_bitmap_region_blocked(bmp.handle, 
+    C.int(x), C.int(y), C.int(width), C.int(height), C.int(flags)))
+}
+
+func (bmp * Bitmap) Unlock(){
+    C.al_unlock_bitmap(bmp.handle)
+}
+
+func (bmp * Bitmap) Locked() bool {
+    return bool(C.al_is_bitmap_locked(bmp.handle))
+}

+ 8 - 0
al/bitmap_draw.go

@@ -68,3 +68,11 @@ func (bmp * Bitmap) DrawTintedScaledRotated(color Color, cx, cy, dx, dy, xscale,
         C.float(xscale), C.float(yscale), C.float(angle), C.int(flags))
 }
 
+func (bmp * Bitmap) DrawTintedScaledRotatedRegion(sx, sy, sw, sh float32, color Color, cx, cy, dx, dy, xscale, yscale, angle float32, flags int) {
+    C.al_draw_tinted_scaled_rotated_bitmap_region(bmp.handle, 
+        C.float(sx), C.float(sy), C.float(sw), C.float(sh),
+        color.toC(),  C.float(cx), C.float(cy),
+        C.float(dx), C.float(dy), 
+        C.float(xscale), C.float(yscale), C.float(angle), C.int(flags))
+}
+

+ 93 - 0
al/blender.go

@@ -0,0 +1,93 @@
+// blender support
+package al
+
+/*
+#include <stdlib.h>
+#include <allegro5/allegro.h>
+#include "helpers.h"
+#include "callbacks.h"
+*/
+import "C"
+
+// import "runtime"
+// import "unsafe"
+
+type BlendMode C.enum_ALLEGRO_BLEND_MODE
+
+/*
+ * Blending modes
+ */
+const (
+   ZERO               = BlendMode(C.ALLEGRO_ZERO)
+   ONE                = BlendMode(C.ALLEGRO_ONE)
+   ALPHA              = BlendMode(C.ALLEGRO_ALPHA)
+   INVERSE_ALPHA      = BlendMode(C.ALLEGRO_INVERSE_ALPHA)
+   SRC_COLOR          = BlendMode(C.ALLEGRO_SRC_COLOR)
+   DEST_COLOR         = BlendMode(C.ALLEGRO_DEST_COLOR)  
+   INVERSE_SRC_COLOR  = BlendMode(C.ALLEGRO_INVERSE_SRC_COLOR)
+   INVERSE_DEST_COLOR = BlendMode(C.ALLEGRO_INVERSE_DEST_COLOR)
+   CONST_COLOR        = BlendMode(C.ALLEGRO_CONST_COLOR)
+   INVERSE_CONST_COLOR= BlendMode(C.ALLEGRO_INVERSE_CONST_COLOR)
+   NUM_BLEND_MODES    = BlendMode(C.ALLEGRO_NUM_BLEND_MODES)
+)
+
+func (bm BlendMode) toC() C.enum_ALLEGRO_BLEND_MODE {
+    return C.enum_ALLEGRO_BLEND_MODE(bm)
+}
+
+type BlendOperations C.enum_ALLEGRO_BLEND_OPERATIONS
+
+func (bo BlendOperations) toC() C.enum_ALLEGRO_BLEND_MODE {
+    return C.enum_ALLEGRO_BLEND_OPERATIONS(bo)
+}
+
+const(
+   ADD                  = BlendOperations(C.ALLEGRO_ADD)     
+   SRC_MINUS_DEST       = BlendOperations(C.ALLEGRO_SRC_MINUS_DEST)     
+   DEST_MINUS_SRC       = BlendOperations(C.ALLEGRO_DEST_MINUS_SRC)
+   NUM_BLEND_OPERATIONS = BlendOperations(C.ALLEGRO_NUM_BLEND_OPERATIONS)
+)
+
+
+func SetBlender(op BlendOperations, src, dest BlendMode) {
+    C.al_set_blender(C.int(op), C.int(src), C.int(dest))
+}
+
+func SetBlendColor(color Color) {
+    C.al_set_blend_color(color.toC())
+}
+
+func GetBlender() (op BlendOperations, src, dest BlendMode) {
+    var cop, csrc, cdest C.int
+    C.al_get_blender(&cop, &csrc, &cdest)
+    op   = BlendOperations(cop)
+    src  = BlendMode(csrc)
+    dest = BlendMode(cdest)
+    return op, src, dest
+}
+
+func GetBlendColor() Color {
+    return wrapColor(C.al_get_blend_color())
+}
+
+
+func SetSeparateBlender(op BlendOperations, src, dest BlendMode,
+    alpha_op BlendOperations, alpha_src, alpha_dest BlendMode) {
+    C.al_set_separate_blender(C.int(op), C.int(src), C.int(dest),
+        C.int(alpha_op), C.int(alpha_src), C.int(alpha_dest))
+}
+
+func GetSeparateBlender() (op BlendOperations, src, dest BlendMode, 
+    alpha_op BlendOperations, alpha_src, alpha_dest BlendMode) {
+    var cop, csrc, cdest, calpha_op, calpha_src, calpha_dest C.int
+    C.al_get_separate_blender(&cop, &csrc, &cdest,
+        &calpha_op, &calpha_src, &calpha_dest)
+    op          = BlendOperations(cop)
+    src         = BlendMode(csrc)
+    dest        = BlendMode(cdest)
+    alpha_op    = BlendOperations(calpha_op)
+    alpha_src   = BlendMode(calpha_src)
+    alpha_dest  = BlendMode(calpha_dest)
+    
+    return op, src, dest, alpha_op, alpha_src, alpha_dest
+}

+ 36 - 18
al/callbacks.go

@@ -15,36 +15,54 @@ type CreateCustomBitmapCallback func(bitmap *Bitmap, data interface{}) bool
 
 // Callback context for CreateCustomBitmap()
 type createCustomBitmapContext struct {
-	fn   CreateCustomBitmapCallback
-	data interface{}
+    fn   CreateCustomBitmapCallback
+    data interface{}
 }
 
 //export go_create_custom_bitmap_callback
 func go_create_custom_bitmap_callback(ptr unsafe.Pointer, context unsafe.Pointer) C.bool {
-	ccbd := (*createCustomBitmapContext)(context)
-	cbmp := (*C.ALLEGRO_BITMAP)(ptr)
-	bmp := wrapBitmapRaw(cbmp)
-	fptr := ccbd.fn
-	return b2cb((fptr)(bmp, ccbd.data))
+    ccbd := (*createCustomBitmapContext)(context)
+    cbmp := (*C.ALLEGRO_BITMAP)(ptr)
+    bmp := wrapBitmapRaw(cbmp)
+    fptr := ccbd.fn
+    return b2cb((fptr)(bmp, ccbd.data))
 }
 
+// Callback function for RunMain()
+type RunMainCallback func(args []string, data interface{}) int
+
+// Callback context for CreateCustomBitmap()
+type runMainContext struct {
+    fn   RunMainCallback    
+    data interface{}
+}
+
+var runMain runMainContext
+
+//export go_run_main_callback
+func go_run_main_callback(argc C.int, argv ** C.char) C.int {
+    args := GoStrings(argc, argv)        
+    return C.int(runMain.fn(args, runMain.data))
+}
+
+
 // generic function pointer caller
 
 var CallbackInt func() int = nil
 
 //export go_generic_callback_int
 func go_generic_callback_int() int {
-	if CallbackInt != nil {
-		return CallbackInt()
-	}
-	return 0
+    if CallbackInt != nil {
+        return CallbackInt()
+    }
+    return 0
 }
 
 type CallbackFunction func() int
 
 type callbackData struct {
-	fn   CallbackFunction
-	data unsafe.Pointer
+    fn   CallbackFunction
+    data unsafe.Pointer
 }
 
 // the function below is the C callback that will be given to the 
@@ -53,13 +71,13 @@ type callbackData struct {
 
 //export go_take_callback_callback
 func go_take_callback_callback(context unsafe.Pointer) int {
-	cbd := (*callbackData)(context)
-	fn := cbd.fn
-	return fn()
+    cbd := (*callbackData)(context)
+    fn := cbd.fn
+    return fn()
 }
 
 // Finally wrap the C callback caller function.
 func TakeCallback(fn CallbackFunction) int {
-	ctx := unsafe.Pointer(&callbackData{fn, nil})
-	return int(C.go_take_callback(ctx))
+    ctx := unsafe.Pointer(&callbackData{fn, nil})
+    return int(C.go_take_callback(ctx))
 }

+ 2 - 0
al/callbacks.h

@@ -5,5 +5,7 @@
 /* wrapper around al_create_custom_bitmap */
 ALLEGRO_BITMAP * go_create_custom_bitmap(int w, int h, void * context);
 
+int go_run_main_callback(int argc, char ** argv);
+
 
 #endif

+ 24 - 0
al/clipboard.go

@@ -0,0 +1,24 @@
+// clipboard support
+package al
+
+/*
+#include <stdlib.h>
+#include <allegro5/allegro.h>
+#include "helpers.h"
+#include "callbacks.h"
+*/
+import "C"
+
+func (disp * Display) ClipboardText() string {
+    return C.GoString(C.al_get_clipboard_text(disp.toC()))
+}
+
+func (disp * Display) ClipboardHasText() bool {
+    return bool(C.al_clipboard_has_text(disp.toC()))
+}
+
+func (disp * Display) SetClipboardText(text string) bool {
+    ctext := cstr(text) ; defer cstrFree(ctext)
+    return bool(C.al_set_clipboard_text(disp.toC(), ctext))
+}
+