2019-12-19 06:08:52 +00:00
|
|
|
package allg5
|
|
|
|
|
|
|
|
// #include <allegro5/allegro.h>
|
|
|
|
import "C"
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
2019-12-28 00:41:32 +00:00
|
|
|
"sort"
|
2019-12-19 06:08:52 +00:00
|
|
|
"unsafe"
|
|
|
|
)
|
|
|
|
|
2019-12-28 00:41:32 +00:00
|
|
|
// Display represents a display.
|
2019-12-19 06:08:52 +00:00
|
|
|
type Display struct {
|
|
|
|
display *C.ALLEGRO_DISPLAY
|
|
|
|
}
|
|
|
|
|
2019-12-28 00:41:32 +00:00
|
|
|
// DisplayMode contains information about a fullscreen display mode.
|
|
|
|
type DisplayMode struct {
|
|
|
|
Width int
|
|
|
|
Height int
|
|
|
|
Format PixelFormat
|
|
|
|
RefreshRate int
|
|
|
|
}
|
|
|
|
|
|
|
|
// DisplayMode returns all available fullscreen display modes.
|
|
|
|
func DisplayModes() []DisplayMode {
|
|
|
|
n := int(C.al_get_num_display_modes())
|
|
|
|
var modes []DisplayMode
|
|
|
|
var mode C.ALLEGRO_DISPLAY_MODE
|
|
|
|
for i := 0; i < n; i++ {
|
|
|
|
C.al_get_display_mode(C.int(i), &mode)
|
|
|
|
modes = append(modes, DisplayMode{
|
|
|
|
Width: int(mode.width),
|
|
|
|
Height: int(mode.height),
|
|
|
|
Format: PixelFormat(mode.format),
|
|
|
|
RefreshRate: int(mode.refresh_rate),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
weight := func(m DisplayMode) int { return (m.Width*m.Height)*10000 + (m.RefreshRate * 100) + int(m.Format) }
|
|
|
|
sort.Slice(modes, func(i, j int) bool { return weight(modes[i]) < weight(modes[j]) })
|
|
|
|
return modes
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewDisplayOptions sets options for creating a new display.
|
2019-12-19 06:08:52 +00:00
|
|
|
type NewDisplayOptions struct {
|
|
|
|
Fullscreen bool
|
|
|
|
Resizable bool
|
|
|
|
Windowed bool
|
|
|
|
Maximized bool
|
|
|
|
Frameless bool
|
|
|
|
Vsync bool
|
|
|
|
Shaders bool
|
|
|
|
OpenGL bool
|
|
|
|
}
|
|
|
|
|
2019-12-28 00:41:32 +00:00
|
|
|
// NewDisplay creates a display.
|
2019-12-19 06:08:52 +00:00
|
|
|
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
|
2019-12-27 23:03:48 +00:00
|
|
|
}
|
|
|
|
if options.Maximized {
|
|
|
|
flags |= C.ALLEGRO_MAXIMIZED
|
2019-12-19 06:08:52 +00:00
|
|
|
}
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2020-02-20 17:15:29 +00:00
|
|
|
func (d *Display) SetIcon(i ...*Bitmap) {
|
|
|
|
if len(i) == 0 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if len(i) == 1 {
|
|
|
|
C.al_set_display_icon(d.display, i[0].bitmap)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
icons := make([]*C.ALLEGRO_BITMAP, len(i))
|
|
|
|
for j := range icons {
|
|
|
|
icons[j] = i[j].bitmap
|
|
|
|
}
|
|
|
|
C.al_set_display_icons(d.display, C.int(len(icons)), &(icons[0]))
|
2019-12-19 06:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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 {
|
2020-05-23 06:56:52 +00:00
|
|
|
return &Bitmap{C.al_get_backbuffer(d.display), d.Width(), d.Height(), nil, nil}
|
2019-12-19 06:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Destroy destroys the display
|
|
|
|
func (d *Display) Destroy() {
|
|
|
|
C.al_destroy_display(d.display)
|
|
|
|
}
|
|
|
|
|
|
|
|
func CurrentTarget() *Bitmap {
|
|
|
|
var bmp = C.al_get_target_bitmap()
|
2020-05-23 06:56:52 +00:00
|
|
|
return &Bitmap{bmp, int(C.al_get_bitmap_width(bmp)), int(C.al_get_bitmap_height(bmp)), nil, nil}
|
2019-12-19 06:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func SetNewWindowTitle(title string) {
|
|
|
|
t := C.CString(title)
|
|
|
|
defer C.free(unsafe.Pointer(t))
|
|
|
|
C.al_set_new_window_title(t)
|
|
|
|
}
|