I'm (new to SO and) attempting to code an "emulator" for an 8-bit CPU I am making with a friend. I have only ever used Java to make simple GUIs with Swing, and from reading similar questions it seems to me that using repaint() and Graphics2D to display 60fps is not the way to go.

From my attempts at using a custom JComponent to draw, I couldn't agree more. Despite calling screenComponent.repaint() 60 times per second, Java was only updating the screen around 2 times per second, whereas the video memory byte array (stores pixel data) that was also updated 60 times per second (before calling repaint) did change every frame.

So my question is: what can I use to display my one-dimension pixel array (using y * width + x to get pixels at a coordinate) and update it at 60fps?

What I need to be able to do:

  1. draw each individual pixel with a set color -draw text with a font and size (the computer I am emulating has a toggle able text-only graphics mode)

  2. efficiency is not a huge concern since the main purpose of this is to test assembly programs that will later run on the physical CPU, but it needs to update the screen at 60 Hertz and run CPU clock cycles at least at 1 kilohertz

  3. scale up the canvas as the cpu only displays at 78 by 128 pixels (I did this in swing by using g2d.fillRect to display pixels and multiplying the arguments by a screen size multiplier integer)

  4. not 3D

  • \$\begingroup\$ What system are you targeting to run this on? Windows? Linux? macOS? iOS? Android? \$\endgroup\$ – user1118321 Apr 12 '19 at 4:17
  • \$\begingroup\$ I only need to support windows. (both my desktop and laptop run it and that's the only times I will use the emulator) \$\endgroup\$ – TheSunCat Apr 12 '19 at 5:12

Try something like LibGDX, JSDL or JSFML and render pixel-plotted results to a fullscreen texture.

These are mentioned because you ideally want an existing, fast 2D pixel plotter founded on an API like OpenGL, that provides hardware rendering support; because even though you don't need 3D, you do need fast draw access. And you need Java bindings.

| improve this answer | |
  • \$\begingroup\$ Will these libraries will allow me to draw pixels and text or do I have to render in 3d orthographically? Also, JSDL seems to have discontinued development since a few years... Which one would you recommend me to try first? \$\endgroup\$ – TheSunCat Apr 12 '19 at 12:25
  • \$\begingroup\$ Did you click the links I gave you? Because if you did, you'd have already had an answer to that on the very first link. \$\endgroup\$ – Engineer Apr 12 '19 at 13:54
  • \$\begingroup\$ Yes, but upon downloading the setup app from libgdx's website, I am asked to select an Android SDK install location. I don't want/need to support mobile. \$\endgroup\$ – TheSunCat Apr 12 '19 at 14:00
  • \$\begingroup\$ Just do as it asks and then you can get going on your Windows coding. You're developing for Windows; we know that. It just so happens that LibGDX was initially designed for Android and that is still its most popular platform for deployment. \$\endgroup\$ – Engineer Apr 12 '19 at 14:02
  • \$\begingroup\$ I don't have the Android SDK installed, but unticking the Android option in the "setup app" allows me not to specify an Android SDK location. My main class is in /Documents/Celsior/src/celsior/Celsior.java, and I entered "celsior" into the package name prompt. Clicking "Generate," however, I am informed that I have an invalid package name. I have tried selecting /Documents/Celsior/ as well as /Documents/Celsior/src/ as my project location, with no luck. \$\endgroup\$ – TheSunCat Apr 12 '19 at 14:11

I eventually figured it out, using libGDX as @Engineer suggested. The trick was to use a Pixbuffer object and write it to a Texture, then call buffer.draw on the texture every time a frame is rendered.

Setting up libGDX was also a bit tricky as I am not familiar with Gradle and prefer to use NetBean's compiler instead. I had to import the correct jars from a nightly build of libGDX as the setup tool offered insists on using Gradle. It was relatively easy to use afterwards, which is really nice.

For reference, I believe I just imported: gdx, gdx-natives, gdx-backend-lwjgl, and the font extension so I could load my text font and scale it according to the screen size.

I (think?) I accepted Engineer's answer and upvoted it, although I believe my vote doesn't count due to my low reputation. Whoops.

Here's a screenshot of the window in action: "Emulator" displaying contents of vram

| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.