Let’s write a Chip8 emulator in Kotlin [Part 0: Motivation & Setup]

Disclaimer

This series is a means for me to learn Kotlin. As such i might misuse some features of Kotlin, not follow best practices or simply to silly things. Please always check the comment section for feedback from more knowledgable people. I’ll also have follow up articles where i refactor the code to be more idiomatic. So, make sure to check back.

Why?

I recently started looking into alternative JVM languages. After a short interaction with Scala, i looked into JetBrains’ Kotlin. When learning a new language/platform, i usually write a simple application that allows me to iteratively explore new concepts and features. For my adventure in Kotlin i chose to write a Chip8 emulator.

My goals with this little series are as follows:

  • Learn a bit of Kotlin
  • Document my journey
  • Get feddback from Kotlin users
  • Show how to write a simple emulator

My non-goals are:

  • Teach anyone Kotlin, use the official docs if you want to learn it all
  • Write the most efficient and precise Chip8 emulator

Let’s get going.

Setting up a Kotlin project

As stated earlier, i’m not going to try and teach anyone Kotlin given my knowledge level. Instead i’ll comment on the tooling surrounding Kotlin. What i present may not be best practices but it’s what has worked for me.

The project i’m going to set up has to fulfil these requirements:

  1. Build management and packaging
  2. Dependency management
  3. IDE integration
  4. Version control

Requirements 1 and 2 can be achieved by choosing one or combining multiple of the following tools: Ant, Ivy, Maven, Gradle, SBT and so on. I’m going to use Gradle as there exists a first class Gradle plugin for Kotlin. It’s also quite a bit less verbose than Maven and hence suitable for a textual series like this.

Being a brain-child of JetBrains, Kotlin has first class support in Intellij IDEA, so that’s what i’m going to use. Quite a change for an Eclipse guy like me.

On the version control front i’m going to go with Git, hosting a repository on Github.

Given these choices, i need to install the following:

  • Latest JDK (make sure the bin/ folder is in your PATH)
  • A Git client (TortoiseGit on Windows, on Linux use your package manager, on Mac OS X use homebrew to get the latest and greatest)
  • Intellij IDEA 13 (community edition will do)
  • Gradle (make sure the bin/ folder is in your path)

Project Structure, Build and Dependency Management

Let’s start by setting up a few folders and files for our project. We’ll add a build.gradle file describing our Gradle build first:

buildscript {
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:0.8.11'
  }
}

apply plugin: "kotlin"
apply plugin: "java"

repositories {
  mavenCentral()
}

dependencies {
  compile 'org.jetbrains.kotlin:kotlin-stdlib:0.8.11'
}

project.ext.mainClassName = "chip8.Chip8Package"

task run(dependsOn: classes, type: JavaExec) {
    main = project.mainClassName
    classpath = sourceSets.main.runtimeClasspath
    standardInput = System.in
    ignoreExitValue = true
}

task dist(type: Jar) {
    from files(sourceSets.main.output.classesDir)
    from files(sourceSets.main.output.resourcesDir)
    from {configurations.compile.collect {zipTree(it)}}
 
    manifest {
        attributes 'Main-Class': project.mainClassName
    }
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.1'
}

The buildscript block is required to pull in the Kotlin Gradle plugin (line 6). Line 10 and 11 specify that this project uses both the Kotlin and Java plugin, allowing us to mix and match the two languages if required. Next we define the repositories from where dependencies are fetched. For now, the only required dependency is the Kotlin standard library (line 18). Finally i added two tasks (run, dist) to run the project and package it into a JAR for distribution. Note line 21 where i define the main class. That class name is used by the run and dist to execute our app and package our app as a runnable JAR respectively.

The wrapper task pulls the Gradle wrapper files into our project structure. This will allow other people to work with the project without installing Gradle themselves.

The last missing bit is a source folder and main entry point. Per convention, the Kotlin source files are placed under src/main/kotlin, Java source files are put into src/main/java. Tests go into src/test/kotlin and src/test/java respectively. I put a very simple Hello-World style Kotlin app in src/main/kotlin/chip8/main.kt:

package chip8;

fun main(args: Array) {
   println("Hello World")
}

Where is the Chip8Package class we defined as the main class in the build.gradle file? Turns out that Kotlin will put all top-level functions of a package into a synthetic class called <Packagename>Package. We therefor have to specify that synthetic class for the JVM to run our main function.

Before moving on, we’ll invoke the wrapper task to pull the Gradle wrapper into our project:

chip8$ gradle wrapper

The wrapper is composed of two script files (gradlew for *nix and gradlew.bat for Windows) and a folder called gradle/ which contains a tiny JAR and a properties file. From now on, we’ll invoke the script files (gradlew, gradlew.bat) in our project directory.

Running the app on the command line is as simple as calling the run task:

chip8$ ./gradlew run
Downloading https://services.gradle.org/distributions/gradle-2.1-bin.zip
.............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Unzipping /Users/badlogic/.gradle/wrapper/dists/gradle-2.1-bin/2pk0g2l49n2sbne636fhtlet6a/gradle-2.1-bin.zip to /Users/badlogic/.gradle/wrapper/dists/gradle-2.1-bin/2pk0g2l49n2sbne636fhtlet6a
Set executable permissions for: /Users/badlogic/.gradle/wrapper/dists/gradle-2.1-bin/2pk0g2l49n2sbne636fhtlet6a/gradle-2.1/bin/gradle
:compileKotlin
warning:Annotations path entry points to a non-existent location: 
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:run
Hello World

BUILD SUCCESSFUL

Total time: 59.466 secs

Note that we now use the gradlew script instead of our local Gradle installation. The first time the wrapper is invoked, it downloads the Gradle version we specified in the wrapper task and installs it. This may take some time but won’t be repeated on subsequent invocations.

We can also package our app as a runnable JAR via the dist task and run that JAR:

chip8$ ./gradlew dist
chip8$ java -jar build/libs/chip8.jar

The project layout now looks like this:

chip8/
   build.gradle   
   src/
      main/
         kotlin/
            main.kt
   gradlew
   gradlew.bat
   gradle/
      wrapper/
         gradle-wrapper.jar
         gradle-wrapper.properties

IDE Integration

Before we can import our project into Intellij IDEA, we need to install the IDEA Gradle plugin. Fire up IDEA, on the welcome screen go to Configure->Plugins, click on Install JetBrains plugin, search for Kotlin and install the plugin.

We can now import the project by clicking on Open Project on the welcome screen, navigating to the project folder and select the build.gradle file. IDEA will ask us some specifics about our Gradle project. Make sure to select Use customizable gradle wrapper, so IDEA uses our wrapper properly.

Once loaded, we can run our main function. The simplest way to do this is to open up the main.kt file in IDEA, right click and select Run 'chip8.Chip8Package':

This will also create a configuration for us which we can use to launch and debug the app later on. Speaking of debugging, it works as you expect. Simply create a breakpoint in a source file in the line number margin on the left and start your app in debug mode:

Version Control

Time to push our master piece to Github. I created a Github repository called chip8 which you can follow along. Since we already have a folder, we can initialize the repository with a few magic incantations on the command line:

chip8$ git init
chip8$ git remote add origin https://github.com/badlogic/chip8.git

We should also create a .gitignore file so we don’t commit the build directory, IDEA project files and so forth:

.DS_STORE
.idea/
.gradle/
build/
target/
*.iml

Let’s add our initial set of files, commit and push them to the remote repository:

chip8$ git add
chip8$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached ..." to unstage)

	new file:   .gitignore
	new file:   build.gradle
	new file:   gradle/wrapper/gradle-wrapper.jar
	new file:   gradle/wrapper/gradle-wrapper.properties
	new file:   gradlew
	new file:   gradlew.bat
	new file:   src/main/kotlin/chip8/main.kt
chip8$ git commit -m "initial commit"
chip8$ git push -u origin master

Let’s also tag this state:

chip8$ git tag -a part0 -m "part0"
chip8$ git push --tags

And we are done!

Up Next

You can now simply clone the repository and follow along the rest of the series, provided you installed all the tools we talked about earlier.

In the next article we’ll write a simple Chip8 ROM disassembler.

Following Along

  1. Install the required tools (JDK, IDEA, IDEA Kotlin plugin, Git)
  2. Clone the repo: git clone https://github.com/badlogic/chip8.git
  3. Checkout the tag for the article you want to work with: git checkout part0
  4. Import the project into IDEA (Open Project, select build.gradle file, select "Use customizable gradle wrapper"

Happy coding!

libGDX wins Duke’s Choice Award

Damn right. The Duke’s Choice Award is an anual thing given out by a jury of judges as well as the community to projects from the Java realm based on various criteria. It’s one of the biggest honors you can get in the Java world. Here’s the Java Magazine article on the winners, including my ugly face, Robotality’s Halfway and Interrupt’s Delver (which you should both buy and play the hell out of):

The story behind that photo is actually quite funny. Oracle send a photographer from the Netherlands to my place in Graz, via car. He took about 500 images. I felt very special that day…

Thanks to all the contributors, this award goes out to all of you (you can put it on your resume :D).

Intel RealSense App Challenge 2014 – Be part of it!

If you are interested in RealSense Technology check out the Intel RealSense App Challenge. RealSense is a suite of software and optional hardware that let’s you explore human computer interaction.

Check out this video from last year’s winning entries:

Intel just released their latest RealSense SDK and Developer Kit, with which you can take part in this years challenge! There are two tracks, Pioneer and Ambassador. Members of the libGDX community can participate in the Pioneer’s track, which consists of two phases:

  • Ideation Phase: register as a pioneer and submit an app idea until the 1st of October (next week!)
  • Development Phase: if your idea was chosen by a panel of judges, you will enter the development phase where you can realize your app idea using Intels’ RealSense SDK

Learn More about the contest and what winners receiver here: https://realsenseappchallenge.intel.com/landing/

If you send an app idea using libGDX (which will support RealSense soon!), let us know in the comments below!