package allg5 // #include import "C" import ( "errors" "sort" "unsafe" ) // Display represents a display. type Display struct { display *C.ALLEGRO_DISPLAY } // 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. 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) { 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])) } 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) }