Beispiel #1
0
// GetDesktopDimensions gets the dimensions of a display for the given index
func GetDesktopDimensions(displayindex int) (int32, int32) {
	var width, height int32
	if displayindex >= 0 && displayindex < GetDisplayCount() {
		var mode sdl.DisplayMode
		sdl.GetDesktopDisplayMode(displayindex, &mode)
		width = mode.W
		height = mode.H
	}
	return width, height
}
Beispiel #2
0
// NewWindow will create a new sdl window with a gl context. It will also destroy
// an old one if there is one already. Errors returned come straight from SDL so
// errors will be indicitive of SDL errors
func NewWindow() (*window, error) {
	if current_window != nil || initError != nil {
		return current_window, initError
	}

	var config *windowConfig
	var err error

	if err = sdl.InitSubSystem(sdl.INIT_VIDEO); err != nil {
		panic(err)
	}

	if config, err = loadConfig(); err != nil {
		panic(err)
	}

	config.Minwidth = int32(math.Max(float64(config.Minwidth), 1.0))
	config.Minheight = int32(math.Max(float64(config.Minheight), 1.0))
	config.Display = int(math.Min(math.Max(float64(config.Display), 0.0), float64(GetDisplayCount()-1)))

	if config.Width == 0 || config.Height == 0 {
		var mode sdl.DisplayMode
		sdl.GetDesktopDisplayMode(config.Display, &mode)
		config.Width = mode.W
		config.Height = mode.H
	}

	sdlflags := uint32(sdl.WINDOW_OPENGL)

	if config.Fullscreen {
		if config.Fstype == "desktop" {
			sdlflags |= sdl.WINDOW_FULLSCREEN_DESKTOP
		} else {
			sdlflags |= sdl.WINDOW_FULLSCREEN

			mode := sdl.DisplayMode{W: int32(config.Width), H: int32(config.Height)}

			// Fullscreen window creation will bug out if no mode can be used.
			if _, err := sdl.GetClosestDisplayMode(config.Display, &mode, &mode); err != nil {
				// GetClosestDisplayMode will fail if we request a size larger
				// than the largest available display mode, so we'll try to use
				// the largest (first) mode in that case.
				if err := sdl.GetDisplayMode(config.Display, 0, &mode); err != nil {
					return nil, err
				}
			}

			config.Width = mode.W
			config.Height = mode.H
		}
	}

	if config.Resizable {
		sdlflags |= sdl.WINDOW_RESIZABLE
	}

	if config.Borderless {
		sdlflags |= sdl.WINDOW_BORDERLESS
	}

	if config.Highdpi {
		sdlflags |= sdl.WINDOW_ALLOW_HIGHDPI
	}

	if config.Fullscreen {
		// The position needs to be in the global coordinate space.
		var displaybounds sdl.Rect
		sdl.GetDisplayBounds(config.Display, &displaybounds)
		config.X += displaybounds.X
		config.Y += displaybounds.Y
	} else {
		if config.Centered {
			config.X = sdl.WINDOWPOS_CENTERED
			config.Y = sdl.WINDOWPOS_CENTERED
		} else {
			config.X = sdl.WINDOWPOS_UNDEFINED
			config.Y = sdl.WINDOWPOS_UNDEFINED
		}
	}

	if current_window != nil {
		Destroy()
	}

	created = false
	new_window, err := createWindowAndContext(config, sdlflags)
	if err != nil {
		return nil, err
	}
	created = true

	if new_window.Config.Icon != "" {
		SetIcon(config.Icon)
	}

	SetMouseGrab(false)
	SetMinimumSize(config.Minwidth, config.Minheight)
	SetTitle(config.Title)

	if config.Centered && !config.Fullscreen {
		SetPosition(config.X, config.Y)
	}

	getCurrent().sdl_window.Raise()

	if config.Vsync {
		sdl.GL_SetSwapInterval(1)
	} else {
		sdl.GL_SetSwapInterval(0)
	}

	new_window.open = true
	return new_window, nil
}
Beispiel #3
0
// win==nil requests a full-screen window
func Run(win WindowSpec) int {
	// All SDL calls must come from same thread.
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	err := sdl.Init(sdl.INIT_EVERYTHING)
	if err != nil {
		panic(err)
	}
	defer sdl.Quit()

	// Install audio callback
	spec := &sdl.AudioSpec{
		Freq:     SampleRate,
		Format:   sdl.AUDIO_F32SYS,
		Channels: 1,
		Samples:  4096,
		Callback: sdl.AudioCallback(C.getSoundSamplesAdaptor),
	}
	audioDevice, err := sdl.OpenAudioDevice("", false, spec, nil, 0)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to open audio device: %v\n", err)
		panic(err)
	}
	if audioDevice < 2 {
		fmt.Fprintf(os.Stderr, "Audio device=%v < 2 contrary to SDL-2 documentation\n", audioDevice, err)
	}
	sdl.PauseAudioDevice(audioDevice, false)

	// Create window
	var window *sdl.Window
	if win != nil {
		// Partial screen
		winWidth, winHeight := win.Size()
		window, err = sdl.CreateWindow(win.Title(), sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
			int(winWidth), int(winHeight), sdl.WINDOW_SHOWN)
	} else {
		// Full screen
		if isMacOS {
			// Contrary to https://wiki.libsdl.org/SDL_CreateWindow, on MacOS 10.11.1
			// a call to sdl.CreateWindow in fullscreen mode *does* use the w and h parameters.
			// So ask what the display size is.
			var mode sdl.DisplayMode
			err = sdl.GetDesktopDisplayMode(0, &mode)
			if err != nil {
				fmt.Fprintf(os.Stderr, "Cannot get desktop display mode")
				panic(err)
			}
			window, err = sdl.CreateWindow("", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
				int(mode.W), int(mode.H), sdl.WINDOW_SHOWN|sdl.WINDOW_FULLSCREEN_DESKTOP)
		} else {
			window, err = sdl.CreateWindow("", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
				0, 0, sdl.WINDOW_SHOWN|sdl.WINDOW_FULLSCREEN_DESKTOP)
		}

	}
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to create window: %v\n", err)
		panic(err)
	}
	defer window.Destroy()

	// Create renderer
	width, height := window.GetSize()
	renderer, err := sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED|sdl.RENDERER_PRESENTVSYNC)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to create renderer: %v\n", err)
		panic(err)
	}
	defer renderer.Destroy()

	var nTex = 1
	if isMacOS {
		// Work around MacOS bug via double buffering
		nTex = 2
	}
	// Create texture
	tex := make([]*sdl.Texture, nTex)
	for i := range tex {
		tex[i], err = renderer.CreateTexture(sdl.PIXELFORMAT_ARGB8888, sdl.TEXTUREACCESS_STREAMING, width, height)
		if err != nil {
			fmt.Fprintf(os.Stderr, "renderer.CreateTexture: %v\n", err)
			panic(err)
		}
		defer tex[i].Destroy()
	}
	for _, r := range renderClientList {
		r.Init(int32(width), int32(height))
	}

	// Loop until quit
	for i := 0; ; i ^= nTex - 1 {
		for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
			switch e := event.(type) {
			case *sdl.QuitEvent:
				return 0
			case *sdl.MouseMotionEvent:
				// Go equivalent of SDL_PRESSED seems to be missing, so compare with zero.
				if e.State != 0 {
					forwardMouseEvent(MouseDrag, int32(e.X), int32(e.Y))
				} else {
					forwardMouseEvent(MouseMove, int32(e.X), int32(e.Y))
				}
			case *sdl.MouseButtonEvent:
				switch e.Type {
				case sdl.MOUSEBUTTONDOWN:
					forwardMouseEvent(MouseDown, int32(e.X), int32(e.Y))
				case sdl.MOUSEBUTTONUP:
					forwardMouseEvent(MouseUp, int32(e.X), int32(e.Y))
				}
			case *sdl.KeyDownEvent:
				var k Key
				if 0x20 <= e.Keysym.Sym && e.Keysym.Sym < 0x7F {
					// Printable ASCII
					k = Key(e.Keysym.Sym)
				} else {
					// Try special character table
					k = keyMap[e.Keysym.Sym]
				}
				if k != 0 {
					forwardKeyEvent(k)
				}
			}
		}
		pixels, pitch := lockTexture(tex[i], width, height)
		pm := MakePixMap(int32(width), int32(height), pixels, int32(pitch))
		for _, r := range renderClientList {
			r.Render(pm)
		}
		tex[i].Unlock()

		err := renderer.Clear()
		if err != nil {
			fmt.Fprintf(os.Stderr, "renderer.Clear: %v", err)
			panic(err)
		}
		renderer.Copy(tex[i], nil, nil)
		if err != nil {
			fmt.Fprintf(os.Stderr, "renderer.Copy: %v", err)
			panic(err)
		}
		renderer.Present()
	}
}