libGDX 1.5.2 released (updated)

edit: well, i’m a bit of a terrible programmer person and botched the update of LWJGL on Mac OS X. Just released libGDX 1.5.2 for that reason. The below still applies :)

Hi!

time for a new release. Here’s what changed:

[1.5.2]
- Fixed issue #2433 with color markup and alpha animation. 
- Fixed natives loading for LWJGL on Mac OS X
[1.5.1]
- Gradle updated to 2.2
- Android Gradle tooling updated to 1.0.0
- API Change: Switched from Timer to AnimationScheduler for driving main loop on GWT. Removed fps field from GwtApplicationConfiguration to instead let the browser choose the most optimal rate.
- API Change: Added pause and resume handling on GWT backend. When the browser supports the page visibility api, pause and resume will be called when the tab or window loses and gains visibility.
- API Change: Added concept of target actor, separate from the actor the action is added to. This allows an action to be added to one actor but affect another. This is useful to create a sequence of actions that affect many different actors. Previously this would require adding actions to each actor and using delays to get them to play in the correct order.
- Added 64-bit support for iOS sim and device
- Deprecated Node#children and Node#parent, added inheritTransform flag and methods to add/get/remove children
- API Change: By default keyframes are no longer copied from Model to ModelInstance but shared instead, can be changed using the `ModelInstance.defaultShareKeyframes` flag or `shareKeyframes` constructor argument.
- JSON minimal format now makes commas optional: newline can be used in place of any comma.
- JSON minimal format is now more lenient with unquoted strings: spaces and more are allowed.
- API Change: Added support for KTX/ZKTX file format, https://github.com/libgdx/libgdx/pull/2431
- Update stb_image from v1.33 to v1.48, see https://github.com/libgdx/libgdx/pull/2668
- Bullet Wrapper: added Gimpact, see https://github.com/libgdx/libgdx/issues/2619
- API Addition: Added MeshPartBuilder#addMesh(...), can be used to more easily combine meshes/models
- Update to LWJGL 2.9.2, fixes fullscreen mode on "retina" displays
- Fixes to RoboVM backend which would crash if accelerometer is used.

Starting with this release we’ll also relax our versioning a little bit. We will not increase the minor version in case of minimal API changes as above.

Let us know if you run into any issues. See this wiki article on how to update your libGDX project to the latest version. The current libGDX version is “1.5.2”, the current nightly version is “1.5.3-SNAPSHOT”, OR you can just check our versions page which details all the versions of dependencies as well.

Let’s write a Chip8 emulator in Kotlin [Part 2: The first refactoring]

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.

Refactoring

Part of learning a new language is to get to know the idioms. Thanks to feedback on the last articles, i have a pretty good idea how to reorganize the code to make it more maintainable and concise. Let’s get going.

Moving things around

In the previous article we created a few top-level methods, loadRom, decode, and disassemble. I put them in different files. Let’s clean that up. We want a single file that contains the top-level methods that make up the functionality of the emulator. (Chip8.kt).

package chip8;

import java.io.DataInputStream
import java.io.BufferedInputStream
import java.io.FileInputStream

fun loadRom(file: String): VmState {
    ...
}

fun decode(decoder: Decoder, address:Int, msb: Byte, lsb: Byte) {
    ...
}

fun disassemble(vmState: VmState): String {
    ...
}

That cleans up the files Disassembler.kt, main.kt. I think i’ll make it a habit to put top-level functions of a package into a file named after the package itself.

Extension properties instead of extension methods

We added a few extension methods to Int and Byte in the previous article. Ioannis Tsakpinis of LWJGL fame and avid Kotlin user pointed out a better way to handle these extensions. We’ll make them extension properties instead of extension methods (Extensions.kt):

val Int.hex: String get() = Integer.toHexString(this)
val Byte.hex: String get() = Integer.toHexString(this.toInt())
val Byte.hi: Int get() = (this.toInt() and 0xf0) shr 4
val Byte.lo: Int get() = this.toInt() and 0xf

I renamed the properties to shower names and fixed up any code relying on the old extension methods accordingly. This makes our decode function a lot more concise, e.g.

0x5 -> decoder.jeqr(msb.low(), lsb.high())

turns into

0x5 -> decoder.jeqr(msb.lo, lsb.hi)

It also cleans up our Disassembler, which is our next refactoring victim.

Shorter single line methods

Disassembler is composed of single line methods for the most part. We can omit all the curly braces and new lines, turning

override fun call(address: Int) {
    builder.line("call 0x${address.toHex()}")
}

into

    override fun call(address: Int) = builder.line("call 0x${address.hex}")

As per the definition of Decoder implemented by Disassembler, all of these methods need to return Unit. For Disassembler#before and Disassembler#unknown we can’t just apply the single line style. Remember, the return type of a single line style function is the type of the expression of that single line. In case of these two methods, we call StringBuilder#append, which returns the StringBuilder. That is obviously not of type Unit.

We can apply a trick pointed out by Andrey Breslav of Kotlin fame: create an Extension method called unit that returns, you guessed it, Unit. Let’s modify Disassembler.kt:

class Disassembler(): Decoder {
    val builder = StringBuilder()
    fun Any?.unit() {}
    override fun before(opCode: Int, address: Int) = builder.append("addr: 0x${address.hex}, op: 0x${opCode.hex}, ").unit()
    override fun unknown(opCode: Int, address: Int) = builder.append("Unknown opcode addr: 0x${address.hex}, op: 0x${opCode.hex}").unit()
    // as before...

Note the fun Any?.unit() {} extension method. It’s attached to any object (!= null) within the scope of Disassembler (i think). We can then rewrite the before and unknown methods to single line style, calling unit() to make the expression’s type Unit in accordance to our Decoder trait.

You can see the entire refactoring diff on Github.

Up Next

Next time we are going to write our first iteration of a simple interpreter.

Previously

Let’s write a Chip8 emulator in Kotlin [Part 0: Motivation & Setup]
Let’s write a Chip8 emulator in Kotlin [Part 1: A simple 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 part2
  4. Import the project into IDEA (Open Project, select build.gradle file, select "Use customizable gradle wrapper"

Stage API changes: Viewport added

noone had a great idea, to provide a Viewport class for determining how world coordinates are scaled to screen coordinates. This was already possible using Camera of course, but it was not noob friendly. Viewport is standalone and just manages a Camera. This means any app that uses Camera can use Viewport to control the strategy for scaling the world to the screen. For example, maybe you want to stretch the world to the screen, or scale it up without changing the aspect ratio by using black bars.

After a couple iterations we’ve now integrated the Viewport class. It’s quite slick, you just pick from one of the ready made Viewport implementations and you’re good to go. See the nice wiki page for docs.

Here’s where I tell you about the pain you are in for! It makes sense for Stage to have a Viewport instead of a Camera (remember Viewport has a Camera). This makes controlling scaling for scene2d super easy, but the bad part is Stage had to change. Instead of telling the Stage the viewport size, you give it a Viewport instance that does what you want.

If your old Stage construction code looked like this:

stage = new Stage(width, height, false); // OR
stage.setViewport(width, height, false);

Then you need to change it to:

stage = new Stage(new StretchViewport(width, height)); // OR
stage.setViewport(new StretchViewport(width, height));

If your old code looked like this:

stage = new Stage(width, height, true); // OR
stage.setViewport(width, height, true);

Then you need to change it to:

stage = new Stage(new ExtendViewport(width, height)); // OR
stage.setViewport(new ExtendViewport(width, height));

There is another important change, resize used to look like:

public void resize (int width, int height) {
    stage.setViewport(width, height);
}

Now you’ll do this:

public void resize (int width, int height) {
    stage.getViewport().update(width, height, true);
}

The boolean centers the camera if true (only really needed for UIs). It can be omitted, which is the same as false.

The other changes that may affect you are where you are using the Stage’s Camera. You can use stage.getViewport().getCamera(), but note that Viewport has project/unproject methods that should be used instead, since they take the viewport into account.

Not too bad for you guys I hope!