Archive

Archive for the ‘Android’ Category

My new game development book got published

October 10, 2015 Leave a comment

Some people may have noticed a drop in published content on this blog for a while. Part of it was due to working on a new book for Packt Publishing, titled ‘Mastering AndEngine Game Development’, which was finalised last month with its publication. For those interested, it can be purchased both at the Packt store [1] and at Amazon [2].

What this book is, is an in-depth look at how to go from ‘making a basic mobile game’ using a game engine such as AndEngine [3], to making a truly advanced (mobile) game using 3D assets in a 2D game with OpenGL ES, dynamic and static lighting, frame-based and skeletal-based animation, anti-aliasing, GLSL shaders, 3D sound and advanced sound effects using OpenAL & OpenSL, and much more. While it’s aimed at extending AndEngine-based games, it’s written in a generic enough manner that it should be useful for those using other game engines, on Android or other platforms.

So far this is my first published book, but it probably won’t be my last. In the meantime I will try to step up the publication of content on this blog again, both with programming and electronics-related postings. Please stay tuned πŸ™‚

Maya

[1] https://www.packtpub.com/game-development/mastering-andengine-game-development
[2] http://www.amazon.com/Mastering-AndEngine-Game-Development-Posch/dp/1783981148/
[3] http://www.andengine.org/

Advertisements

Java On Android TCP Socket Issue

August 8, 2013 1 comment

Related to my previous post [1] involving a project using Java sockets, I’d like to post about an issue I encountered while debugging the project. Allow me to first describe the environment and set up.

The Java side as an extended version of the class described in the linked post ran as client on Android, specifically a Galaxy Nexus device running Android 4.2.2 and later 4.3. Its goal was to send locally collected arrays of bytes via the socket to the server after connecting. The server was written in C++ with part of the networking side handled by the Qt framework (QTcpServer) and the actual communication via native sockets on a Windows 7 Ultimate x64 system.

The problem occurred upon the connecting of the Android client to the server: the connecting would be handled fine, the thread to handle the native socket initialized and started as it should be. After that however the issue was that never any data would be received on the server-side of the client socket. Checks using select() showed that there never arrived any data in the buffer. Upon verification with a telnet client (Putty) it turned out that the server was able to receive data just fine, and thus that the issue had to lie with the client side, i.e. the Android client.

Inspection using the Wireshark network traffic sniffer during the communication between the Android client and the server showed a normal TCP sequence, with SYN, SYN-ACK and ACK packets followed by a PSH-ACK from the client with the first data. This followed by an ACK from the server, indicating that the server network stack had at least acknowledged the data package. Everything seemed in order, although it was somewhat remarkable that the first client-side ACK had the exact same timestamp in Wireshark as the PSH-ACK packet.

Mystified, I stumbled over a few posts [2][3] on StackOverflow in which it was suggested that using Thread.sleep() after the connecting phase would resolve this. Trying this solution with a 500 ms sleep period I found that suddenly the client-server communication went flawlessly. My only question hereby is why this is the case.

Looking through the TCP specifications I didn’t find anything definite, even though the evidence so far suggests that the ACK on SYN-ACK can not be accompanied by a PSH or similar at the same time. Possibly that something else plays a role here, but it seems that the lesson here is that in case of non-functioning Java sockets one just has to wait a little while before starting to send data. I’d gladly welcome further clarification on why this happens.

Maya

[1] https://mayaposch.wordpress.com/2013/07/26/binary-network-protocol-implementation-in-java-using-byte-arrays/
[2] http://stackoverflow.com/questions/5326652/java-socket-read-not-receiving-write-sent-immediatly-after-connection-is-establi
[3] http://stackoverflow.com/questions/17073045/why-does-java-send-needs-thread-sleep

Binary Network Protocol Implementation In Java Using Byte Arrays

July 26, 2013 2 comments

Java in many ways is a very eccentric programming language. Reading the designer’s responses to questions on its design lead to interesting ideas, such as that unsigned integer types would be confusing and error-prone to the average programmer. There’s also the thought that Java is purely object-oriented, even though it has many primitive types and concepts lurking in its depths. Its design poses very uncomfortable issues for developers who seek to read, write and generally handle binary data and files, as the entire language seems to be oriented towards text-based formats such as XML. This leads one to such problems as how to implement a basic binary networking protocol.

Many network and communication protocols are binary as this makes them easier and faster to parse, more light-weight to transfer and generally less prone to interpretation. The question hereby is how to implement such a protocol in a language which is wholly unfamiliar with the concepts of unsigned integers, operator overloading and similar. The most elegant answer I have found so far is to stay low-level, and I really do mean low-level. We will treat Java’s built-in signed integers as though they are unsigned using bitwise operators where necessary and use byte-arrays to translate between Java and the outside world.

The byte type in Java is an 8-bit signed integer with a range from -128 to 127. For our purposes we will ignore the sign bit and treat it as an unsigned 8-bit integer. Network communication occurs in streams of bytes, with the receiving side interpreting it according to a predefined protocol. This means that to write on the Java side to the network socket we will have to put the required bytes into a prepared byte array. As Java arrays are fixed size like in C, it makes the most sense to either use one byte-array per field or to pre-allocate the whole array and copy the bytes into it.

Writing is done into the Java Socket via its OutputStream which we wrap into a BufferedOutputStream.

public class BinaryExample {
	Socket mSocket;
	String mServer = "127.0.0.1";
	int mServerPort = 123;
	byte[] header = {0x53, 0x41, 0x4D, 0x50, 0x4C, 0x45}; // SAMPLE
	int mProtocolVersion = 0;
	OutputStream mOutputStream;
	InputStream mInputStream;
	BufferedOutputStream mBufferedOutputStream;

	public void run() {
		try {
			// set up connection with server
			this.mSocket = new Socket(mServer, mServerPort);
		} catch (Exception ee) {
			return;
		}

		// get the I/O streams for the socket.
		try {
			mOutputStream = this.mSocket.getOutputStream();
			mBufferedOutputStream = new BufferedOutputStream(mOutputStream);
			mInputStream = this.mSocket.getInputStream();
		} catch (IOException e) {
			e.printStackTrace();
			return;
		}

		byte version = (byte) mProtocolVersion;
		int messageLength = 4 + header.length + version.length;
		byte[] msgSize = intToByteArray(messageLength);

		// write to the socket
		try {
			mBufferedOutputStream.write(msgSize);
			mBufferedOutputStream.write(header);
			mBufferedOutputStream.flush();
		} catch (IOException e1) {
			e1.printStackTrace();
		}

		// Writes provided 4-byte integer to a 4 element byte array in Little-Endian order.
		public static final byte[] intToByteArray(int value) {
			return new byte[] {
				(byte)(value & 0xff),
				(byte)(value >> 8 & 0xff),
				(byte)(value >> 16 & 0xff),
				(byte)(value >>> 24)
			};
		}
	}
}

Any ASCII strings in the protocol we define as individual bytes. Fortunately the ASCII codes only go to 127 (0x7F) and thus fit within the positive part of Java’s byte type. For values stretching into the negative range of the byte we might have to use bit masking to deal with the sign bit, or do the conversion ourselves. We define the protocol version as an int (BE signed, 32-bit), which we convert to a byte using a simple cast, stripping off the higher three bytes. Again pay attention to the value of the int. If it’s higher than 127 you have to deal with the sign bit again or risk an overflow.

In this example we implement a lower-endian (LE) protocol. This means that in converting to a byte array from a 16-bit or larger integer we have to place the LSB first, as is done in the function intToByteArray(). We also add a message length indicator at the beginning of the message we’re sending in the form of an int, extending the message by 4 bytes.

Reading the response and interpreting it is similar:

		// wait for response. This is a blocking example.
		byte[] responseBytes = new byte[5];
		int bytesRead = 0;
		try {
			bytesRead = mInputStream.read(responseBytes, 0, 4);
		} catch (IOException e1) {
			e1.printStackTrace();
		}

		if (bytesRead != 5) {
			// communication error. Abort.
			return;
		}

		// the fifth byte now contains the value of the response code. 0 means OK, everything else is an error.
		short responseCode = (short) responseBytes[4];
		if (responseCode != 0) { return; }

This is a brief and naive sample which just has to read a single response, skipping the message length indicator and reading just five bytes. In a more complex application you would convert the individual sections of the byte array to their respective formats (strings, ints, etc.) and verify them. For this you would use a function to invert from LE-order byte array to BE-order int such as the following:

	// Writes provided 4-byte array containing a little-endian integer to a big-endian integer.
	public static final int byteArrayToInt(byte[] value) {
		int ret = ((value[0] & 0xFF) << 24) | ((value[1] & 0xFF) << 16) |
					((value[2] & 0xFF) << 8) | (value[3] & 0xFF);

		return ret;
	}

In many ways it’s ironic that bit shifts and bitwise operators are the way to go with a language which profiles itself as a high-level language, but such is the result of the design choices made. While it is true that the above byte array-oriented code could be encapsulated by fancy classes which would take the tediousness out of implementing such a protocol, in essence they would do the exact same as detailed above. With the upcoming Java 8 release unsigned integers will be introduced for the first time in a limited manner, but for most projects (including Android-based ones) it’s not an option to upgrade to it.

For reference, the above code is used in an actual project I’m working on and is as far as I am aware functional. I can however not accept any liability for anything going haywire, applications crashing, marriages torn up or pets set on fire. Any further checks and handling of errors is probably an awesome idea to make the code more robust.

Maya

Getting Started With jPCT-AE 3D Game Engine

August 9, 2011 1 comment

Today I got started with the jPCT-AE game engine for Android (http://www.jpct.net/jpct-ae/). Even with the shortage of documentation, it’s not too hard to figure out how to use it. Download the release, get the single JAR file and put it into a ‘libs’ folder you create in the root folder of the Android project. In Eclipse you then open the project properties, Java Build Path option and add the JAR from there to the project. Congratulations, you just installed jPCT for Android πŸ™‚

The ‘Hello World’ demo project as presented in the jPCT wiki shows quite well how to use the API, though you have to use the documentation provided in the release ZIP file to get a full understanding of its workings. I won’t replicate the entire demo project here, but you can find it in the wiki: http://www.jpct.net/wiki/index.php/Hello_World_for_Android

You first initialize the engine, set upΒ  (http://developer.android.com/reference/android/opengl/GLSurfaceView.html) to act as a rendering surface for the renderer. The renderer is connected to this surface and everything moves from there. You can use the input events from the touchscreen (touch, move, etc.) to manipulate the game world.

The basics of the renderer function are as follows:

world = new World();
world.setAmbientLight(20, 20, 20);

sun = new Light(world);
sun.setIntensity(250, 250, 250);

// Create a texture out of the icon...:-)
Texture texture = new Texture(BitmapHelper.rescale(BitmapHelper.convert(getResources().getDrawable(R.drawable.icon)), 64, 64));
TextureManager.getInstance().addTexture("texture", texture);

cube = Primitives.getCube(10);
cube.calcTextureWrapSpherical();
cube.setTexture("texture");
cube.strip();
cube.build();

world.addObject(cube);

Camera cam = world.getCamera();
cam.moveCamera(Camera.CAMERA_MOVEOUT, 50);
cam.lookAt(cube.getTransformedCenter());

SimpleVector sv = new SimpleVector();
sv.set(cube.getTransformedCenter());
sv.y -= 100;
sv.z -= 100;
sun.setPosition(sv);

Very easy to get started with. With the demo running, you’ll see a cube on the screen with the standard Android icon used as texture. Touching the screen allows you to spin and manipulate the cube. Hello indeed πŸ™‚

Next up is creating something more closely resembling a game world, and play with the lighting. Expect screenshots soon πŸ™‚

Until then,

Maya

Categories: Android, jPCT-AE, programming

Getting Started With Android Development

August 9, 2011 10 comments

Before I start off with the whole development series, I’d like to talk about how to get started with Android development and my thoughts on some parts of it. I already gave some of my thoughts on parts of it in the previous post, but I would like to expand on them.

I started with Android development early this year, deciding it would be nice to get started on this fancy smartphone thing. There are four options total if you want to get into smartphone development: iOS from Apple, Android from Google, Windows Phone 7 (WP7) from Microsoft and WebOS from Hewlett-Packard (HP). Development environments for these platforms are as follows: Objective-C, custom Java version with most of the standard Java library replaced, C#, and C++.

In terms of development ease, WP7 and iOS rank pretty high. They also feature fast and accurate emulators to test applications without having to resort to testing on a hardware device. Often the emulator is faster than the real hardware. In comparison, Android makes for a frankly rather poor showing.

The Android SDK emulator uses VirtualBox code as its base for ARM emulation, but only runs in interpreted mode, meaning that all of the virtual hardware’s registers and GPU actions are all run in software. This results in a speed penalty compared to the real hardware of between 10x and 100x. In brief this means that when it’s emulating a 1 GHz single-core ARM chip (Cortex A8 or so), the emulated speed makes it comparable to maybe 10-100 MHz. The GPU part will be even more slow, as doing OpenGL and similar operations in software is just beyond slow.

In short, this means that you won’t be using the emulator much and should basically consider it only as a bridging method until you can get your hands on a real hardware device. I got a Huawei IDEOS X5 U8800 for this reason. This is a mainstream to high-end phone, with an 0.8-1 GHz Cortex-A8 CPU, one of the better mobile GPUs currently available for smartphones. Uploading an application to it via USB and running applications on it, even the more demanding ones is painless, quick and makes using the emulator afterwards an extremely painful experience. Summarized, get a real Android device for testing πŸ™‚

While WP7 and iOS use standard languages with standard APIs, Android is the odd one out. Knowing Java before programming for Android isn’t required and probably will just confuse you in some parts. Google thought that things like non-blocking (non-modal) dialogue windows were a good idea, meaning that you can’t ask for user input and wait for the dialogue to return. Code will be branching off all the time, ensuring that you keep having to patch up unexpected behaviours. In many ways the API feels immature and incomplete.

I have a lot of C++/Qt experience, and I must say that while similar to Android in some respects, the former is mature, feature-complete and always has new ways to make things run more efficiently. The latter needs a lot more work before it can be called mature. Considering that Android is still very new this isn’t surprising, especially with Google not investing much time and effect into it in the beginning.

Why I chose Android instead of iOS or WP7 is largely because of the costs and troubles involved in getting your applications out there. Both IOS and WP7 are very much walled gardens, with having to pay to be recognized as a developer, having to get one’s application approved before it can be sold on the single application market for the platform, and so on. Android is attractive because it’s free, open and offers the most freedom. Even if the API and tools aren’t as shiny. Android marketshare is growing the most rapidly because of this reason too, causing a big demand for Android developers.

The best IDE for Android development is Eclipse combined with the ADT plugin. This offers the best level of integration with ADB, the tool used to push applications onto a phone and retrieve data, but also with the debugger and such. There’s the IntelliJ IDEA IDE, but its level of Android integration isn’t nearly as refined.

So there you have it, a big rant from an Android developer why she dislikes the platform she develops for and why it’s still the best platform πŸ™‚

Maya

Categories: Android, programming

Here’s The Traditional ‘Hello World!’

August 8, 2011 2 comments

Welcome to the first post on this new blog. Here I’d like to talk a bit about what you can expect to find here the coming time. For details about myself, I’ll refer you to my personal website. All I’ll say regarding myself is that I have been a professional software developer for a number of years now, and have experience with a wide variety of languages and tools. How’s that for qualifications? πŸ™‚

The primary reason why I’m starting this blog is to detail the development of a new Android game I recently came up with. I have been professionally programming for the Android platform since early this year and have developed a number of applications, including for other companies. While I do not particularly enjoy programming in Java (I’m more of a procedural-style C/C++ programmer by preference), smartphones nevertheless are an interesting platform to develop games for, if only because of the radically different interface and mobility compared to a PC and laptop.

While I won’t be spilling the beans on the game’s idea yet, I will be blogging about the low-level issues I encounter and the libraries, game engine, etc. I will be using. I’ll also be blogging about Android and other programming issues not directly related to the game. You may encounter posts about C++, ASM, VHDL and a variety of other languages I use too, so be prepared πŸ™‚

Back to the game. The main issue with developing games for Android or basically any kind of application which is heavy on multimedia is the lack of support for advanced audio features in particular. While OpenGL ES (1.0, 1.1, 2.0) is supported, with ES 2.0 common in recent phones, there’s no audio support beyond basic stereo audio. IOS on the iPhone/iPad has had OpenAL support since the beginning, and video codec support is also very strong. Assuming you stick to the Apple-endorsed formats, naturally.

Only with Android 2.3 did we get OpenSL support, a kind of competitor to OpenAL developed by Khronos. Both are 3D positional audio libraries and APIs, so beyond the annoyance of porting existing audio code between both APIs, it’s good to have native support. Unfortunately Android 2.3 isn’t that widely used yet, with the Android Market statistics showing a usage of under 25%: http://developer.android.com/resources/dashboard/platform-versions.html

Android 2.1 and 2.2 combined still account for a marketshare of about 71%, making them the main targets for development. Other Android versions – including 3.x – can be basically ignored at this point. The target I use for my Android development is 2.1 and up, although I suspect that most if not all of the applications developed by me also run on 1.6. Anyway, our target for new development clearly should be 2.1, which will make it run on all Android devices but the 3.3% which runs 1.5 and 1.6 and no doubt run on antiquated hardware.

Then the OpenGL version. Again, we look at the Android Market: http://developer.android.com/resources/dashboard/opengl.html

Clearly OpenGL ES 2.0 is the way to go, with over 90% marketshare. If the game engine we end up using supports 1.1 as well, then that’s just a bonus. Next, for screen resolutions. Here we see that normal screens at hdpi densities are most common. This means WVGA800 (480×800), WVGA854 (480×854) and 600×1024 with a DPI of 240, according to the Android documentation. My own Android device (Huawei U8800 IDEOS X5) is an 800×480 device with ~240 DPI, running Android 2.2.3.

Finally, back to audio. If on sub-2.3 versions of Android we do not have access to a proper audio API for games, what should we do? The best answer I have found is to use a ported version of OpenAL Soft, the non-hardware-accelerated version of OpenAL. Instructions on how to use it can be found here: http://pielot.org/2010/12/14/openal-on-android/

There are some issues with OpenAL on Android, particularly due to the underlying audio hardware often not being designed for low-latency operations. Do be aware of this and be mindful of the limitations of the platform. I only intend to use basic positional sound for this reason in the game.

At long last, the game engine. After looking around for a few days, I think I have found the best engine for Android in terms of feature set and documentation: http://www.jpct.net/jpct-ae/. This is the Android port of the jPCT Java-based game engine. It’s fairly basic and doesn’t take too much time to understand. From what I gather it should have complete OpenGL ES 2.0 support soon: http://www.jpct.net/forum2/index.php/topic,2067.0.html. It’s also a 3D engine unlike the many 2D game engines for Android also available πŸ™‚ My game is going to be 3D, of course.

I guess that this about wraps up the low-level preparations for an advanced 3D Android game. I hope to update soon with more progress πŸ™‚

Until then,

Maya