Exemple #1
2
func main() {
	// Handle options
	help := flag.Bool("help", false, "Show usage")
	verbose := flag.Bool("verbose", false, "Verbose output")
	fullscreen := flag.Bool("fullscreen", false, "Go fullscreen!")
	bgImage := flag.String("bg-image", "", "Background image file")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "shell - A system shell based on CLIngon (Command Line INterface for Go Nerds\n\n")
		fmt.Fprintf(os.Stderr, "Usage:\n\n")
		fmt.Fprintf(os.Stderr, "\tshell [options] <fontfile> \n\n")
		fmt.Fprintf(os.Stderr, "Options are:\n\n")
		flag.PrintDefaults()
	}

	flag.Parse()

	if *help == true {
		flag.Usage()
		return
	}

	if len(flag.Args()) < 1 {
		flag.Usage()
		return
	}

	config := configuration{
		verbose:         *verbose,
		fullscreen:      *fullscreen,
		bgImage:         *bgImage,
		consoleX:        40,
		consoleY:        40,
		consoleW:        560,
		consoleH:        400,
		animationLength: ANIMATION_LENGTH,
	}

	r := initialize(&config)

	y_channel := make(chan int16)
	running := true

	// Have to start this *before* printing to the console,
	// because the printing will cause some messages to be sent to 'sdlrenderer.UpdatedRectsCh()'
	go func() {
		var y int16 = config.consoleY
		for running {
			select {
			case newY := <-y_channel:
				y = newY
				r.render(nil, y)
			case rects := <-sdlrenderer.UpdatedRectsCh():
				r.render(rects, y)
			}
		}
	}()

	var console *clingon.Console = clingon.NewConsole(&ShellEvaluator{})
	console.SetRenderer(r.sdlRenderer)
	y_channel <- config.consoleY
	console.Print(greetingText)
	console.SetPrompt("shell:$ ")

	var anim *clingon.Animation = nil
	var animValueCh <-chan float64 = nil
	toggleAnimation := false

	for running {

		select {
		case event := <-sdl.Events:
			switch e := event.(type) {
			case sdl.QuitEvent:
				running = false
			case sdl.MouseMotionEvent:
				var y int
				state := sdl.GetRelativeMouseState(nil, &y)
				if state == 1 {
					if y < 0 {
						sdlrenderer.EventCh() <- clingon.Cmd_Scroll{clingon.SCROLL_UP}
					} else if y > 0 {
						sdlrenderer.EventCh() <- clingon.Cmd_Scroll{clingon.SCROLL_DOWN}

					}
				}
			case sdl.KeyboardEvent:
				keyName := sdl.GetKeyName(sdl.Key(e.Keysym.Sym))
				if config.verbose {
					fmt.Printf("\n")
					fmt.Printf("%v: %v", e.Keysym.Sym, ": ", keyName)

					fmt.Printf("%04x ", e.Type)

					for i := 0; i < len(e.Pad0); i++ {
						fmt.Printf("%02x ", e.Pad0[i])
					}
					fmt.Printf("\n")

					fmt.Printf("Type: %02x Which: %02x State: %02x Pad: %02x\n", e.Type, e.Which, e.State, e.Pad0[0])
					fmt.Printf("Scancode: %02x Sym: %08x Mod: %04x Unicode: %04x\n", e.Keysym.Scancode, e.Keysym.Sym, e.Keysym.Mod, e.Keysym.Unicode)
				}
				if (keyName == "escape") && (e.Type == sdl.KEYDOWN) {
					running = false
				} else if (keyName == "f10") && (e.Type == sdl.KEYDOWN) {
					if anim != nil {
						anim.Terminate()
						<-anim.FinishedCh()
						anim = nil
					}

					toggleAnimation = !toggleAnimation

					slidingDistance := int16(r.appSurface.H) - config.consoleY
					anim = clingon.NewSliderAnimation(config.animationLength, float64(slidingDistance))

					animValueCh = anim.ValueCh()
					anim.Start()

				} else if (keyName == "page up") && (e.Type == sdl.KEYDOWN) {
					sdlrenderer.EventCh() <- clingon.Cmd_Scroll{clingon.SCROLL_UP}
				} else if (keyName == "page down") && (e.Type == sdl.KEYDOWN) {
					sdlrenderer.EventCh() <- clingon.Cmd_Scroll{clingon.SCROLL_DOWN}
				} else if (keyName == "up") && (e.Type == sdl.KEYDOWN) {
					console.PutReadline(clingon.HISTORY_PREV)
				} else if (keyName == "down") && (e.Type == sdl.KEYDOWN) {
					console.PutReadline(clingon.HISTORY_NEXT)
				} else if (keyName == "left") && (e.Type == sdl.KEYDOWN) {
					console.PutReadline(clingon.CURSOR_LEFT)
				} else if (keyName == "right") && (e.Type == sdl.KEYDOWN) {
					console.PutReadline(clingon.CURSOR_RIGHT)
				} else {
					unicode := e.Keysym.Unicode
					if unicode > 0 {
						console.PutUnicode(unicode)
					}
				}
			}

		case value := <-animValueCh:
			var y float64
			if toggleAnimation {
				y = 40 + value
			} else {
				y = float64(r.appSurface.H) - value
			}

			y_channel <- int16(y)
		}

	} // End of "for running"

	sdl.Quit()
}
Exemple #2
0
// A Go routine for processing SDL events.
func sdlEventLoop(app *spectrum.Application, speccy *spectrum.Spectrum48k, verboseInput bool) {
	evtLoop := app.NewEventLoop()

	consoleIsVisible := false

	shutdown.Add(1)
	for {
		select {
		case <-evtLoop.Pause:
			evtLoop.Pause <- 0

		case <-evtLoop.Terminate:
			// Terminate this Go routine
			if app.Verbose {
				app.PrintfMsg("SDL event loop: exit")
			}
			evtLoop.Terminate <- 0
			shutdown.Done()
			return

		case event := <-sdl.Events:
			switch e := event.(type) {
			case sdl.QuitEvent:
				if app.Verbose {
					app.PrintfMsg("SDL quit -> request[exit the application]")
				}
				app.RequestExit()

			case sdl.JoyAxisEvent:
				if verboseInput {
					app.PrintfMsg("[Joystick] Axis: %d, Value: %d", e.Axis, e.Value)
				}
				if e.Axis == 0 {
					if e.Value > 0 {
						speccy.Joystick.KempstonDown(spectrum.KEMPSTON_RIGHT)
					} else if e.Value < 0 {
						speccy.Joystick.KempstonDown(spectrum.KEMPSTON_LEFT)
					} else {
						speccy.Joystick.KempstonUp(spectrum.KEMPSTON_RIGHT)
						speccy.Joystick.KempstonUp(spectrum.KEMPSTON_LEFT)
					}
				} else if e.Axis == 1 {
					if e.Value > 0 {
						speccy.Joystick.KempstonDown(spectrum.KEMPSTON_UP)
					} else if e.Value < 0 {
						speccy.Joystick.KempstonDown(spectrum.KEMPSTON_DOWN)
					} else {
						speccy.Joystick.KempstonUp(spectrum.KEMPSTON_UP)
						speccy.Joystick.KempstonUp(spectrum.KEMPSTON_DOWN)
					}
				}

			case sdl.JoyButtonEvent:
				if verboseInput {
					app.PrintfMsg("[Joystick] Button: %d, State: %d", e.Button, e.State)
				}
				if e.Button == 0 {
					if e.State > 0 {
						speccy.Joystick.KempstonDown(spectrum.KEMPSTON_FIRE)
					} else {
						speccy.Joystick.KempstonUp(spectrum.KEMPSTON_FIRE)
					}
				}

			case sdl.KeyboardEvent:
				keyName := sdl.GetKeyName(sdl.Key(e.Keysym.Sym))

				if verboseInput {
					app.PrintfMsg("\n")
					app.PrintfMsg("%v: %v", e.Keysym.Sym, keyName)
					app.PrintfMsg("Type: %02x Which: %02x State: %02x\n", e.Type, e.Which, e.State)
					app.PrintfMsg("Scancode: %02x Sym: %08x Mod: %04x Unicode: %04x\n", e.Keysym.Scancode, e.Keysym.Sym, e.Keysym.Mod, e.Keysym.Unicode)
				}

				if (keyName == "escape") && (e.Type == sdl.KEYDOWN) {
					if app.Verbose {
						app.PrintfMsg("escape key -> request[exit the application]")
					}
					app.RequestExit()

				} else if (keyName == "f10") && (e.Type == sdl.KEYDOWN) {
					//if app.Verbose {
					//	app.PrintfMsg("f10 key -> toggle console")
					//}
					if !r.toggling {
						r.toggling = true

						if r.cliSurface_orNil == nil {
							done := make(chan bool)
							r.cliSurfaceCh <- cmd_newCliSurface{newCLISurface(r.scale2x, r.fullscreen), done}
							<-done
						}

						anim := clingon.NewSliderAnimation(0.500, 1.0)

						var targetState int
						if consoleIsVisible {
							targetState = HIDE
						} else {
							targetState = SHOW
						}

						r.sliderCh <- cmd_newSlider{anim, targetState}
						anim.Start()

						consoleIsVisible = !consoleIsVisible
					}
				} else {
					if r.cliSurface_orNil != nil {
						cliSurface := r.cliSurface_orNil

						if (keyName == "page up") && (e.Type == sdl.KEYDOWN) {
							cliSurface.EventCh() <- clingon.Cmd_Scroll{clingon.SCROLL_UP}
						} else if (keyName == "page down") && (e.Type == sdl.KEYDOWN) {
							cliSurface.EventCh() <- clingon.Cmd_Scroll{clingon.SCROLL_DOWN}
						} else if (keyName == "up") && (e.Type == sdl.KEYDOWN) {
							cli.PutReadline(clingon.HISTORY_PREV)
						} else if (keyName == "down") && (e.Type == sdl.KEYDOWN) {
							cli.PutReadline(clingon.HISTORY_NEXT)
						} else if (keyName == "left") && (e.Type == sdl.KEYDOWN) {
							cli.PutReadline(clingon.CURSOR_LEFT)
						} else if (keyName == "right") && (e.Type == sdl.KEYDOWN) {
							cli.PutReadline(clingon.CURSOR_RIGHT)
						} else {
							unicode := e.Keysym.Unicode
							if unicode > 0 {
								cli.PutUnicode(unicode)
							}
						}
					} else {
						sequence, haveMapping := spectrum.SDL_KeyMap[keyName]

						if haveMapping {
							switch e.Type {
							case sdl.KEYDOWN:
								// Normal order
								for i := 0; i < len(sequence); i++ {
									speccy.Keyboard.KeyDown(sequence[i])
								}
							case sdl.KEYUP:
								// Reverse order
								for i := len(sequence) - 1; i >= 0; i-- {
									speccy.Keyboard.KeyUp(sequence[i])
								}
							}
						}
					}
				}
			}
		}
	}
}