1515import java .util .Timer ;
1616import java .util .logging .Logger ;
1717
18+ import org .lwjgl .*;
19+ import org .lwjgl .glfw .*;
20+ import org .lwjgl .opengl .*;
21+ import org .lwjgl .system .*;
22+
23+ import java .nio .*;
24+
25+ import static org .lwjgl .glfw .Callbacks .*;
26+ import static org .lwjgl .glfw .GLFW .*;
27+ import static org .lwjgl .opengl .GL11 .*;
28+ import static org .lwjgl .system .MemoryStack .*;
29+ import static org .lwjgl .system .MemoryUtil .*;
30+
1831/**
1932 * The main Emulator class.
2033 */
@@ -49,6 +62,8 @@ public class Emulator
4962 private Timer timer ;
5063 private TimerTask timerTask ;
5164
65+ private long window ;
66+
5267 /**
5368 * Convenience constructor that sets the emulator running with a 1x
5469 * screen scale, a cycle time of 0, a null rom, and trace mode off.
@@ -108,33 +123,33 @@ public Emulator(
108123 System .exit (1 );
109124 }
110125
111- Color converted_color0 = null ;
126+ PixelColor converted_color0 = null ;
112127 try {
113- converted_color0 = Color .decode ("#" + color0 );
128+ converted_color0 = new PixelColor ( Color .decode ("#" + color0 ) );
114129 } catch (NumberFormatException e ) {
115130 System .out .println ("color_0 parameter could not be decoded (" + e .getMessage () +")" );
116131 System .exit (1 );
117132 }
118133
119- Color converted_color1 = null ;
134+ PixelColor converted_color1 = null ;
120135 try {
121- converted_color1 = Color .decode ("#" + color1 );
136+ converted_color1 = new PixelColor ( Color .decode ("#" + color1 ) );
122137 } catch (NumberFormatException e ) {
123138 System .out .println ("color_1 parameter could not be decoded (" + e .getMessage () +")" );
124139 System .exit (1 );
125140 }
126141
127- Color converted_color2 = null ;
142+ PixelColor converted_color2 = null ;
128143 try {
129- converted_color2 = Color .decode ("#" + color2 );
144+ converted_color2 = new PixelColor ( Color .decode ("#" + color2 ) );
130145 } catch (NumberFormatException e ) {
131146 System .out .println ("color_2 parameter could not be decoded (" + e .getMessage () +")" );
132147 System .exit (1 );
133148 }
134149
135- Color converted_color3 = null ;
150+ PixelColor converted_color3 = null ;
136151 try {
137- converted_color3 = Color .decode ("#" + color3 );
152+ converted_color3 = new PixelColor ( Color .decode ("#" + color3 ) );
138153 } catch (NumberFormatException e ) {
139154 System .out .println ("color_3 parameter could not be decoded (" + e .getMessage () +")" );
140155 System .exit (1 );
@@ -172,9 +187,7 @@ public Emulator(
172187 IO .closeStream (romFileStream );
173188 }
174189
175- // Initialize the screen
176- initEmulatorJFrame ();
177- start ();
190+ init ();
178191 }
179192
180193 /**
@@ -190,23 +203,97 @@ public void run() {
190203 };
191204 timer .scheduleAtFixedRate (timerTask , 0L , 17L );
192205
193- while (state != EmulatorState .KILLED ) {
194- if (state != EmulatorState .PAUSED ) {
195- if (!cpu .isAwaitingKeypress ()) {
196- cpu .fetchIncrementExecute ();
197- } else {
198- cpu .decodeKeypressAndContinue ();
199- }
200- }
201-
202- if (keyboard .getRawKeyPressed () == Keyboard .CHIP8_QUIT ) {
203- break ;
204- }
206+ while (!glfwWindowShouldClose (window )) {
207+ // if (state != EmulatorState.PAUSED) {
208+ // if (!cpu.isAwaitingKeypress()) {
209+ // cpu.fetchIncrementExecute();
210+ // } else {
211+ // cpu.decodeKeypressAndContinue();
212+ // }
213+
214+ glClearColor (0.2f , 0.3f , 0.3f , 1.0f );
215+ glClear (GL_COLOR_BUFFER_BIT );
216+ glfwSwapBuffers (window );
217+ // glReadPixels();
218+ glfwPollEvents ();
219+ // }
205220 }
221+
206222 kill ();
207223 System .exit (0 );
208224 }
209225
226+ void init () {
227+ int scaleFactor = screen .getScale ();
228+ int scaledWidth = Screen .WIDTH * scaleFactor ;
229+ int scaledHeight = Screen .HEIGHT * scaleFactor ;
230+
231+ if (!glfwInit ()) {
232+ throw new IllegalStateException ("Unable to initialize GLFW" );
233+ }
234+
235+ glfwDefaultWindowHints ();
236+ glfwWindowHint (GLFW_RESIZABLE , GLFW_FALSE );
237+ glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR , 3 );
238+ glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR , 3 );
239+ glfwWindowHint (GLFW_OPENGL_PROFILE , GLFW_OPENGL_CORE_PROFILE );
240+
241+ window = glfwCreateWindow (scaledWidth , scaledHeight , DEFAULT_TITLE , NULL , NULL );
242+ if (window == NULL ) {
243+ glfwTerminate ();
244+ throw new RuntimeException ("Failed to create the GLFW window" );
245+ }
246+
247+ GLFWErrorCallback errorCallback = new GLFWErrorCallback () {
248+ @ Override
249+ public void invoke (int error , long description ) {
250+ System .out .println ("Error: " + error + ", " + description );
251+ }
252+ };
253+ glfwSetErrorCallback (errorCallback );
254+
255+ // The main emulator keyboard callback function
256+ GLFWKeyCallback keyCallback = new GLFWKeyCallback () {
257+ @ Override
258+ public void invoke (long window , int key , int scancode , int action , int mods ) {
259+ if (action == GLFW_PRESS ) {
260+ keyboard .keyPressed (key );
261+ }
262+
263+ if (action == GLFW_RELEASE ) {
264+ keyboard .keyReleased (key );
265+ }
266+
267+ if (key == Keyboard .CHIP8_QUIT && action == GLFW_RELEASE ) {
268+ glfwSetWindowShouldClose (window , true );
269+ }
270+ }
271+ };
272+ glfwSetKeyCallback (window , keyCallback );
273+
274+ // Get the thread stack and push a new frame
275+ // try ( MemoryStack stack = stackPush() ) {
276+ // IntBuffer pWidth = stack.mallocInt(1); // int*
277+ // IntBuffer pHeight = stack.mallocInt(1); // int*
278+ // glfwGetWindowSize(window, pWidth, pHeight);
279+ // GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
280+ // glfwSetWindowPos(window, (vidmode.width() - pWidth.get(0)) / 2, (vidmode.height() - pHeight.get(0)) / 2);
281+ // }
282+
283+ glfwMakeContextCurrent (window );
284+ // glfwSwapInterval(1);
285+ // glfwShowWindow(window);
286+
287+ // This line is critical for LWJGL's interoperation with GLFW's
288+ // OpenGL context, or any context that is managed externally.
289+ // LWJGL detects the context that is current in the current thread,
290+ // creates the GLCapabilities instance and makes the OpenGL
291+ // bindings available for use.
292+ GL .createCapabilities ();
293+
294+ // glViewport(0, 0, scaledWidth, scaledHeight);
295+ }
296+
210297 /**
211298 * Returns the main frame for the emulator.
212299 *
@@ -290,18 +377,14 @@ private void attachCanvas() {
290377 canvas .setFocusable (true );
291378 canvas .requestFocus ();
292379
293- canvas .addKeyListener (keyboard );
380+ // canvas.addKeyListener(keyboard);
294381 }
295382
296383 /**
297- * Will redraw the contents of the screen to the emulator window. Optionally, if
298- * isInTraceMode is True, will also draw the contents of the overlayScreen to the screen.
384+ * Will redraw the contents of the screen to the emulator window.
299385 */
300386 private void refreshScreen () {
301- Graphics2D graphics = (Graphics2D ) canvas .getBufferStrategy ().getDrawGraphics ();
302- graphics .drawImage (screen .getBuffer (), null , 0 , 0 );
303- graphics .dispose ();
304- canvas .getBufferStrategy ().show ();
387+ glfwSwapBuffers (window );
305388 }
306389
307390 /**
@@ -313,8 +396,11 @@ public void kill() {
313396 timer .cancel ();
314397 timer .purge ();
315398 timerTask .cancel ();
316- dispose ();
399+ // dispose();
317400 state = EmulatorState .KILLED ;
401+ glfwFreeCallbacks (window );
402+ glfwDestroyWindow (window );
403+ glfwTerminate ();
318404 }
319405
320406 /**
0 commit comments