Friday, November 14, 2008

Arctan in J2ME

Presenting:


// calculation functions
public class Calculation {

// Because J2ME has no floating point numbers,
// some sort of fixed point math is required.
// My implementation is simply to shift 10 places.
// for example, 1024 (>> 10) = 1
// and 512 (>> 10) = 0.5
public static final int[] CosTable90 = {
1024, 1023, 1023, 1022, 1021, 1020, 1018,
1016, 1014, 1011, 1008, 1005, 1001, 997,
993, 989, 984, 979, 973, 968, 962,
955, 949, 942, 935, 928, 920, 912,
904, 895, 886, 877, 868, 858, 848,
838, 828, 817, 806, 795, 784, 772,
760, 748, 736, 724, 711, 698, 685,
671, 658, 644, 630, 616, 601, 587,
572, 557, 542, 527, 512, 496, 480,
464, 448, 432, 416, 400, 383, 366,
350, 333, 316, 299, 282, 265, 247,
230, 212, 195, 177, 160, 142, 124,
107, 89, 71, 53, 35, 17, 0
};

public static final int[] AtanTable = {
0, 1, 2, 3, 5, 6, 7, 8, 10, 11,
12, 13, 14, 16, 17, 18, 19, 20, 21, 22,
23, 25, 26, 27, 28, 29, 30, 30, 31, 32,
33, 34, 35, 36, 37, 37, 38, 39, 40, 40,
41, 42, 43, 43, 44, 45
};


// angle calculation function based on x = x1 - x2, y = y1 - y2
public static boolean ArcTan(int x, int y, AngleArray sincos)
{
int angle = atan( y, x );
if (angle == -300)
return false;

int rotangle = abs(angle) % 90;

int cos = CosTable90[rotangle];
int sin = CosTable90[90-rotangle];

if (angle >= 270) // quadrant IV
{
int tCos = cos;
cos = sin;
sin = -tCos;
}
else if (angle >= 180) // quadrant III
{
cos = -cos;
sin = -sin;
}
else if (angle >= 90) // quadrant II
{
int tCos = cos;
cos = -sin;
sin = tCos;
}


sincos.sin = sin;
sincos.cos = cos;

return true;
}


/// returns angle 0->359 in degrees
public static int atan( int Y, int X )
{
boolean swap = false;

int top = abs(Y);
int bottom = abs(X);
if (top > bottom)
{
int btemp = bottom;
bottom = top;
top = btemp;
swap = true;
}
else if (bottom == 0)
return -300;

// this should keep index inbounds [0, 45]
int index = (top * 45) / bottom;
int angle = AtanTable[index];

if (swap)
angle = 90 - angle;

// X & Y += 180
// X & !Y = ...90
// !X & Y = ... 270
if ( (X < 0) && (Y < 0) )
angle += 180;
else if (Y < 0)
{
angle = 90 - angle;
angle += 270;
}
else if ( X < 0)
{
angle = 90 - angle;
angle += 90;
}

if (angle == 360)
angle = 0;

return angle;
}

// for good measure, sin and cos functions
public static int sin( int angle )
{
int rotangle = abs(angle);
while (rotangle > 89)
rotangle -= 90;

int cos = CosTable90[rotangle];
int sin = CosTable90[90-rotangle];

if (angle >= 270) // quadrant IV
sin = -cos;

else if (angle >= 180) // quadrant III
sin = -sin;

else if (angle >= 90) // quadrant II
sin = cos;

return sin;
}

public static int cos( int angle )
{
int rotangle = abs(angle);
while (rotangle > 89)
rotangle -= 90;

int cos = CosTable90[rotangle];
int sin = CosTable90[90-rotangle];

if (angle >= 270) // quadrant IV
cos = sin;

else if (angle >= 180) // quadrant III
cos = -cos;

else if (angle >= 90) // quadrant II
cos = -sin;

return cos;
}

}

Thursday, July 31, 2008

Stiria Website

I've gone ahead and set up a little website for Stiria at http://galacticicecube.com. Check it out!

Thursday, July 24, 2008

Quick code sample

A rather innoculous C++ class (of static functions) for placing/extracting 32-bit ints and floats to/from a C-style byte array. As mentioned in the comment, this was written for use in UDP network programming.

DEFAULTARRAYLENGTH is a constant declared elsewhere. It's helpful if the majority of the char* buffers passed in are of the same, fixed size.



/// implements some Bit library type functions for use with UDP/char* buffers

class PBitLib
{
public:

// assumes 32bit int
static void toBuffer( int num, char* buffer, int start = 0, int buflen = DEFAULTARRAYLENGTH )
{
if (buflen < 4 + start)
return;

int x = num;
unsigned char * bytes = (unsigned char *) &x;

for (int i = 0; i < 4; i++)
buffer[i+start] = (char) (bytes[i]);
};

// assumes 32bit float
// copies float into buffer from buffer[start] to buffer[start+3]
static void toBuffer( float num, char* buffer, int start = 0, int buflen = DEFAULTARRAYLENGTH )
{
if (buflen < 4 + start)
return;

float x = num;
unsigned char * bytes = (unsigned char *) &x;

for (int i = 0; i < 4; i++)
buffer[i+start] = (char) (bytes[i]);
};

// assumes 32bit int
static int bufferToInt( char* buffer, int start = 0, int buflen = DEFAULTARRAYLENGTH )
{
if (buflen < 4 + start)
return 0;

unsigned char bytes[4];
for (int i = 0; i < 4; i++)
bytes[i] = (unsigned char) buffer[i+start];

int num = *(int*)(bytes);
return num;
};


//
static float bufferToFloat( const char* buffer, int start = 0, int buflen = DEFAULTARRAYLENGTH )
{
if (buflen < 4 + start)
return 0;

unsigned char bytes[4];
for (int i = 0; i < 4; i++)
bytes[i] = (unsigned char) buffer[i+start];

float num = *(float*)(bytes);
return num;
};
};

Thursday, July 17, 2008

Stiria - Demo 1!

There's still work to be done, as mentioned previously, but I've decided to throw caution to the wind and release the first demo of this game.

STIRIA - Galactic Ice Cube game

Download here (Stiria.jar, 152 kB)

Phone requirements:

The game runs under Java Micro Edition. As such, if your phone does not support Java, this game will not run on it. If you're not sure if your phone has Java, you can do a few things:

  1. Take a look at what games/apps you have on your cell phone. If they mention Java when they start up, you have Java.
  2. Try to install it anyway. It shouldn't cause any harm, apart from the time it takes to try.

Apart from that, your cell phone should have a reasonable resolution, something in the range of 150x150 pixels (hopefully larger) to enjoy the game experience. That last phrase is code for, "if your screen is too small you won't be able to see where you're going".  However, the game should run, and if you want to chance it on a smaller resolution, go ahead.

The current version of the game has a maximum resolution (of sorts) at 400x400 pixels. I have not tested it at that large a resolution, but some graphics stuff is likely to be messed up.

How to install on cell phone:

Download the above .jar file onto your phone.  If you can transfer files directly from your computer to your phone, that will work as well. (in that case just download the .jar onto your hard disk, then move it onto your phone)

.jad installer - Certain phones may require an installer to help them figure out what to do with the .jar.  This is it.  Transfer it onto your phone with the .jar, then (if it doesn't auto-install), run it from wherever it is on your phone.

Hopefully these instructions are enough to get the game up and running.  If not, complain in the comments section of this post or something. Hopefully I'll be able to resolve most issues. =)

How to play

Okay, now that the lame stuff is out of the way, it's hopefully running on your phone.  You have no idea what you've gotten yourself into!

  • Control our nameless, heroic ice cube as he adventures in OUTER SPACE! Why is he in outer space? That's a mystery.
  • Up = jump.
  • Right = accelerate to the right.
  • Left = accelerate to the left.
  • Fire = attack with ICE FURY (less impressive than it sounds)
  • Select = pause/unpause the game.
  • Up, Down, and Fire navigate the pause menu.

Tips:

  • Space is an unforgiving place. A jump in the wrong place or at the wrong time may result in your heading in exactly the direction you want to avoid. So plan ahead! That's how NASA does it.
  • There's no direct penalty for dying, apart from forcing you to restart the level.  There are many hazards in space, including asteroids and fire.  Ice cubes happen to be very negatively impacted by fire.
  • You have a mini-map than can be accessed when the game is paused.  On the map, the center of the screen is marked as your current location.  Things marked with a light blue "X" will lead to the completion of the level.
  • There are two levels in total.  Both are rather difficult.

That's it! Have fun, and don't be afraid to die!

Thursday, July 10, 2008

Stiria - status update

Slowly but surely, the demo is approaching completion. There's some stuff that needs to be done but is best left until after the demo -- an overhaul of the slow collision detection code, for example -- but by and large it's getting very close to where I'm comfortable releasing it into the wild.

The current plan is for the demo to have two levels and a boss. Initially I had planned to have a single level demo, but I don't want to waste anybody's time by making the gameplay shorter than the download time. =)

Stay tuned.

Saturday, May 24, 2008

UIUC Senior Project

This project carried over my two final semesters at the University of Illinois, as a senior project in conjunction with a business interested in exploring 3D gaming as a learning tool. To satisfy their curiosity, our group of 4 used the Torque Game Engine, along with Autodesk Maya for modeling purposes to model part of the business complex and create a prototype learning tool and first person game for both teaching an escape route, as well as providing some small sample of what it might be like to be within the building when it was on fire.

The modeling work was rather extensive, and mostly handled by other members of the group. In general, the work for the project was rather extensive as well. However, by April we were more or less finished, and the client was by all rights satisfied with what we had accomplished. In all honesty, I'm not sure he had initially thought we would end with a completely working prototype. As four full-time university students with no outside help, completing a full 3D videogame of sorts seemed both then and now to be a monumental task. Thankfully, we had a great, motivated group.


There are a number of ongoing activities that go into a project like this: from the seemingly endless and sometimes irrelevant administrative reports, requirement specifications, and detailed documentation, to the modeling of a large portion of a building, to finally the actual coding of things like smoke and program flow, the placement of objects like fire extinguishers, and the constant reassessment of what features belong in the game, and which might be better left out. This final point had an atypically large role in our project. A few of us had made small videogames before it, but out of the four of us not one had any experience working on a 3D game. We didn't know what to look for, or what to expect to some extent. We made this clear to the client, however, and thankfully were able to overcome it with some flexibility on his part.

My favorite accomplishment of this project is probably that we finished. But beyond that, I'm pretty happy with how some of the stuff I put together worked out: Those light blue arrows on the edge of the screen that point the player in the direction of the exit are mine, both programmatically and Paint Shop Programmatically. The smoke effect is something I figured out as well, as is the annoying fire alarm which mercifully none of us can hear. (it is extremely annoying, I'm not going to lie.)

I also made those subpar tables obscured by smoke on the right, not that that was much of an accomplishment.


As mentioned in brief above, we used GarageGames Torque in the creation of this game. Despite our inexperience with actually making 3D games, it seemed clear from the start that mucking around with low level things like lighting effects and collision detection would only give us an extra degree of difficulty towards finishing the project. Torque has lighting tools built in, as well as collision detection and particle effects. All of these things came in handy immensely. Of course, an otherwise helpful tool like Torque wouldn't be complete without a plethora of frustrating shortcomings, some of which forced us to modify parts of the project. However, by and large it proved to be a boon.

One final, slightly odd note about this project. You may have noticed that after referring to them as "a business" and "the client", I have not referred to the company we made this prototype for. That is due to an NDA they required us to sign at the start of the project, stating among other things that we would not mention their company in relation to this game, so as to keep their videogame related research a secret, I suppose. It seems pretty bizarre, but I'm not one to judge. In any case, that agreement also prevents me from posting the game here. It's theirs, though for only internal use.

(This last fact is not a big deal. While I'm proud of the game, etc, it's ultimately a learning tool and not much of a fun game. The two aren't necessarily mutually exclusive, but for this game they were.)

Thursday, March 6, 2008

SEL Relay Password Changing Utility

The Password Changing Utility was as the name suggests. SEL's electric relays and communication processors are communicated with through either serial or ethernet (or some jumping through hoops with old-school modems), but the interface is pure command line. Changing the password on a relay -- a single relay -- requires something like 6-10 commands + connection configurations. Changing 20 of them is somewhat cringe inducing.

So, written in wxWidgets, C++, and teraterm script, and calling on Teraterm and PWGen to do some work for it, this utility was meant to fill a need. =)

Now... because so much of programming is procedural in nature, and easiest to explain as if it was a procedure, here's how it works:

1) The user, with the same settings they would use if doing things the "old" way, enter the information needed to communicate/change the password of a relay, then add that job to the queue.

2) According to the parameters selected -- such as the Method of connection and the Relay to change the settings of, the program, using a number of Teraterm template scripts I created, mixes and matches together the appropriate script to get the job done.

3) After the user has added all jobs to the queue, they press Go. And presumably leave the program for a while.

4) The program flashes rather annoyingly (like AIM or IRC clients do on a new message) when the tasks are done. It also provides a log file of whether or not each password was successfully changed.


Programmer's note: This was my first wxWidgets project, and after using it I concluded that Win32 (now the Windows API) should never be used again, if possible. There's something to be said for not having to reinvent the wheel every time you make a gui app.

note2: Because wxWidgets executables are enormously gigantic (no single word in the english language can properly describe a 1.5 MB Hello World program), this project led me to the brilliant little program UPX, which shrinks the bloated exe quite nicely back down to something more acceptable.

PHP Web HMI

The PHP Web HMI was the first project I made last summer as an intern at SEL. The basic idea, given to me by my boss/coworker Roger, was to create a web interface to report and interact with the status of a series of relays connected to a SEL 33xx device in (something like) real time.

The SEL 33xx (3351, 3332 ...) are specialized, hardy computers running software that can be communicated with using a number of different protocols -- such as Modbus. From a previous project at SEL that was done during the previous summer, I had experience with Modbus.

So, using PHP to act as a TCP client, I wrote the program. It runs in IE, Firefox, and Opera, and is probably maybe standards compliant, though I don't think I made sure. (oops)


Essentially, here's how it works:
  1. Page loads. PHP HMI runs...
  2. Using Modbus, the HMI gets the appropriate data from the Modbus server (the 33xx device).
  3. The data comes as a number of 16 bit registers. According to those, the breakers are displayed as open or closed. The values correspond to current or voltage, depending on what the end user wants to see.
  4. Page uses an HTTP header to trigger a refresh every 3-5 seconds. Go back to #1.

After this was working, I was asked if I could make clicking on the individual breakers send a message that would open or close them respectively.

That required:
  • a relatively secure PHP login. (if the page is public, allowing everyone who can find it to mess with the breakers seems, at minimum, a nuisance)
  • Javascript to confirm the action (avoiding catastrophic accidental clicks ;P)
  • JSON to make the open/close action occur while still staying on the same page.

Anyway, I did it, it worked, there was much rejoicing. This project is and/or will be, I am told, something used to visualize and operate parts of electrical power systems.

Friday, February 15, 2008

'uʍop əpısdn sı ʇsod sıɥ⊥

Some code:


#include <cstdlib>
#include <iostream>
#include <fstream>

#define BUFFERLENGTH 500

using namespace std;

// character map for upside down characters
char* charactermap[] = { "¡", ",,", "#", "$", "%", "&", ",", //33-39
")", "(", "*", "+", "´", "-", "'", "/", // 40-47
"0", "1", "&#9761;", "&#400;", "&#4281;", "S", "9", "L", "8", "6", // 48-57
":", ";", ">", "=", "<", "¿", "@", // 58-64
"&#8704;", "&#666;", "&#390;", "p", "&#8707;", "&#8498;", "&#1508;", // A-G
"H", "I", "&#383;", "&#65276;", "&#1498;", "W", "N", "O", "d", "&#8184;", // H-Q
"&#641;", "S", "&#8869;", "&#8745;", "&#923;", "M", "X", "&#411;", "Z", // R-Z
"]", "\\", "[", "^", "¯", ".", // 91-96
"&#592;", "q", "&#596;", "p", "&#601;", "&#607;", "&#387;", "&#613;", // a-h
"&#305;", "&#1360;", "&#670;", "&#1503;", "&#623;", "u", "o", "d", "b", "&#633;", // i-r
"s", "&#647;", "n", "&#652;", "&#653;", "x", "&#654;", "z", // s-z
"}", "|", "{", "~" // 123-126
};

// returns length of word
int getLength(const char* word)
{
int len = 0;
while (word[len] != 0 && len < BUFFERLENGTH)
len++;

if (len == BUFFERLENGTH)
len = 0;

return len-1;
}

// writes upside down character sequence into stream
void writeConvertedChar(ofstream& stream, char c)
{
if (c < 33 || c > 126)
stream << c;
else
stream << charactermap[c-33];
}

int main (int argc, char** argv)
{
// open input file
ifstream fin;

if (argc >= 2)
fin.open(argv[1]);
else
fin.open("data.txt");

if ( !fin )
return 1;

// open output file
ofstream fout("upsidedown.html");
if ( !fout )
return 2;

// go through input file, iterate through each line backwards,
// and call writeConvertedChar to put the upside down version of each
// character in
char buffer[BUFFERLENGTH];
while ( fin.getline(buffer, BUFFERLENGTH) )
{
cout << buffer << endl;

for (int i = getLength(buffer); i >= 0; i--)
writeConvertedChar( fout, buffer[i] );

fout << endl;
}

fin.close();
fout.close();

return 0;
}


This extremely exciting program allows me to be a prankster on message boards and post entire messages uʍop əpısdn.

Monday, February 4, 2008

Videogame Database

Link here

This was a final project for CS411: Databases.

The backend was done in mySQL via PHP, the front a mixture of CSS and Javascript (using JSON). I handled nearly all of the Javascript/JSON frontend coding, as well as some of the HTML/CSS and a few of the backend PHP queries. Another group member populated the database via perl and the power of the internet, and the result was the final product. (hosted on his webspace)

I also chose the color scheme, which might be a good reason for a company not to hire me.

Friday, February 1, 2008

The "city browser"

Link here
This was a one week web 2.0 project done for the CS242 course at the University of Illinois. The assignment was to be creative, come up with a project involving dynamic web content with no page refreshes, and to go nuts. CS242's ultimate goal was coding practice (for example, commenting code, making sure it was understandable and not a jumbled mess, and the like), so a more boring project may have been a safer bet... but a boring project would've been boring.

The result was the "city browser". I learned to use JSON in conjunction with Javascript for this assignment, and using data from yahoo and geonames.org I created a small web page that ... well, it's a little hard to explain.


Here's how it works. The user (you) types in the name of a city or specific location into the search box, then hits search. Then the following things happen:

1a) a request is sent to yahoo with whatever was entered into the box as a query
2a) Yahoo!'s JSON services return a JavaScript object with the first 10 search results
3a) those results are displayed in the left panel

1b) simultaneously, a similar request is sent to geonames.org, which collects geographic and weather data and has a JSON service of its own as well.
2b) geonames.org returns a JavaScript object with 4 locations + data.
3b) That data goes into the rightmost panel.

4) By clicking on any of the locations in the right panel, another request is sent to geonames.org. The returned data from this request is displayed in the middle panel, and includes the current weather data at that location.

Thursday, January 31, 2008

Stiria

Stiria is a cell phone game I conceived of in late 2005/early 2006, involving a rather Kirby-like (), friendly ice cube as the playable character. The ice guy character (who I'm not sure if I even named), initially was to have all sorts of transformations in his quest to conquer/survive the difficulties of outer space and its wacky, varying gravity.

Shortly after I thought of the project, the first videos of Super Mario Galaxy came out -- and I felt a certain sense of being beaten to the punch. The project laid on the backburner
for a while, until I had to come up with a 4 week project for the final part of a software design course at the University of Illinois. I picked up the project then, and 4 weeks and a painful amount of work later, I had this to show for it:

Written in J2ME (now called java micro edition, or JME) using the Java Wireless Toolkit, the current version involves 40 or so planets floating around in space and exerting their gravity on the little guy.

The game in its present form is a single level without a real objective -- in the short time frame I had I was unable to finish a boss to end the level with. I have worked on the game some in the half-year since, but mostly on the underlying code to speed up the process. That said, I'm hoping I can find some time to come back to and finish the one level demo, at the very least. When I do I will post it here.

I have also considered this game a candidate for the Nintendo DS system, utilizing the DS's touchscreen. Taking on a DS homebrew project is another matter entirely, however. =)


Download both files to try on Java-supported cell phone (~152 kb total):

Demo 1 -- Java executable + installer (July 30, '08)

Newest beta release: 0.9.09