示例#1
0
文件: DMG.go 项目: jlukacs/gameboy
func (dmg *DMG) Run(file string, width, height int) {
	sdl.Init(sdl.INIT_VIDEO)
	defer sdl.Quit()

	dmg.init(file, width, height)
	dmg.exec()
}
示例#2
0
func main() {
	if err := sdl.Init(sdl.INIT_AUDIO); err != nil {
		log.Println(err)
		return
	}

	if err := mix.Init(mix.INIT_MP3); err != nil {
		log.Println(err)
		return
	}
	defer sdl.Quit()
	defer mix.Quit()
	defer mix.CloseAudio()

	if err := mix.OpenAudio(22050, mix.DEFAULT_FORMAT, 2, 4096); err != nil {
		log.Println(err)
		return
	}

	if music, err := mix.LoadMUS("test.mp3"); err != nil {
		log.Println(err)
	} else if err = music.Play(1); err != nil {
		log.Println(err)
	} else {
		sdl.Delay(5000)
		music.Free()
	}
}
示例#3
0
/*
Destroy the controller object.
*/
func (c *Controller) Destroy() {
	c.window.Destroy()
	// TODO can I call this anywhere? is this... ok?
	sdl.Quit()
	// MUST unlock OS thread
	runtime.UnlockOSThread()
}
示例#4
0
func (gui *Gui) Start() {
	window, err := sdl.CreateWindow(
		"nice life",
		sdl.WINDOWPOS_UNDEFINED,
		sdl.WINDOWPOS_UNDEFINED,
		gui.cam.width,
		gui.cam.height,
		sdl.WINDOW_SHOWN|sdl.WINDOW_RESIZABLE)

	if err != nil {
		panic(err)
	}

	surface, err := window.GetSurface()
	if err != nil {
		panic(err)
	}

	gui.sdlWindow = window
	gui.sdlSurface = surface

	go gui.handleInput()

	gui.mainLoop()
	sdl.Quit()
}
示例#5
0
文件: display.go 项目: kierdavis/anna
func (d *Display) Close() {
	if d.renderer != nil {
		d.renderer.Destroy()
	}

	if d.window != nil {
		d.window.Destroy()
	}

	sdl.Quit()
}
示例#6
0
文件: opengl.go 项目: emlai/go-sdl2
func main() {
	var winTitle string = "Go-SDL2 + Go-GL"
	var winWidth, winHeight int = 800, 600
	var window *sdl.Window
	var context sdl.GLContext
	var event sdl.Event
	var running bool
	var err error

	if err = sdl.Init(sdl.INIT_EVERYTHING); err != nil {
		panic(err)
	}
	defer sdl.Quit()

	if err = gl.Init(); err != nil {
		panic(err)
	}

	window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
		winWidth, winHeight, sdl.WINDOW_OPENGL)
	if err != nil {
		panic(err)
	}
	defer window.Destroy()
	context, err = sdl.GL_CreateContext(window)
	if err != nil {
		panic(err)
	}
	defer sdl.GL_DeleteContext(context)

	gl.Enable(gl.DEPTH_TEST)
	gl.ClearColor(0.2, 0.2, 0.3, 1.0)
	gl.ClearDepth(1)
	gl.DepthFunc(gl.LEQUAL)
	gl.Viewport(0, 0, int32(winWidth), int32(winHeight))

	running = true
	for running {
		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\tid:%d\tx:%d\ty:%d\txrel:%d\tyrel:%d\n", t.Timestamp, t.Which, t.X, t.Y, t.XRel, t.YRel)
			}
		}
		drawgl()
		sdl.GL_SwapWindow(window)
	}
}
示例#7
0
func main() {
	flag.Parse()
	//	go doesMyCodeWork()
	//	go doesMyCodeWork2()

	var x, y int
	if len(os.Args) < 3 {
		fmt.Println("No size was specified, using defaults")
		x = int(640 * 1.5)
		y = int(480 * 1.5)
	} else {
		var err error
		x, err = strconv.Atoi(os.Args[1])
		if err != nil {
			fmt.Println("Could not parse " + os.Args[1] + " to int!")
			return
		}
		y, err = strconv.Atoi(os.Args[2])
		if err != nil {
			fmt.Println("Could not parse " + os.Args[2] + " to int!")
			return
		}
	}
	window, err := sdl.CreateWindow("Campus Fighter I", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, x, y, sdl.WINDOWPOS_UNDEFINED)
	if err != nil {
		panic(err)
	}
	defer window.Destroy()
	//sdl.ShowCursor(0)
	window.UpdateSurface()

	renderer, err := sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED)
	if err != nil {
		panic(err)
	}
	surface, err := window.GetSurface()
	if err != nil {
		panic(err)
	}

	controlManager := inputManager.GetControlManager()

	updateFunctionsToStartWith := make([]inputManager.Update, 1)
	updateFunctionsToStartWith[0] = menus.CreateMenus(window, surface, renderer, &controlManager)
	inputManager.StateMachine(controlManager.ReadInput(), updateFunctionsToStartWith)

	sdl.Quit()
}
示例#8
0
func main() {
	sdlInit()

	gm := gamemanager.GGameManager
	gc := gamecontext.GContext

	createMainWindow()
	defer gc.MainWindow.Destroy()

	intro := &introstate.IntroState{}
	play := &playstate.PlayState{}

	gm.RegisterMode(gamemanager.GameModeIntro, intro)
	gm.RegisterMode(gamemanager.GameModePlay, play)

	done := false

	// Keep handy for use in the loop
	mainWindow := gc.MainWindow
	mainWindowSurface := gc.MainSurface

	gm.SetMode(gamemanager.GameModeIntro)

	gm.SetEventMode(gamemanager.GameManagerEventDriven)

	for done == false {
		event := gm.GetNextEvent()
		for ; event != nil; event = sdl.PollEvent() {
			done = done || gm.HandleEvent(&event)

			switch event := event.(type) {
			case *sdl.WindowEvent:
				//fmt.Printf("Window: %#v\n", event)
				//fmt.Printf("Event: %t %t\n", event.Event, sdl.WINDOWEVENT_CLOSE)
				if event.Event == sdl.WINDOWEVENT_CLOSE {
					done = done || true
				}
			}
		}

		gm.Render(mainWindowSurface)
		mainWindow.UpdateSurface()

		gm.DelayToNextFrame()
	}

	sdl.Quit()
}
示例#9
0
// Destroys SDL and releases the memory
func (e *Engine) Destroy() {
	for _, v := range e.StateText {
		v.Texture.Destroy()
	}

	e.Sprite.Destroy()
	e.Font.Close()
	e.Music.Free()
	e.Sound.Free()
	e.Renderer.Destroy()
	e.Window.Destroy()

	ttf.Quit()
	mix.CloseAudio()
	mix.Quit()
	sdl.Quit()
}
示例#10
0
文件: audio.go 项目: emlai/go-sdl2
func main() {
	if err := sdl.Init(sdl.INIT_AUDIO); err != nil {
		log.Println(err)
		return
	}
	defer sdl.Quit()

	spec := &sdl.AudioSpec{
		Freq:     sampleHz,
		Format:   sdl.AUDIO_U8,
		Channels: 2,
		Samples:  sampleHz,
		Callback: sdl.AudioCallback(C.SineWave),
	}
	sdl.OpenAudio(spec, nil)
	sdl.PauseAudio(false)
	time.Sleep(1 * time.Second)
}
示例#11
0
文件: pong.go 项目: gophercoders/pong
// The programs main function
func main() {
	// ---- This is the start of Owen's graphics setup code ----

	// First we have to initalise the SDL library, before we can use it
	sdl.Init(sdl.INIT_EVERYTHING)
	// defer is a go keyword and a special feature.
	// This means that go will automatically call the function sdl.Quit() before
	// the program exits for us. We don't have to remember to put this at the end!
	defer sdl.Quit()

	// if you want to change these try 800 for the width and 600 for the height
	windowWidth = 1024
	windowHeight = 768

	// Now we have to create the window we want to use.
	// We need to tell the SDL library how big to make the window of the correct
	// size - that's what the bit in the brackets does
	window = createWindow(windowWidth, windowHeight)
	// automatically destroy the window when the program finishes
	defer window.Destroy()
	// Now we have a window we need to create a renderer so we can draw into
	// it. In this case we want to use the first graphics card that supports faster
	// drawing
	renderer = createRenderer(window)
	// automatically destroy the renderer when the program exits.
	defer renderer.Destroy()

	// Set a black i.e. RGBA (0,0,0,0) background colour and clear the window
	renderer.SetDrawColor(0, 0, 0, 0)
	renderer.Clear()
	// ---- This is the end of Owen's graphics setup code ----

	// defer any cleanup actions
	defer cleanup()
	// initialise the games variables.
	initialise()
	// render everything initially so that we can see the game before it starts
	render()
	// now start the main game loop of the game.
	gameMainLoop()
}
示例#12
0
func main() {
	var (
		err     error
		window  *sdl.Window
		context sdl.GLContext
	)

	if err = sdl.Init(sdl.INIT_EVERYTHING); err != nil {
		panic(err)
	}
	defer sdl.Quit()

	sdl.GL_SetAttribute(sdl.GL_CONTEXT_MAJOR_VERSION, 3)
	sdl.GL_SetAttribute(sdl.GL_CONTEXT_MINOR_VERSION, 2)
	sdl.GL_SetAttribute(sdl.GL_CONTEXT_PROFILE_MASK, sdl.GL_CONTEXT_PROFILE_CORE)

	window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, winWidth, winHeight, sdl.WINDOW_OPENGL)
	if err != nil {
		panic(err)
	}
	defer window.Destroy()

	context, err = sdl.GL_CreateContext(window)
	if err != nil {
		panic(err)
	}
	defer sdl.GL_DeleteContext(context)

	if err = sdl.GL_MakeCurrent(window, context); err != nil {
		panic(err)
	}

	if err = gl.Init(); err != nil {
		panic(err)
	}

	printGLInfo()
	cameraMatrixUniform := setupGL()
	windowLoop(window, cameraMatrixUniform)
}
示例#13
0
func main() {
	var (
		err     error
		window  *sdl.Window
		context sdl.GLContext
	)

	if err = sdl.Init(sdl.INIT_EVERYTHING); err != nil {
		panic(err)
	}
	defer sdl.Quit()

	sdl.GL_SetAttribute(sdl.GL_CONTEXT_PROFILE_MASK, sdl.GL_CONTEXT_PROFILE_COMPATIBILITY)

	window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, winWidth, winHeight, sdl.WINDOW_OPENGL)
	if err != nil {
		panic(err)
	}
	defer window.Destroy()

	context, err = sdl.GL_CreateContext(window)
	if err != nil {
		panic(err)
	}
	defer sdl.GL_DeleteContext(context)

	if err = sdl.GL_MakeCurrent(window, context); err != nil {
		panic(err)
	}

	if err = gl.Init(); err != nil {
		panic(err)
	}

	sdl.GL_SetSwapInterval(1)

	printGLInfo()
	setupGL()
	windowLoop(window)
}
示例#14
0
func TestTexture(t *testing.T) {
	if sdl.Init(sdl.INIT_EVERYTHING) != 0 {
		panic(sdl.GetError())
	}
	defer sdl.Quit()

	window := sdl.CreateWindow("test", 0, 0, 320, 200, sdl.WINDOW_HIDDEN|sdl.WINDOW_OPENGL)
	defer window.Destroy()

	sdl.GL_SetAttribute(sdl.GL_CONTEXT_PROFILE_MASK, sdl.GL_CONTEXT_PROFILE_ES)
	sdl.GL_SetAttribute(sdl.GL_CONTEXT_MAJOR_VERSION, 2)
	sdl.GL_SetAttribute(sdl.GL_CONTEXT_MINOR_VERSION, 0)

	glctx := sdl.GL_CreateContext(window)
	defer sdl.GL_DeleteContext(glctx)

	tex := gl.CreateTexture()
	gl.BindTexture(gl.TEXTURE_2D, tex)
	if !gl.IsTexture(tex) {
		t.Error(tex, "is not a texture")
	}
}
示例#15
0
func main() {
	sdl.Init(sdl.INIT_EVERYTHING)

	window, err := sdl.CreateWindow("test", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
		800, 600, sdl.WINDOW_SHOWN)
	if err != nil {
		panic(err)
	}
	defer window.Destroy()

	surface, err := window.GetSurface()
	if err != nil {
		panic(err)
	}

	rect := sdl.Rect{0, 0, 200, 200}
	surface.FillRect(&rect, 0xffff0000)
	window.UpdateSurface()

	sdl.Delay(1000)
	sdl.Quit()
}
示例#16
0
文件: in.go 项目: Oralordos/Tank
func main() {
	sdl.Init(sdl.INIT_VIDEO)
	defer sdl.Quit()
	window, err := sdl.CreateWindow("Tank", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, windowWidth, windowHeight, 0)
	if err != nil {
		panic(err)
	}
	defer window.Destroy()

mainloop:
	for {
		for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
			switch event.(type) {
			case *sdl.QuitEvent:
				break mainloop
			}
		}
		windowSurface, _ := window.GetSurface()
		windowSurface.FillRect(nil, sdl.MapRGB(windowSurface.Format, 0, 0, 0))

		window.UpdateSurface()
		sdl.Delay(1000)
	}
}
示例#17
0
func main() {
	fmt.Print()

	sdl.SetHint(sdl.HINT_RENDER_VSYNC, "1")

	check(sdl.Init(sdl.INIT_EVERYTHING))
	defer sdl.Quit()

	window, r, err := sdl.CreateWindowAndRenderer(
		640, 480,
		sdl.WINDOW_RESIZABLE,
	)
	check(err)
	renderer = r
	defer renderer.Destroy()
	defer window.Destroy()
	window.SetTitle("Gophette's Adventures - Level Editor")
	window.SetPosition(50, 50)
	window.SetSize(1800, 900)
	window.SetFullscreen(sdl.WINDOW_FULLSCREEN_DESKTOP)
	renderer.SetDrawBlendMode(sdl.BLENDMODE_BLEND)

	if len(LevelImages) == 0 {
		for i, id := range []string{
			"grass left",
			"grass right",
			"grass center 1",
			"grass center 2",
			"grass center 3",
			"small tree",
		} {
			images = append(images, image{id, loadImage(id), 0, i * 50})
		}
	} else {
		for i := range LevelImages {
			id := LevelImages[i].ID
			x, y := LevelImages[i].X, LevelImages[i].Y
			img := loadImage(id)
			images = append(images, image{id, img, x, y})
		}
	}

	leftDown := false
	middleDown := false
	rightDown := false
	selectedImage := -1
	selectedObject := -1
	var lastX, lastY int

	moveImage := func(dx, dy int) {
		if selectedImage != -1 {
			images[selectedImage].x += dx
			images[selectedImage].y += dy
		}
	}

	stretchObject := func(dx, dy int) {
		if selectedObject != -1 {
			if sdl.GetKeyboardState()[sdl.SCANCODE_LCTRL] != 0 {
				dx *= 20
				dy *= 20
			}
			obj := &LevelObjects[selectedObject]
			obj.W += dx
			obj.H += dy
		}
	}

	running := true
	for running {
		for e := sdl.PollEvent(); e != nil; e = sdl.PollEvent() {
			switch event := e.(type) {
			case *sdl.QuitEvent:
				running = false
			case *sdl.MouseButtonEvent:
				if event.Button == sdl.BUTTON_LEFT {
					leftDown = event.State == sdl.PRESSED
					if !leftDown {
						draggingImage = false
						draggingObject = false
					} else {
						selectedObject = -1
						selectedImage = -1
						for i := range images {
							if images[i].contains(
								int(event.X)-cameraX,
								int(event.Y)-cameraY,
							) {
								draggingImage = true
								selectedImage = i
							}
						}

						if selectedImage == -1 {
							for i := range LevelObjects {
								if contains(LevelObjects[i],
									int(event.X)-cameraX,
									int(event.Y)-cameraY,
								) {
									draggingObject = true
									selectedObject = i
								}
							}
						}
					}
				}
				if event.Button == sdl.BUTTON_MIDDLE {
					middleDown = event.State == sdl.PRESSED
				}
				if event.Button == sdl.BUTTON_RIGHT {
					rightDown = event.State == sdl.PRESSED
					LevelObjects = append(LevelObjects, LevelObject{
						int(event.X) - cameraX,
						int(event.Y) - cameraY,
						0,
						0,
						true,
					})
					selectedObject = -1
				}
			case *sdl.MouseMotionEvent:
				dx, dy := int(event.X)-lastX, int(event.Y)-lastY
				if selectedImage != -1 && draggingImage {
					img := &images[selectedImage]
					img.x += dx
					img.y += dy
				}
				if selectedObject != -1 && draggingObject {
					obj := &LevelObjects[selectedObject]
					obj.X += dx
					obj.Y += dy
				}
				lastX, lastY = int(event.X), int(event.Y)

				if middleDown {
					cameraX += dx
					cameraY += dy
				}

				if rightDown {
					last := &LevelObjects[len(LevelObjects)-1]
					last.W += dx
					last.H += dy
				}
			case *sdl.KeyDownEvent:
				switch event.Keysym.Sym {
				case sdl.K_ESCAPE:
					running = false
				case sdl.K_LEFT:
					cameraX += 100
				case sdl.K_RIGHT:
					cameraX -= 100
				case sdl.K_UP:
					cameraY += 100
				case sdl.K_DOWN:
					cameraY -= 100
				case sdl.K_a:
					moveImage(-1, 0)
				case sdl.K_d:
					moveImage(1, 0)
				case sdl.K_w:
					moveImage(0, -1)
				case sdl.K_s:
					moveImage(0, 1)
				case sdl.K_j:
					stretchObject(-1, 0)
				case sdl.K_l:
					stretchObject(1, 0)
				case sdl.K_i:
					stretchObject(0, -1)
				case sdl.K_k:
					stretchObject(0, 1)
				case sdl.K_MINUS:
					if selectedImage != -1 && selectedImage != 0 {
						images = append(append(
							[]image{images[selectedImage]},
							images[0:selectedImage]...),
							images[selectedImage+1:]...,
						)
						selectedImage = 0
					}
				case sdl.K_PLUS:
					last := len(images) - 1
					fmt.Println("last", last, len(images))
					fmt.Println("selectedImage", selectedImage)
					if selectedImage != -1 && selectedImage != last {
						images = append(append(
							images[0:selectedImage],
							images[selectedImage+1:]...),
							images[selectedImage],
						)
						selectedImage = last
						fmt.Println("selectedImage after", selectedImage)
					}
				case sdl.K_SPACE:
					if selectedObject != -1 {
						obj := &LevelObjects[selectedObject]
						obj.Solid = !obj.Solid
					}
				case sdl.K_c:
					if selectedImage != -1 {
						copy := images[selectedImage]
						copy.x += 10
						copy.y += 10
						images = append(images, copy)
					}
				case sdl.K_DELETE:
					if selectedImage != -1 {
						images = append(images[:selectedImage], images[selectedImage+1:]...)
						selectedImage = -1
					} else if selectedObject != -1 {
						LevelObjects = append(
							LevelObjects[:selectedObject],
							LevelObjects[selectedObject+1:]...,
						)
						selectedObject = -1
					}
				case sdl.K_F3:
					saveLevel()
				}
			}
		}

		renderer.SetDrawColor(backColor[0], backColor[1], backColor[2], 255)
		renderer.Clear()

		for i, img := range images {
			img.render(i == selectedImage)
		}

		for i, obj := range LevelObjects {
			var g uint8 = 0
			var a uint8 = 100
			if i == selectedObject {
				g = 255
			}
			renderer.SetDrawColor(0, g, 0, a)
			if obj.Solid {
				renderer.SetDrawColor(0, g, 255, a)
			}
			obj.X += cameraX
			obj.Y += cameraY
			r := sdl.Rect{int32(obj.X), int32(obj.Y), int32(obj.W), int32(obj.H)}
			renderer.FillRect(&r)
		}

		renderer.Present()
	}
}
示例#18
0
文件: window.go 项目: xladykiller/GT
func (w Window) Close() {
	sdl.GL_DeleteContext(w.contextSDL)
	w.windowSDL.Destroy()
	sdl.Quit()
}
示例#19
0
文件: opengl3.go 项目: emlai/go-sdl2
func main() {
	var window *sdl.Window
	var context sdl.GLContext
	var event sdl.Event
	var running bool
	var err error
	runtime.LockOSThread()
	if err = sdl.Init(sdl.INIT_EVERYTHING); err != nil {
		panic(err)
	}
	defer sdl.Quit()
	window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED,
		sdl.WINDOWPOS_UNDEFINED,
		winWidth, winHeight, sdl.WINDOW_OPENGL)
	if err != nil {
		panic(err)
	}
	defer window.Destroy()
	context, err = sdl.GL_CreateContext(window)
	if err != nil {
		panic(err)
	}
	defer sdl.GL_DeleteContext(context)

	gl.Init()
	gl.Viewport(0, 0, gl.Sizei(winWidth), gl.Sizei(winHeight))
	// OPENGL FLAGS
	gl.ClearColor(0.0, 0.1, 0.0, 1.0)
	gl.Enable(gl.DEPTH_TEST)
	gl.DepthFunc(gl.LESS)
	gl.Enable(gl.BLEND)
	gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)

	// VERTEX BUFFER
	var vertexbuffer gl.Uint
	gl.GenBuffers(1, &vertexbuffer)
	gl.BindBuffer(gl.ARRAY_BUFFER, vertexbuffer)
	gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(len(triangle_vertices)*4), gl.Pointer(&triangle_vertices[0]), gl.STATIC_DRAW)

	// COLOUR BUFFER
	var colourbuffer gl.Uint
	gl.GenBuffers(1, &colourbuffer)
	gl.BindBuffer(gl.ARRAY_BUFFER, colourbuffer)
	gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(len(triangle_colours)*4), gl.Pointer(&triangle_colours[0]), gl.STATIC_DRAW)

	// GUESS WHAT
	program := createprogram()

	// VERTEX ARRAY
	var VertexArrayID gl.Uint
	gl.GenVertexArrays(1, &VertexArrayID)
	gl.BindVertexArray(VertexArrayID)
	gl.EnableVertexAttribArray(0)
	gl.BindBuffer(gl.ARRAY_BUFFER, vertexbuffer)
	gl.VertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 0, nil)

	// VERTEX ARRAY HOOK COLOURS
	gl.EnableVertexAttribArray(1)
	gl.BindBuffer(gl.ARRAY_BUFFER, colourbuffer)
	gl.VertexAttribPointer(1, 3, gl.FLOAT, gl.FALSE, 0, nil)

	//UNIFORM HOOK
	unistring := gl.GLString("scaleMove")
	UniScale = gl.GetUniformLocation(program, unistring)
	fmt.Printf("Uniform Link: %v\n", UniScale+1)

	gl.UseProgram(program)

	running = true
	for running {
		for event = sdl.PollEvent(); event != nil; event =
			sdl.PollEvent() {
			switch t := event.(type) {
			case *sdl.QuitEvent:
				running = false
			case *sdl.MouseMotionEvent:

				xrot = float32(t.Y) / 2
				yrot = float32(t.X) / 2
				fmt.Printf("[%dms]MouseMotion\tid:%d\tx:%d\ty:%d\txrel:%d\tyrel:%d\n", t.Timestamp, t.Which, t.X, t.Y, t.XRel, t.YRel)
			}
		}
		drawgl()
		sdl.GL_SwapWindow(window)
	}
}
示例#20
0
func main() {
	runtime.LockOSThread()

	flag.Parse()
	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	if err := sdl.Init(sdl.INIT_EVERYTHING); err != nil {
		panic(err)
	}
	defer sdl.Quit()

	sdl.GL_SetAttribute(sdl.GL_MULTISAMPLESAMPLES, 4)
	sdl.GL_SetAttribute(sdl.GL_CONTEXT_MAJOR_VERSION, 3)
	sdl.GL_SetAttribute(sdl.GL_CONTEXT_MINOR_VERSION, 3)
	sdl.GL_SetAttribute(sdl.GL_CONTEXT_PROFILE_MASK, sdl.GL_CONTEXT_PROFILE_CORE)
	sdl.GL_SetAttribute(sdl.GL_DOUBLEBUFFER, 1)
	sdl.GL_SetAttribute(sdl.GL_DEPTH_SIZE, 24)
	sdl.GL_SetAttribute(sdl.GL_CONTEXT_FLAGS, sdl.GL_CONTEXT_DEBUG_FLAG|sdl.GL_CONTEXT_FORWARD_COMPATIBLE_FLAG)

	window, err := sdl.CreateWindow("TOW", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, 1024, 768, sdl.WINDOW_OPENGL|sdl.WINDOW_SHOWN|sdl.WINDOW_RESIZABLE)
	if err != nil {
		log.Fatal("can't create window", err)
	}
	defer window.Destroy()

	//defer renderer.Destroy()

	glcontext, err := sdl.GL_CreateContext(window)
	if err != nil {
		log.Fatal("can't create context", err)
	}
	defer sdl.GL_DeleteContext(glcontext)
	sdl.GL_MakeCurrent(window, glcontext)

	//err := gl.GlewInit()
	//fmt.Println(gl.GlewGetErrorString(err))
	//glew init
	gl.Init()
	sdl.GL_SetSwapInterval(1)

	fmt.Println("glVersion", gl.GetString(gl.VERSION))

	tw.Init(tw.OPENGL_CORE, nil)
	defer tw.Terminate()

	gl.GetError() // Ignore error
	debugContext.InitDebugContext()

	world := generation.GenerateWorld(64, 64, 2)
	gs := gamestate.NewGameState(window, world)
	defer gs.Delete()
	worldRenderer := rendering.NewWorldRenderer(window, gs.World)
	defer worldRenderer.Delete()

	gs.Bar.AddButton("screen shot", worldRenderer.ScreenShot, "")

	MainLoop(gs, worldRenderer)

	if *memprofile != "" {
		f, err := os.Create(*memprofile)
		if err != nil {
			panic(err)
		}
		pprof.WriteHeapProfile(f)
		f.Close()
		return
	}
}
示例#21
0
func main() {
	defaultConfig := config{
		Axes: map[string][3]int{
			strconv.Itoa(sdl.CONTROLLER_AXIS_LEFTX):  {0x4000, 0x7B, 0x7C}, // Arrow Left + Right
			strconv.Itoa(sdl.CONTROLLER_AXIS_LEFTY):  {0x4000, 0x7E, 0x7D}, // Arrow Up + Down
			strconv.Itoa(sdl.CONTROLLER_AXIS_RIGHTX): {0x4000, 0x00, 0x07}, // A + X
			strconv.Itoa(sdl.CONTROLLER_AXIS_RIGHTY): {0x4000, 0x01, 0x06}, // S + Z
		},
		Buttons: map[string]int{
			strconv.Itoa(sdl.CONTROLLER_BUTTON_DPAD_UP):       0X7E, // Up
			strconv.Itoa(sdl.CONTROLLER_BUTTON_DPAD_DOWN):     0X7D, // Down
			strconv.Itoa(sdl.CONTROLLER_BUTTON_DPAD_LEFT):     0x7B, // Left
			strconv.Itoa(sdl.CONTROLLER_BUTTON_DPAD_RIGHT):    0x7C, // Right
			strconv.Itoa(sdl.CONTROLLER_BUTTON_A):             0X06, // Z
			strconv.Itoa(sdl.CONTROLLER_BUTTON_B):             0x07, // X
			strconv.Itoa(sdl.CONTROLLER_BUTTON_X):             0x00, // A
			strconv.Itoa(sdl.CONTROLLER_BUTTON_Y):             0x01, // S
			strconv.Itoa(sdl.CONTROLLER_BUTTON_LEFTSHOULDER):  0x0C, // Q
			strconv.Itoa(sdl.CONTROLLER_BUTTON_RIGHTSHOULDER): 0x0D, // W
			strconv.Itoa(sdl.CONTROLLER_BUTTON_LEFTSTICK):     0x38, // Shift
			strconv.Itoa(sdl.CONTROLLER_BUTTON_RIGHTSTICK):    0x3B, // Ctrl
			strconv.Itoa(sdl.CONTROLLER_BUTTON_BACK):          0x33, // Delete
			strconv.Itoa(sdl.CONTROLLER_BUTTON_GUIDE):         0x30, // Tab
			strconv.Itoa(sdl.CONTROLLER_BUTTON_START):         0x24, // Return
		},
		Triggers: map[string][2]int{
			strconv.Itoa(sdl.CONTROLLER_AXIS_TRIGGERLEFT):  {0x4000, 0x0E}, // E
			strconv.Itoa(sdl.CONTROLLER_AXIS_TRIGGERRIGHT): {0x4000, 0x0F}, // R
		},
	}

	conf := newConfig()
	if file, err := os.Open("config.json"); err != nil {
		f, err := os.Create("config.json")
		if err != nil {
			log.Fatal(err)
		}
		defer f.Close()

		conf = defaultConfig

		buf, err := json.MarshalIndent(conf, "", "    ")
		if err != nil {
			log.Fatal(err)
		}
		f.Write(buf)
	} else {
		err := json.NewDecoder(file).Decode(&conf)
		if err != nil {
			os.Remove("config.json")
			log.Fatal(err)
		}

		file.Close()
	}

	controller, err := newController(conf)
	if err != nil {
		log.Fatal(err)
	}
	defer controller.close()

	err = sdl.Init((1 << 14) | sdl.INIT_GAMECONTROLLER)
	if err != nil {
		log.Fatal(err)
	}
	defer sdl.Quit()

	sdlController := sdl.GameControllerOpen(0)
	if sdlController == nil {
		log.Fatal(sdl.GetError())
	}
	defer sdlController.Close()

	for {
		for e := sdl.PollEvent(); e != nil; e = sdl.PollEvent() {
			switch e := e.(type) {
			case *sdl.ControllerButtonEvent:
				if e.State == 0 {
					controller.Buttons[int(e.Button)].handleUp()
				} else {
					controller.Buttons[int(e.Button)].handleDown()
				}
			case *sdl.ControllerAxisEvent:
				if e.Axis == sdl.CONTROLLER_AXIS_TRIGGERLEFT || e.Axis == sdl.CONTROLLER_AXIS_TRIGGERRIGHT {
					controller.Triggers[int(e.Axis)].handleEvent(int(e.Value))
				} else {
					controller.Axes[int(e.Axis)].handleEvent(int(e.Value))
				}
			}
		}
		sdl.Delay(10)
	}
}
示例#22
0
文件: window.go 项目: fmd/gogol
// Destroys the Bronson window.
func (w *Window) Destroy() {
	sdl.GL_DeleteContext(w.Context)
	w.Window.Destroy()
	sdl.Quit()
}
示例#23
0
func TestBindVariables(t *testing.T) {
	if sdl.Init(sdl.INIT_EVERYTHING) != 0 {
		panic(sdl.GetError())
	}

	window := sdl.CreateWindow("test", 0, 0, 320, 200, sdl.WINDOW_HIDDEN|sdl.WINDOW_OPENGL)

	sdl.GL_SetAttribute(sdl.GL_CONTEXT_PROFILE_MASK, sdl.GL_CONTEXT_PROFILE_ES)
	sdl.GL_SetAttribute(sdl.GL_CONTEXT_MAJOR_VERSION, 2)
	sdl.GL_SetAttribute(sdl.GL_CONTEXT_MINOR_VERSION, 0)

	glctx := sdl.GL_CreateContext(window)

	vs := gl.CreateShader(gl.VERTEX_SHADER)
	vs.Source(`
uniform mat4 u_projection;
uniform vec2 u_size;
attribute vec2 a_vertex;
attribute vec2 a_texcoord;
varying vec2 v_texcoord;

void main()
{
	v_texcoord = a_texcoord;
	gl_Position = u_projection * vec4(a_vertex * u_size, 0, 1);
}
`)
	vs.Compile()

	fs := gl.CreateShader(gl.FRAGMENT_SHADER)
	fs.Source(`
precision mediump float;

uniform sampler2D u_tex;
uniform vec4 u_color;

varying vec2 v_texcoord;

void main()
{
	gl_FragColor = texture2D(u_tex, v_texcoord).a * u_color;
}
`)
	fs.Compile()

	p := gl.CreateProgram()

	p.AttachShader(vs)
	p.AttachShader(fs)
	p.Link()

	var v struct {
		Proj      gl.UniformMatrix4f `glsl:"u_projection"`
		Size      gl.Uniform2f       `glsl:"u_size"`
		Tex       gl.Uniform1i       `glsl:"u_tex"`
		Color     gl.Uniform4f       `glsl:"u_color"`
		Vertices  gl.Vec2Attrib      `glsl:"a_vertex"`
		TexCoords gl.Vec2Attrib      `glsl:"a_texcoord"`
	}

	p.BindVariables(&v)

	uniforms := []gl.Uniform{v.Proj, v.Size, v.Tex, v.Color}
	cksum := 0
	for _, u := range uniforms {
		cksum |= 1 << uint(u.Location())
	}

	if cksum != 0xF {
		t.Errorf("unexpected uniform locations: %#x", cksum)
	}

	attributes := []gl.VertexAttrib{v.Vertices, v.TexCoords}
	cksum = 0
	for _, a := range attributes {
		cksum |= 1 << uint(a.Index())
	}

	if cksum != 0x3 {
		t.Errorf("unexpected attribute locations: %#x", cksum)
	}

	sdl.GL_DeleteContext(glctx)
	window.Destroy()
	sdl.Quit()
}
示例#24
0
文件: events.go 项目: veandco/go-sdl2
func run() int {
	var window *sdl.Window
	var event sdl.Event
	var running bool
	var err error

	sdl.Init(sdl.INIT_EVERYTHING)

	window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
		winWidth, winHeight, sdl.WINDOW_SHOWN)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err)
		return 1
	}
	defer window.Destroy()

	sdl.JoystickEventState(sdl.ENABLE)

	running = true
	for running {
		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.KeyDownEvent:
				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.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.JoyAxisEvent:
				fmt.Printf("[%d ms] JoyAxis\ttype:%d\twhich:%c\taxis:%d\tvalue:%d\n",
					t.Timestamp, t.Type, t.Which, t.Axis, t.Value)
			case *sdl.JoyBallEvent:
				fmt.Printf("[%d ms] JoyBall\ttype:%d\twhich:%d\tball:%d\txrel:%d\tyrel:%d\n",
					t.Timestamp, t.Type, t.Which, t.Ball, t.XRel, t.YRel)
			case *sdl.JoyButtonEvent:
				fmt.Printf("[%d ms] JoyButton\ttype:%d\twhich:%d\tbutton:%d\tstate:%d\n",
					t.Timestamp, t.Type, t.Which, t.Button, t.State)
			case *sdl.JoyHatEvent:
				fmt.Printf("[%d ms] JoyHat\ttype:%d\twhich:%d\that:%d\tvalue:%d\n",
					t.Timestamp, t.Type, t.Which, t.Hat, t.Value)
			case *sdl.JoyDeviceEvent:
				if t.Type == sdl.JOYDEVICEADDED {
					joysticks[int(t.Which)] = sdl.JoystickOpen(t.Which)
					if joysticks[int(t.Which)] != nil {
						fmt.Printf("Joystick %d connected\n", t.Which)
					}
				} else if t.Type == sdl.JOYDEVICEREMOVED {
					if joystick := joysticks[int(t.Which)]; joystick != nil {
						joystick.Close()
					}
					fmt.Printf("Joystick %d disconnected\n", t.Which)
				}
			default:
				fmt.Printf("Some event\n")
			}
		}
	}

	sdl.Quit()

	return 0
}
示例#25
0
文件: init.go 项目: eandre/drip
func Quit() {
	sdl.Quit()
}
示例#26
0
func main() {
	runtime.LockOSThread()
	err := sdl.Init(sdl.INIT_EVERYTHING)
	if err != nil {
		panic(err)
	}
	defer sdl.Quit()

	err = ttf.Init()
	if err != nil {
		panic(err)
	}
	defer ttf.Quit()

	window, err := sdl.CreateWindow("test", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
		800, 600, sdl.WINDOW_SHOWN)
	if err != nil {
		panic(err)
	}
	defer window.Destroy()

	surface, err := window.GetSurface()
	if err != nil {
		panic(err)
	}
	var bgRect sdl.Rect
	surface.GetClipRect(&bgRect)

	font, err = ttf.OpenFont("/Library/Fonts/Arial.ttf", 128)
	if err != nil {
		panic(err)
	}
	defer font.Close()

	fpsTimer := time.NewTicker(time.Second / 60)

	newNumTicker := time.NewTicker(time.Second / 2)

	go func() {
		num := NewNum()
		nums[num] = num
		for {
			<-newNumTicker.C
			num := NewNum()
			nums[num] = num
		}
	}()

	inputTimer := time.NewTicker(time.Second / 100)

MainLoop:
	for {
		select {
		case <-fpsTimer.C:

			surface.FillRect(&bgRect, BACKGROUND_COLOR.Uint32())

			for _, num := range nums {
				num.Draw(surface)
			}

			window.UpdateSurface()
		case <-inputTimer.C:
			for e := sdl.PollEvent(); e != nil; e = sdl.PollEvent() {
				switch t := e.(type) {
				case *sdl.QuitEvent:
					break MainLoop
				case *sdl.KeyDownEvent:
					if t.Keysym.Sym == sdl.K_ESCAPE {
						break MainLoop
					}
				}
			}
		}

	}

	fmt.Println("main thread exiting")
}
示例#27
0
// Close closes the toolbox, releasing any underlying resources. It must
// be called before the program exits to prevent a resource leak. The toolbox
// cannot be used again until the Initialise function is called again.
func Close() {
	sdl.Quit()
	initialised = true
}
示例#28
0
// win==nil requests a full-screen window
func Run(win WindowSpec) int {
	// All SDL calls must come from same thread.
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	err := sdl.Init(sdl.INIT_EVERYTHING)
	if err != nil {
		panic(err)
	}
	defer sdl.Quit()

	// Install audio callback
	spec := &sdl.AudioSpec{
		Freq:     SampleRate,
		Format:   sdl.AUDIO_F32SYS,
		Channels: 1,
		Samples:  4096,
		Callback: sdl.AudioCallback(C.getSoundSamplesAdaptor),
	}
	audioDevice, err := sdl.OpenAudioDevice("", false, spec, nil, 0)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to open audio device: %v\n", err)
		panic(err)
	}
	if audioDevice < 2 {
		fmt.Fprintf(os.Stderr, "Audio device=%v < 2 contrary to SDL-2 documentation\n", audioDevice, err)
	}
	sdl.PauseAudioDevice(audioDevice, false)

	// Create window
	var window *sdl.Window
	if win != nil {
		// Partial screen
		winWidth, winHeight := win.Size()
		window, err = sdl.CreateWindow(win.Title(), sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
			int(winWidth), int(winHeight), sdl.WINDOW_SHOWN)
	} else {
		// Full screen
		if isMacOS {
			// Contrary to https://wiki.libsdl.org/SDL_CreateWindow, on MacOS 10.11.1
			// a call to sdl.CreateWindow in fullscreen mode *does* use the w and h parameters.
			// So ask what the display size is.
			var mode sdl.DisplayMode
			err = sdl.GetDesktopDisplayMode(0, &mode)
			if err != nil {
				fmt.Fprintf(os.Stderr, "Cannot get desktop display mode")
				panic(err)
			}
			window, err = sdl.CreateWindow("", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
				int(mode.W), int(mode.H), sdl.WINDOW_SHOWN|sdl.WINDOW_FULLSCREEN_DESKTOP)
		} else {
			window, err = sdl.CreateWindow("", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
				0, 0, sdl.WINDOW_SHOWN|sdl.WINDOW_FULLSCREEN_DESKTOP)
		}

	}
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to create window: %v\n", err)
		panic(err)
	}
	defer window.Destroy()

	// Create renderer
	width, height := window.GetSize()
	renderer, err := sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED|sdl.RENDERER_PRESENTVSYNC)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to create renderer: %v\n", err)
		panic(err)
	}
	defer renderer.Destroy()

	var nTex = 1
	if isMacOS {
		// Work around MacOS bug via double buffering
		nTex = 2
	}
	// Create texture
	tex := make([]*sdl.Texture, nTex)
	for i := range tex {
		tex[i], err = renderer.CreateTexture(sdl.PIXELFORMAT_ARGB8888, sdl.TEXTUREACCESS_STREAMING, width, height)
		if err != nil {
			fmt.Fprintf(os.Stderr, "renderer.CreateTexture: %v\n", err)
			panic(err)
		}
		defer tex[i].Destroy()
	}
	for _, r := range renderClientList {
		r.Init(int32(width), int32(height))
	}

	// Loop until quit
	for i := 0; ; i ^= nTex - 1 {
		for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
			switch e := event.(type) {
			case *sdl.QuitEvent:
				return 0
			case *sdl.MouseMotionEvent:
				// Go equivalent of SDL_PRESSED seems to be missing, so compare with zero.
				if e.State != 0 {
					forwardMouseEvent(MouseDrag, int32(e.X), int32(e.Y))
				} else {
					forwardMouseEvent(MouseMove, int32(e.X), int32(e.Y))
				}
			case *sdl.MouseButtonEvent:
				switch e.Type {
				case sdl.MOUSEBUTTONDOWN:
					forwardMouseEvent(MouseDown, int32(e.X), int32(e.Y))
				case sdl.MOUSEBUTTONUP:
					forwardMouseEvent(MouseUp, int32(e.X), int32(e.Y))
				}
			case *sdl.KeyDownEvent:
				var k Key
				if 0x20 <= e.Keysym.Sym && e.Keysym.Sym < 0x7F {
					// Printable ASCII
					k = Key(e.Keysym.Sym)
				} else {
					// Try special character table
					k = keyMap[e.Keysym.Sym]
				}
				if k != 0 {
					forwardKeyEvent(k)
				}
			}
		}
		pixels, pitch := lockTexture(tex[i], width, height)
		pm := MakePixMap(int32(width), int32(height), pixels, int32(pitch))
		for _, r := range renderClientList {
			r.Render(pm)
		}
		tex[i].Unlock()

		err := renderer.Clear()
		if err != nil {
			fmt.Fprintf(os.Stderr, "renderer.Clear: %v", err)
			panic(err)
		}
		renderer.Copy(tex[i], nil, nil)
		if err != nil {
			fmt.Fprintf(os.Stderr, "renderer.Copy: %v", err)
			panic(err)
		}
		renderer.Present()
	}
}
示例#29
0
文件: game.go 项目: doddo/gfx
// Start the game and enter the event loop
func (g *Game) Start() {
	g.playing = true
	g.gameArea = newGameArea()
	r := sdl.Rect{650, 150, 300, 300}
	g.scoreBoard = &scoreBoard{area: &r}

	//g.scoreBoard.area = &r
	//TODO: make these values take them from somewhere
	//g.gameArea.color = 0x000dd0c
	// get some settings
	g.settings = &misc.GfxSettings{}
	running := true
	// Random seed
	//s1 := rand.NewSource(time.Now().UnixNano())

	sdl.Init(sdl.INIT_EVERYTHING)

	g.window, err = sdl.CreateWindow("test", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
		1200, 800, sdl.WINDOW_SHOWN)
	if err != nil {
		panic(err)
	}

	// Draw the nice background
	g.drawGameArea()
	g.drawScoreBoard()

	// freshen the screen
	//g.updateScreen()

	fmt.Println("it works")

	for running {
		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.KeyDownEvent:
				if t.Keysym.Sym == 27 { // Quit on ESC, fix this better later
					running = false
				} else {
					g.handleKeyStroke(t.Keysym)
				}

			case *sdl.KeyUpEvent:
				// handleKeyPress(false, t.Keysym)
			}
		}
		g.tick()
	}

	sdl.Quit()

}
示例#30
0
func main() {
	sdl.SetHint(sdl.HINT_RENDER_VSYNC, "1")

	check(sdl.Init(sdl.INIT_EVERYTHING))
	defer sdl.Quit()

	check(mix.Init(mix.INIT_OGG))
	defer mix.Quit()
	check(mix.OpenAudio(44100, mix.DEFAULT_FORMAT, 1, 512))
	defer mix.CloseAudio()

	if img.Init(img.INIT_PNG)&img.INIT_PNG == 0 {
		panic("error init png")
	}
	defer img.Quit()

	window, renderer, err := sdl.CreateWindowAndRenderer(
		640, 480,
		sdl.WINDOW_RESIZABLE,
	)
	check(err)
	defer renderer.Destroy()
	defer window.Destroy()
	window.SetTitle("Gophette's Adventures")
	window.SetSize(800, 600)
	sdl.ShowCursor(0)

	window.SetFullscreen(sdl.WINDOW_FULLSCREEN_DESKTOP)
	fullscreen := true

	camera := newWindowCamera(window.GetSize())

	assetLoader := newSDLAssetLoader(camera, renderer)
	defer assetLoader.close()

	// charIndex selects which character is being controlled by the user, for
	// the final game this must be 0 but for creating the "AI" for Barney, set
	// this to 1 and delete the recorded inputs so they are not applied
	// additionally to the user controls

	var charIndex int
	const recordingAI = false // NOTE switch for development mode
	if !recordingAI {
		charIndex = 0
	} else {
		charIndex = 1
		recordedInputs = recordedInputs[:0]
		recordingInput = true
	}

	game := NewGame(
		assetLoader,
		&sdlGraphics{renderer, camera},
		camera,
		charIndex,
	)

	frameTime := time.Second / 65
	lastUpdate := time.Now().Add(-frameTime)

	music, err := mix.LoadMUS("./rsc/background_music.ogg")
	if err != nil {
		fmt.Println("error loading music:", err)
	} else {
		defer music.Free()
		music.FadeIn(-1, 500)
	}

	for game.Running() {
		for e := sdl.PollEvent(); e != nil; e = sdl.PollEvent() {
			switch event := e.(type) {
			case *sdl.KeyDownEvent:
				if event.Repeat == 0 {
					switch event.Keysym.Sym {
					case sdl.K_LEFT:
						game.HandleInput(InputEvent{GoLeft, true, charIndex})
					case sdl.K_RIGHT:
						game.HandleInput(InputEvent{GoRight, true, charIndex})
					case sdl.K_UP:
						game.HandleInput(InputEvent{Jump, true, charIndex})
					case sdl.K_ESCAPE:
						game.HandleInput(InputEvent{QuitGame, true, charIndex})
					}
				}
			case *sdl.KeyUpEvent:
				switch event.Keysym.Sym {
				case sdl.K_LEFT:
					game.HandleInput(InputEvent{GoLeft, false, charIndex})
				case sdl.K_RIGHT:
					game.HandleInput(InputEvent{GoRight, false, charIndex})
				case sdl.K_UP:
					game.HandleInput(InputEvent{Jump, false, charIndex})
				case sdl.K_F11:
					if fullscreen {
						window.SetFullscreen(0)
					} else {
						window.SetFullscreen(sdl.WINDOW_FULLSCREEN_DESKTOP)
					}
					fullscreen = !fullscreen
				case sdl.K_ESCAPE:
					game.HandleInput(InputEvent{QuitGame, false, charIndex})
				}
			case *sdl.WindowEvent:
				if event.Event == sdl.WINDOWEVENT_SIZE_CHANGED {
					width, height := int(event.Data1), int(event.Data2)
					camera.setWindowSize(width, height)
				}
			case *sdl.QuitEvent:
				game.HandleInput(InputEvent{QuitGame, true, charIndex})
			}
		}

		now := time.Now()
		dt := now.Sub(lastUpdate)
		if dt > frameTime {
			game.Update()
			lastUpdate = now
		}

		check(renderer.SetDrawColor(0, 95, 83, 255))
		check(renderer.Clear())
		game.Render()
		renderer.Present()
	}
}