//The main loop. Handles drawing, events, ... This should be broken up into a smaller set of functions // if more event logic is handled. func mainLoop(screen *sdl.Surface, markers []Marker, goals []*Goal) { var curGoal int timer := make(chan bool, 0) running := true redraw := true requestRedraw := false stickCount := len(markers) // start the timer go timeLoop(timer) for running { if redraw { items := list.New() nextGoal := false var curRect *sdl.Rect if curGoal >= 0 && curGoal < len(goals) { curRect = goals[curGoal].Rect() } for i := 0; i < stickCount; i++ { markers[i].Update() items.PushBack(markers[i]) if curRect != nil { if markers[i].Intersects(curRect) { nextGoal = true } } } if nextGoal { curGoal++ if curGoal >= len(goals) { curGoal = 0 } } if curGoal >= 0 && curGoal < len(goals) { items.PushBack(goals[curGoal]) } draw(screen, items) screen.Flip() //fmt.Printf(".") redraw = false requestRedraw = false } select { case <-timer: zeroCnt := 0 for _, m := range markers { if m.last2Zero { zeroCnt++ } } if zeroCnt < stickCount || requestRedraw { redraw = true } case _event := <-sdl.Events: switch e := _event.(type) { case sdl.QuitEvent: running = false case sdl.KeyboardEvent: if e.Keysym.Sym == sdl.K_ESCAPE || e.Keysym.Sym == sdl.K_q { running = false } case sdl.JoyAxisEvent: if e.Axis < 2 { val := float32(0.0) if e.Value > 2000 || e.Value < -2000 { val = float32(e.Value) / float32(uint32(0x0ffff)) } //fmt.Println("got joystick axis event ", e) if e.Axis == 0 { markers[e.Which].Vax = val } else { markers[e.Which].Vay = val } requestRedraw = true } case sdl.JoyButtonEvent: if e.State > 0 { markers[e.Which].Big++ } else { markers[e.Which].Big-- } if markers[e.Which].Big < 0 { markers[e.Which].Big = 0 } requestRedraw = true case sdl.JoyHatEvent: switch e.Value { case sdl.HAT_CENTERED: markers[e.Which].Vhx = 0.0 markers[e.Which].Vhy = 0.0 case sdl.HAT_UP: markers[e.Which].Vhx = 0.0 markers[e.Which].Vhy = -1.0 case sdl.HAT_RIGHT: markers[e.Which].Vhx = 1.0 markers[e.Which].Vhy = 0.0 case sdl.HAT_DOWN: markers[e.Which].Vhx = 0.0 markers[e.Which].Vhy = 1.0 case sdl.HAT_LEFT: markers[e.Which].Vhx = -1.0 markers[e.Which].Vhy = 0.0 case sdl.HAT_RIGHTUP: markers[e.Which].Vhx = 1.0 markers[e.Which].Vhy = -1.0 case sdl.HAT_RIGHTDOWN: markers[e.Which].Vhx = 1.0 markers[e.Which].Vhy = 1.0 case sdl.HAT_LEFTUP: markers[e.Which].Vhx = -1.0 markers[e.Which].Vhy = -1.0 case sdl.HAT_LEFTDOWN: markers[e.Which].Vhx = -1.0 markers[e.Which].Vhy = 1.0 } //fmt.Println("Hat event ", e, " (",markers[e.Which].Vhx,",",markers[e.Which].Vhy,")") requestRedraw = true case sdl.ResizeEvent: //println("resize screen ", e.W, e.H) panic("Resize not supported yet") //screen = sdl.SetVideoMode(int(e.W), int(e.H), 32, sdl.RESIZABLE) //if screen == nil { // fmt.Println(sdl.GetError()) //} } } // yeild to allow other activities (such as the timer loop) runtime.Gosched() } }