1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
package gui
import GameBoy
import cpu.Cpu
import gli_.Texture
import gli_.gli
import glm_.vec2.Vec2i
import glm_.vec4.Vec4
import gln.checkError
import gln.texture.glDeleteTexture
import gln.texture.initTexture2d
import gpu.TestPatternGpu
import imgui.Context
import imgui.ImGui
import imgui.TextureID
import imgui.destroy
import imgui.impl.LwjglGL3
import org.lwjgl.opengl.GL11
import org.lwjgl.opengl.GL30
import uno.glfw.GlfwWindow
import uno.glfw.glfw
import java.awt.image.BufferedImage
import java.io.File
class WindowContainer {
val gameBoy: GameBoy
init {
glfw.init("3.2")
gameBoy = GameBoy(Cpu(), TestPatternGpu())
gameBoy.loadRom(File("src/main/resources/roms/boot-rom.gb"))
}
val window = GlfwWindow(1280, 720, "KGB - KotlinGameBoy").apply {
init()
}
fun run() {
// Enable vsync
glfw.swapInterval = 1
val ctx = Context()
LwjglGL3.init(window)
ImGui.styleColorsDark()
window.loop(::mainLoop)
LwjglGL3.shutdown()
ctx.destroy()
window.destroy()
glfw.terminate()
}
private fun mainLoop() {
LwjglGL3.newFrame()
val (texture, textureId) = createAndRegisterTexture(gameBoy.gpu.getFrame())
with(ImGui) {
paintDebugWindow()
paintCpuRegisterWindow(gameBoy.cpu.registers)
paintRunControlWindow(gameBoy.cpu)
paintRamDumpWindow(gameBoy.cpu.ram)
paintEmulationOutputWindow(textureId)
}
gln.glViewport(window.framebufferSize)
gln.glClearColor(Vec4(0.45f, 0.55f, 0.6f, 1f))
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT)
ImGui.render()
LwjglGL3.renderDrawData(ImGui.drawData!!)
// TODO - render direct to framebuffer rather than creating and destroying texture each frame
disposeTexture(texture, textureId)
checkError("mainLoop")
}
private fun createAndRegisterTexture(frame: BufferedImage): Pair<Texture, TextureID> {
val texture = gli.createTexture(frame)
val textureId = initTexture2d {
minFilter = linear
magFilter = linear
GL30.glPixelStorei(GL30.GL_UNPACK_ROW_LENGTH, 0)
image(GL30.GL_RGB, Vec2i(640,576), GL30.GL_RGB, GL30.GL_UNSIGNED_BYTE, texture.data())
}
return Pair(texture, textureId)
}
private fun disposeTexture(texture: Texture, textureID: TextureID) {
glDeleteTexture(textureID)
texture.dispose()
}
}
|