Created new repository.
This commit is contained in:
commit
6151f28ef3
37
audio.go
Normal file
37
audio.go
Normal file
@ -0,0 +1,37 @@
|
||||
package allg5
|
||||
|
||||
/*
|
||||
#define ALLEGRO_KCM_AUDIO_SRC
|
||||
|
||||
#include <allegro5/allegro_audio.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
type Recorder struct {
|
||||
recorder *C.ALLEGRO_AUDIO_RECORDER
|
||||
Frequency int
|
||||
Depth int
|
||||
}
|
||||
|
||||
func NewRecorder(fragments, samples, frequency, depth int) *Recorder {
|
||||
var depthC C.ALLEGRO_AUDIO_DEPTH
|
||||
switch depth {
|
||||
case 16:
|
||||
depthC = C.ALLEGRO_AUDIO_DEPTH_INT16
|
||||
default:
|
||||
depthC = C.ALLEGRO_AUDIO_DEPTH_UINT8
|
||||
}
|
||||
var rec = C.al_create_audio_recorder(C.size_t(fragments), C.uint(samples), C.uint(frequency), depthC, C.ALLEGRO_CHANNEL_CONF_1)
|
||||
if rec == nil {
|
||||
return nil
|
||||
}
|
||||
return &Recorder{rec, frequency, depth}
|
||||
}
|
||||
|
||||
func (r *Recorder) Start() {
|
||||
C.al_start_audio_recorder(r.recorder)
|
||||
}
|
||||
|
||||
func (r *Recorder) Destroy() {
|
||||
C.al_destroy_audio_recorder(r.recorder)
|
||||
}
|
260
bitmap.go
Normal file
260
bitmap.go
Normal file
@ -0,0 +1,260 @@
|
||||
package allg5
|
||||
|
||||
// #include <allegro5/allegro.h>
|
||||
// #include <stdlib.h>
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"image"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Bitmap represents an in memory bitmap
|
||||
type Bitmap struct {
|
||||
bitmap *C.ALLEGRO_BITMAP
|
||||
width int
|
||||
height int
|
||||
subs []*Bitmap
|
||||
}
|
||||
|
||||
type DrawOptions struct {
|
||||
Center bool
|
||||
Scale *Scale
|
||||
Tint *Color
|
||||
Rotation *Rotation
|
||||
}
|
||||
|
||||
type Scale struct {
|
||||
Horizontal float32
|
||||
Vertical float32
|
||||
}
|
||||
|
||||
func NewScale(hor, ver float32) *Scale {
|
||||
return &Scale{hor, ver}
|
||||
}
|
||||
|
||||
func NewUniformScale(s float32) *Scale {
|
||||
return &Scale{s, s}
|
||||
}
|
||||
|
||||
type Rotation struct {
|
||||
Angle float32
|
||||
Center bool
|
||||
}
|
||||
|
||||
func newBitmap(width, height int, mut func(m FlagMutation), flags []NewBitmapFlag) (*Bitmap, error) {
|
||||
var newBmpFlags = CaptureNewBitmapFlags()
|
||||
defer newBmpFlags.Revert()
|
||||
newBmpFlags.Mutate(func(m FlagMutation) {
|
||||
if mut != nil {
|
||||
mut(m)
|
||||
}
|
||||
for _, f := range flags {
|
||||
m.Set(f)
|
||||
}
|
||||
})
|
||||
b := C.al_create_bitmap(C.int(width), C.int(height))
|
||||
if b == nil {
|
||||
return nil, errors.New("error creating bitmap")
|
||||
}
|
||||
return &Bitmap{b, width, height, nil}, nil
|
||||
}
|
||||
|
||||
// NewBitmap creates a new bitmap of given width and height and optional flags
|
||||
func NewBitmap(width, height int, flags ...NewBitmapFlag) (*Bitmap, error) {
|
||||
return newBitmap(width, height, nil, flags)
|
||||
}
|
||||
|
||||
// NewVideoBitmap creates a new video bitmap of given width and height and optional flags
|
||||
func NewVideoBitmap(width, height int, flags ...NewBitmapFlag) (*Bitmap, error) {
|
||||
return newBitmap(width, height, func(m FlagMutation) {
|
||||
m.Unset(NewBitmapFlagMemoryBitmap)
|
||||
m.Set(NewBitmapFlagVideoBitmap)
|
||||
}, flags)
|
||||
}
|
||||
|
||||
// NewMemoryBitmap creates a new video bitmap of given width and height and optional flags
|
||||
func NewMemoryBitmap(width, height int, flags ...NewBitmapFlag) (*Bitmap, error) {
|
||||
return newBitmap(width, height, func(m FlagMutation) {
|
||||
m.Unset(NewBitmapFlagVideoBitmap)
|
||||
m.Set(NewBitmapFlagMemoryBitmap)
|
||||
}, flags)
|
||||
}
|
||||
|
||||
// NewBitmapFromImage creates a new bitmap starting from a Go native image (image.Image)
|
||||
func NewBitmapFromImage(src image.Image, video bool) (*Bitmap, error) {
|
||||
var newBmpFlags = CaptureNewBitmapFlags()
|
||||
defer newBmpFlags.Revert()
|
||||
newBmpFlags.Mutate(func(m FlagMutation) {
|
||||
m.Unset(NewBitmapFlagVideoBitmap)
|
||||
m.Set(NewBitmapFlagMemoryBitmap)
|
||||
m.Set(NewBitmapFlagMinLinear)
|
||||
})
|
||||
var bnd = src.Bounds()
|
||||
width, height := bnd.Dx(), bnd.Dy()
|
||||
var b = C.al_create_bitmap(C.int(width), C.int(height))
|
||||
if b == nil {
|
||||
return nil, errors.New("error creating memory bitmap")
|
||||
}
|
||||
region := C.al_lock_bitmap(b, C.ALLEGRO_PIXEL_FORMAT_ABGR_8888, C.ALLEGRO_LOCK_WRITEONLY)
|
||||
if region == nil {
|
||||
C.al_destroy_bitmap(b)
|
||||
return nil, errors.New("unable to lock bitmap")
|
||||
}
|
||||
dst := (*[1 << 30]uint8)(region.data)
|
||||
left, top := bnd.Min.X, bnd.Min.Y
|
||||
for y := 0; y < height; y++ {
|
||||
row := dst[y*int(region.pitch):]
|
||||
for x := 0; x < width; x++ {
|
||||
r, g, b, a := src.At(left+x, top+y).RGBA()
|
||||
row[x*4] = uint8(r >> 8)
|
||||
row[x*4+1] = uint8(g >> 8)
|
||||
row[x*4+2] = uint8(b >> 8)
|
||||
row[x*4+3] = uint8(a >> 8)
|
||||
}
|
||||
}
|
||||
C.al_unlock_bitmap(b)
|
||||
if video {
|
||||
newBmpFlags.Mutate(func(m FlagMutation) {
|
||||
m.Unset(NewBitmapFlagMemoryBitmap)
|
||||
m.Set(NewBitmapFlagVideoBitmap)
|
||||
m.Set(NewBitmapFlagMinLinear)
|
||||
})
|
||||
C.al_convert_bitmap(b)
|
||||
}
|
||||
return &Bitmap{b, width, height, nil}, nil
|
||||
}
|
||||
|
||||
// LoadBitmap tries to load the image at the specified path as a bitmap
|
||||
func LoadBitmap(path string) (*Bitmap, error) {
|
||||
p := C.CString(path)
|
||||
defer C.free(unsafe.Pointer(p))
|
||||
b := C.al_load_bitmap(p)
|
||||
if b == nil {
|
||||
return nil, errors.New("error loading bitmap")
|
||||
}
|
||||
width := int(C.al_get_bitmap_width(b))
|
||||
height := int(C.al_get_bitmap_height(b))
|
||||
return &Bitmap{b, width, height, nil}, nil
|
||||
}
|
||||
|
||||
// Draw draws the bitmap at the given location
|
||||
func (b *Bitmap) Draw(left, top float32) {
|
||||
C.al_draw_bitmap(b.bitmap, C.float(left), C.float(top), 0)
|
||||
}
|
||||
|
||||
func (b *Bitmap) DrawOptions(left, top float32, options DrawOptions) {
|
||||
width := float32(b.width)
|
||||
height := float32(b.height)
|
||||
|
||||
scale := options.Scale != nil
|
||||
if scale {
|
||||
width *= options.Scale.Horizontal
|
||||
height *= options.Scale.Vertical
|
||||
}
|
||||
if options.Center {
|
||||
left -= width * 0.5
|
||||
top -= height * 0.5
|
||||
}
|
||||
rotated := options.Rotation != nil
|
||||
var centerX C.float
|
||||
var centerY C.float
|
||||
if rotated && options.Rotation.Center {
|
||||
centerX = C.float(b.width) * 0.5
|
||||
centerY = C.float(b.height) * 0.5
|
||||
}
|
||||
|
||||
if scale {
|
||||
if options.Tint == nil { // scaled
|
||||
if rotated { // scaled & rotated
|
||||
C.al_draw_scaled_rotated_bitmap(b.bitmap, centerX, centerY, C.float(left), C.float(top), C.float(options.Scale.Horizontal), C.float(options.Scale.Vertical), C.float(options.Rotation.Angle), 0)
|
||||
} else { // scaled
|
||||
C.al_draw_scaled_bitmap(b.bitmap, 0, 0, C.float(b.width), C.float(b.height), C.float(left), C.float(top), C.float(width), C.float(height), 0)
|
||||
}
|
||||
} else { // tinted & scaled
|
||||
if rotated { // scaled, tinted & rotated
|
||||
C.al_draw_tinted_scaled_rotated_bitmap(b.bitmap, options.Tint.color, centerX, centerY, C.float(left), C.float(top), C.float(options.Scale.Horizontal), C.float(options.Scale.Vertical), C.float(options.Rotation.Angle), 0)
|
||||
} else { // tinted, scaled
|
||||
C.al_draw_tinted_scaled_bitmap(b.bitmap, options.Tint.color, 0, 0, C.float(b.width), C.float(b.height), C.float(left), C.float(top), C.float(width), C.float(height), 0)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if options.Tint == nil {
|
||||
if rotated { // rotated
|
||||
C.al_draw_rotated_bitmap(b.bitmap, centerX, centerY, C.float(left), C.float(top), C.float(options.Rotation.Angle), 0)
|
||||
} else {
|
||||
C.al_draw_bitmap(b.bitmap, C.float(left), C.float(top), 0)
|
||||
}
|
||||
} else { // tinted
|
||||
if rotated { // tinted & rotated
|
||||
C.al_draw_tinted_rotated_bitmap(b.bitmap, options.Tint.color, centerX, centerY, C.float(left), C.float(top), C.float(options.Rotation.Angle), 0)
|
||||
} else {
|
||||
C.al_draw_tinted_bitmap(b.bitmap, options.Tint.color, C.float(left), C.float(top), 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sub creates a sub-bitmap of the original bitmap
|
||||
func (b *Bitmap) Sub(x, y, w, h int) *Bitmap {
|
||||
var sub = C.al_create_sub_bitmap(b.bitmap, C.int(x), C.int(y), C.int(w), C.int(h))
|
||||
if sub == nil {
|
||||
return nil
|
||||
}
|
||||
var bmp = &Bitmap{sub, w, h, nil}
|
||||
b.subs = append(b.subs, bmp)
|
||||
return bmp
|
||||
}
|
||||
|
||||
// Subs returns the slice of sub-bitmaps
|
||||
func (b *Bitmap) Subs() []*Bitmap {
|
||||
return b.subs
|
||||
}
|
||||
|
||||
func (b *Bitmap) Width() int {
|
||||
return b.width
|
||||
}
|
||||
|
||||
func (b *Bitmap) Height() int {
|
||||
return b.height
|
||||
}
|
||||
|
||||
func (b *Bitmap) IsVideo() bool {
|
||||
return C.al_get_bitmap_flags(b.bitmap)&C.ALLEGRO_VIDEO_BITMAP == C.ALLEGRO_VIDEO_BITMAP
|
||||
}
|
||||
|
||||
func (b *Bitmap) Image() image.Image {
|
||||
im := image.NewRGBA(image.Rect(0, 0, b.width, b.height))
|
||||
region := C.al_lock_bitmap(b.bitmap, C.ALLEGRO_PIXEL_FORMAT_ABGR_8888, C.ALLEGRO_LOCK_READONLY)
|
||||
if region == nil {
|
||||
return nil
|
||||
}
|
||||
defer C.al_unlock_bitmap(b.bitmap)
|
||||
src := (*[1 << 30]uint8)(region.data)
|
||||
dst := im.Pix
|
||||
var srcOff, dstOff int
|
||||
for y := 0; y < b.height; y++ {
|
||||
copy(dst[dstOff:], src[srcOff:srcOff+b.width*4])
|
||||
srcOff += int(region.pitch)
|
||||
dstOff += im.Stride
|
||||
}
|
||||
return im
|
||||
}
|
||||
|
||||
func (b *Bitmap) SetAsTarget() {
|
||||
C.al_set_target_bitmap(b.bitmap)
|
||||
}
|
||||
|
||||
// Destroy destroys the bitmap
|
||||
func (b *Bitmap) Destroy() {
|
||||
var bmp = b.bitmap
|
||||
if bmp == nil {
|
||||
return
|
||||
}
|
||||
b.bitmap = nil
|
||||
for _, sub := range b.subs {
|
||||
sub.Destroy()
|
||||
}
|
||||
C.al_destroy_bitmap(bmp)
|
||||
}
|
6
c.go
Normal file
6
c.go
Normal file
@ -0,0 +1,6 @@
|
||||
// +build !windows
|
||||
|
||||
package allg5
|
||||
|
||||
// #cgo pkg-config: allegro-5 allegro_audio-5 allegro_font-5 allegro_image-5 allegro_primitives-5 allegro_ttf-5
|
||||
import "C"
|
6
c_windows.go
Normal file
6
c_windows.go
Normal file
@ -0,0 +1,6 @@
|
||||
// +build windows,!static
|
||||
|
||||
package allg5
|
||||
|
||||
// #cgo LDFLAGS: -lallegro -lallegro_audio -lallegro_font -lallegro_image -lallegro_primitives -lallegro_ttf
|
||||
import "C"
|
6
c_windows_static.go
Normal file
6
c_windows_static.go
Normal file
@ -0,0 +1,6 @@
|
||||
// +build windows,static
|
||||
|
||||
package allg5
|
||||
|
||||
// #cgo LDFLAGS: -lallegro_monolith-static -static -ljpeg -ldumb -lFLAC -lfreetype -lvorbisfile -lvorbis -logg -lphysfs -lpng16 -lzlib -luuid -lkernel32 -lwinmm -lpsapi -lopengl32 -lglu32 -luser32 -lcomdlg32 -lgdi32 -lshell32 -lole32 -ladvapi32 -lws2_32 -lshlwapi -lstdc++ -lwebp
|
||||
import "C"
|
36
color.go
Normal file
36
color.go
Normal file
@ -0,0 +1,36 @@
|
||||
package allg5
|
||||
|
||||
// #include <allegro5/allegro.h>
|
||||
import "C"
|
||||
import "image/color"
|
||||
|
||||
var _ color.Color = &Color{}
|
||||
|
||||
type Color struct {
|
||||
color C.ALLEGRO_COLOR
|
||||
}
|
||||
|
||||
func NewColor(r, g, b byte) Color {
|
||||
return Color{C.al_map_rgb(C.uchar(r), C.uchar(g), C.uchar(b))}
|
||||
}
|
||||
|
||||
func NewColorAlpha(r, g, b, a byte) Color {
|
||||
return Color{C.al_map_rgba(C.uchar(r), C.uchar(g), C.uchar(b), C.uchar(a))}
|
||||
}
|
||||
|
||||
func NewColorGo(c color.Color) Color {
|
||||
r, g, b, a := c.RGBA()
|
||||
return Color{C.al_premul_rgba(C.uchar(r>>8), C.uchar(g>>8), C.uchar(b>>8), C.uchar(a>>8))}
|
||||
}
|
||||
|
||||
// RGBA implements the color.Color interface.
|
||||
func (c Color) RGBA() (r, g, b, a uint32) {
|
||||
var cr, cg, cb, ca C.uchar
|
||||
C.al_unmap_rgba(c.color, &cr, &cg, &cb, &ca)
|
||||
a = uint32(ca)
|
||||
r = uint32(cr) * a
|
||||
g = uint32(cg) * a
|
||||
b = uint32(cb) * a
|
||||
a *= a
|
||||
return
|
||||
}
|
129
display.go
Normal file
129
display.go
Normal file
@ -0,0 +1,129 @@
|
||||
package allg5
|
||||
|
||||
// #include <allegro5/allegro.h>
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Display represents a display
|
||||
type Display struct {
|
||||
display *C.ALLEGRO_DISPLAY
|
||||
}
|
||||
|
||||
type NewDisplayOptions struct {
|
||||
Fullscreen bool
|
||||
Resizable bool
|
||||
Windowed bool
|
||||
Maximized bool
|
||||
Frameless bool
|
||||
Vsync bool
|
||||
Shaders bool
|
||||
OpenGL bool
|
||||
}
|
||||
|
||||
// NewDisplay creates a display
|
||||
func NewDisplay(width, height int, options NewDisplayOptions) (*Display, error) {
|
||||
var flags C.int = C.ALLEGRO_WINDOWED
|
||||
if options.Fullscreen {
|
||||
if options.Windowed {
|
||||
flags |= C.ALLEGRO_FULLSCREEN_WINDOW
|
||||
} else {
|
||||
flags = C.ALLEGRO_FULLSCREEN
|
||||
}
|
||||
} else if options.Frameless {
|
||||
flags |= C.ALLEGRO_FRAMELESS
|
||||
}
|
||||
if options.Resizable {
|
||||
flags |= C.ALLEGRO_RESIZABLE
|
||||
if options.Maximized {
|
||||
flags |= C.ALLEGRO_MAXIMIZED
|
||||
}
|
||||
}
|
||||
if options.Vsync {
|
||||
C.al_set_new_display_option(C.ALLEGRO_VSYNC, 1, C.ALLEGRO_SUGGEST)
|
||||
}
|
||||
if options.OpenGL {
|
||||
flags |= C.ALLEGRO_OPENGL
|
||||
}
|
||||
if options.Shaders {
|
||||
flags |= C.ALLEGRO_PROGRAMMABLE_PIPELINE
|
||||
}
|
||||
C.al_set_new_display_flags(flags)
|
||||
d := C.al_create_display(C.int(width), C.int(height))
|
||||
if d == nil {
|
||||
return nil, errors.New("error creating display")
|
||||
}
|
||||
return &Display{d}, nil
|
||||
}
|
||||
|
||||
// Flip flips the buffer to the display
|
||||
func (d *Display) Flip() {
|
||||
C.al_flip_display()
|
||||
}
|
||||
|
||||
func (d *Display) Width() int {
|
||||
return int(C.al_get_display_width(d.display))
|
||||
}
|
||||
|
||||
func (d *Display) Height() int {
|
||||
return int(C.al_get_display_height(d.display))
|
||||
}
|
||||
|
||||
func (d *Display) Position() (int, int) {
|
||||
var x, y C.int
|
||||
C.al_get_window_position(d.display, &x, &y)
|
||||
return int(x), int(y)
|
||||
}
|
||||
|
||||
func (d *Display) Resize(w, h int) {
|
||||
C.al_resize_display(d.display, C.int(w), C.int(h))
|
||||
}
|
||||
|
||||
func (d *Display) SetAsTarget() {
|
||||
C.al_set_target_backbuffer(d.display)
|
||||
}
|
||||
|
||||
func (d *Display) SetIcon(i *Bitmap) {
|
||||
C.al_set_display_icon(d.display, i.bitmap)
|
||||
}
|
||||
|
||||
func (d *Display) SetMouseCursor(c MouseCursor) {
|
||||
C.al_set_system_mouse_cursor(d.display, C.ALLEGRO_SYSTEM_MOUSE_CURSOR(c))
|
||||
}
|
||||
|
||||
func (d *Display) SetMousePosition(x, y int) {
|
||||
C.al_set_mouse_xy(d.display, C.int(x), C.int(y))
|
||||
}
|
||||
|
||||
func (d *Display) SetPosition(x, y int) {
|
||||
C.al_set_window_position(d.display, C.int(x), C.int(y))
|
||||
}
|
||||
|
||||
func (d *Display) SetWindowTitle(title string) {
|
||||
t := C.CString(title)
|
||||
defer C.free(unsafe.Pointer(t))
|
||||
C.al_set_window_title(d.display, t)
|
||||
}
|
||||
|
||||
func (d *Display) Target() *Bitmap {
|
||||
return &Bitmap{C.al_get_backbuffer(d.display), d.Width(), d.Height(), nil}
|
||||
}
|
||||
|
||||
// Destroy destroys the display
|
||||
func (d *Display) Destroy() {
|
||||
C.al_destroy_display(d.display)
|
||||
}
|
||||
|
||||
func CurrentTarget() *Bitmap {
|
||||
var bmp = C.al_get_target_bitmap()
|
||||
return &Bitmap{bmp, int(C.al_get_bitmap_width(bmp)), int(C.al_get_bitmap_height(bmp)), nil}
|
||||
}
|
||||
|
||||
func SetNewWindowTitle(title string) {
|
||||
t := C.CString(title)
|
||||
defer C.free(unsafe.Pointer(t))
|
||||
C.al_set_new_window_title(t)
|
||||
}
|
265
event.go
Normal file
265
event.go
Normal file
@ -0,0 +1,265 @@
|
||||
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 {
|
||||
queue *C.ALLEGRO_EVENT_QUEUE
|
||||
}
|
||||
|
||||
type Event interface {
|
||||
Stamp() float64
|
||||
}
|
||||
|
||||
type EventBase struct {
|
||||
stamp float64
|
||||
}
|
||||
|
||||
func (eb EventBase) Stamp() float64 {
|
||||
return eb.stamp
|
||||
}
|
||||
|
||||
type DisplayCloseEvent struct {
|
||||
EventBase
|
||||
}
|
||||
|
||||
type DisplayResizeEvent struct {
|
||||
EventBase
|
||||
X, Y int
|
||||
Width int
|
||||
Height int
|
||||
}
|
||||
|
||||
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 {
|
||||
EventBase
|
||||
Orientation DisplayOrientation
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
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")
|
||||
}
|
||||
return &EventQueue{q}, nil
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
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)}
|
||||
case C.ALLEGRO_EVENT_DISPLAY_CLOSE:
|
||||
return &DisplayCloseEvent{eb}
|
||||
case C.ALLEGRO_EVENT_DISPLAY_ORIENTATION:
|
||||
display := (*C.ALLEGRO_DISPLAY_EVENT)(unsafe.Pointer(e))
|
||||
return &DisplayOrientationEvent{eb, toDisplayOrientation(display.orientation)}
|
||||
case C.ALLEGRO_EVENT_DISPLAY_RESIZE:
|
||||
display := (*C.ALLEGRO_DISPLAY_EVENT)(unsafe.Pointer(e))
|
||||
C.al_acknowledge_resize(display.source)
|
||||
return &DisplayResizeEvent{eb, int(display.x), int(display.y), int(display.width), int(display.height)}
|
||||
case C.ALLEGRO_EVENT_MOUSE_AXES:
|
||||
mouse := (*C.ALLEGRO_MOUSE_EVENT)(unsafe.Pointer(e))
|
||||
return &MouseMoveEvent{MouseEvent{eb, int(mouse.x), int(mouse.y), int(mouse.z), int(mouse.w), nil}, int(mouse.dx), int(mouse.dy), int(mouse.dz), int(mouse.dw), float32(mouse.pressure)}
|
||||
case C.ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
|
||||
mouse := (*C.ALLEGRO_MOUSE_EVENT)(unsafe.Pointer(e))
|
||||
return &MouseButtonDownEvent{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_ENTER_DISPLAY:
|
||||
mouse := (*C.ALLEGRO_MOUSE_EVENT)(unsafe.Pointer(e))
|
||||
return &MouseEnterEvent{MouseEvent{eb, int(mouse.x), int(mouse.y), int(mouse.z), int(mouse.w), nil}}
|
||||
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)
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
23
flagmut.go
Normal file
23
flagmut.go
Normal file
@ -0,0 +1,23 @@
|
||||
package allg5
|
||||
|
||||
// #include <stdlib.h>
|
||||
import "C"
|
||||
|
||||
type FlagMutation interface {
|
||||
Set(f NewBitmapFlag)
|
||||
Unset(f NewBitmapFlag)
|
||||
}
|
||||
|
||||
type flagMut struct {
|
||||
flg C.int
|
||||
}
|
||||
|
||||
func (m *flagMut) Set(f NewBitmapFlag) {
|
||||
m.flg |= C.int(f)
|
||||
}
|
||||
|
||||
func (m *flagMut) Unset(f NewBitmapFlag) {
|
||||
if m.flg&C.int(f) == C.int(f) {
|
||||
m.flg ^= C.int(f)
|
||||
}
|
||||
}
|
107
font.go
Normal file
107
font.go
Normal file
@ -0,0 +1,107 @@
|
||||
package allg5
|
||||
|
||||
// #include <allegro5/allegro.h>
|
||||
// #include <allegro5/allegro_font.h>
|
||||
// #include <allegro5/allegro_ttf.h>
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type Font struct {
|
||||
font *C.ALLEGRO_FONT
|
||||
hght float32
|
||||
asc float32
|
||||
desc float32
|
||||
}
|
||||
|
||||
type HorizontalAlignment int
|
||||
|
||||
const (
|
||||
AlignLeft HorizontalAlignment = iota
|
||||
AlignCenter
|
||||
AlignRight
|
||||
)
|
||||
|
||||
func LoadTTFFont(path string, size int) (*Font, error) {
|
||||
p := C.CString(path)
|
||||
defer C.free(unsafe.Pointer(p))
|
||||
|
||||
f := C.al_load_ttf_font(p, C.int(size), 0)
|
||||
if f == nil {
|
||||
return nil, fmt.Errorf("unable to load ttf font '%s'", path)
|
||||
}
|
||||
return &Font{f, 0, 0, 0}, nil
|
||||
}
|
||||
|
||||
func (f *Font) drawFlags(a HorizontalAlignment) C.int {
|
||||
switch a {
|
||||
case AlignLeft:
|
||||
return C.ALLEGRO_ALIGN_LEFT
|
||||
case AlignCenter:
|
||||
return C.ALLEGRO_ALIGN_CENTRE
|
||||
case AlignRight:
|
||||
return C.ALLEGRO_ALIGN_RIGHT
|
||||
}
|
||||
return C.ALLEGRO_ALIGN_LEFT
|
||||
}
|
||||
|
||||
func (f *Font) Draw(left, top float32, color Color, align HorizontalAlignment, text string) {
|
||||
t := C.CString(text)
|
||||
defer C.free(unsafe.Pointer(t))
|
||||
|
||||
flags := f.drawFlags(align)
|
||||
C.al_draw_text(f.font, color.color, C.float(left), C.float(top), flags, t)
|
||||
}
|
||||
|
||||
// Ascent returns the ascent of the font
|
||||
func (f *Font) Ascent() float32 {
|
||||
if f.asc == 0 {
|
||||
f.asc = float32(C.al_get_font_ascent(f.font))
|
||||
}
|
||||
return f.asc
|
||||
}
|
||||
|
||||
// Descent returns the descent of the font.
|
||||
func (f *Font) Descent() float32 {
|
||||
if f.desc == 0 {
|
||||
f.desc = float32(C.al_get_font_descent(f.font))
|
||||
}
|
||||
return f.desc
|
||||
}
|
||||
|
||||
// Height returns the height of the font
|
||||
func (f *Font) Height() float32 {
|
||||
if f.hght == 0 {
|
||||
f.hght = f.Ascent() + f.Descent()
|
||||
}
|
||||
return f.hght
|
||||
}
|
||||
|
||||
// TextDimensions returns the bounding box of the rendered text.
|
||||
func (f *Font) TextDimensions(text string) (x, y, w, h float32) {
|
||||
t := C.CString(text)
|
||||
defer C.free(unsafe.Pointer(t))
|
||||
|
||||
var bbx, bby, bbw, bbh C.int
|
||||
C.al_get_text_dimensions(f.font, t, &bbx, &bby, &bbw, &bbh)
|
||||
x = float32(bbx)
|
||||
y = float32(bby)
|
||||
w = float32(bbw)
|
||||
h = float32(bbh)
|
||||
return
|
||||
}
|
||||
|
||||
// TextWidth returns the width of the rendered text.
|
||||
func (f *Font) TextWidth(text string) float32 {
|
||||
t := C.CString(text)
|
||||
defer C.free(unsafe.Pointer(t))
|
||||
|
||||
return float32(C.al_get_text_width(f.font, t))
|
||||
}
|
||||
|
||||
func (f *Font) Destroy() {
|
||||
C.al_destroy_font(f.font)
|
||||
}
|
26
graphics.go
Normal file
26
graphics.go
Normal file
@ -0,0 +1,26 @@
|
||||
package allg5
|
||||
|
||||
// #include <allegro5/allegro.h>
|
||||
import "C"
|
||||
|
||||
// BitmapFlag is extra information provided for creating a bitmap
|
||||
type BitmapFlag int
|
||||
|
||||
const (
|
||||
// BitmapFlagLinearScaleDown enables linear scaling when scaling down. Gives better results when combined with BitmapFlagMipMap
|
||||
BitmapFlagLinearScaleDown BitmapFlag = C.ALLEGRO_MIN_LINEAR
|
||||
// BitmapFlagLinearScaleUp enables linear scaling when scaling up.
|
||||
BitmapFlagLinearScaleUp = C.ALLEGRO_MAG_LINEAR
|
||||
// BitmapFlagMipMap enables mipmaps for drawing a scaled down version. Bitmap must square and its sides must be a power of two.
|
||||
BitmapFlagMipMap = C.ALLEGRO_MIPMAP
|
||||
)
|
||||
|
||||
// ClearToColor clears the target bitmap to the color
|
||||
func ClearToColor(c Color) {
|
||||
C.al_clear_to_color(c.color)
|
||||
}
|
||||
|
||||
// SetNewBitmapFlags sets the default bitmap flags for a newly created bitmap
|
||||
func SetNewBitmapFlags(flags BitmapFlag) {
|
||||
C.al_set_new_bitmap_flags(C.int(flags))
|
||||
}
|
188
keyboard.go
Normal file
188
keyboard.go
Normal file
@ -0,0 +1,188 @@
|
||||
package allg5
|
||||
|
||||
// #include <allegro5/allegro.h>
|
||||
import "C"
|
||||
|
||||
type Key int
|
||||
|
||||
const (
|
||||
KeyA Key = 1
|
||||
KeyB = 2
|
||||
KeyC = 3
|
||||
KeyD = 4
|
||||
KeyE = 5
|
||||
KeyF = 6
|
||||
KeyG = 7
|
||||
KeyH = 8
|
||||
KeyI = 9
|
||||
KeyJ = 10
|
||||
KeyK = 11
|
||||
KeyL = 12
|
||||
KeyM = 13
|
||||
KeyN = 14
|
||||
KeyO = 15
|
||||
KeyP = 16
|
||||
KeyQ = 17
|
||||
KeyR = 18
|
||||
KeyS = 19
|
||||
KeyT = 20
|
||||
KeyU = 21
|
||||
KeyV = 22
|
||||
KeyW = 23
|
||||
KeyX = 24
|
||||
KeyY = 25
|
||||
KeyZ = 26
|
||||
Key0 = 27
|
||||
Key1 = 28
|
||||
Key2 = 29
|
||||
Key3 = 30
|
||||
Key4 = 31
|
||||
Key5 = 32
|
||||
Key6 = 33
|
||||
Key7 = 34
|
||||
Key8 = 35
|
||||
Key9 = 36
|
||||
KeyPad0 = 37
|
||||
KeyPad1 = 38
|
||||
KeyPad2 = 39
|
||||
KeyPad3 = 40
|
||||
KeyPad4 = 41
|
||||
KeyPad5 = 42
|
||||
KeyPad6 = 43
|
||||
KeyPad7 = 44
|
||||
KeyPad8 = 45
|
||||
KeyPad9 = 46
|
||||
KeyF1 = 47
|
||||
KeyF2 = 48
|
||||
KeyF3 = 49
|
||||
KeyF4 = 50
|
||||
KeyF5 = 51
|
||||
KeyF6 = 52
|
||||
KeyF7 = 53
|
||||
KeyF8 = 54
|
||||
KeyF9 = 55
|
||||
KeyF10 = 56
|
||||
KeyF11 = 57
|
||||
KeyF12 = 58
|
||||
KeyEscape = 59
|
||||
KeyTilde = 60
|
||||
KeyMinus = 61
|
||||
KeyEquals = 62
|
||||
KeyBackspace = 63
|
||||
KeyTab = 64
|
||||
KeyOpenBrace = 65
|
||||
KeyCloseBrace = 66
|
||||
KeyEnter = 67
|
||||
KeySemicolon = 68
|
||||
KeyQuote = 69
|
||||
KeyBackslash = 70
|
||||
KeyBackslash2 = 71 /* DirectInput calls this DIK_OEM_102: "< > | on UK/Germany keyboards" */
|
||||
KeyComma = 72
|
||||
KeyFullstop = 73
|
||||
KeySlash = 74
|
||||
KeySpace = 75
|
||||
KeyInsert = 76
|
||||
KeyDelete = 77
|
||||
KeyHome = 78
|
||||
KeyEnd = 79
|
||||
KeyPageUp = 80
|
||||
KeyPageDown = 81
|
||||
KeyLeft = 82
|
||||
KeyRight = 83
|
||||
KeyUp = 84
|
||||
KeyDown = 85
|
||||
KeyPadSlash = 86
|
||||
KeyPadAsterisk = 87
|
||||
KeyPadMinus = 88
|
||||
KeyPadPlus = 89
|
||||
KeyPadDelete = 90
|
||||
KeyPadEnter = 91
|
||||
KeyPrintScreen = 92
|
||||
KeyPause = 93
|
||||
KeyAbntC1 = 94
|
||||
KeyYen = 95
|
||||
KeyKana = 96
|
||||
KeyConvert = 97
|
||||
KeyNoConvert = 98
|
||||
KeyAt = 99
|
||||
KeyCircumflex = 100
|
||||
KeyColon2 = 101
|
||||
KeyKanji = 102
|
||||
KeyPadEquals = 103 /* MacOS X */
|
||||
KeyBackQuote = 104 /* MacOS X */
|
||||
KeySemicolon2 = 105 /* MacOS X -- TODO: ask lillo what this should be */
|
||||
KeyCommand = 106 /* MacOS X */
|
||||
KeyBack = 107 /* Android back key */
|
||||
KeyVolumeUp = 108
|
||||
KeyVolumeDown = 109
|
||||
KeySearch = 110
|
||||
KeyDPadCenter = 111
|
||||
KeyButtonX = 112
|
||||
KeyButtonY = 113
|
||||
KeyDPadUp = 114
|
||||
KeyDPadDown = 115
|
||||
KeyDPadLeft = 116
|
||||
KeyDPadRight = 117
|
||||
KeySelect = 118
|
||||
KeyStart = 119
|
||||
KeyButtonL1 = 120
|
||||
KeyButtonR1 = 121
|
||||
KeyButtonL2 = 122
|
||||
KeyButtonR2 = 123
|
||||
KeyButtonA = 124
|
||||
KeyButtonB = 125
|
||||
KeyThumbL = 126
|
||||
KeyThumbR = 127
|
||||
KeyUnknown = 128
|
||||
KeyModifiers = 215
|
||||
KeyLShift = 215
|
||||
KeyRShift = 216
|
||||
KeyLCtrl = 217
|
||||
KeyRCtrl = 218
|
||||
KeyAlt = 219
|
||||
KeyAltGr = 220
|
||||
KeyLWin = 221
|
||||
KeyRWin = 222
|
||||
KeyMenu = 223
|
||||
KeyScrollLock = 224
|
||||
KeyNumLock = 225
|
||||
KeyCapsLock = 226
|
||||
)
|
||||
|
||||
type KeyMod uint
|
||||
|
||||
const (
|
||||
KeyModShift KeyMod = 0x00001
|
||||
KeyModCtrl = 0x00002
|
||||
KeyModAlt = 0x00004
|
||||
KeyModLWin = 0x00008
|
||||
KeyModRWin = 0x00010
|
||||
KeyModMenu = 0x00020
|
||||
KeyModAltGr = 0x00040
|
||||
KeyModCommand = 0x00080
|
||||
KeyModScrollLock = 0x00100
|
||||
KeyModNumlock = 0x00200
|
||||
KeyModCapsLock = 0x00400
|
||||
KeyModInaltseq = 0x00800
|
||||
KeyModAccent1 = 0x01000
|
||||
KeyModAccent2 = 0x02000
|
||||
KeyModAccent3 = 0x04000
|
||||
KeyModAccent4 = 0x08000
|
||||
)
|
||||
|
||||
func IsKeyDown(k Key) bool {
|
||||
var state C.ALLEGRO_KEYBOARD_STATE
|
||||
C.al_get_keyboard_state(&state)
|
||||
return bool(C.al_key_down(&state, C.int(k)))
|
||||
}
|
||||
|
||||
func IsAnyKeyDown(keys ...Key) bool {
|
||||
var state C.ALLEGRO_KEYBOARD_STATE
|
||||
C.al_get_keyboard_state(&state)
|
||||
for _, k := range keys {
|
||||
if bool(C.al_key_down(&state, C.int(k))) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
34
monitor.go
Normal file
34
monitor.go
Normal file
@ -0,0 +1,34 @@
|
||||
package allg5
|
||||
|
||||
// #include <allegro5/allegro.h>
|
||||
import "C"
|
||||
|
||||
type Monitor struct {
|
||||
X1, Y1 int
|
||||
X2, Y2 int
|
||||
}
|
||||
|
||||
func monitor(m *C.ALLEGRO_MONITOR_INFO) Monitor {
|
||||
return Monitor{int(m.x1), int(m.y1), int(m.x2), int(m.y2)}
|
||||
}
|
||||
|
||||
func DefaultMonitor() Monitor {
|
||||
var m C.ALLEGRO_MONITOR_INFO
|
||||
C.al_get_monitor_info(C.ALLEGRO_DEFAULT_DISPLAY_ADAPTER, &m)
|
||||
return monitor(&m)
|
||||
}
|
||||
|
||||
func Monitors() []Monitor {
|
||||
var n = NumberOfVideoAdapters()
|
||||
var mons []Monitor
|
||||
var m C.ALLEGRO_MONITOR_INFO
|
||||
for i := 0; i < n; i++ {
|
||||
C.al_get_monitor_info(C.int(i), &m)
|
||||
mons = append(mons, monitor(&m))
|
||||
}
|
||||
return mons
|
||||
}
|
||||
|
||||
func NumberOfVideoAdapters() int {
|
||||
return int(C.al_get_num_video_adapters())
|
||||
}
|
54
mouse.go
Normal file
54
mouse.go
Normal file
@ -0,0 +1,54 @@
|
||||
package allg5
|
||||
|
||||
// #include <allegro5/allegro.h>
|
||||
import "C"
|
||||
|
||||
type MouseButton uint
|
||||
|
||||
const (
|
||||
MouseButtonLeft MouseButton = 1
|
||||
MouseButtonRight = 2
|
||||
MouseButtonMiddle = 3
|
||||
)
|
||||
|
||||
type MouseCursor uint
|
||||
|
||||
const (
|
||||
MouseCursorNone MouseCursor = 0
|
||||
MouseCursorDefault = 1
|
||||
MouseCursorArrow = 2
|
||||
MouseCursorBusy = 3
|
||||
MouseCursorQuestion = 4
|
||||
MouseCursorEdit = 5
|
||||
MouseCursorMove = 6
|
||||
MouseCursorResizeN = 7
|
||||
MouseCursorResizeW = 8
|
||||
MouseCursorResizeS = 9
|
||||
MouseCursorResizeE = 10
|
||||
MouseCursorResizeNW = 11
|
||||
MouseCursorResizeSW = 12
|
||||
MouseCursorResizeSE = 13
|
||||
MouseCursorResizeNE = 14
|
||||
MouseCursorProgress = 15
|
||||
MouseCursorPrecision = 16
|
||||
MouseCursorLink = 17
|
||||
MouseCursorAltSelect = 18
|
||||
MouseCursorUnavailable = 19
|
||||
)
|
||||
|
||||
func IsMouseButtonDown(b MouseButton) bool {
|
||||
var state C.ALLEGRO_MOUSE_STATE
|
||||
C.al_get_mouse_state(&state)
|
||||
return bool(C.al_mouse_button_down(&state, C.int(b)))
|
||||
}
|
||||
|
||||
func IsAnyMouseButtonDown(buttons ...MouseButton) bool {
|
||||
var state C.ALLEGRO_MOUSE_STATE
|
||||
C.al_get_mouse_state(&state)
|
||||
for _, b := range buttons {
|
||||
if bool(C.al_mouse_button_down(&state, C.int(b))) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
31
newbitmapflag.go
Normal file
31
newbitmapflag.go
Normal file
@ -0,0 +1,31 @@
|
||||
package allg5
|
||||
|
||||
// #include <allegro5/allegro.h>
|
||||
import "C"
|
||||
|
||||
type NewBitmapFlag int
|
||||
|
||||
const (
|
||||
NewBitmapFlagMemoryBitmap = NewBitmapFlag(C.ALLEGRO_MEMORY_BITMAP)
|
||||
NewBitmapFlagVideoBitmap = NewBitmapFlag(C.ALLEGRO_VIDEO_BITMAP)
|
||||
NewBitmapFlagMinLinear = NewBitmapFlag(C.ALLEGRO_MIN_LINEAR)
|
||||
)
|
||||
|
||||
type NewBitmapFlagsCapture struct {
|
||||
cap C.int
|
||||
}
|
||||
|
||||
func CaptureNewBitmapFlags() *NewBitmapFlagsCapture {
|
||||
var cap = C.al_get_new_bitmap_flags()
|
||||
return &NewBitmapFlagsCapture{cap}
|
||||
}
|
||||
|
||||
func (c *NewBitmapFlagsCapture) Mutate(mut func(FlagMutation)) {
|
||||
var m = &flagMut{c.cap}
|
||||
mut(m)
|
||||
C.al_set_new_bitmap_flags(m.flg)
|
||||
}
|
||||
|
||||
func (c *NewBitmapFlagsCapture) Revert() {
|
||||
C.al_set_new_bitmap_flags(c.cap)
|
||||
}
|
12
platform_windows.go
Normal file
12
platform_windows.go
Normal file
@ -0,0 +1,12 @@
|
||||
// +build windows
|
||||
|
||||
package allg5
|
||||
|
||||
// #include <allegro5/allegro.h>
|
||||
// #include <allegro5/allegro_windows.h>
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
func (d *Display) WindowHandle() unsafe.Pointer {
|
||||
return unsafe.Pointer(C.al_get_win_window_handle(d.display))
|
||||
}
|
30
primitives.go
Normal file
30
primitives.go
Normal file
@ -0,0 +1,30 @@
|
||||
package allg5
|
||||
|
||||
// #include <allegro5/allegro.h>
|
||||
// #include <allegro5/allegro_primitives.h>
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
func DrawFilledRectangle(x1, y1, x2, y2 float32, c Color) {
|
||||
C.al_draw_filled_rectangle(C.float(x1), C.float(y1), C.float(x2), C.float(y2), c.color)
|
||||
}
|
||||
|
||||
func DrawFilledTriangle(x1, y1, x2, y2, x3, y3 float32, c Color) {
|
||||
C.al_draw_filled_triangle(C.float(x1), C.float(y1), C.float(x2), C.float(y2), C.float(x3), C.float(y3), c.color)
|
||||
}
|
||||
|
||||
func DrawLine(x1, y1, x2, y2 float32, c Color, thickness float32) {
|
||||
C.al_draw_line(C.float(x1), C.float(y1), C.float(x2), C.float(y2), c.color, C.float(thickness))
|
||||
}
|
||||
|
||||
func DrawPolyline(vertices []float32, c Color, thickness float32) {
|
||||
C.al_draw_polyline((*C.float)(unsafe.Pointer(&vertices[0])), 8, C.int(len(vertices)>>1), C.ALLEGRO_LINE_JOIN_ROUND, C.ALLEGRO_LINE_CAP_ROUND, c.color, C.float(thickness), 1)
|
||||
}
|
||||
|
||||
func DrawRectangle(x1, y1, x2, y2 float32, c Color, thickness float32) {
|
||||
C.al_draw_rectangle(C.float(x1), C.float(y1), C.float(x2), C.float(y2), c.color, C.float(thickness))
|
||||
}
|
||||
|
||||
func DrawTriangle(x1, y1, x2, y2, x3, y3 float32, c Color, thickness float32) {
|
||||
C.al_draw_triangle(C.float(x1), C.float(y1), C.float(x2), C.float(y2), C.float(x3), C.float(y3), c.color, C.float(thickness))
|
||||
}
|
66
system.go
Normal file
66
system.go
Normal file
@ -0,0 +1,66 @@
|
||||
package allg5
|
||||
|
||||
/*
|
||||
#define ALLEGRO_KCM_AUDIO_SRC
|
||||
|
||||
#include <allegro5/allegro.h>
|
||||
#include <allegro5/allegro_audio.h>
|
||||
#include <allegro5/allegro_font.h>
|
||||
#include <allegro5/allegro_image.h>
|
||||
#include <allegro5/allegro_primitives.h>
|
||||
#include <allegro5/allegro_ttf.h>
|
||||
|
||||
bool init() {
|
||||
return al_init();
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func init() {
|
||||
runtime.LockOSThread()
|
||||
}
|
||||
|
||||
type InitConfig struct {
|
||||
Audio bool
|
||||
Font bool
|
||||
Image bool
|
||||
Primitives bool
|
||||
Keyboard bool
|
||||
Mouse bool
|
||||
}
|
||||
|
||||
var InitAll = InitConfig{true, true, true, true, true, true}
|
||||
|
||||
// Init initializes the Allegro system
|
||||
func Init(config InitConfig) error {
|
||||
if !bool(C.init()) {
|
||||
return errors.New("failed to initialize Allegro")
|
||||
}
|
||||
if config.Audio && !bool(C.al_install_audio()) {
|
||||
return errors.New("failed to initialize audio addon")
|
||||
}
|
||||
if config.Font && !bool(C.al_init_font_addon()) {
|
||||
return errors.New("failed to initialize font addon")
|
||||
}
|
||||
if config.Font && !bool(C.al_init_ttf_addon()) {
|
||||
return errors.New("failed to initialize ttf addon")
|
||||
}
|
||||
if config.Image && !bool(C.al_init_image_addon()) {
|
||||
return errors.New("failed to initialize image addon")
|
||||
}
|
||||
if config.Primitives && !bool(C.al_init_primitives_addon()) {
|
||||
return errors.New("failed to initialize primitives addon")
|
||||
}
|
||||
if config.Keyboard && !bool(C.al_install_keyboard()) {
|
||||
return errors.New("failed to install keyboard")
|
||||
}
|
||||
if config.Mouse && !bool(C.al_install_mouse()) {
|
||||
return errors.New("failed to install mouse")
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user