Aozora is a work in progress but there is quite a bit in the demo. It's a 3D adventure game, or it will be once it's finished, the version available for download allows you to walk around a fairly large 3D area and have a look around. The finished game will hopefully by an RPG with Zelda-esque battles and a fairly large map.

The version of the game you can download has already been improved upon. There is no jerking when you move around as the game loads in more of the map. I have also made 2 other maps that join this one and there is only a minor pause while the other gets loaded in, otherwise the game should appear to be as one large map.

You move relative to the camera using the D-pad and can spin the camera around with L1 and R1. You can also jump using X. ---


Game Download game(v0.1)(44k)
Source codeThe source code is unavailable as the game is not yet finished

If you have comments about Aozora (good or bad) then you can Email me at /


Other details about the game

Some of this stuff is probably really boring, but anyway:

Map Info

The map for an area consists of a 128x128 grid. Each location within this grid has with it:

In memory 2 bytes are used for each grid square. One byte is used for the tile ID and the second byte contains the orientation in the lower 2 bits and the height in the 4 bits above it. The upper two bits of this byte may need to be used to represent an extra two high bits for the tile ID.

The maps are stored in memory using a 12-bit LZW algorithm and the map the player is currently in is decompressed into a seperate area of memory. This not only allows more maps to be stored but ensures that the current map is always at the same point in memory.

Tile IDs

A tile ID refers to polygon data that is used to fill a column of 3D space which is regarded in the data as being 15x15x225 units big.
At the beginning of the block of memory containing translations between tile IDs and polys (tileinfo) is a header. This header consists of a list of relative addresses from the beginning of the header. Each address occupies 2 bytes so that the address for polygon data for tile ID n is located at tileinfo+*(tileinfo+(n*2)).

The data for each tile ID is built up as follows:

Each vertex occupies 2 bytes. The lower 4 bits of the first byte contain the X value with the upper 4 containing the Z value. The Y value is stored in the 2nd value. (This is why each model can only be 15x15x225 units big)

The first byte of each polygon specifies the type of polygon that it is. The following is a list of possible types along with the information that follows it:

0 - 0/128 (Texture mapped quadrangle, 128 if transparent)
1 - Sprite no. (see below)
2 - Vertex 1
3 - Vertex 2
4 - Vertex 3
5 - Vertex 4
6 - Normal (This isn't used as lighting is never performed)

0 - 1/129 (Texture mapped triangle, 129 if transparent)
1 - Sprite no.
2 - Corner of sprite (see below)
3 - Vertex 1
4 - Vertex 2
5 - Vertex 3
6 - Normal (This isn't used as lighting is never performed)

0 - 2/130 (Coloured quadrangle, 130 if transparent)
1 - red
2 - green
3 - blue
4 - Vertex 1
5 - Vertex 2
6 - Vertex 3
7 - Vertex 4
8 - Normal (This isn't used as lighting is never performed)

0 - 3/131 (Animated texture mapped quadrangle, 131 if transparent)
1 - Animation type
2 - Sprite no.
3 - Vertex 1
4 - Vertex 2
5 - Vertex 3
6 - Vertex 4
7 - Starting position (see below)

0 - 4/132 (Coloured triangle, 132 if transparent)
1 - red
2 - green
3 - blue
4 - Vertex 1
5 - Vertex 2
6 - Vertex 3

A sprite number refers to one of the standard sprites in the game. The u & v coordinates for the sprites position in VRAM is calculated within the game.

The corner of sprite value in the texture mapped triangle is needed because the sprite number refers to a square sprite. This value determines wether the top-left, top-right, bottom-left or bottom-right triangle of the sprite is used.

The starting position in the animated poly is used to let animated polygons around it be offset from each other and thus retain a fluid animation.

A vertex number refers to a point in 3D that the polygon has corner at. If this value is greater or equal to 64 then the value-64th entry in the vertex table is used. However if the number is in the range 0..63 then a standard vertex is used.

A standard vertex is one that lies on the corner of a standard block. 0 is the vertex at the bottom-back-left of the 3D column, 1 is back-right, 2 is front-left and 3 is front-right. This sequence continues moving one block up the 3D column at a time so vertex 63 is the vertex at the very top of the column at the front-right.

Creating TMD data

Within the game only a grid of 24x24 tiles are created as 3D models and displayed at a time. A 512k section of memory is set aside for building TMD models into. A pointer is kept which begins at the start of this section of memory and every time a new TMD model is needed it is built and the pointer moved on.
A list of pointers is kept, one for every possible tile, whenever a TMD model is built it's pointer value is updated so that if it is needed in the future the same model can be used.
So, when moving and new objects are needed the current one's are moved along and new one's are created, either by referencing existing models or by creating new one's. If this memory is about to be overrun then the whole lot are scrapped and the pointer is moved back to the beginning. The process then repeats with initially only the models required for the current area loaded.

Randomizing textures

Some textures in the game appear often (grass, mud wall) so 3 different textures are actually used to break up the monotony. This also helps prevent the problem of a player moving down a passage of the same texture and appearing not to move.

However, as the TMD data is recreated each time the area is updated a model that the player can see could get re-made as he watches it. If a different random texture is picked at this point it doesn't look very good. To solve this when the map is decompressed into memory a random number for each tile is also stored. This is used to create the random texture and ensures that the same one gets used each time.

Night and Day

To create the effect of going from day to night and vica versa 16 CLUTs are stored. CLUT 0 represents the true colours of the sprites and CLUT 15 represents the colours of the sprites at night (a slight blue). When the TMD data is getting built the correct CLUT for the time of day is stored with it.

The timer that keeps track of the time of day forces an update of the current area if the CLUT should change.

For the coloured polys that have an RGB value the following equation is used to calculate their true colour:

displayed_red = red+=(CLUT*((red+green+blue)/3-16))/16);
displayed_green = green+=(CLUT*((red+green+blue)/3-16))/16);
displayed_blue = blue+=(CLUT*((red+green+blue)/3+24))/16); ---

For more information about this site contact: David Johnston
(This page was last updated on 16/7/99)