Пример #1
0
func TestLoadTyped_RW(t *testing.T) {
	defer Quit()

	// test expected success
	rwops := sdl.RWFromMem(unsafe.Pointer(&testPNG[0]), len(testPNG))
	defer rwops.RWclose()
	surf, err := LoadTyped_RW(rwops, false, "PNG")
	if surf != nil {
		defer surf.Free()
	}
	if surf == nil || err != nil {
		t.Errorf("LoadTyped_RW(%#v) == %v, %v; want surface without error",
			"PNG", surf, err)
	}

	// test expected failure
	rwops = sdl.RWFromMem(unsafe.Pointer(&testBadData[0]), len(testBadData))
	defer rwops.RWclose()
	surf, err = LoadTyped_RW(rwops, false, "PNG")
	if surf != nil {
		defer surf.Free()
	}
	if surf != nil || err == nil {
		t.Errorf("LoadTyped_RW(%#v) == %v, %v; want error without surface",
			"PNG", surf, err)
	}
}
Пример #2
0
func TestIsFormat(t *testing.T) {
	Init(INIT_JPG | INIT_PNG | INIT_TIF | INIT_WEBP)
	defer Quit()

	functions := map[string](func(*sdl.RWops) bool){
		"BMP": IsBMP, "CUR": IsCUR, "GIF": IsGIF, "ICO": IsICO, "JPG": IsJPG,
		"LBM": IsLBM, "PCX": IsPCX, "PNG": IsPNG, "PNM": IsPNM, "TIF": IsTIF,
		"XCF": IsXCF, "XPM": IsXPM, "XV": IsXV, "WEBP": IsWEBP,
	}
	tests := []isTest{
		{"BMP", IsBMP, testBMP}, {"GIF", IsGIF, testGIF},
		{"ICO", IsICO, testICO}, {"JPG", IsJPG, testJPG},
		{"PCX", IsPCX, testPCX}, {"PNG", IsPNG, testPNG},
		{"PNM", IsPNM, testPNM}, {"TIF", IsTIF, testTIF},
		{"WEBP", IsWEBP, testWEBP}, {"XCF", IsXCF, testXCF},
		{"XPM", IsXPM, testXPM},
	}

	for _, test := range tests {
		rwops := sdl.RWFromMem(unsafe.Pointer(&test.data[0]), len(test.data))
		defer rwops.RWclose()
		for fname, function := range functions {
			got, want := function(rwops), fname == test.name
			if got != want {
				t.Errorf("%s: Is%s() == %v; want %v", test.name, fname, got,
					want)
			}
		}
	}
}
Пример #3
0
func (l *sdlAssetLoader) loadResources() error {
	resourceData, err := payload.Read()
	if err != nil {
		return err
	}
	l.resources, err = blob.Read(bytes.NewBuffer(resourceData))
	if err != nil {
		return err
	}

	// load the texture atlas
	atlas, found := l.resources.GetByID("atlas")
	if !found {
		panic("texture atlas not found in resources")
	}
	rwOps := sdl.RWFromMem(unsafe.Pointer(&atlas[0]), len(atlas))
	surface, err := img.Load_RW(rwOps, false)
	check(err)
	defer surface.Free()
	texture, err := l.renderer.CreateTextureFromSurface(surface)
	check(err)
	l.textureAtlas = texture

	return err
}
Пример #4
0
func loadImageRotated(image_name string, angle float64) (*sdl.Surface, error) {
	file, err := assets.Asset(image_name)
	if err != nil {
		return nil, err
	}
	i, _, err := image.Decode(bytes.NewReader(file))
	if err != nil {
		return nil, err
	}

	dst := image.NewRGBA(i.Bounds())
	err = graphics.Rotate(dst, i, &graphics.RotateOptions{
		Angle: angle * tau})
	if err != nil {
		return nil, err
	}

	var buf bytes.Buffer
	err = png.Encode(&buf, dst)
	if err != nil {
		return nil, err
	}
	b := buf.Bytes()

	return img.Load_RW(sdl.RWFromMem(unsafe.Pointer(&b[0]), len(b)), 0)
}
Пример #5
0
func loadSounds() (
	sounds map[string]*mix.Chunk, err error) {
	files, err := assets.AssetDir("final/sounds")
	if err != nil {
		return nil, err
	}
	sounds = make(map[string]*mix.Chunk)
	for _, file := range files {
		if !strings.HasSuffix(file, ".wav") {
			continue
		}
		data, err := assets.Asset(filepath.Join("final/sounds", file))
		if err != nil {
			return nil, err
		}
		mem := sdl.RWFromMem(unsafe.Pointer(&data[0]), len(data))
		sound, err := mix.LoadWAV_RW(mem, false)
		if err != nil {
			cleanupSounds(sounds)
			return nil, err
		}
		sounds[file[:len(file)-len(".wav")]] = sound
	}
	return sounds, nil
}
Пример #6
0
func NewRenderer(title string, width, height, players int,
	update_duration time.Duration) (rv *SDLRenderer, err error) {
	return rv, exec(func() error {
		window, err := sdl.CreateWindow(title, sdl.WINDOWPOS_UNDEFINED,
			sdl.WINDOWPOS_UNDEFINED, width, height, sdl.WINDOW_SHOWN)
		if err != nil {
			rv = nil
			return err
		}
		data, err := assets.Asset("final/Fixedsys500c.ttf")
		if err != nil {
			window.Destroy()
			rv = nil
			return err
		}
		mem := sdl.RWFromMem(unsafe.Pointer(&data[0]), len(data))
		font, err := ttf.OpenFontRW(mem, 0, 128)
		if err != nil {
			window.Destroy()
			rv = nil
			return err
		}
		frames := int(frameRate * update_duration / time.Second)
		images, player_rotations, err := loadImages(frames, players)
		if err != nil {
			window.Destroy()
			font.Close()
			rv = nil
			return err
		}
		sounds, err := loadSounds()
		if err != nil {
			cleanupImages(images)
			cleanupRotations(player_rotations)
			window.Destroy()
			font.Close()
			rv = nil
			return err
		}

		var frame_time time.Duration
		if frames > 0 {
			frame_time = update_duration / time.Duration(frames)
		}

		rv = &SDLRenderer{Title: title,
			window:           window,
			font:             font,
			images:           images,
			sounds:           sounds,
			frame_time:       frame_time,
			frames:           frames,
			player_rotations: player_rotations,
			closed:           false}
		return nil
	})
}
Пример #7
0
func TestLoadFormat(t *testing.T) {
	defer Quit()

	tests := []loadTest{
		{"BMP", LoadBMP_RW, testBMP}, {"GIF", LoadGIF_RW, testGIF},
		{"ICO", LoadICO_RW, testICO}, {"JPG", LoadJPG_RW, testJPG},
		{"PCX", LoadPCX_RW, testPCX}, {"PNG", LoadPNG_RW, testPNG},
		{"PNM", LoadPNM_RW, testPNM}, {"TGA", LoadTGA_RW, testTGA},
		{"TIF", LoadTIF_RW, testTIF}, {"XCF", LoadXCF_RW, testXCF},
		{"XPM", LoadXPM_RW, testXPM},
		// WEBP is undocumented and panics, so none of that.
	}

	for _, test := range tests {
		// test expected success
		rwops := sdl.RWFromMem(unsafe.Pointer(&test.data[0]), len(test.data))
		defer rwops.RWclose()
		surf, err := test.function(rwops)
		if surf != nil {
			defer surf.Free()
		}
		if surf == nil || err != nil {
			t.Errorf("Load%s_RW() == %v, %v; want surface without error",
				test.name, surf, err)
		}

		// test expected failure... unless we're loading XCF, since XCF will
		// load anything.
		if test.name == "XCF" {
			continue
		}

		rwops = sdl.RWFromMem(unsafe.Pointer(&testBadData[0]), len(testBadData))
		defer rwops.RWclose()
		surf, err = test.function(rwops)
		if surf != nil {
			defer surf.Free()
		}
		if surf != nil || err == nil {
			t.Errorf("Load%s_RW() == %v, %v; want error without surface",
				test.name, surf, err)
		}
	}
}
Пример #8
0
func loadImage(id string) *sdl.Texture {
	data := resource.Resources[id]
	rwOps := sdl.RWFromMem(unsafe.Pointer(&data[0]), len(data))
	surface, err := img.Load_RW(rwOps, false)
	check(err)
	defer surface.Free()
	texture, err := renderer.CreateTextureFromSurface(surface)
	check(err)
	return texture
}
Пример #9
0
func LoadSurface(p []byte) (*Surface, error) {
	if len(p) == 0 {
		return nil, errors.New("drip: LoadSurface passed an empty slice")
	}

	ptr := unsafe.Pointer(&p[0])
	rw := sdl.RWFromMem(ptr, len(p))
	surf, err := img.Load_RW(rw, true)
	if err != nil {
		return nil, err
	}
	return newSurface(surf), nil
}
Пример #10
0
func overlay(surface *sdl.Surface, img_name string) error {
	data, err := assets.Asset(img_name)
	if err != nil {
		return err
	}
	mem := sdl.RWFromMem(unsafe.Pointer(&data[0]), len(data))
	ontop, err := img.Load_RW(mem, 0)
	defer ontop.Free()
	if err != nil {
		return err
	}
	return ontop.BlitScaled(nil, surface, nil)
}
Пример #11
0
func BackgroundMusic(asset string) error {
	return exec(func() error {
		data, err := assets.Asset(asset)
		if err != nil {
			return err
		}
		mem := sdl.RWFromMem(unsafe.Pointer(&data[0]), len(data))
		music, err := mix.LoadMUS_RW(mem, 0)
		if err != nil {
			return err
		}
		return music.Play(-1)
	})
}
Пример #12
0
func (l *sdlAssetLoader) LoadSound(id string) Sound {
	if sound, ok := l.sounds[id]; ok {
		return sound
	}
	data := resource.Resources[id]
	if data == nil {
		panic("unknown sound resource: " + id)
	}

	rwOps := sdl.RWFromMem(unsafe.Pointer(&data[0]), len(data))
	chunk, err := mix.LoadWAV_RW(rwOps, false)
	check(err)
	sound := &wavSound{chunk}
	l.sounds[id] = sound

	return sound
}
Пример #13
0
func (l *sdlAssetLoader) LoadImage(id string) Image {
	if img, ok := l.images[id]; ok {
		return img
	}
	data := resource.Resources[id]
	if data == nil {
		panic("unknown image resource: " + id)
	}

	rwOps := sdl.RWFromMem(unsafe.Pointer(&data[0]), len(data))
	surface, err := img.Load_RW(rwOps, false)
	check(err)
	defer surface.Free()
	texture, err := l.renderer.CreateTextureFromSurface(surface)
	check(err)
	image := &textureImage{l.renderer, l.camera, texture}
	l.images[id] = image

	return image
}
Пример #14
0
func loadImages(frames, players int) (
	images map[grid.Cell]*sdl.Surface,
	rotations map[grid.Owner][]*sdl.Surface, err error) {
	images = make(map[grid.Cell]*sdl.Surface)
	for _, simple := range []string{"battery", "floor", "wall"} {
		for _, exploding := range []bool{false, true} {
			data, err := assets.Asset(fmt.Sprintf("final/images/%s.png", simple))
			if err != nil {
				cleanupImages(images)
				return nil, nil, err
			}
			mem := sdl.RWFromMem(unsafe.Pointer(&data[0]), len(data))
			surface, err := img.Load_RW(mem, 0)
			if err != nil {
				cleanupImages(images)
				return nil, nil, err
			}
			if exploding {
				err = overlay(surface, "final/images/ex.png")
				if err != nil {
					surface.Free()
					cleanupImages(images)
					return nil, nil, err
				}
			}
			for orientation := 0; orientation < 4; orientation++ {
				for owner := 0; owner < players+1; owner++ {
					images[grid.Cell{
						Exploding:   exploding,
						Type:        typeMapping(simple),
						Orientation: grid.Orientation(orientation),
						Owner:       grid.Owner(owner)}] = surface
				}
			}
		}
	}
	for _, rotateable := range []string{"l", "p"} {
		for rotations := 0; rotations < 4; rotations++ {
			for player := 1; player <= players; player++ {
				for _, exploding := range []bool{false, true} {
					surface, err := loadImageRotated(fmt.Sprintf("final/images/%s%d.png",
						rotateable, (player-1)%2+1), float64(rotations)/4)
					if err != nil {
						cleanupImages(images)
						return nil, nil, err
					}
					if exploding {
						err = overlay(surface, "final/images/ex.png")
						if err != nil {
							surface.Free()
							cleanupImages(images)
							return nil, nil, err
						}
					}
					images[grid.Cell{
						Exploding:   exploding,
						Type:        typeMapping(rotateable),
						Owner:       grid.Owner(player),
						Orientation: grid.Orientation(rotations)}] = surface
				}
			}
		}
	}

	rotations = make(map[grid.Owner][]*sdl.Surface)
	for _, rotateable := range []string{"p"} {
		for player := 1; player <= players; player++ {
			for frame := 0; frame < 4*frames; frame++ {
				surface, err := loadImageRotated(fmt.Sprintf("final/images/%s%d.png",
					rotateable, (player-1)%2+1), float64(frame)/(4*float64(frames)))
				if err != nil {
					cleanupImages(images)
					cleanupRotations(rotations)
					return nil, nil, err
				}
				rotations[grid.Owner(player)] = append(
					rotations[grid.Owner(player)], surface)
			}
		}
	}

	return images, rotations, nil
}
Пример #15
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,
	)

	musicData, found := assetLoader.resources.GetByID("music")
	if found {
		musicRWOps := sdl.RWFromMem(unsafe.Pointer(&musicData[0]), len(musicData))
		music, err := mix.LoadMUS_RW(musicRWOps, 0)
		if err != nil {
			fmt.Println("error loading music:", err)
		} else {
			defer music.Free()
			music.FadeIn(-1, 500)
		}
	}

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

	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, sdl.K_SPACE, sdl.K_LCTRL:
						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, sdl.K_SPACE, sdl.K_LCTRL:
					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()
	}
}