22
33namespace App ;
44
5+ use App \Renderer \GuiRenderer ;
56use App \Renderer \MonitorRenderer ;
7+ use App \Renderer \RenderState ;
68use Error ;
9+ use GL \Math \Vec2 ;
710use GL \VectorGraphics \{VGAlign , VGColor , VGContext };
811
9- use VISU \Graphics \{RenderTarget , Texture , TextureOptions };
12+ use VISU \Graphics \{RenderTarget , Texture , TextureOptions , Viewport };
1013use VISU \Graphics \Rendering \Pass \ClearPass ;
1114use VISU \Graphics \Rendering \RenderContext ;
1215use VISU \Graphics \Rendering \Resource \RenderTargetResource ;
@@ -23,8 +26,12 @@ class Application extends QuickstartApp
2326
2427 private bool $ isRunning = false ;
2528
29+ private RenderState $ renderState ;
30+
2631 private MonitorRenderer $ monitorRenderer ;
2732
33+ private GuiRenderer $ guiRenderer ;
34+
2835 /**
2936 * A function that is invoked once the app is ready to run.
3037 * This happens exactly just before the game loop starts.
@@ -47,9 +54,13 @@ public function ready() : void
4754
4855 $ this ->inputContext ->registerAndActivate ('main ' , $ actions );
4956
50- // load the inconsolata font to display the current score
51- if ($ this ->vg ->createFont ('inconsolata ' , VISU_PATH_FRAMEWORK_RESOURCES_FONT . '/inconsolata/Inconsolata-Regular.ttf ' ) === -1 ) {
52- throw new Error ('Inconsolata font could not be loaded. ' );
57+ // load the VT323 font
58+ if ($ this ->vg ->createFont ('vt323 ' , VISU_PATH_RESOURCES . '/font/VT323-Regular.ttf ' ) === -1 ) {
59+ throw new Error ('vt323 font could not be loaded. ' );
60+ }
61+
62+ if ($ this ->vg ->createFont ('bebas ' , VISU_PATH_RESOURCES . '/font/BebasNeue-Regular.ttf ' ) === -1 ) {
63+ throw new Error ('Bebas font could not be loaded. ' );
5364 }
5465
5566 // create the chip8
@@ -73,9 +84,15 @@ public function ready() : void
7384
7485 // create a texture for the monitor
7586 $ this ->monitorTexture = new Texture ($ this ->gl , 'chip8_monitor ' );
87+
88+ // rendering state
89+ $ this ->renderState = new RenderState ;
7690
7791 // create a renderer for the monitor
78- $ this ->monitorRenderer = new MonitorRenderer ($ this ->gl );
92+ $ this ->monitorRenderer = new MonitorRenderer ($ this ->gl , $ this ->renderState );
93+
94+ // create a renderer for the GUI
95+ $ this ->guiRenderer = new GuiRenderer ($ this ->vg , $ this ->renderState , $ this ->input );
7996 }
8097 /**
8198 * Prepare / setup additional render passes before the quickstart draw pass
@@ -88,6 +105,19 @@ public function ready() : void
88105 */
89106 public function setupDrawBefore (RenderContext $ context , RenderTargetResource $ renderTarget ) : void
90107 {
108+ // we construct a viewport that matches the render target
109+ // this is not what we would usally use this helper for but in this case
110+ // its just a nice helper to work with our screen real estate
111+ $ this ->renderState ->viewport = new Viewport (
112+ 0 ,
113+ $ renderTarget ->width / $ renderTarget ->contentScaleX ,
114+ $ renderTarget ->height / $ renderTarget ->contentScaleY ,
115+ 0 ,
116+ 1.0 ,
117+ 1.0
118+
119+ );
120+
91121 // upload the buffer
92122 $ options = new TextureOptions ();
93123 $ options ->dataFormat = GL_RED_INTEGER ;
@@ -117,8 +147,11 @@ public function draw(RenderContext $context, RenderTarget $renderTarget) : void
117147
118148 $ currentInst = $ this ->chip8 ->programCounter ;
119149
150+ // draw the screen frame
151+ $ this ->guiRenderer ->renderGUI ($ this ->chip8 );
152+
120153 // draw the current opcode
121- $ this ->vg ->fontFace ('inconsolata ' );
154+ $ this ->vg ->fontFace ('vt323 ' );
122155 $ this ->vg ->fontSize (16 );
123156 $ this ->vg ->fillColor (VGColor::white ());
124157 $ this ->vg ->textAlign (VGAlign::LEFT | VGAlign::TOP );
@@ -169,7 +202,7 @@ public function update() : void
169202
170203 // toggle fullscreen
171204 if ($ this ->inputContext ->actions ->didButtonPress ('fullscreen ' )) {
172- $ this ->monitorRenderer -> fullscreen = !$ this ->monitorRenderer -> fullscreen ;
205+ $ this ->renderState -> fullscreenMonitor = !$ this ->renderState -> fullscreenMonitor ;
173206 }
174207
175208 // toggle crt effect
@@ -183,29 +216,32 @@ public function update() : void
183216 }
184217
185218 // update the keyboard states
186- $ this ->chip8 ->keyPressStates [0x1 ] = (int ) $ this ->input ->isKeyPressed (Key::NUM_1 );
187- $ this ->chip8 ->keyPressStates [0x2 ] = (int ) $ this ->input ->isKeyPressed (Key::NUM_2 );
188- $ this ->chip8 ->keyPressStates [0x3 ] = (int ) $ this ->input ->isKeyPressed (Key::NUM_3 );
189- $ this ->chip8 ->keyPressStates [0xC ] = (int ) $ this ->input ->isKeyPressed (Key::NUM_4 );
190- $ this ->chip8 ->keyPressStates [0x4 ] = (int ) $ this ->input ->isKeyPressed (Key::Q);
191- $ this ->chip8 ->keyPressStates [0x5 ] = (int ) $ this ->input ->isKeyPressed (Key::W);
192- $ this ->chip8 ->keyPressStates [0x6 ] = (int ) $ this ->input ->isKeyPressed (Key::E);
193- $ this ->chip8 ->keyPressStates [0xD ] = (int ) $ this ->input ->isKeyPressed (Key::R);
194- $ this ->chip8 ->keyPressStates [0x7 ] = (int ) $ this ->input ->isKeyPressed (Key::A);
195- $ this ->chip8 ->keyPressStates [0x8 ] = (int ) $ this ->input ->isKeyPressed (Key::S);
196- $ this ->chip8 ->keyPressStates [0x9 ] = (int ) $ this ->input ->isKeyPressed (Key::D);
197- $ this ->chip8 ->keyPressStates [0xE ] = (int ) $ this ->input ->isKeyPressed (Key::F);
198- $ this ->chip8 ->keyPressStates [0xA ] = (int ) $ this ->input ->isKeyPressed (Key::Y);
199- $ this ->chip8 ->keyPressStates [0x0 ] = (int ) $ this ->input ->isKeyPressed (Key::X);
200- $ this ->chip8 ->keyPressStates [0xB ] = (int ) $ this ->input ->isKeyPressed (Key::C);
201- $ this ->chip8 ->keyPressStates [0xF ] = (int ) $ this ->input ->isKeyPressed (Key::V);
202-
219+ if ($ this ->chip8 ->wantKeyboardUpdates ) {
220+ $ this ->chip8 ->keyPressStates [0x1 ] = (int ) $ this ->input ->isKeyPressed (Key::NUM_1 );
221+ $ this ->chip8 ->keyPressStates [0x2 ] = (int ) $ this ->input ->isKeyPressed (Key::NUM_2 );
222+ $ this ->chip8 ->keyPressStates [0x3 ] = (int ) $ this ->input ->isKeyPressed (Key::NUM_3 );
223+ $ this ->chip8 ->keyPressStates [0xC ] = (int ) $ this ->input ->isKeyPressed (Key::NUM_4 );
224+ $ this ->chip8 ->keyPressStates [0x4 ] = (int ) $ this ->input ->isKeyPressed (Key::Q);
225+ $ this ->chip8 ->keyPressStates [0x5 ] = (int ) $ this ->input ->isKeyPressed (Key::W);
226+ $ this ->chip8 ->keyPressStates [0x6 ] = (int ) $ this ->input ->isKeyPressed (Key::E);
227+ $ this ->chip8 ->keyPressStates [0xD ] = (int ) $ this ->input ->isKeyPressed (Key::R);
228+ $ this ->chip8 ->keyPressStates [0x7 ] = (int ) $ this ->input ->isKeyPressed (Key::A);
229+ $ this ->chip8 ->keyPressStates [0x8 ] = (int ) $ this ->input ->isKeyPressed (Key::S);
230+ $ this ->chip8 ->keyPressStates [0x9 ] = (int ) $ this ->input ->isKeyPressed (Key::D);
231+ $ this ->chip8 ->keyPressStates [0xE ] = (int ) $ this ->input ->isKeyPressed (Key::F);
232+ $ this ->chip8 ->keyPressStates [0xA ] = (int ) $ this ->input ->isKeyPressed (Key::Y);
233+ $ this ->chip8 ->keyPressStates [0x0 ] = (int ) $ this ->input ->isKeyPressed (Key::X);
234+ $ this ->chip8 ->keyPressStates [0xB ] = (int ) $ this ->input ->isKeyPressed (Key::C);
235+ $ this ->chip8 ->keyPressStates [0xF ] = (int ) $ this ->input ->isKeyPressed (Key::V);
236+ }
203237
204238 if (!$ this ->isRunning ) {
205239 return ;
206240 }
207241
208242 $ this ->chip8 ->updateTimers ();
209- $ this ->chip8 ->runCycles (8 );
243+ if ($ this ->chip8 ->runCycles (8 ) === 0 ) {
244+ $ this ->isRunning = false ;
245+ }
210246 }
211247}
0 commit comments