예제 #1
0
func info(p pak.MultiPak, args ...string) {
	fs := flag.NewFlagSet("info", flag.ExitOnError)
	fs.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s -pak <pak0,pak1,...> info [options] <demofile.dem> \n", os.Args[0])
		fs.PrintDefaults()
	}
	fs.Parse(args)
	if fs.NArg() == 0 {
		log.Fatalf("Need to specify a demo name.")
	}

	demo := fs.Arg(0)
	df, err := p.Get(demo)
	if err != nil {
		log.Fatalf("Getting %q: %v", demo, err)
	}
	d := dem.Open(df)

	timeUpdates := 0
	messages := 0
	blockCount := 0
	for {
		block, err := d.ReadBlock()
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatalf("Demo error: %v", err)
		}
		blockCount++
		msgs, err := block.Messages()
		if err != nil {
			log.Fatalf("Getting messages: %v", err)
		}
		timeUpdatesInBlock := 0
		for _, msg := range msgs {
			messages++
			if _, ok := msg.(*dem.MsgTime); ok {
				timeUpdates++
				timeUpdatesInBlock++
			}
		}
		if timeUpdatesInBlock > 1 {
			fmt.Printf("Block %d had %d time updates\n", blockCount, timeUpdatesInBlock)
		}
	}
	fmt.Printf("Blocks: %d\n", blockCount)
	fmt.Printf("Messages: %d\n", messages)
	fmt.Printf("Time updates: %d\n", timeUpdates)
}
예제 #2
0
func convert(p pak.MultiPak, args ...string) {
	fs := flag.NewFlagSet("convert", flag.ExitOnError)
	fs.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s -pak <pak0,pak1,...> convert [options] <demofile.dem> \n", os.Args[0])
		fs.PrintDefaults()
	}
	radiosity := fs.Bool("radiosity", false, "Use radiosity lighting.")
	fps := fs.Float64("fps", 30.0, "Frames per second.")
	outDir := fs.String("out", "render", "Output directory.")
	cameraLight := fs.Bool("camera_light", false, "Add camera light.")
	threesixty := fs.Bool("threesixty", false, "360 degree view mode.")
	fs.Parse(args)
	if fs.NArg() == 0 {
		log.Fatalf("Need to specify a demo name.")
	}
	demo := fs.Arg(0)

	df, err := p.Get(demo)
	if err != nil {
		log.Fatalf("Getting %q: %v", demo, err)
	}
	d := dem.Open(df)

	var oldState *dem.State
	newState := dem.NewState()
	frameNum := 0
	for {
		block, err := d.ReadBlock()
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatalf("Demo error: %v", err)
		}
		if !newState.CameraSetViewAngle {
			newState.ViewAngle = block.Header.ViewAngle
		}

		seenTime := false
		msgs, err := block.Messages()
		if err != nil {
			log.Fatalf("Getting messages: %v", err)
		}
		for _, msg := range msgs {
			msg.Apply(newState)
			if _, ok := msg.(*dem.MsgTime); ok {
				seenTime = true
			} else if m, ok := msg.(*dem.MsgCameraPos); ok {
				if *verbose {
					fmt.Printf("Camera set to %d\n", m.Entity)
				}
			} else if m, ok := msg.(*dem.MsgIntermission); ok {
				if *verbose {
					fmt.Printf("Intermission: %q\n", m.Text)
				}
			} else if m, ok := msg.(*dem.MsgFinale); ok {
				if *verbose {
					fmt.Printf("Finale: %q\n", m.Text)
				}
			} else if m, ok := msg.(*dem.MsgCameraOrientation); ok {
				if *verbose {
					fmt.Printf("Camera angle set to <%g,%g,%g>\n", m.X, m.Y, m.Z)
				}
			} else if m, ok := msg.(*dem.MsgSpawnBaseline); ok {
				if false {
					fmt.Printf("Spawning %d: %+v\n", m.Entity, newState.ServerInfo.Models[m.Model])
				}
			} else if m, ok := msg.(*dem.MsgUpdate); ok {
				if false {
					debugEnt := uint16(1)
					if m.Entity == debugEnt {
						fmt.Printf("MOVE Frame %d Ent %d moved from %v %v to %v %v\n", frameNum, m.Entity,
							oldState.Entities[m.Entity].Pos,
							oldState.Entities[m.Entity].Angle,
							newState.Entities[m.Entity].Pos,
							newState.Entities[m.Entity].Angle,
						)
					}
				}
			}
		}

		if seenTime {
			anyFrame := false
			for n := range newState.Entities {
				newState.Entities[n].Visible = newState.SeenEntity[uint16(n)]
			}
			newState.Entities[0].Visible = true // World.
			if oldState != nil {
				if *verbose {
					fmt.Printf("Saw time, outputting frames between %g and %g\n",
						oldState.Time,
						newState.Time,
					)
				}
				for _, t := range genTimeFrames(float64(oldState.Time), float64(newState.Time), *fps) {
					// TODO: Only generate frames if client state is 2.
					if *verbose {
						log.Printf("Generating frame %d", frameNum)
					}
					generateFrame(p, *outDir, oldState, newState, frameNum, t, *cameraLight, *radiosity, *threesixty)
					anyFrame = true
					frameNum++
				}
			}

			// Only wipe old state if we generate any frame at all.
			if oldState == nil || anyFrame {
				oldState = newState.Copy()
				newState.SeenEntity = make(map[uint16]bool)
			}
		}
	}
}