package main import ( "fmt" "github.com/veandco/go-sdl2/sdl" ) func initializeSDL() { if err := sdl.Init(sdl.INIT_EVERYTHING); err != nil { panic(err) } } func setupWindowAndSurface(playerIndex uint8) (*sdl.Window, *sdl.Surface) { const windowWidth, windowHeight = 160, 100 window, err := sdl.CreateWindow(fmt.Sprintf("Tunneler - player %d", playerIndex), sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, windowWidth, windowHeight, sdl.WINDOW_SHOWN|sdl.WINDOW_RESIZABLE) if err != nil { panic(err) } logicalSurface, err := sdl.CreateRGBSurface(0, windowWidth, windowHeight, 32, 0, 0, 0, 0) if err != nil { panic(err) } return window, logicalSurface } func setupMapWindowAndSurface() (*sdl.Window, *sdl.Surface) { window, err := sdl.CreateWindow("Tunneler map", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, int32(serverConfig.MapWidth), int32(serverConfig.MapWidth), sdl.WINDOW_SHOWN|sdl.WINDOW_RESIZABLE) if err != nil { panic(err) } logicalSurface, err := sdl.CreateRGBSurface(0, int32(serverConfig.MapWidth), int32(serverConfig.MapWidth), 32, 0, 0, 0, 0) if err != nil { panic(err) } return window, logicalSurface } func setupPlaySurface() (*sdl.Surface, *sdl.Rect, *sdl.Rect) { playSurface, err := sdl.CreateRGBSurface(0, config.CameraW, config.CameraH, 32, 0, 0, 0, 0) if err != nil { panic(err) } playSurfaceRect := &sdl.Rect{X: 0, Y: 0, W: config.CameraW, H: config.CameraH} playSurfaceTargetRect := &sdl.Rect{X: 42, Y: 0, W: config.CameraW, H: config.CameraH} return playSurface, playSurfaceRect, playSurfaceTargetRect } func setupHUDSurface() (*sdl.Surface, *sdl.Rect, *sdl.Rect) { HUDSurface, err := sdl.CreateRGBSurface(0, 112, 25, 32, 0, 0, 0, 0) if err != nil { panic(err) } HUDSurfaceRect := &sdl.Rect{X: 0, Y: 0, W: 112, H: 25} HUDSurfaceTargetRect := &sdl.Rect{X: 24, Y: config.CameraH, W: 112, H: 25} return HUDSurface, HUDSurfaceRect, HUDSurfaceTargetRect } func handleEvents(window *sdl.Window, logicalSurface *sdl.Surface) bool { for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { switch e := event.(type) { case *sdl.QuitEvent: return false case *sdl.WindowEvent: if e.Event == sdl.WINDOWEVENT_RESIZED { handleWindowResize(window, logicalSurface) } } } return true } func handleWindowResize(window *sdl.Window, logicalSurface *sdl.Surface) { windowSurface, err := window.GetSurface() if err != nil { panic(err) } windowWidth, windowHeight := windowSurface.W, windowSurface.H aspectRatio := float64(logicalSurface.W) / float64(logicalSurface.H) newWidth := windowWidth newHeight := int32(float64(windowWidth) / aspectRatio) if newHeight > windowHeight { newHeight = windowHeight newWidth = int32(float64(windowHeight) * aspectRatio) } letterboxX := (windowWidth - newWidth) / 2 letterboxY := (windowHeight - newHeight) / 2 srcRect := &sdl.Rect{X: 0, Y: 0, W: logicalSurface.W, H: logicalSurface.H} dstRect := &sdl.Rect{X: letterboxX, Y: letterboxY, W: newWidth, H: newHeight} logicalSurface.BlitScaled(srcRect, windowSurface, dstRect) window.UpdateSurface() } func adjustWindow(window *sdl.Window, logicalSurface *sdl.Surface) { // Get window surface and handle any errors windowSurface, err := window.GetSurface() if err != nil { panic(err) } // Retrieve window dimensions windowWidth, windowHeight := windowSurface.W, windowSurface.H // Calculate aspect ratio logicalAspectRatio := float64(logicalSurface.W) / float64(logicalSurface.H) windowAspectRatio := float64(windowWidth) / float64(windowHeight) var newWidth, newHeight int32 if windowAspectRatio > logicalAspectRatio { // Window is wider than logical surface newHeight = windowHeight newWidth = int32(float64(windowHeight) * logicalAspectRatio) } else { // Window is taller or equal in aspect ratio newWidth = windowWidth newHeight = int32(float64(windowWidth) / logicalAspectRatio) } // Calculate letterbox positions letterboxX := (windowWidth - newWidth) / 2 letterboxY := (windowHeight - newHeight) / 2 // Fill background windowSurface.FillRect(nil, sdl.MapRGBA(logicalSurface.Format, 80, 20, 10, 255)) // Set source and destination rectangles srcRect := &sdl.Rect{X: 0, Y: 0, W: logicalSurface.W, H: logicalSurface.H} dstRect := &sdl.Rect{X: letterboxX, Y: letterboxY, W: newWidth, H: newHeight} // Perform the scaled blit logicalSurface.BlitScaled(srcRect, windowSurface, dstRect) // Update the window surface window.UpdateSurface() }