Skip to content

Instantly share code, notes, and snippets.

@tapir
Created September 1, 2013 19:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tapir/6406617 to your computer and use it in GitHub Desktop.
Save tapir/6406617 to your computer and use it in GitHub Desktop.
package main
import (
al "github.com/tapir/allegro5"
"github.com/tapir/allegro5/imageio"
"runtime"
"log"
)
func init() {
// Lock the main thread
runtime.LockOSThread()
}
const (
dt = 0.03
maxFrameTime = 0.2
)
const (
title = "Core Game"
width = 800
height = 600
)
func render(alphaIn <-chan float64, displayOut chan<- *al.Display) {
// Lock the render thread
runtime.LockOSThread()
// Setup display flag and options
al.SetNewDisplayFlags(al.Windowed | al.Opengl30)
al.SetNewDisplayOption(al.Vsync, 1, al.Suggest)
al.SetNewDisplayOption(al.DepthSize, 0, al.Suggest)
al.SetNewDisplayOption(al.SampleBuffers, 1, al.Suggest)
al.SetNewDisplayOption(al.UpdateDisplayRegion_, 1, al.Suggest)
al.SetNewDisplayOption(al.RedSize, 8, al.Require)
al.SetNewDisplayOption(al.GreenSize, 8, al.Require)
al.SetNewDisplayOption(al.BlueSize, 8, al.Require)
al.SetNewDisplayOption(al.AlphaSize, 8, al.Require)
// Create window
display := al.CreateDisplay(width, height)
if display == nil {
log.Fatalln("Could not create display.")
}
defer display.Destroy()
// Set title
display.SetWindowTitle(title)
// Send display to main goroutine
displayOut <- display
// Make context current in this goroutine
display.SetTargetBackbuffer()
// Preapre a bitmap for rendering test
bmp := al.LoadBitmap("test.png")
if bmp == nil {
log.Fatalln("Can't load bmp.")
}
// Main rendering loop
for {
//Do things with interpolation value
<-alphaIn
al.ClearToColor(al.MapRgb(255, 0, 255))
bmp.Draw(0, 0, 0)
al.FlipDisplay()
}
}
func processLogic(alphaOut chan<- float64, inputIn <-chan uint) {
var (
t = 0.0
currentTime = al.GetTime()
accumulator = 0.0
)
// Main logic loop
for {
newTime := al.GetTime()
frameTime := newTime - currentTime
currentTime = newTime
if frameTime > maxFrameTime {
frameTime = maxFrameTime
}
accumulator += frameTime
for accumulator >= dt {
// Update logic
<-inputIn
t += dt
accumulator -= dt
}
// Switch to render coroutine by sending the interpolation
alphaOut <- accumulator / dt
}
}
func main() {
// Start Allegro
if !al.Init() {
log.Fatalln("Could not start Allegro.")
}
//defer al.UninstallSystem()
// Load image addon
if !imageio.Init() {
log.Fatalln("Could not start image IO addon.")
}
imageio.Shutdown()
// Create an event queue
queue := al.CreateEventQueue()
if queue == nil {
log.Fatalln("Could not create event queue.")
}
defer queue.Destroy()
// Prepare channels
alpha := make(chan float64) // Logic-render interpolation value
input := make(chan uint)
display := make(chan *al.Display)
// Process logic
go processLogic(alpha, input)
// Process render
go render(alpha, display)
// Get display created in render goroutine
d := <-display
// Register event sources
queue.RegisterEventSource(d.GetEventSource())
// Start timer and process input
done := false
for !done {
ok, event := queue.GetNextEvent()
if ok {
// Handle all allegro events here
if event.Type == al.EventDisplayClose {
done = true
}
}
//Send input data to logic goroutine
input <- 0
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment