Пример #1
0
// AddPlayers adds numPlayers to the specified side.  In standard game mode side
// should be zero, otherwise it should be between 0 and number of side - 1,
// inclusive.
func (g *Game) AddPlayers(engineIds []int64, side int) []Gid {
	switch {
	case g.Standard != nil:
		if side != 0 {
			base.Error().Fatalf("AddPlayers expects side == 0 for Standard game mode.")
		}
	case g.Moba != nil:
		if side < 0 || side >= len(g.Levels[GidInvadersStart].Room.Starts) {
			base.Error().Fatalf("Got side %d, but this level only supports sides from 0 to %d.", len(g.Levels[GidInvadersStart].Room.Starts)-1)
		}
	default:
		base.Error().Fatalf("Cannot add players without first specifying a game mode.")
	}
	var gids []Gid
	for i, engineId := range engineIds {
		var p PlayerEnt
		p.StatsInst = stats.Make(stats.Base{
			Health: 1000,
			Mass:   750,
			Acc:    1000.0,
			Turn:   0.07,
			Rate:   0.5,
			Size:   12,
			Vision: 600,
		})
		p.CurrentLevel = GidInvadersStart

		// Evenly space the players on a circle around the starting position.
		rot := (linear.Vec2{25, 0}).Rotate(float64(i) * 2 * 3.1415926535 / float64(len(engineIds)))
		p.Position = g.Levels[GidInvadersStart].Room.Starts[side].Add(rot)

		// NEXT: REthing Gids and how the levels are laid out - should they just
		// be indexed by gids?
		p.Side_ = side
		p.Gid = Gid(fmt.Sprintf("Engine:%d", engineId))
		p.Processes = make(map[int]Process)
		p.SetLevel(GidInvadersStart)
		g.AddEnt(&p)
		gids = append(gids, p.Gid)
	}
	return gids
}
Пример #2
0
func (ms *ManaSource) Init(options *ManaSourceOptions) {
	ms.options = *options
	if options.NumNodeCols < 2 || options.NumNodeRows < 2 {
		base.Error().Fatalf(fmt.Sprintf("Invalid options: %v", options))
	}

	r := rand.New(options.Rng)

	seeds := make([]nodeSeed, options.NumSeeds)
	for i := range seeds {
		seed := &seeds[i]
		seed.x = options.BoardLeft + r.Float64()*(options.BoardRight-options.BoardLeft)
		seed.y = options.BoardTop + r.Float64()*(options.BoardBottom-options.BoardTop)
		seed.color = r.Intn(3)
	}

	ms.rawNodes = newNodes(options.NumNodeCols * options.NumNodeRows)
	// ms.rawNodes = make([]node, options.NumNodeCols*options.NumNodeRows)
	ms.nodes = make([][]node, options.NumNodeCols)
	for col := 0; col < options.NumNodeCols; col++ {
		ms.nodes[col] = ms.rawNodes[col*options.NumNodeRows : (col+1)*options.NumNodeRows]
		for row := 0; row < options.NumNodeRows; row++ {
			x := options.BoardLeft + float64(col)/float64(options.NumNodeCols-1)*(options.BoardRight-options.BoardLeft)
			y := options.BoardTop + float64(row)/float64(options.NumNodeRows-1)*(options.BoardBottom-options.BoardTop)

			maxWeightByColor := [3]float64{0.0, 0.0, 0.0}
			for _, seed := range seeds {
				c := seed.color
				dx := x - seed.x
				dy := y - seed.y
				distSquared := dx*dx + dy*dy
				weight := 1 / (distSquared + 1.0)
				if weight > maxWeightByColor[c] {
					maxWeightByColor[c] = weight
				}
			}

			normalizeWeights(options.NodeMagnitude, maxWeightByColor[:])
			var weightsCopy [3]float64
			copy(weightsCopy[:], maxWeightByColor[:])

			ms.nodes[col][row] = node{
				X:             x,
				Y:             y,
				RegenPerFrame: options.RegenPerFrame,
				Mana:          maxWeightByColor,
				MaxMana:       weightsCopy,
			}
		}
	}
}
Пример #3
0
func (ms *ManaSource) regenerateMana() {
	for i := range ms.rawNodes {
		node := &ms.rawNodes[i]
		for c := range node.Mana {
			if node.MaxMana[c] == 0 {
				continue
			}
			maxRecovery := node.MaxMana[c] * node.RegenPerFrame
			scale := (node.MaxMana[c] - node.Mana[c]) / node.MaxMana[c]
			node.Mana[c] += scale * maxRecovery
			if scale != scale || maxRecovery != maxRecovery {
				base.Error().Fatalf("NaN showed up somewhere!")
			}
		}
	}
}
Пример #4
0
func setupSound() {
	soundInit.Do(func() {
		var err error
		// fmodSys, err = fmod.CreateSystem()
		if err != nil {
			// base.Error().Fatalf("Unable to initialize fmod: %v", err)
		}
		// err = fmodSys.Init(2, 0, nil)
		if err != nil {
			// base.Error().Fatalf("Unable to initialize fmod: %v", err)
		}
		target := filepath.Join(base.GetDataDir(), "sound/ping.wav")
		base.Log().Printf("Trying to load ", target)
		// sound, err = fmodSys.CreateSound_FromFilename(target, fmod.MODE_DEFAULT)
		if err != nil {
			base.Error().Fatalf("Unable to load sound: %v", err)
		}
	})
}
Пример #5
0
func newLocalDataHelper(engine *cgf.Engine, sys system.System, mode LocalMode) *LocalData {
	var local LocalData
	if local.engine != nil {
		base.Error().Fatalf("Engine has already been set.")
	}
	local.engine = engine
	local.mode = mode
	local.setup = &localSetupData{}
	if mode == LocalModeArchitect {
		// local.architect.abs.abilities =
		// 	append(
		// 		local.architect.abs.abilities,
		// 		ability_makers["placePoly"](map[string]int{"wall": 1}))
		// local.architect.abs.abilities =
		// 	append(
		// 		local.architect.abs.abilities,
		// 		ability_makers["placePoly"](map[string]int{"pests": 1}))
		// local.architect.abs.abilities = append(local.architect.abs.abilities, ability_makers["removePoly"](nil))
	}
	local.sys = sys
	gin.In().RegisterEventListener(&gameResponderWrapper{&local})
	return &local
}
Пример #6
0
func main() {
	defer base.StackCatcher()
	fmt.Printf("sys.Startup()...")
	sys.Startup()
	fmt.Printf("successful.\n")
	fmt.Printf("gl.Init()...")
	err := gl.Init()
	fmt.Printf("successful.\n")
	if err != nil {
		base.Error().Fatalf("%v", err)
	}

	fmt.Printf("render.Init()...")
	render.Init()
	fmt.Printf("successful.\n")
	render.Queue(func() {
		fmt.Printf("sys.CreateWindow()...")
		sys.CreateWindow(10, 10, wdx, wdy)
		fmt.Printf("successful.\n")
		sys.EnableVSync(true)
	})
	base.InitShaders()
	runtime.GOMAXPROCS(10)
	fmt.Printf("sys.Think()...")
	sys.Think()
	fmt.Printf("successful.\n")

	base.LoadAllDictionaries()

	if Version() != "standard" {
		engine, local := debugHookup(Version())
		mainLoop(engine, local, "standard")
	} else {
		standardHookup()
	}
}
Пример #7
0
func main() {
	fmt.Printf("%v\n", key_map)
	sys.Startup()
	err := gl.Init()
	if err != nil {
		panic(err)
	}

	render.Init()
	render.Queue(func() {
		sys.CreateWindow(10, 10, wdx, wdy)
		sys.EnableVSync(true)
		err := gl.Init()
		if err != nil {
			panic(err)
		}
	})
	base.InitShaders()
	runtime.GOMAXPROCS(2)
	ui, err = gui.Make(gin.In(), gui.Dims{wdx, wdy}, filepath.Join(datadir, "fonts", "skia.ttf"))
	if err != nil {
		panic(err)
	}
	sys.Think()
	for false && len(sys.GetActiveDevices()[gin.DeviceTypeController]) < 2 {
		time.Sleep(time.Millisecond * 100)
		sys.Think()
	}

	var ids []int
	var engine *cgf.Engine
	var room game.Room
	err = base.LoadJson(filepath.Join(base.GetDataDir(), "rooms/basic.json"), &room)
	if err != nil {
		panic(err)
	}
	if IsHost() {
		sys.Think()
		var g game.Game
		g.Rng = cmwc.MakeGoodCmwc()
		g.Rng.SeedWithDevRand()
		g.Dx = 900
		g.Dy = 600
		g.Friction = 0.97
		g.Friction_lava = 0.85
		g.Room = room
		var p game.Player
		p.Color.R = 255
		err := json.NewDecoder(bytes.NewBuffer([]byte(`
      {
        "Base": {
          "Max_turn": 0.07,
          "Max_acc": 0.2,
          "Mass": 750,
          "Max_rate": 10,
          "Influence": 75,
          "Health": 1000
        },
        "Dynamic": {
          "Health": 1000
        }
      }
    `))).Decode(&p.Stats)
		if err != nil {
			panic(err)
		}
		Nx := 2
		Ny := 1
		p.X = float64(g.Dx-Nx)/2 - 200
		p.Y = float64(g.Dy-Ny)/2 - 200
		for x := 0; x < Nx; x++ {
			for y := 0; y < Ny; y++ {
				p.X += float64(x * 25)
				p.Y += float64(y * 25)
				p.Gid++
				// p.Mass += float64(x+y) * 150
				p.Processes = make(map[int]game.Process)
				temp := p
				ids = append(ids, g.AddEnt(&temp))

				// p.Mass -= float64(x+y) * 150
				p.X -= float64(x * 25)
				p.Y -= float64(y * 25)
			}
		}
		g.Ents[0].(*game.Player).X = 500
		g.Ents[0].(*game.Player).Y = 300
		g.Ents[1].(*game.Player).X = 550
		g.Ents[1].(*game.Player).Y = 300
		g.SetLocalData()
		d := sys.GetActiveDevices()
		base.Log().Printf("%v\n", d)
		n := 0
		base.Log().Printf("%v\n", d[gin.DeviceTypeController])
		for _, index := range d[gin.DeviceTypeController] {
			// panic("ASD")
			g.SetLocalPlayer(g.Ents[n].(*game.Player), index)
			n++
			if n > 2 {
				break
			}
		}
		if len(d[gin.DeviceTypeController]) == 0 {
			g.SetLocalPlayer(g.Ents[0].(*game.Player), 0)
		}
		// g.Ents[0], g.Ents[(N*N)/2+(1-N%2)*N/2] = g.Ents[(N*N)/2+(1-N%2)*N/2], g.Ents[0]
		g.Init()
		// engine, err = cgf.NewLocalEngine(&g, 17, base.Log())
		engine, err = cgf.NewHostEngine(&g, 17, "", 1231, base.Log())
		if err != nil {
			panic(err.Error())
		}
		g.SetEngine(engine)
	} else {
		engine, err = cgf.NewClientEngine(17, "", 1231, base.Log())
		if err != nil {
			panic(err.Error())
		}
		engine.CopyState().(*game.Game).SetEngine(engine)
	}

	anchor := gui.MakeAnchorBox(gui.Dims{wdx, wdy})
	ui.AddChild(anchor)
	anchor.AddChild(&game.GameWindow{Engine: engine}, gui.Anchor{0.5, 0.5, 0.5, 0.5})
	var v float64
	var profile_output *os.File
	var num_mem_profiles int
	// ui.AddChild(base.MakeConsole())

	base.LoadAllDictionaries()

	for gin.In().GetKey(gin.AnyEscape).FramePressCount() == 0 {
		sys.Think()
		render.Queue(func() {
			ui.Draw()
		})
		render.Queue(func() {
			sys.SwapBuffers()
		})
		render.Purge()
		game.LocalThink()

		if IsHost() {
			for i := 0; i <= 0; i++ {
				// down_axis := gin.In().GetKeyFlat(gin.ControllerAxis0Positive+1, gin.DeviceTypeController, gin.DeviceIndexAny)
				// up_axis := gin.In().GetKeyFlat(gin.ControllerAxis0Negative+1, gin.DeviceTypeController, gin.DeviceIndexAny)
				// right_axis := gin.In().GetKeyFlat(gin.ControllerAxis0Positive, gin.DeviceTypeController, gin.DeviceIndexAny)
				// left_axis := gin.In().GetKeyFlat(gin.ControllerAxis0Negative, gin.DeviceTypeController, gin.DeviceIndexAny)
				// up := key_map[fmt.Sprintf("%dup", i)].FramePressAvg()
				// down := key_map[fmt.Sprintf("%ddown", i)].FramePressAvg()
				// left := key_map[fmt.Sprintf("%dleft", i)].FramePressAvg()
				// right := key_map[fmt.Sprintf("%dright", i)].FramePressAvg()
				// up = axisControl(up_axis.FramePressAmt())
				// down = axisControl(down_axis.FramePressAmt())
				// left = axisControl(left_axis.FramePressAmt())
				// right = axisControl(right_axis.FramePressAmt())
				// if up-down != 0 {
				// 	engine.ApplyEvent(game.Accelerate{ids[i], 2 * (up - down)})
				// }
				// if left-right != 0 {
				// 	engine.ApplyEvent(game.Turn{ids[i], (left - right)})
				// }

				// if key_map[fmt.Sprintf("%d-1", i)].FramePressCount() > 0 {
				// 	engine.ApplyEvent(game.Pull{ids[i], 0, 20000})
				// }
				// if key_map[fmt.Sprintf("%d-2", i)].FramePressCount() > 0 {
				// 	engine.ApplyEvent(game.MoonFire{ids[i], 1, 50, 50})
				// }
				// if gin.In().GetKeyFlat(gin.ControllerButton0, gin.DeviceTypeController, gin.DeviceTypeAny).FramePressCount() > 0 {
				// if key_map[fmt.Sprintf("%d-3", i)].FramePressCount() > 0 {
				// engine.ApplyEvent(game.Burst{ids[i], 2, 3, 100000})
				// }
			}
		}

		// TODO: Replace the 'P' key with an appropriate keybind
		if gin.In().GetKey(gin.AnyKeyP).FramePressCount() > 0 {
			if profile_output == nil {
				profile_output, err = os.Create(filepath.Join(datadir, "cpu.prof"))
				if err == nil {
					err = pprof.StartCPUProfile(profile_output)
					if err != nil {
						fmt.Printf("Unable to start CPU profile: %v\n", err)
						profile_output.Close()
						profile_output = nil
					}
					fmt.Printf("profout: %v\n", profile_output)
				} else {
					fmt.Printf("Unable to start CPU profile: %v\n", err)
				}
			} else {
				pprof.StopCPUProfile()
				profile_output.Close()
				profile_output = nil
			}
		}

		// TODO: Replace the 'M' key with an appropriate keybind
		if gin.In().GetKey(gin.AnyKeyM).FramePressCount() > 0 {
			f, err := os.Create(filepath.Join(datadir, fmt.Sprintf("mem.%d.prof", num_mem_profiles)))
			if err != nil {
				base.Error().Printf("Unable to write mem profile: %v", err)
			}
			pprof.WriteHeapProfile(f)
			f.Close()
			num_mem_profiles++
		}

		v += 0.01
	}
}
Пример #8
0
func (g *Game) Think() {
	g.GameThinks++
	if g.Setup != nil {
		return
	}
	defer base.StackCatcher()

	// cache wall data
	if g.temp.AllWalls == nil || g.temp.AllWallsDirty {
		g.temp.AllWalls = make(map[Gid][]linear.Seg2)
		g.temp.WallCache = make(map[Gid]*wallCache)
		g.temp.VisibleWallCache = make(map[Gid]*wallCache)
		for gid := range g.Levels {
			var allWalls []linear.Seg2
			base.DoOrdered(g.Levels[gid].Room.Walls, func(a, b string) bool { return a < b }, func(_ string, walls linear.Poly) {
				for i := range walls {
					allWalls = append(allWalls, walls.Seg(i))
				}
			})
			// g.DoForEnts(func(entGid Gid, ent Ent) {
			// 	if ent.Level() == gid {
			// 		for _, walls := range ent.Walls() {
			// 			for i := range walls {
			// 				allWalls = append(allWalls, walls.Seg(i))
			// 			}
			// 		}
			// 	}
			// })
			g.temp.AllWalls[gid] = allWalls
			g.temp.WallCache[gid] = &wallCache{}
			g.temp.WallCache[gid].SetWalls(g.Levels[gid].Room.Dx, g.Levels[gid].Room.Dy, allWalls, 100)
			g.temp.VisibleWallCache[gid] = &wallCache{}
			g.temp.VisibleWallCache[gid].SetWalls(g.Levels[gid].Room.Dx, g.Levels[gid].Room.Dy, allWalls, stats.LosPlayerHorizon)
			base.Log().Printf("WallCache: %v", g.temp.WallCache)
		}
		g.Moba.losCache.SetWallCache(g.temp.VisibleWallCache[GidInvadersStart])
	}

	// cache ent data
	for _, ent := range g.temp.AllEnts {
		if ent.Dead() {
			if _, ok := ent.(*PlayerEnt); ok {
				var id int64
				_, err := fmt.Sscanf(string(ent.Id()), "Engine:%d", &id)
				if err != nil {
					base.Error().Printf("Unable to parse player id '%v'", ent.Id())
				} else {
					if engineData, ok := g.Engines[id]; ok {
						if !ok {
							base.Error().Printf("Unable to find engine %d for player %v", id, ent.Id())
						} else {
							engineData.CountdownFrames = 60 * 10
						}
					}
				}
			}
			ent.OnDeath(g)
			g.RemoveEnt(ent.Id())
		}
	}

	// Death countdown
	for engineId, engineData := range g.Engines {
		if engineData.CountdownFrames > 0 {
			engineData.CountdownFrames--
			if engineData.CountdownFrames == 0 {
				// TODO: It's a bit janky to do it like this, right?
				g.AddPlayers([]int64{engineId}, engineData.Side)
			}
		}
	}

	if g.temp.AllEnts == nil || g.temp.AllEntsDirty {
		g.temp.AllEnts = g.temp.AllEnts[0:0]
		g.DoForEnts(func(gid Gid, ent Ent) {
			g.temp.AllEnts = append(g.temp.AllEnts, ent)
		})
		g.temp.AllEntsDirty = false
	}

	for _, proc := range g.Processes {
		proc.Think(g)
	}
	algorithm.Choose(&g.Processes, func(proc Process) bool { return proc.Phase() != PhaseComplete })

	// Advance players, check for collisions, add segments
	for _, ent := range g.temp.AllEnts {
		ent.Think(g)
		pos := ent.Pos()
		eps := 1.0e-3
		pos.X = clamp(pos.X, eps, float64(g.Levels[ent.Level()].Room.Dx)-eps)
		pos.Y = clamp(pos.Y, eps, float64(g.Levels[ent.Level()].Room.Dy)-eps)
		ent.SetPos(pos)
	}

	for i := 0; i < len(g.temp.AllEnts); i++ {
		for j := i + 1; j < len(g.temp.AllEnts); j++ {
			outerEnt := g.temp.AllEnts[i]
			innerEnt := g.temp.AllEnts[j]
			distSq := outerEnt.Pos().Sub(innerEnt.Pos()).Mag2()
			colDist := outerEnt.Stats().Size() + innerEnt.Stats().Size()
			if distSq > colDist*colDist {
				continue
			}
			if distSq < 0.0001 {
				continue
			}
			if distSq <= 0.25 {
				distSq = 0.25
			}
			dist := math.Sqrt(distSq)
			force := 50.0 * (colDist - dist)
			outerEnt.ApplyForce(outerEnt.Pos().Sub(innerEnt.Pos()).Scale(force / dist))
			innerEnt.ApplyForce(innerEnt.Pos().Sub(outerEnt.Pos()).Scale(force / dist))
		}
	}

	switch {
	case g.Moba != nil:
		g.ThinkMoba()
	case g.Standard != nil:
		panic("Thinkgs aren't implemented, like thinking on mana sources")
		// Do standard thinking
	default:
		panic("Game mode not set")
	}
}
Пример #9
0
func (u SetupComplete) Apply(_g interface{}) {
	g := _g.(*Game)
	if g.Setup == nil {
		return
	}

	g.Engines = make(map[int64]*PlayerData)
	for _, id := range g.Setup.EngineIds {
		g.Engines[id] = &PlayerData{
			PlayerGid: Gid(fmt.Sprintf("Engine:%d", id)),
			Side:      g.Setup.Sides[id].Side,
		}
	}

	// Add a single Ai player to side 0
	g.Engines[123123] = &PlayerData{
		PlayerGid: Gid(fmt.Sprintf("Engine:%d", 123123)),
		Side:      0,
		Ai:        &AiPlayerData{},
	}
	g.Setup.Sides[123123] = &SetupSideData{
		Champ: 0,
		Side:  0,
	}

	var room Room
	dx, dy := 1024, 1024
	generated := generator.GenerateRoom(float64(dx), float64(dy), 100, 64, u.Seed)
	data, err := json.Marshal(generated)
	if err != nil {
		base.Error().Fatalf("%v", err)
	}
	err = json.Unmarshal(data, &room)
	// err = base.LoadJson(filepath.Join(base.GetDataDir(), "rooms/basic.json"), &room)
	if err != nil {
		base.Error().Fatalf("%v", err)
	}
	g.Levels = make(map[Gid]*Level)
	g.Levels[GidInvadersStart] = &Level{}
	g.Levels[GidInvadersStart].Room = room
	g.Rng = cmwc.MakeGoodCmwc()
	g.Rng.Seed(12313131)
	g.Ents = make(map[Gid]Ent)
	g.Friction = 0.97
	// g.Standard = &GameModeStandard{}
	g.Moba = &GameModeMoba{
		Sides: make(map[int]*GameModeMobaSideData),
	}
	sides := make(map[int][]int64)
	for id, data := range g.Engines {
		sides[data.Side] = append(sides[data.Side], id)
	}
	for _, players := range sides {
		var ids []int64
		for _, id := range players {
			ids = append(ids, id)
		}
		side := g.Setup.Sides[ids[0]].Side
		gids := g.AddPlayers(ids, side)
		g.Moba.Sides[side] = &GameModeMobaSideData{}
		for i := range ids {
			player := g.Ents[gids[i]].(*PlayerEnt)
			player.Champ = g.Setup.Sides[ids[i]].Champ
		}
	}
	g.Moba.losCache = makeLosCache(dx, dy)

	g.MakeControlPoints()
	g.Init()
	base.Log().Printf("Nillifying g.Setup()")
	g.Setup = nil
}
Пример #10
0
func debugHookup(version string) (*cgf.Engine, *game.LocalData) {
	// if version != "standard" && version != "moba" && version != "host" && version != "client" {
	// 	base.Log().Fatalf("Unable to handle Version() == '%s'", Version())
	// }

	for false && len(sys.GetActiveDevices()[gin.DeviceTypeController]) < 2 {
		time.Sleep(time.Millisecond * 100)
		sys.Think()
	}

	var engine *cgf.Engine
	var room game.Room
	generated := generator.GenerateRoom(1024, 1024, 100, 64, 64522029961391019)
	data, err := json.Marshal(generated)
	if err != nil {
		base.Error().Fatalf("%v", err)
	}
	err = json.Unmarshal(data, &room)
	// err = base.LoadJson(filepath.Join(base.GetDataDir(), "rooms/basic.json"), &room)
	if err != nil {
		base.Error().Fatalf("%v", err)
	}
	var players []game.Gid
	var localData *game.LocalData
	var g *game.Game
	if version != "host" {
		res, err := cgf.SearchLANForHosts(20007, 20002, 500)
		if err != nil || len(res) == 0 {
			base.Log().Printf("Unable to connect: %v", err)
			base.Error().Fatalf("%v", err.Error())
		}
		engine, err = cgf.NewClientEngine(17, res[0].Ip, 20007, base.EmailCrashReport, base.Log())
		if err != nil {
			base.Log().Printf("Unable to connect: %v", err)
			base.Error().Fatalf("%v", err.Error())
		}
		localData = game.NewLocalDataArchitect(engine, sys)
		g = engine.GetState().(*game.Game)
		for _, ent := range g.Ents {
			if _, ok := ent.(*game.PlayerEnt); ok {
				players = append(players, ent.Id())
			}
		}
	} else {
		sys.Think()
		g = game.MakeGame()
		if version == "host" {
			engine, err = cgf.NewHostEngine(g, 17, "", 20007, base.EmailCrashReport, base.Log())
			if err != nil {
				panic(err)
			}
			err = cgf.Host(20007, "thunderball")
			if err != nil {
				panic(err)
			}
		} else {
			engine, err = cgf.NewLocalEngine(g, 17, base.EmailCrashReport, base.Log())
		}
		if err != nil {
			base.Error().Fatalf("%v", err.Error())
		}
	}
	localData = game.NewLocalDataMoba(engine, gin.DeviceIndexAny, sys)
	// localData = game.NewLocalDataInvaders(engine, sys)

	// Hook the players up regardless of in we're architect or not, since we can
	// switch between the two in debug mode.
	// d := sys.GetActiveDevices()
	// n := 0
	// for _, index := range d[gin.DeviceTypeController] {
	// 	localData.SetLocalPlayer(g.Ents[players[n]], index)
	// 	n++
	// 	if n > len(players) {
	// 		break
	// 	}
	// }
	// if len(d[gin.DeviceTypeController]) == 0 {
	// 	localData.SetLocalPlayer(g.Ents[players[0]], 0)
	// }

	base.Log().Printf("Engine Id: %v", engine.Id())
	base.Log().Printf("All Ids: %v", engine.Ids())
	return engine, localData
}
Пример #11
0
func mainLoop(engine *cgf.Engine, local *game.LocalData, mode string) {
	defer engine.Kill()
	var profile_output *os.File
	var contention_output *os.File
	var num_mem_profiles int
	// ui.AddChild(base.MakeConsole())

	ticker := time.Tick(time.Millisecond * 17)
	ui := g2.Make(0, 0, wdx, wdy)
	ui.AddChild(&game.GameWindow{Engine: engine, Local: local, Dims: g2.Dims{wdx, wdy}}, g2.AnchorDeadCenter)
	ui.AddChild(g2.MakeConsole(wdx, wdy), g2.AnchorDeadCenter)
	side0Index := gin.In().BindDerivedKeyFamily("Side0", gin.In().MakeBindingFamily(gin.Key1, []gin.KeyIndex{gin.EitherControl}, []bool{true}))
	side1Index := gin.In().BindDerivedKeyFamily("Side1", gin.In().MakeBindingFamily(gin.Key2, []gin.KeyIndex{gin.EitherControl}, []bool{true}))
	side2Index := gin.In().BindDerivedKeyFamily("Side2", gin.In().MakeBindingFamily(gin.Key3, []gin.KeyIndex{gin.EitherControl}, []bool{true}))
	side0Key := gin.In().GetKeyFlat(side0Index, gin.DeviceTypeAny, gin.DeviceIndexAny)
	side1Key := gin.In().GetKeyFlat(side1Index, gin.DeviceTypeAny, gin.DeviceIndexAny)
	side2Key := gin.In().GetKeyFlat(side2Index, gin.DeviceTypeAny, gin.DeviceIndexAny)
	defer ui.StopEventListening()
	for {
		<-ticker
		if gin.In().GetKey(gin.AnyEscape).FramePressCount() != 0 {
			return
		}
		if mode == "moba" {
			if side0Key.FramePressCount() > 0 {
				local.DebugCyclePlayers()
			}
			// if side0Key.FramePressCount() > 0 {
			// 	local.DebugSetSide(0)
			// }
			// if side1Key.FramePressCount() > 0 {
			// 	local.DebugSetSide(1)
			// }
		}
		if mode == "standard" {
			if side0Key.FramePressCount() > 0 {
				local.DebugChangeMode(game.LocalModeInvaders)
			}
			if side1Key.FramePressCount() > 0 {
				local.DebugChangeMode(game.LocalModeArchitect)
			}
			if side2Key.FramePressCount() > 0 {
				local.DebugChangeMode(game.LocalModeEditor)
			}
		}
		sys.Think()
		render.Queue(func() {
			ui.Draw()
		})
		render.Queue(func() {
			sys.SwapBuffers()
		})
		render.Purge()
		// TODO: Replace the 'P' key with an appropriate keybind
		var err error
		if gin.In().GetKey(gin.AnyKeyP).FramePressCount() > 0 {
			if profile_output == nil {
				profile_output, err = os.Create(filepath.Join(datadir, "cpu.prof"))
				if err == nil {
					err = pprof.StartCPUProfile(profile_output)
					if err != nil {
						base.Log().Printf("Unable to start CPU profile: %v\n", err)
						profile_output.Close()
						profile_output = nil
					}
					base.Log().Printf("cpu prof: %v\n", profile_output)
				} else {
					base.Log().Printf("Unable to start CPU profile: %v\n", err)
				}
			} else {
				pprof.StopCPUProfile()
				profile_output.Close()
				profile_output = nil
			}
		}

		if gin.In().GetKey(gin.AnyKeyL).FramePressCount() > 0 {
			if contention_output == nil {
				contention_output, err = os.Create(filepath.Join(datadir, "contention.prof"))
				if err == nil {
					runtime.SetBlockProfileRate(1)
					base.Log().Printf("contention prof: %v\n", contention_output)
				} else {
					base.Log().Printf("Unable to start contention profile: %v\n", err)
				}
			} else {
				pprof.Lookup("block").WriteTo(contention_output, 0)
				contention_output.Close()
				contention_output = nil
			}
		}

		// TODO: Replace the 'M' key with an appropriate keybind
		if gin.In().GetKey(gin.AnyKeyM).FramePressCount() > 0 {
			f, err := os.Create(filepath.Join(datadir, fmt.Sprintf("mem.%d.prof", num_mem_profiles)))
			if err != nil {
				base.Error().Printf("Unable to write mem profile: %v", err)
			}
			pprof.WriteHeapProfile(f)
			f.Close()
			num_mem_profiles++
		}
	}
}