Example #1
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()
	}
}
Example #2
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()
	}
}
Example #3
0
func main() {
	flag.Parse()

	fmt.Sscanf(arguments.windowSize, "%d,%d", &screenWidth, &screenHeight)
	fmt.Sscanf(arguments.resolution, "%d,%d", &resolutionX, &resolutionY)

	fp, err := os.Open(arguments.inputFile)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		return
	}
	defer fp.Close()

	tree, vpa, err := trace.LoadOctree(fp)
	if err != nil {
		panic(err)
	}
	maxDepth := trace.TreeWidthToDepth(vpa)

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

	title := "AJ's Raytracer"
	window, err := sdl.CreateWindow(title, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, screenWidth, screenHeight, sdl.WINDOW_SHOWN)
	if err != nil {
		panic(err)
	}
	defer window.Destroy()
	sdl.SetRelativeMouseMode(true)

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

	sdl.SetHint(sdl.HINT_RENDER_SCALE_QUALITY, arguments.scaleFilter)
	renderer.SetLogicalSize(resolutionX, resolutionY)
	renderer.SetDrawColor(0, 0, 0, 255)

	rect := image.Rect(0, 0, resolutionX, resolutionY)
	if arguments.enableJitter {
		rect.Max.X /= 2
	}

	surfaces := [2]*image.RGBA{image.NewRGBA(rect), image.NewRGBA(rect)}
	backBuffer := image.NewRGBA(image.Rect(0, 0, resolutionX, resolutionY))

	texture, err := renderer.CreateTexture(sdl.PIXELFORMAT_ABGR8888, sdl.TEXTUREACCESS_STREAMING, resolutionX, resolutionY)
	if err != nil {
		panic(err)
	}
	defer texture.Destroy()

	var pos [3]float32
	fmt.Sscanf(arguments.treePosition, "%f,%f,%f", &pos[0], &pos[1], &pos[2])

	cfg := trace.Config{
		FieldOfView:   float32(arguments.fieldOfView),
		TreeScale:     float32(arguments.treeScale),
		TreePosition:  pos,
		ViewDist:      float32(arguments.viewDistance),
		Images:        surfaces,
		Jitter:        arguments.enableJitter,
		MultiThreaded: arguments.multiThreaded,
		Depth:         enableDepthTest,
	}

	raytracer := trace.NewRaytracer(cfg)
	defer raytracer.Close()

	camera := trace.FreeFlightCamera{XRot: 0, YRot: 0}

	nf := 0
	dt := time.Duration(1000 / 60)
	ft := time.Duration(nf)

	if arguments.pprof {
		go func() {
			fmt.Fprintln(os.Stderr, http.ListenAndServe("localhost:6060", nil))
		}()

		fp, err := os.Create("raytracer.pprof")
		if err != nil {
			panic(err)
		}
		defer fp.Close()

		pprof.StartCPUProfile(fp)
		defer pprof.StopCPUProfile()
	}

	for {
		t := time.Now()
		dtf := float32(dt / time.Millisecond)

		for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
			switch t := event.(type) {
			case *sdl.QuitEvent:
				return
			case *sdl.MouseMotionEvent:
				if enableInput {
					camera.XRot -= dtf * float32(t.XRel) * mouseSpeed
					camera.YRot -= dtf * float32(t.YRel) * mouseSpeed
				}
			case *sdl.KeyUpEvent:
				switch t.Keysym.Sym {
				case sdl.K_ESCAPE:
					return
				case sdl.K_f:
					toggleFullscreen(window)
				case sdl.K_c:
					if !arguments.ppm {
						fmt.Println("Camera:", camera)
					}
				case sdl.K_SPACE:
					enableInput = !enableInput
					sdl.SetRelativeMouseMode(enableInput)
				}
			}
		}

		renderer.Clear()

		if enableInput || arguments.ppm || arguments.pprof {
			if enableInput {
				moveCamera(&camera, dtf)
				window.WarpMouseInWindow(screenWidth/2, screenHeight/2)
			}

			if enableDepthTest {
				raytracer.ClearDepth(raytracer.Frame())
			}

			raytracer.Trace(&camera, tree, maxDepth)
		}

		if arguments.enableJitter {
			if err := trace.Reconstruct(raytracer.Image(0), raytracer.Image(1), backBuffer); err != nil {
				panic(err)
			}
		} else {
			backBuffer = surfaces[0]
		}

		texture.Update(nil, unsafe.Pointer(&backBuffer.Pix[0]), backBuffer.Stride)
		renderer.Copy(texture, nil, nil)
		renderer.Present()

		if arguments.ppm {
			writePPM(backBuffer)
		}

		dt = time.Since(t)
		ft += dt
		nf++

		if ft >= time.Second {
			window.SetTitle(fmt.Sprintf("%v - fps: %v, dt: %vms", title, nf, int(ft/time.Millisecond)/nf))
			nf = 0
			ft = 0
		}
	}
}