// Render updates the screen, based on the new positions of the bats and the ball. func render() { var fps uint32 fps = 60 var delay uint32 delay = 1000 / fps var frameStart uint32 frameStart = sdl.GetTicks() renderer.Clear() renderMyBat() renderComputersBat() renderScore() // if the game is over render the gameOver graphic if gameOver == true { renderGameOver() } else { // otherwise we need to draw the ball renderBall() } // Show the game window window. renderer.Present() var frameTime uint32 frameTime = sdl.GetTicks() - frameStart if frameTime < delay { sdl.Delay(delay - frameTime) } }
func MainLoop(gs *gamestate.GameState, renderer *rendering.WorldRenderer) { var frames int time := float32(sdl.GetTicks()) / 1000 window := gs.Window running := true for running { currentTime := float32(sdl.GetTicks()) / 1000 if currentTime > time+1 { gs.Fps = float32(frames) frames = 0 time = currentTime } frames += 1 running = Input(gs, renderer) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) gl.Disable(gl.BLEND) simulation.Simulate(gs, renderer.ParticleSystem) renderer.View = gs.Camera.View() renderer.Render(gs.World, &gs.Options, window) tw.Draw() sdl.GL_SwapWindow(window) helpers.UpdateManagers() } }
func main() { start() defer window.Destroy() defer renderer.Destroy() text := loadText("Press enter to reset", sdl.Color{0, 0, 0, 255}) startTime := sdl.GetTicks() quit := false for !quit { for e := sdl.PollEvent(); e != nil; e = sdl.PollEvent() { switch t := e.(type) { case *sdl.QuitEvent: quit = true case *sdl.KeyDownEvent: if t.Keysym.Sym == sdl.K_RETURN { startTime = sdl.GetTicks() } } } renderer.SetDrawColor(0xFF, 0xFF, 0xFF, 0xFF) renderer.Clear() timeText := loadText(fmt.Sprintf("time: %d", sdl.GetTicks()-startTime), sdl.Color{0, 0, 0, 255}) renderer.Copy(text, nil, &sdl.Rect{0, 0, 400, 100}) renderer.Copy(timeText, nil, &sdl.Rect{400, 0, 400, 100}) renderer.Present() } }
func main() { rom, err := LoadROM(os.Args[1]) if err != nil { panic(err) } frameDelay := 1000 / frameRate window := sdl.CreateWindow( "Go NES", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, 256, 240, sdl.WINDOW_SHOWN, ) if window == nil { panic(sdl.GetError()) } defer window.Destroy() controller := NewController() ppu := NewPPU(window, NewVRAM(rom.Mapper())) cpu := NewCPU(NewMMU(rom.Mapper(), ppu, controller), ppu) ticksPerFrame := uint32(341 * 262) for { expectedTicks := sdl.GetTicks() + frameDelay for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { switch event := event.(type) { case *sdl.KeyDownEvent: controller.SetKeyState(event.Keysym.Sym, true) case *sdl.KeyUpEvent: controller.SetKeyState(event.Keysym.Sym, false) case *sdl.QuitEvent: return } } ppuTicks := uint32(0) for ppuTicks < ticksPerFrame { ppuTicks += ppu.Tick(cpu.Tick()) } actualTicks := sdl.GetTicks() if actualTicks < expectedTicks { sdl.Delay(expectedTicks - actualTicks) } } }
func (g *Game) tick() { //var ticks uint32 g.defaultSleep = 300 // this param will control the speed somehow TODO Fix this sdl.Delay(1) if sdl.GetTicks()%g.defaultSleep == 0 { g.heartbeat(sdl.GetTicks()) } }
// DelayToNextFrame waits until it's time to do the next event/render loop func (g *GameManager) DelayToNextFrame() { curTime := sdl.GetTicks() if g.prevFrameTime == 0 { if curTime >= g.FrameDelay { g.prevFrameTime = curTime - g.FrameDelay } } diff := curTime - g.prevFrameTime if g.FrameDelay > diff { frameDelayUnder := g.FrameDelay - diff // we have not yet exceeded one frame, so we need to sleep //fmt.Printf("Under: %d %d %d %d\n", curTime, g.prevFrameTime, diff, frameDelayUnder) sdl.Delay(frameDelayUnder) } else { //frameDelayOver := diff - g.FrameDelay //fmt.Printf("Over: %d %d %d %d\n", curTime, g.prevFrameTime, diff, frameDelayOver) // we have exceeded one frame, so no sleep // TODO sleep less in the future to make up for it? } g.prevFrameTime = curTime }
// GetTickCount returns the amount of time that has passed since the toolbox // was initialised. // // The toolbox counts time in 'ticks'. One 'tick' is 1/1000th of a second. // Time starts when Initialise() is called. The number for ticks always // increases. The number of ticks cannot be reset, and time does cannot // run backwards. // // If the function succeeds then a variable of type int64 will be returned // back to the calling function. It is the programmers responsibility to // store this in a variable of type int64. // GetTickCount returns an int64 type, not an int because the maximum number // of ticks is to large to store in an int. // // GetTickCount will panic if: // // 1. The toolbox has not been initialised. func GetTickCount() int64 { if !initialised { // this stops execution here, so ne need for an else after the if panic(notInitialisedMessage) } var ticks uint32 ticks = sdl.GetTicks() return int64(ticks) }
func main() { // Run the game on main thread only. // This is important because SDL will freeze / crash // if an action is running outside the main thread runtime.LockOSThread() // Show us a welomce message log.Println("Welcome to Kaori") // Don't forget to say goodbye ;) defer log.Println("Goodbye o/") // Show information about the runtime log.Printf("Compiled with %s for %s %s\n", runtime.Compiler, runtime.GOOS, runtime.GOARCH) // Don't forget to clean the game after it's done game.Init("Kaori", sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, 800, 600, false) // Don't forget to clean the game after it's done defer game.Clean() for game.Running() { // Get the current time to mark a frame start frameStart = sdl.GetTicks() // Run all of the 'update' functions game.HandleEvents() game.Update() game.Render() // Record the time frameTime = sdl.GetTicks() - frameStart // Check if it's faster than delay time if frameTime < DELAY_TIME { // If it is faster, delay the game to prevent "speeding" on certain tick event sdl.Delay(DELAY_TIME - frameTime) } } }
// updateState watches for internal state changes func (ps *PlayState) updateState() { curTime := sdl.GetTicks() diff := curTime - ps.state.startTime switch ps.state.state { case stateInterlude: var duration uint32 switch ps.level { case 1: duration = stateInterludeDurationLevel1 default: duration = stateInterludeDuration } if diff >= duration { ps.setState(stateAction) } case stateAction: } }
func main() { var window *sdl.Window var renderer *sdl.Renderer var event sdl.Event var running bool window = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, winWidth, winHeight, sdl.WINDOW_SHOWN) if window == nil { fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", sdl.GetError()) os.Exit(1) } renderer = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED) if renderer == nil { fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", sdl.GetError()) os.Exit(2) } var peepArray []sdl.Event = make([]sdl.Event, 2) peepArray[0] = &sdl.UserEvent{sdl.USEREVENT, sdl.GetTicks(), window.GetID(), 1331, nil, nil} peepArray[1] = &sdl.UserEvent{sdl.USEREVENT, sdl.GetTicks(), window.GetID(), 10101, nil, nil} running = true lastPushTime := sdl.GetTicks() for running { if lastPushTime+pushTime < sdl.GetTicks() { lastPushTime = sdl.GetTicks() sdl.PumpEvents() numEventsHandled := sdl.PeepEvents(peepArray, sdl.ADDEVENT, sdl.FIRSTEVENT, sdl.LASTEVENT) if numEventsHandled < 0 { fmt.Printf("PeepEvents error: %s\n", sdl.GetError()) } else { fmt.Printf("Successful push of %d events\n", numEventsHandled) } } for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent() { switch t := event.(type) { case *sdl.QuitEvent: running = false case *sdl.MouseMotionEvent: fmt.Printf("[%d ms] MouseMotion\ttype:%d\tid:%d\tx:%d\ty:%d\txrel:%d\tyrel:%d\n", t.Timestamp, t.Type, t.Which, t.X, t.Y, t.XRel, t.YRel) case *sdl.MouseButtonEvent: fmt.Printf("[%d ms] MouseButton\ttype:%d\tid:%d\tx:%d\ty:%d\tbutton:%d\tstate:%d\n", t.Timestamp, t.Type, t.Which, t.X, t.Y, t.Button, t.State) case *sdl.MouseWheelEvent: fmt.Printf("[%d ms] MouseWheel\ttype:%d\tid:%d\tx:%d\ty:%d\n", t.Timestamp, t.Type, t.Which, t.X, t.Y) case *sdl.KeyUpEvent: fmt.Printf("[%d ms] Keyboard\ttype:%d\tsym:%c\tmodifiers:%d\tstate:%d\trepeat:%d\n", t.Timestamp, t.Type, t.Keysym.Sym, t.Keysym.Mod, t.State, t.Repeat) case *sdl.UserEvent: fmt.Printf("[%d ms] UserEvent\tcode:%d\n", t.Timestamp, t.Code) } } sdl.Delay(1000 / 30) } renderer.Destroy() window.Destroy() }
func windowLoop(window *sdl.Window) { data := &renderData{} data.renderSections = true data.zoom = -250 data.nodes = loadTree("cmd/packer/test.priv.oct") data.box = genBox() defer gl.DeleteLists(data.box, 1) buttonDown := false t := float64(sdl.GetTicks()) for { ticks := float64(sdl.GetTicks()) * 0.001 dt := ticks - t t = ticks for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { switch t := event.(type) { case *sdl.QuitEvent: return case *sdl.KeyDownEvent: switch t.Keysym.Sym { case sdl.K_ESCAPE: return case sdl.K_SPACE: data.renderSections = !data.renderSections case sdl.K_PLUS: data.minNodeSize += 1.0 case sdl.K_MINUS: data.minNodeSize -= 1.0 } case *sdl.MouseButtonEvent: if t.State == 1 { buttonDown = true } else { buttonDown = false } case *sdl.MouseMotionEvent: if buttonDown { data.xrot += dt * float64(t.YRel) * rotSpeed data.yrot += dt * float64(t.XRel) * rotSpeed } case *sdl.MouseWheelEvent: data.zoom += dt * float64(t.Y) * rotSpeed } } gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) renderTree(data, &data.nodes[0], point3d{0, 0, 0}, 100) gl.Disable(gl.DEPTH_TEST) drawAxis(data) gl.Enable(gl.DEPTH_TEST) sdl.GL_SwapWindow(window) if glErr := gl.GetError(); glErr != gl.NO_ERROR { panic(fmt.Errorf("GL error: %x", glErr)) } } }
func (this *WorldRenderer) render(ww *gamestate.World, options *settings.BoolOptions, viewport Viewport, recursion int, srcPortal *gamestate.Portal) { this.Framebuffer[recursion].Bind() defer this.Framebuffer[recursion].Unbind() gl.Clear(gl.DEPTH_BUFFER_BIT) camera := gamestate.NewCameraFromMat4(this.View) Rot2D := camera.Rotation2D() gl.CullFace(gl.BACK) time := float64(sdl.GetTicks()) / 1000 if options.Wireframe { gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE) } else { gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL) } if options.Skybox { gl.Disable(gl.DEPTH_TEST) this.SkyboxRenderer.Render(this.Skybox, this.Proj, this.View, this.ClippingPlane_ws, nil) gl.Enable(gl.DEPTH_TEST) } gl.Enable(gl.CULL_FACE) if recursion != 0 { gl.Enable(gl.CLIP_DISTANCE0) defer gl.Disable(gl.CLIP_DISTANCE0) } for _, entity := range ww.ExampleObjects { this.MeshRenderer.Render(entity, this.Proj, this.View, this.ClippingPlane_ws, nil) } gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) gl.Disable(gl.CULL_FACE) if options.WorldRender { this.HeightMapRenderer.Render(ww.HeightMap, this.Proj, this.View, this.ClippingPlane_ws, nil) } PlayerPos := ww.Player.Position() ww.Water.Height = PlayerPos[2] - 15 if options.WaterRender { this.WaterRendererA.Render(ww.Water, this.Proj, this.View, this.ClippingPlane_ws, WaterRenderUniforms{time, PlayerPos}) } if options.WaterNormals { this.WaterRendererB.Render(ww.Water, this.Proj, this.View, this.ClippingPlane_ws, WaterRenderUniforms{time, PlayerPos}) } gl.Disable(gl.CULL_FACE) gl.Disable(gl.BLEND) if options.TreeRender { this.TreeRenderer.Render(ww.Trees, this.Proj, this.View, this.ClippingPlane_ws, Rot2D) } gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE) if options.ParticleRender { this.ParticleSystem.Render(this.Proj, this.View, this.ClippingPlane_ws) } gl.Disable(gl.BLEND) boxVertices := (*gamestate.TriangleMesh)(gamestate.QuadMesh()).MakeBoxVertices() pv := this.Proj.Mul4(this.View) // calculating nearest portal pos4f := this.View.Inv().Mul4x1(mgl.Vec4{0, 0, 0, 1}) nearestPortal := ww.NearestPortal(pos4f) // draw all portals except the nearest and the portal that we are looking throug for _, portal := range ww.Portals { // do not draw the nearest portal or the portal behind the source portal if available if (nearestPortal != portal) && (srcPortal == nil || srcPortal.Target != portal) { gl.Enable(gl.DEPTH_CLAMP) additionalUniforms := map[string]int{"Image": 7} this.PortalRenderer.Render(portal, this.Proj, this.View, this.ClippingPlane_ws, additionalUniforms) } } gl.Disable(gl.BLEND) gl.Disable(gl.CULL_FACE) if options.DebugLines { if options.DepthTestDebugLines { gl.Disable(gl.DEPTH_TEST) } this.DebugRenderer.Render(this.Proj, this.View) gl.Enable(gl.DEPTH_TEST) } // draw if recursion < this.MaxRecursion { portal := nearestPortal pos := portal.Position rotation := portal.Orientation.Mat4() Model := mgl.Translate3D(pos[0], pos[1], pos[2]).Mul4(rotation) pvm := pv.Mul4(Model) meshMin := mgl.Vec4{math.MaxFloat32, math.MaxFloat32, math.MaxFloat32, math.MaxFloat32} meshMax := mgl.Vec4{-math.MaxFloat32, -math.MaxFloat32, -math.MaxFloat32, -math.MaxFloat32} for _, v := range boxVertices { v = pvm.Mul4x1(v) v = v.Mul(1 / v[3]) meshMin = gamestate.Min(meshMin, v) meshMax = gamestate.Max(meshMax, v) } // at least partially visible if -1 < meshMax[0] && meshMin[0] < 1 && -1 < meshMax[1] && meshMin[1] < 1 && -1 < meshMax[2] && meshMin[2] < 1 { p1x, p1y := viewport.ToPixel(meshMin.Vec2()) p2x, p2y := viewport.ToPixel(meshMax.Vec2()) pw, ph := p2x-p1x, p2y-p1y // do scissoring only when all vertices are in front of the camera scissor := meshMax[2] < 1 scissor = scissor && (p1x != 0 || p1y != 0 || pw != viewport.W-1 || ph != viewport.H-1) if scissor { gl.Enable(gl.SCISSOR_TEST) gl.Scissor(p1x, p1y, pw, ph) } // omit rendering when portal is not in frustum at all // calculation View matrix that shows the target portal from the same angle as view shows the source portal //pos2 := portal.Target.Position Model2 := portal.Target.Model() // model matrix, so that portal 1 in camera 1 looks identical to portal 2 in camera oldView := this.View this.View = this.View.Mul4(Model).Mul4(Model2.Inv()) normal_os := portal.Target.Normal normal_ws := Model.Mul4x1(normal_os) view_dir := helpers.HomogenDiff(portal.Position, camera.Position) sign := view_dir.Dot(normal_ws) oldClippingPlane := this.ClippingPlane_ws this.ClippingPlane_ws = portal.Target.ClippingPlane(sign > 0) this.render(ww, options, viewport, recursion+1, nearestPortal) this.ClippingPlane_ws = oldClippingPlane this.View = oldView gl.ActiveTexture(gl.TEXTURE0) this.Framebuffer[recursion+1].RenderTexture.Bind(gl.TEXTURE_RECTANGLE) if scissor { //gl.Scissor(0, 0, w, h) gl.Disable(gl.SCISSOR_TEST) } this.Framebuffer[recursion].Bind() gl.Enable(gl.DEPTH_CLAMP) additionalUniforms := map[string]int{"Image": 0} this.PortalRenderer.Render(nearestPortal, this.Proj, this.View, this.ClippingPlane_ws, additionalUniforms) } } }
func StartGame() { window := initSDL() context := initGL(window) nvg := initNanovg() ww, wh := window.GetSize() gw := ww / 5 gh := wh / 5 life := NewLife(gw, gh) refgrid := make([][]bool, gh) for i := range refgrid { refgrid[i] = make([]bool, gw) } // Run the game at 15fps. This gives us about 66ms to calculate // and render everything. 30ms is not possible yet. minms := uint32(1000 / 15) running := true gl.ClearColor(0.3, 0.3, 0.32, 1.0) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT) // Draw all squares first. tw, th := float32(life.w), float32(life.h) for y := float32(0); y < th; y++ { for x := float32(0); x < tw; x++ { nvg.BeginPath() nvg.Rect(x*5+1, y*5+1, 3, 3) nvg.FillColor(nanovg.RGBA(100, 100, 100, 255)) nvg.Fill() nvg.ClosePath() } } // Loop! for running { lt := sdl.GetTicks() for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { switch t := event.(type) { case *sdl.QuitEvent: running = false case *sdl.KeyUpEvent: if t.Keysym.Sym == sdl.K_ESCAPE { running = false } } } life.Step() ww, wh := window.GetSize() gl.Viewport(0, 0, ww, wh) nvg.BeginFrame(ww, wh, 1.0) drawGrid(life, nvg, refgrid) nvg.EndFrame() if d := sdl.GetTicks() - lt; d < minms { sdl.Delay(minms - d) } sdl.GL_SwapWindow(window) } // Cleanup. window.Destroy() sdl.GL_DeleteContext(context) nvg.Close() sdl.Quit() }
// GetTime get the current time from the length that the application has been running. func GetTime() float32 { return float32(sdl.GetTicks()) / 1000.0 }
// setState sets the current states and does timer management func (ps *PlayState) setState(state int) { ps.state.state = state ps.state.startTime = sdl.GetTicks() }
// Get time in seconds. Time zero is platform specific. func Now() float64 { return float64(sdl.GetTicks()) * 0.001 }
func main() { var window *sdl.Window var renderer *sdl.Renderer var event sdl.Event var running bool window = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, winWidth, winHeight, sdl.WINDOW_SHOWN) if window == nil { fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", sdl.GetError()) os.Exit(1) } renderer = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED) if renderer == nil { fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", sdl.GetError()) os.Exit(2) } running = true lastPushTime := sdl.GetTicks() for running { // Push a UserEvent every second if lastPushTime+pushTime < sdl.GetTicks() { lastPushTime = sdl.GetTicks() pEvent := &sdl.UserEvent{sdl.USEREVENT, sdl.GetTicks(), window.GetID(), 1331, nil, nil} retVal := sdl.PushEvent(pEvent) // Here's where the event is actually pushed switch retVal { case 1: fmt.Println("PushEvent returned success") case 0: fmt.Println("PushEvent returned filtered") case -1: fmt.Printf("PushEvent returned error: %s\n", sdl.GetError) } } for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent() { switch t := event.(type) { case *sdl.QuitEvent: running = false case *sdl.MouseMotionEvent: fmt.Printf("[%d ms] MouseMotion\ttype:%d\tid:%d\tx:%d\ty:%d\txrel:%d\tyrel:%d\n", t.Timestamp, t.Type, t.Which, t.X, t.Y, t.XRel, t.YRel) case *sdl.MouseButtonEvent: fmt.Printf("[%d ms] MouseButton\ttype:%d\tid:%d\tx:%d\ty:%d\tbutton:%d\tstate:%d\n", t.Timestamp, t.Type, t.Which, t.X, t.Y, t.Button, t.State) case *sdl.MouseWheelEvent: fmt.Printf("[%d ms] MouseWheel\ttype:%d\tid:%d\tx:%d\ty:%d\n", t.Timestamp, t.Type, t.Which, t.X, t.Y) case *sdl.KeyUpEvent: fmt.Printf("[%d ms] Keyboard\ttype:%d\tsym:%c\tmodifiers:%d\tstate:%d\trepeat:%d\n", t.Timestamp, t.Type, t.Keysym.Sym, t.Keysym.Mod, t.State, t.Repeat) case *sdl.UserEvent: fmt.Printf("[%d ms] UserEvent\tcode:%d\n", t.Timestamp, t.Code) } } sdl.Delay(1000 / 30) } renderer.Destroy() window.Destroy() }