JVic libGDX
Posted: Sun Jan 31, 2016 4:41 am
Hi all,
After seeing the posts from a few months back about VIC 20 emulators on Android, I thought I'd have a crack at working on something. I've never built an app for Android, but I am a Java developer with about 18 years experience, and I do have an Android phone. And I still have the source code for the JVic emulator I wrote back in 2003. So I started wondering if I could hack the JVic code to make it work on Android (I lost the C code for V20 many years ago, and besides, I haven't touched a line of C code since 1998).
Although I haven't built any Android apps, I've been wanting to give it a try. So I've been doing some reading here and there and it wasn't long before I took notice of a cross platform game development library called libGDX. The idea is that you write your code once, in Java, building it against the libGDX libraries, and it will in theory build a version that will run on Android, desktop, HTML5, and iOS.
When I started thinking about an Android version of JVic, the libGDX library quickly came to mind. I started thinking "Converting JVic to use libGDX will not only produce an Android version but I'd get an HTML5 nearly for free (apparently there are a few gotchas) and I might be able to put that up on my web site as replacement for the applet that browsers have in general refused to run in recent years". Applets are deader than dead, so I need a new approach to make JVic run in a browser.
So on Wednesday, I started putting the plan in to action. It began by installing libGDX and its dependencies (the Android SDK, etc). I'm ignoring iOS for now but given that libGDX can generate an iOS app, that might come later when I've got it polished on the Android. On that first night, it was all about the environment setup. By the end of the evening, I had the project files all set up in the eclipse IDE.
Then on Friday I dropped in the JVic source code and started looking over the bits that I would need to convert to the libGDX equivalent. We're obviously talking about things such as the graphics, asset loading, and the keyboard input. The libGDX library provides its own classes for handling these, and if you code to those classes, the app generation for the different platforms will map that to the platform specific equivalents. The JVic code was using the JVM classes for rendering graphics and getting keyboard input. I'll admit that I spent almost all of Friday night reading up on rendering a pixel array using libGDX. It's not particularly straight forward. Under the hood, all of the target platforms are using opengl for the graphics, so its all about sending commands to a GPU in an efficient way. Sending an array of pixels to the GPU on every frame isn't something that opengl is particularly designed for. It's more about trying to get the GPU to do as much as it can for you. I found a lot of people asking the same questions on the Internet, about what the fastest way to send an array of pixels to the GPU using opengl was. LibGDX does hide the opengl calls from you if you don't want to use them directly, but it also gives you easy access to the opengl APIs if you do want to use them. So I'd identified a number of possible solutions but most people seemed to be saying that the things they'd tried were too slow.
I did begin to wonder at that point if libGDX was the right choice. I had a look over the source code of other 8-bit home computer emulators for Android (such as BeebDroid and a couple of Spectrum emulators) and every example I found was using native code for the graphics, and for most of the app. I started thinking that that is what I should be doing. But then I thought "No, this is all about JVic, an emulator written in Java, so I should just give this a go with libGDX (which incidentally does use native code under the hood for a number of things) and see what happens". If it turned out to be too slow then I'd take a look at what I could do about it at that point.
So that was it for Friday's effort. All reading and not much coding.
Saturday night is where it all happened. It didn't take long to convert the keyboard input over to the libGDX equivalent (although for some reason I couldn't find a key mapping for the dollar sign! It just doesn't seem to be there; certainly not obvious if it is) and then the asset loading code (ROMs) followed quickly after. And then I began on the graphics conversion. My Vic chip emulation was already producing an array of RGB values that represented a frame. I'd identified a way that should allow me to send an array of pixels to the GPU. It supposedly wasn't the quickest way of doing it, but seemed to be the simplest, which is all I wanted at the time. I just wanted to see something get rendered. After I'd done the conversion, and it was compiling, I clicked run for the first time and suddenly I had a blinking cursor!
Now, there were a few things wrong with that blinking cursor. There were actually four blinking cursors, appearing at different parts of the screen, and it looked more grayscale that coloured. It was fairly obvious that the RGB pixel data was not in the right format. So I tweaked the format description being used with libGDX and that fixed that problem. I now had the VIC 20 BASIC screen with the flashing cursor, but the border was yellow, and the text was red. Clearly there was still something wrong with the RGB pixel encoding. After a while I figured out the RGBA bytes were in the wrong order. I switched them around a bit and hey presto, it was now rendering the correct colours.
That was getting quite late at night by that point, but I typed in a quick "Hello world" BASIC program, typed in RUN, and it all worked.
I'd been testing it on the "Desktop" platform up to that point, but just before retiring for the night, I thought I'd plug in my Android phone and click the "Run on Android" option. Do you know what? It actually worked. I had the same screen appear on my Android phone with a flashing cursor, and the flashing appears to be at the expected rate. There are several issues with it though. It's only taking up a very tiny part of the screen (I'd say maybe 1/25th of the screen) and I couldn't figure out how to bring up the keyboard. These will be trivial to solve. I was just really glad to see that tiny little VIC screen spring in to life on the phone and thought it was a good time to hit the sack.
Now that I've got that far, I think the next step is to get this in to github. I don't want the JVic source to go the way of the V20 source code. Now that I've posted this post, I'll try to add regular updates over the next few weeks.
Lance
After seeing the posts from a few months back about VIC 20 emulators on Android, I thought I'd have a crack at working on something. I've never built an app for Android, but I am a Java developer with about 18 years experience, and I do have an Android phone. And I still have the source code for the JVic emulator I wrote back in 2003. So I started wondering if I could hack the JVic code to make it work on Android (I lost the C code for V20 many years ago, and besides, I haven't touched a line of C code since 1998).
Although I haven't built any Android apps, I've been wanting to give it a try. So I've been doing some reading here and there and it wasn't long before I took notice of a cross platform game development library called libGDX. The idea is that you write your code once, in Java, building it against the libGDX libraries, and it will in theory build a version that will run on Android, desktop, HTML5, and iOS.
When I started thinking about an Android version of JVic, the libGDX library quickly came to mind. I started thinking "Converting JVic to use libGDX will not only produce an Android version but I'd get an HTML5 nearly for free (apparently there are a few gotchas) and I might be able to put that up on my web site as replacement for the applet that browsers have in general refused to run in recent years". Applets are deader than dead, so I need a new approach to make JVic run in a browser.
So on Wednesday, I started putting the plan in to action. It began by installing libGDX and its dependencies (the Android SDK, etc). I'm ignoring iOS for now but given that libGDX can generate an iOS app, that might come later when I've got it polished on the Android. On that first night, it was all about the environment setup. By the end of the evening, I had the project files all set up in the eclipse IDE.
Then on Friday I dropped in the JVic source code and started looking over the bits that I would need to convert to the libGDX equivalent. We're obviously talking about things such as the graphics, asset loading, and the keyboard input. The libGDX library provides its own classes for handling these, and if you code to those classes, the app generation for the different platforms will map that to the platform specific equivalents. The JVic code was using the JVM classes for rendering graphics and getting keyboard input. I'll admit that I spent almost all of Friday night reading up on rendering a pixel array using libGDX. It's not particularly straight forward. Under the hood, all of the target platforms are using opengl for the graphics, so its all about sending commands to a GPU in an efficient way. Sending an array of pixels to the GPU on every frame isn't something that opengl is particularly designed for. It's more about trying to get the GPU to do as much as it can for you. I found a lot of people asking the same questions on the Internet, about what the fastest way to send an array of pixels to the GPU using opengl was. LibGDX does hide the opengl calls from you if you don't want to use them directly, but it also gives you easy access to the opengl APIs if you do want to use them. So I'd identified a number of possible solutions but most people seemed to be saying that the things they'd tried were too slow.
I did begin to wonder at that point if libGDX was the right choice. I had a look over the source code of other 8-bit home computer emulators for Android (such as BeebDroid and a couple of Spectrum emulators) and every example I found was using native code for the graphics, and for most of the app. I started thinking that that is what I should be doing. But then I thought "No, this is all about JVic, an emulator written in Java, so I should just give this a go with libGDX (which incidentally does use native code under the hood for a number of things) and see what happens". If it turned out to be too slow then I'd take a look at what I could do about it at that point.
So that was it for Friday's effort. All reading and not much coding.
Saturday night is where it all happened. It didn't take long to convert the keyboard input over to the libGDX equivalent (although for some reason I couldn't find a key mapping for the dollar sign! It just doesn't seem to be there; certainly not obvious if it is) and then the asset loading code (ROMs) followed quickly after. And then I began on the graphics conversion. My Vic chip emulation was already producing an array of RGB values that represented a frame. I'd identified a way that should allow me to send an array of pixels to the GPU. It supposedly wasn't the quickest way of doing it, but seemed to be the simplest, which is all I wanted at the time. I just wanted to see something get rendered. After I'd done the conversion, and it was compiling, I clicked run for the first time and suddenly I had a blinking cursor!
Now, there were a few things wrong with that blinking cursor. There were actually four blinking cursors, appearing at different parts of the screen, and it looked more grayscale that coloured. It was fairly obvious that the RGB pixel data was not in the right format. So I tweaked the format description being used with libGDX and that fixed that problem. I now had the VIC 20 BASIC screen with the flashing cursor, but the border was yellow, and the text was red. Clearly there was still something wrong with the RGB pixel encoding. After a while I figured out the RGBA bytes were in the wrong order. I switched them around a bit and hey presto, it was now rendering the correct colours.
That was getting quite late at night by that point, but I typed in a quick "Hello world" BASIC program, typed in RUN, and it all worked.
I'd been testing it on the "Desktop" platform up to that point, but just before retiring for the night, I thought I'd plug in my Android phone and click the "Run on Android" option. Do you know what? It actually worked. I had the same screen appear on my Android phone with a flashing cursor, and the flashing appears to be at the expected rate. There are several issues with it though. It's only taking up a very tiny part of the screen (I'd say maybe 1/25th of the screen) and I couldn't figure out how to bring up the keyboard. These will be trivial to solve. I was just really glad to see that tiny little VIC screen spring in to life on the phone and thought it was a good time to hit the sack.
Now that I've got that far, I think the next step is to get this in to github. I don't want the JVic source to go the way of the V20 source code. Now that I've posted this post, I'll try to add regular updates over the next few weeks.
Lance