From e6690c3e2bfddcb6ecb4ed817ac6e99356a9246c Mon Sep 17 00:00:00 2001 From: a dinosaur Date: Sat, 21 Sep 2024 22:06:48 +1000 Subject: [PATCH] more complicated viewport resizing logic to make sure viewport offset works --- Sources/Voxelotl/Application.swift | 2 +- Sources/Voxelotl/GameDelegate.swift | 4 +- Sources/Voxelotl/Input/Keyboard.swift | 3 ++ Sources/Voxelotl/SpriteTestGame.swift | 62 ++++++++++++++++++++++----- 4 files changed, 57 insertions(+), 14 deletions(-) diff --git a/Sources/Voxelotl/Application.swift b/Sources/Voxelotl/Application.swift index 1288ed9..d1cb391 100644 --- a/Sources/Voxelotl/Application.swift +++ b/Sources/Voxelotl/Application.swift @@ -133,7 +133,7 @@ public class Application { case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: let backBufferSize = Size(Int(event.window.data1), Int(event.window.data2)) self.renderer!.resize(size: backBufferSize) - self.del.resize(backBufferSize) + self.del.resize(.init(origin: .zero, size: backBufferSize)) return .running default: diff --git a/Sources/Voxelotl/GameDelegate.swift b/Sources/Voxelotl/GameDelegate.swift index 69197f9..26a1c1b 100644 --- a/Sources/Voxelotl/GameDelegate.swift +++ b/Sources/Voxelotl/GameDelegate.swift @@ -3,13 +3,13 @@ public protocol GameDelegate { func fixedUpdate(_ time: GameTime) func update(_ time: GameTime) func draw(_ renderer: Renderer, _ time: GameTime) - func resize(_ size: Size) + func resize(_ frame: Rect) } public extension GameDelegate { func fixedUpdate(_ time: GameTime) {} func update(_ time: GameTime) {} - func resize(_ size: Size) {} + func resize(_ frame: Rect) {} } public struct GameTime { diff --git a/Sources/Voxelotl/Input/Keyboard.swift b/Sources/Voxelotl/Input/Keyboard.swift index 0d39882..fd390f6 100644 --- a/Sources/Voxelotl/Input/Keyboard.swift +++ b/Sources/Voxelotl/Input/Keyboard.swift @@ -6,6 +6,7 @@ public class Keyboard { case leftBracket case right, left, up, down case space, tab + case enter } public static func down(_ key: Keys) -> Bool { @@ -93,6 +94,7 @@ internal extension Keyboard.Keys { case .down: SDLK_DOWN case .space: SDLK_SPACE case .tab: SDLK_TAB + case .enter: SDLK_RETURN } } @@ -131,6 +133,7 @@ internal extension Keyboard.Keys { case .down: SDL_SCANCODE_DOWN case .space: SDL_SCANCODE_SPACE case .tab: SDL_SCANCODE_TAB + case .enter: SDL_SCANCODE_RETURN } } } diff --git a/Sources/Voxelotl/SpriteTestGame.swift b/Sources/Voxelotl/SpriteTestGame.swift index e61e0a2..e928d54 100644 --- a/Sources/Voxelotl/SpriteTestGame.swift +++ b/Sources/Voxelotl/SpriteTestGame.swift @@ -3,13 +3,25 @@ import simd internal class SpriteTestGame: GameDelegate { private var spriteBatch: SpriteBatch! - private var player = TestPlayer(position: .one * 10) + private var player = TestPlayer(position: .one * 100) private var texture: RendererTexture2D! private var wireShark: RendererTexture2D! private var level = TestLevel() + private var frame: Size! + + var worldMousePosition: SIMD2 { + var mpos = Mouse.position + if self.spriteBatch.viewport != .init(origin: .zero, size: self.frame) { + mpos /= SIMD2(self.frame) + mpos *= SIMD2(self.spriteBatch.viewport.size) + mpos += SIMD2(self.spriteBatch.viewport.origin) + } + return mpos + } func create(_ renderer: Renderer) { self.spriteBatch = renderer.createSpriteBatch() + self.resize(renderer.frame) renderer.clearColor = .init(hue: 301.2, saturation: 0.357, value: 0.488).linear // .magenta.mix(.white, 0.4).mix(.black, 0.8) self.texture = renderer.loadTexture(resourcePath: "test.png") self.wireShark = renderer.loadTexture(resourcePath: "wireshark.png") @@ -22,7 +34,8 @@ internal class SpriteTestGame: GameDelegate { if let pad = GameController.current?.state { self.player.velocity.x = pad.leftStick.x.axisDeadzone(0.1, 0.8) * 660 if pad.pressed(.start) { - self.player.position = .one * 10 + self.player.position = .one * 100 + self.player.velocity = .zero } if pad.pressed(.east) && player.onGround { self.player.velocity.y = -1000 @@ -30,6 +43,10 @@ internal class SpriteTestGame: GameDelegate { self.player.velocity.y = -550 } } + if Keyboard.pressed(.enter) { + self.player.position = .one * 100 + self.player.velocity = .zero + } if Keyboard.down(.left) { self.player.velocity.x = -660 } else if Keyboard.down(.right) { @@ -41,10 +58,11 @@ internal class SpriteTestGame: GameDelegate { self.player.velocity.y = -550 } + let mpos = self.worldMousePosition if Mouse.down(.left) { - self.level.set(SIMD2(Mouse.position / TestLevel.cellScale, rounding: .down), true) + self.level.set(SIMD2(mpos / TestLevel.cellScale, rounding: .down), true) } else if Mouse.down(.right) { - self.level.set(SIMD2(Mouse.position / TestLevel.cellScale, rounding: .down), false) + self.level.set(SIMD2(mpos / TestLevel.cellScale, rounding: .down), false) } self.player.update(deltaTime: dt, level: self.level) @@ -93,11 +111,7 @@ internal class SpriteTestGame: GameDelegate { position: doorPosition, transform: doorAffine, color: .red.mix(.white, 0.3)) // Draw mouse cursor - var mpos = Mouse.position - if self.spriteBatch.viewport.size != Size(renderer.frame.size) { - mpos /= SIMD2(Size(renderer.frame.size)) - mpos *= SIMD2(self.spriteBatch.viewport.size) - } + let mpos = self.worldMousePosition let inter = 0.5 + sin(Float(time.total) * 10) * 0.5 let color = Color.green.mix(.white, 0.3) let mesh = Mesh.init(vertices: [ @@ -115,8 +129,34 @@ internal class SpriteTestGame: GameDelegate { self.spriteBatch.end() } - func resize(_ size: Size) { - self.spriteBatch.viewport.size = Size(size) + func resize(_ frame: Rect) { + let viewport = Rect(frame) + self.frame = viewport.size + + let rect = Rect(origin: .zero, size: .init(2560, 1440)) + if viewport == rect { + self.spriteBatch.viewport = rect + return + } + + let viewportRatio = viewport.w / viewport.h + let rectRatio = rect.w / rect.h + if abs(viewportRatio - rectRatio) <= .ulpOfOne * 10 { self.spriteBatch.viewport = rect } + else if viewportRatio > rectRatio { + let width = rect.h * viewportRatio + self.spriteBatch.viewport = .init( + x: (rect.w - width) * 0.5, + y: 0, + width: width, + height: rect.h) + } else { + let height = rect.w / viewportRatio + self.spriteBatch.viewport = .init( + x: 0, + y: (rect.h - height) * 0.5, + width: rect.w, + height: height) + } } }