Following on from yesterday's fixed point maths routines, here's a little demo which builds on that. It's another oldie, again from around 2002/3, which I've used in a more advanced form on quite a few projects. It's a very simple texture mapper, visually in the style of the SNES's famed mode 7. Given a 2D map, it presents the image as a horizontal texture mapped surface. It's primitive stuff but can be used to quite nice effect, and with it being entirely software based it doesn't require any additional APIs on the phone.
Grab the source and take a look at Renderer.java. Most of the work is done in renderFloor(), which simply works out a pixel offset for each scanline and fills the buffer accordingly. I've taken out some of the optimisations so it's easier to read, but even still it's no slouch!
Thursday, 27 September 2007
Wednesday, 26 September 2007
Java Fixed Point Maths
One of the first things I wrote when I started J2ME was a set of fixed point maths routines. I've seen quite a few others over the years, for Java and other languages, and they all seemed to follow the same pattern: sin and cos tables, plus a few methods for basic operations (multiply and divide, usually). The one I offer here, which in various guises and languages has served me well since forever, is a little more advanced (not much, but enough for most mobile games and applications).
The sin and cos (and by extension tan) routines are still table based, but instead of providing the table in-line with the code, it's generated using recursive synthesis at runtime. The advantage here is that the class can be quickly tailored for less or more fixed point precision, depending on the use (16.16 for general usage, 12.20 for audio work, etc.). There's also a fast atan, which was most useful for the physics and AI in Jet Set Racing (seen here, and Opposite Lock, seen here), plus a few other bits and bobs.
Most of the algorithms I devised myself, unless otherwise noted in the comments. The precision is pretty good (I have a test suite for it somewhere) but don't go taking my word for it, find out for yourself!
The sin and cos (and by extension tan) routines are still table based, but instead of providing the table in-line with the code, it's generated using recursive synthesis at runtime. The advantage here is that the class can be quickly tailored for less or more fixed point precision, depending on the use (16.16 for general usage, 12.20 for audio work, etc.). There's also a fast atan, which was most useful for the physics and AI in Jet Set Racing (seen here, and Opposite Lock, seen here), plus a few other bits and bobs.
Most of the algorithms I devised myself, unless otherwise noted in the comments. The precision is pretty good (I have a test suite for it somewhere) but don't go taking my word for it, find out for yourself!
Labels:
fixed point,
j2me,
java,
maths,
midp,
recursive synthesis
Friday, 21 September 2007
Streaming Audio on J2ME
For years I've been wanting to create a circular audio buffer for J2ME. Midi is okay but what I would really like is MOD playback, with maybe a few real-time sound effects thrown in, and generally a way of altering sound on-the-fly. I'd tried a mixer based on a blocking InputStream, which worked in Sun's WTK emulator but not on any actual phones (which load in the entire stream). I'd also tried a custom MMAPI DataSource, which didn't work either (same result as using an InputStream). I'd even tried the "switching between two Player instances" method, which although it (sorta) worked, wasn't low latency.
One idea I was hopeful about was running an RTSP (Real Time Streaming Protocol) server on the phone and playing the audio stream using MMAPI. This was interesting since the latency could realistically be as low as 1/25th of a second, perfect for generated sound and audio effects. I started by reading the protocol documentation (RFC 2326), along with RTP (RFC 3550) and SDP (RFC 4566), then by snooping the traffic between Quicktime and Darwin Streaming Server. The whole thing was hacked together in marathon coding session, then refined the following day. I'd like to end by saying "and it worked beautifully" but unfortunately whilst the server itself worked, playing the stream didn't work on any of the phones I tried. Grab the source code and have a play. Start the server running in WTK (or use the GCF implementation I posted earlier) and listen to the audio stream (which is just a rasping noise) in Quicktime, Realplayer, VLC, etc. Try the midlet version on a phone and you might get lucky... then again, you might not! I tried it in a few Sony Ericsson and Nokia phones, which I know can play back RTSP streams. The Nokia phones (6600, 6630) showed the most promise, since the loopback address appears to work, unlike the SE phones (K750, K800).
The server isn't the most elegant you'll ever see, and a better method would be to run the RTP part in a single thread, pumping out packets to all the connected clients. Then again, it was only designed for one client (the phone itself) and works well for this purpose. Like most of the code I'm planning on posting, I'm releasing it under a "do with it as you please, only give me credit for it" license. If you have any bugs, questions or suggestions, I'd like to hear them.
One idea I was hopeful about was running an RTSP (Real Time Streaming Protocol) server on the phone and playing the audio stream using MMAPI. This was interesting since the latency could realistically be as low as 1/25th of a second, perfect for generated sound and audio effects. I started by reading the protocol documentation (RFC 2326), along with RTP (RFC 3550) and SDP (RFC 4566), then by snooping the traffic between Quicktime and Darwin Streaming Server. The whole thing was hacked together in marathon coding session, then refined the following day. I'd like to end by saying "and it worked beautifully" but unfortunately whilst the server itself worked, playing the stream didn't work on any of the phones I tried. Grab the source code and have a play. Start the server running in WTK (or use the GCF implementation I posted earlier) and listen to the audio stream (which is just a rasping noise) in Quicktime, Realplayer, VLC, etc. Try the midlet version on a phone and you might get lucky... then again, you might not! I tried it in a few Sony Ericsson and Nokia phones, which I know can play back RTSP streams. The Nokia phones (6600, 6630) showed the most promise, since the loopback address appears to work, unlike the SE phones (K750, K800).
The server isn't the most elegant you'll ever see, and a better method would be to run the RTP part in a single thread, pumping out packets to all the connected clients. Then again, it was only designed for one client (the phone itself) and works well for this purpose. Like most of the code I'm planning on posting, I'm releasing it under a "do with it as you please, only give me credit for it" license. If you have any bugs, questions or suggestions, I'd like to hear them.
Labels:
j2me,
java,
midp,
mmapi,
rtp,
rtsp,
rtsp server,
streaming audio
Generic Connection Framework on J2SE
This is the first of my "poking around the the dusty corners of my harddrive, digging out snippets of code that someone might find useful" posts. This one stems from my preference for working interactively with a shell when writing network code, something I couldn't really do with J2ME. The announcement of JSR-197 (the Generic Connection Framework for J2SE) 4-5 years ago made be believe I'd be able to hack away in the shell Real Soon Now™, then place the same code into a J2ME project (as well as the more obvious share code between platforms). Nothing seemed to materialise out of the JSR spec (or at least anything complete), and as I'd already written most of my own J2ME implementation, I wrote a GCF package to complement it. Anyway, so here it is! It has working HTTP, HTTPS, socket and UDP datagram protocols (I also have a JSR-82 over IP implementation too, but I'm saving that for another day!) and I've been using it for quite a few years without issues. I'm releasing it under a "do with it as you please, only give me credit for it" license. If you have any bugs, questions or suggestions, feel free to get in touch.
Subscribe to:
Posts (Atom)