Path: scea!hobbes
From: (Jamin Frederick)
Newsgroups: scee.yaroze.programming
Subject: New Yaroze Dev FAQ
Date: Mon, 29 Jun 1998 22:51:52 GMT
Organization: SCEA News Server
Lines: 1445
Message-ID: <6n95ai$51f5@scea>
X-Newsreader: News Xpress 2.01

I am reposting this (was in scea.yaroze.announce), apparently there's problems 
writing to the SCEA server sometimes:

"I tried to post the mail I sent you before to the newsgroup
scea.yaroze.announce, but repeatedly got the error message 'permission
denied'. Is it a moderated group, or do SCEE members not have write

Also, some extra info:

If you would like to help out with this FAQ, and you have an answer to one of 
the questions, email me the question, along with the answer.  I will include 
it in the next version of the FAQ.

If you have a question, email it to me and I will also include it in the next 
version of the FAQ.  At the bottom of each new version I will post all of the 
unanswered questions.

Sorry about some of the formatting (extra carriage returns), the ascii version 
is a lot better.



From: (Jamin Frederick)
Subject: New Yaroze Dev FAQ
Date: Mon, 29 Jun 1998 03:28:13 GMT
Organization: SCEA News Server

Hi, I've been working on a Yaroze Development FAQ.   Here is a preliminary 
version of it, and I was hoping that anyone that would wish to contribute to 
it would let me know.  I'm especially looking for answers to some questions 
I've provided.  It would be nice to have one common resource to go to for 
any technical Net Yaroze questions, and I'm hoping this can be the start of 
it.  If there's any more questions/answers/comments you could provide, please 
email at, thanks!


Yaroze Dev FAQ  0.5


In this FAQ, I would like to keep some definitions consistent so that there is
no confusion about terminology.  If you are adding something to this FAQ, 
please use the following conventions, thanks.

CLUT - color look-up table (4-bit or 8-bit)

display buffer (or display area or frame buffer) - portion of video memory 
that actually gets displayed when the playstation is running

main memory - memory used for normal program storage and operation; also the 
initial place for all incoming code and data when a yaroze project is 

model - the information making up the 3D representation of a game object; it 
includes orientation of the primitives making up the object and their coloring

object - the arbitrary game object in a Yaroze game, which can have state 
information attached to it, including sprite and 3D model references

OT - ordering table, the thing that sorts primitives such as lines, sprites, 
triangles, and quads

texture - image for sprite or image for mapping onto a model

translucency - image or polygons appear "clear", meaning you can see through 
it, but not invisible

transparency - doesn't show up at all, like the black background pixels of a 

video memory - memory physically apart from main memory, used for image 
storage and blitting to display area of video memory

TIM = image file
RSD = intermediate model file
TMD = playstation format model(s) file


See the following:

1) Why is display from my Net Yaroze is completely grey and grainy / shudders?

"You may be running an NTSC configured program on a PAL configured monitor.
If you have the source, make sure that the program contains a 
SetVideoMode(MODE_PAL) command and does not contain a SetVideoMode(MODE_NTSC) 

If you only have the executable, you can pick up the 'Screen Mode Changer' 
(N!K/Napalm) from the Napalm hacker site (see link section) - it is able to 
change executables which contain a SetVideoMode(...) command.
If, like me, you own an old Amiga monitor (1084/1084S/CM1884), an RGB to SCART 

cable should do the trick - forget your old Amiga lead!" -- James Rutherford 

2) I am trying to use graphic functions, but the screen locks / judders?

"These kind of effects can occur when you haven't allocated enough GPU packet 
space." -- James Rutherford


1) How does priority work in the ordering table?

For each "primitive" that you "sort", you can give a priority of 0 to 
2^MY_OT_LENGTH - 1, where 0 is the frontmost to the screen, and 2^MY_OT_LENGTH 

- 1 is backmost on the screen.  So obviously, increasing MY_OT_LENGTH gives 
you more layers, or priorities, to work with.

If you sort primitives at the *same* priority, then the ones you sort first 
are drawn last, meaning they will appear frontmost (at that priority level) 
when displayed. 

2) How does the display loop work?  Do I sort stuff and update stuff every 
single cycle, or what?

3) Why would you want to "turn off" a primitive/object for display instead of 
just not sorting it?


1) How do sprites work?

Sprites are simply references to rectangular regions in video memory that are 
transferred to the "display" or "frame buffer" position in  video memory when 
they are "sorted" into the ordering table.  So to make these images appear, 
you must load textures (also called bitmaps or TIMs) into the video memory 
first, and set up your sprites so that they reference portions of these 
textures.  So what the playstation does is simply make use of the information 
stored in the sprite to "blit", or transfer, the pixels from one part of video 

memory to the other.  The reason it is done this way is that copying from 
video mem to video mem is much faster than main mem to video mem.

2) What's the deal with video memory -- what's with the 4-bit, 8-bit, and 
16-bit stuff?

TIM images can be specified as either 4-bit, 8-bit, or 16-bit (or 24-bit, but 
that will be covered later) meaning that there are 4, 8, or 16 bits of 
information, respectively, for each pixel in the image.  However, all image 
colors on the playstation (besides the 24-bit true color picture mode) are 
displayed using 15 bits of information for the actual RGB values altogether -- 

5 bits for R, 5 bits for G, and 5 bits for B.  However, unsigned shorts are 16 

bits, meaning there's one bit left over when storing a color -- and this is 
used for "translucency". This bit is '1' if the color is to be considered for 
translucency (the docs call it "transparency", but I reserve this word for 
something else).  In other words, if a sprite or model texture using this 
color would like to be translucent, then the translucent color will be 
calculated.  Otherwise, if the bit is '0', the color will not even be 
considered for translucency, even if the sprite or texture feels like being 
translucent. Note that there's a special case if each R,G,B value is 0, and 
then the remaining bit is considered as something totally different -- which I 

call "transparency", which is what is used to draw sprites without the black 
background.  In this case, the 0 and 1 stand for the color black to be 
considered transparent or not when blitting the image.

So even though 16 bits are used for color, what about 4-bit and 8-bit TIMs? 
Well, obviously, 4-bit and 8-bit TIMs take up less space than 16-bit TIMs, 
which have a 16-bit value for each pixel, which is the actual color of the 
image pixel.  4-bit and 8-bit TIMs work differently, though.  Instead of using 

their data bits for actual color, their data bits are used to reference a 
*table* of 16-bit colors (remember, I said all object colors are really 
16-bit).  This is where the term "CLUT" comes into play.  With 4 bits, 16 
different CLUT entries can be accessed, and for 8 bits, 256 different CLUT 
entries can be accessed.  So 4-bit TIMs need to include a 16-value CLUT, and 
8-bit TIMs need to include a 256-value CLUT.  The CLUT values themselves are 
16-bit, though, since they're referring to an actual color (well, actually 
15-bit color...this is where some confusion sometimes arises).  There are 
tools to edit the pixel positions and CLUT positions of the TIM image in video
memory -- the TIM must include both the pixel information and the CLUT itself.

What about video memory?  Well, the video memory is considered to be 1024 x 
512 *pixels* -- where a pixel is an unsigned 16-bit color value.  But the TIMs 

contained in video memory (when transferred with LoadImage()) are actually 
compressed, so that one "video memory pixel" takes up *two* 8-bit TIM pixels, 
and *four* 4-bit TIM pixels.  But remember, these pixels represent CLUT 
look-up values, not actual 16-bit colors.  So the TIM sprites are actually 
"squished" in video memory, before they get to have fun in their decompressed 
state over in the display buffer. 

So what this means is that all of the sprites you see on the screen are 
actually 16-bit pixels, not 4-bit or 8-bit CLUT pixels -- so what actually 
happens when a blit occurs in the video memory with a 4-bit or 8-bit image, is 

that the playstation automatically references the TIM's pixel color by 
referencing the CLUT, and expands the pixel in its true color on the display 
buffer.  Pretty neat, huh?  

3) How do the 24-bit images work?
4) What's (x,y), (mx,my), and (u,v) for in the sprite structure GsSPRITE?

The vars x and y refer to the sprite's position on the screen when it is 
sorted to the OT.  However, note that this x and y is with respect to the 
sprite's center, which is denoted by the vars mx and my.  These vars describe 
the "center" of the sprite, which is the thing that gets placed at x and y on 
the screen.  This can be used if you want to refer to some other part of the 
sprite as the center, instead of the upper left corner.  Note that x and y can 

be negative, or even larger than the screen, but this does not cause an error. 

 The OT compensates and automatically "clips" the sprite if it is partially or 

even totally off screen.   

The u and v refer to the *pixel* location of the sprite's upper left corner 
with reference to its parent image (or texture page, or TIM). This can be 
considered as if the sprite is already expanded from its original 4-bit or 
8-bit compressed image size.  So if my sprite starts on pixel 20 over and on 
pixel 10 down in my TIM (just like it is painted, not worrying about 
compression), then you just specify (u,v) = (20, 10).  The playstation takes 
care of the actual referencing in video memory, which takes into consideration 

the compression and the texture offset in video memory, via the information 
included in the TIM file.  

5) Why are my sprites colored wrong?

Check the CLUT position in TimTool.  All CLUTS must have unique positions in 
video mem; if any of them are the same, one CLUT will get loaded over another, 

using the color scheme of the other picture.

6) Why do my sprite textures look misaligned on the screen?

Double check the alignment of the texture in TimTool. Sometimes TimTool nudges 

the texture down some, messing up what you might think is the proper offset 
for the texture.

7) Why is my sprite losing pixels, especially along the vertical axis?

Change sprite scaling from 4096 to 4095.

8) How can I cycle colors on my sprites?

Use MoveImage() to make a copy in video memory of the CLUT of the image that 
the sprite is using (to somewhere below the original CLUT), and between update 

frames, use MoveImage() to copy colors from the copied CLUT into the original 
CLUT, and the palette colors that are mapped to the sprite will give it an 
appearance of cycling, if it's set up right.  Check out Jamin Frederick's Pt 
(Palette) library, which you can use to do this. 

7) How can I do pixel-by-pixel collision detection on my sprites?

Typically, you can use just bounding boxes to see if sprites collide, but 
sometimes it is necessary to get down to the pixel level.  One way to do this 
is to first see if the bounding boxes intersect, and if they do, then you can 
do a pixel-by-pixel collision detection on the intersection rectangle of the 
corresponding sprite images.  The only problem is that these images are in 
video memory, unless you haven't written over the images that are in main 
memory when they originally were copied over from the com utility.  In other 
words, we don't really have byte-by-byte access to the video memory for close 
comparisons, so we are forced to work with main memory.  So once you get 
access to the intersection rectangles of the sprite images, all you have to do 

is compare corresponding pixels in the rectangles, one at a time, until you 
get a "hit" (non-black) pixel from one image with a "hit" pixel from the other 

image.  However, this involves some rather tricky interpretation of the TIM 
image data in main memory.  This is implemented in the CollisionDetect() 
function available on Jamin Frederick's web page.

8) What other methods of collision detection are there?

From a newsgroup discussion:

"Have you considered whether a pixel-by-pixel collision detect is *really* 
necessary? It sounds so time expensive when you could be doing some freaky 
special effects or better AI or something instead... I've used gobs of weird 
hacks for collision detection in games, and I've always been able to find a 
way around pixel-by-pixel. I thought I'd list some of them off: 

0. Make your game so intense no one has time to notice that collisions are 
pixel exact or not. 

1. Simple shapes as hit regions - design the art so it fits well into shapes 
that are easy to mathematically check against, like rectangles, circles, and 

2. Rotated simple shapes as hit regions - sometimes you've got objects that 
can rotate - rotating a rectangle and checking it against another rotated 
rectangle is still cheaper than pixel-by-pixel. 

3. Stick Figures. Say you've got a figure like a character in a 2d fighter. 
Make a simple stick figure that mimics the shape and motion of the sprite, ie: 

a line for the head, a line for upper arm, lower arm, hand, two lines for the 
torso, etc. etc. Then to do hit detect with the other character in the game 
all you have to do is treat each line as a fat line and check them against the 

fat lines in the other character. This has the advantage of letting you know 
that the hand connected with the noggin. 

4. Simple hierarchical shapes. Say you've got a top down view of the TOS 
U.S.S. Enterprise on the screen. Do your hit detecting on a circle and three 
rectangles, one for the two engines and one for the engineering hull, with the 

rectangles of course rotated according to the orientation of the ship on the 

5. Polygon shapes. Make a polygon outline that fits around the shape as 
tightly as you'd like so that game feels good, then check for intersection 
with collidable objects. If you design it right you can have one complicated 
polygon collision shape which you test against some trivial shape like a 
rectangle, but even still, poly-poly intersection is faster than 
pixel-by-pixel, unless your sprites are really tiny, in which case suggestion 
number 1. is probably the best IMO." -- Nick Porcino


1) Where do my images have to be aligned in video memory?

2) Do my sprites have to be in a special position within an image?  I heard 
they have to be on even coords or something.

3) Can I have more than one image on a given texture page?  Can I arrange 
several images next to each other within the texture page?

4) What's the max size of a TIM? Does it depend on the number of colors?

Max size of a TIM is 256 x 256 pixels, no matter how few colors it is.  One of 

the reasons is because sprites are referenced (u,v) via pixel offsets of 
texture pages (or TIMs), and since u and v are both unsigned chars, the 
biggest they can both be is 255, meaning sprite (u,v)s can only be from (0,0) 
to (255, 255).    

5) Where are the best places for CLUTs in video memory?

The typical convention is placement below the display buffers, since the area 
is too small to have any decent-sized sprites down there.

6) How do you set up transparency for a sprite / texture?

7) How do you set up translucency for a sprite / texture / model / polygon?

8) What do the different translucency settings mean?

50% back + 50% polygon
100% back + 100% polygon
100% back - 100% polygon
100% back + 25% polygon

9) Do all the translucency settings work right?

10) Why do you have to specify translucency for GetTPage()?

"You can use GetTPage to calculate the tsb section of a tmd primitive
which does require the semi-transpency rate.  Just & the result with 31
to get the Texture page number." -- Jim

11) How are texture pages numbered, and what is their ID?

12) Why doesn't LoadImage() work for large rectangles, close to the size of 
the video memory (1024 x 512)?


1) How does the 16x16 pixel tiling work?

2) How do I make tiled backgrounds with sprites (bigger than 16x16 pixel 

This is a nifty trick.  The ordering table accepts information in the sprite 
struct (GsSPRITE) that you give it as a *new* sprite, so that  you don't have 
to maintain the same information in the struct within a screen update.  So 
what you can do is keep changing the info in the sprite struct and sort it 
into the OT.  So to make a checkered background, for instance, you just need a 

black square struct and a  white square struct, and repeatedly sort them while 

changing their positions.    

3) How does the offsetting work -- I mean, how do you get sprites to scroll 
around in the background and stuff (2D)?

It usually depends on the game, but here it goes...

First of all, let's draw a difference between a game object and a game sprite. 

 A game object is something in the game that has a state and presence, but is 
not necessarily displayed.  A sprite is just a representation of the object ON 

THE SCREEN, and always refers to the thing being displayed.  So an object can 
easily have many sprites, each one representing different states of the 
object, or an object's current position on the screen.

Ok, so first you set up a world coordinate system, where all of the  objects 
that you intend to have in the game are given a position in the  world. So all 

the changes that you give to your objects are with respect  to the world 
coordinates, NOT THE SPRITE COORDINATES.  The reason for  this is that the 
sprite coordinates can be calculated from the object's position in the world 
with respect to the SCREEN's position in the world.  That's right -- you 
consider the "game screen" to have a position in the world as well, so that 
when you want to "scroll around" the world, you're just moving the screen's 
position around in the world,  and the sprites that get displayed on your 
screen are just a result of them being around the screen when it gets close to 

them in the world. 

So for instance, if you chose your world to start at (0,0) in the top left 
corner, then you could assign objects coordinates like (8,20) or (67,258) or 
(600,780) or even (4563,23453), depending on  how big you want to make your 
world.  Of course you're limited by how large your numbers can get, which for 
an unsigned long (32-bit) is 0 to 4,294,967,295.  So just imagine that you 
have a bunch of  (rectangular) objects positioned in your world like this 
(usually when you're referring to an object's world coord, it is the upper 
left corner of its rectangle, at least in this example) and think about a  
rectangular, 320x240 screen, moving and scrolling around in the world  with 
them (again using the upper-left corner pixel as the world coord).   Now to 
get them to be on the proper position on the screen, you want  their sprite 
representations to be according to where the object is in  reference to the 
screen in the world.  If the object stays still and the screen moves, for 
instance, well then the sprite moves on the screen  even though the object 
hasn't moved in the world at all.  So what you have to do is set up a relation 

between the sprite and the screen.   It's just:

         SpriteX = ObjectX - ScreenX
        SpriteY = ObjectY - ScreenY

So if the object position gets bigger with the screen position fixed,  then 
the sprite position gets bigger, and moves right and down on the screen.  If 
the screen position gets bigger with the object position  fixed, then the 
sprite position get smaller, and moves left and up on the screen.  Now 
remember, this example is all in terms of the origin  of the world being to 
the upper left, and the origin of the objects and  screen at the upper left of 

their bounding boxes as well.

When you give the OT a sprite to sort, you're giving it the sprite's SCREEN 
position.  From experimentation I have found out that this does not mean it 
has to be from (0,0) - (SCREENW-1, SCREENH-1), but it can be any number at 
all, even negative!  The OT compensates and does all the clipping for you, so 
that the formula above works fine when using SpriteX and SpriteY as the 
position to be be placed on the screen.      

If you have trouble visualizing it, just start out with 1 object and the 
screen at the origin of the world, and imaging what happens to the sprite 
image on the screen when you try to move either one according  to the formula:

  |       |      |                          |
  |OBJECT |      |                          |
  |-------+      |                          |
  |              |                          |
  |   SCREEN     |                          |
  |              |                          |       
  +--------------+                          |
  |                        WORLD            |
  |                                         |
  |                                         |
  |                                         |
  |                                         |                 

4) Why am I getting a "banding" effect with my background tiles, where a 
vertical line in the tile is smeared over a pixel?

The individual tile textures of a background each have to be on an even u 
coordinate. If each sprite texture is not positioned on an even number in the 
video memory, you will get this effect.  This can easily happen if you use 
gridlines to separate your tiles for easy editing, for instance.


1) What is the 3D coordinate system of the playstation? I've looked everywhere 

in the manuals but couldn't find a simple description!

It's actually a right-handed coordinate system, meaning (with your right hand) 

+X cross +Y gives you +Z. The +X axis is to the right of the screen, +Y is 
down on the screen, and +Z is in towards (behind) the screen.

2) What's the difference between RSD and TMD?

RSD is the file format used to convert from modelers, similar to DXF and other 

model formats.  It is in ascii, making it easy to edit by hand.  The info 
making up an RSD is actually four files, .rsd, .ply, .mat, and .grp.  It's 
easy to mix up talking about RSD (which includes all four files) with just 
rsd.  A modeler converting to RSD will generate all four of these files.  
Also, an RSD refers to only one model, and the grouping information (.grp) in 
the model doesn't carry over to TMD.

TMD is the file format the playstation uses, and the data making up this file 
actually resides in memory when your Yaroze program is drawing objects on the 
screen.  A TMD can have more than one model, and each model has its own set of 

primitives, which are made up of those model's own vertices and normals.  Each 

primitive is described in detail as a triangle, quad, flat shaded, gourand 
shaded, colored, color gradated, or textured.  All the combinations are 
described in the Sony online docs.

3) Are the coordinates different in RSD and TMD?

3) How can I see information on my RSD?

To view an RSD, use RSDTool.  To get information on the vertex extents and 
"center" position, do rsdform -v mymodel.rsd.  Follow this with > to output to 

a file.

4) How can I see information on my TMD?

To view a TMD, try this:

You can also get vertex information on the TMD when you are converting from 
the RSD with rsdlink, just do rsdlink -v mymodel.rsd or rsdlink -info 
mymodel.rsd.  Follow this with > to output to a file.

5) Can I save multiple models in one RSD file?

Yes and no.  An RSD contains only one model per file, so if you wish to put 
several models into one RSD with rsdcat, you are really only merging several 
models into one big one, and in effect, merging three coordinate systems into 

6) Can I save multiple RSD models to one TMD file?

Yes.  Unlike RSD files, TMD files can make references to several different 
models within the file.  To put several RSD models together into one TMD, you 
can use rsdlink with several RSD file names as arguments (see top of p.149 in 
yellow manual).

7) Is there any reason to put several models within a TMD file instead of only 


8) What do the coordinates mean in rsdform (option -v)?  What is "center"?

These coordinates refer to the offsets from the model's coordinate system.  If 

you "translate" the model with rsdform, you are moving all the vertices within 

the fixed model coord system, and you can imagine a bounding box of all the 
vertices that comprise the primitives of the model moving around in space with 

respect to the model's fixed coordinate axis.  The "center" is just a 
reference to the center of mass of the model, which can usually be specified 
within a modeler program.  The playstation will rotate models around (0,0,0) 
of the coordinate system, *not* the "center", which can be a nonzero offset 
from (0,0,0).  

When you save an object in a modeler and it is not placed in the middle of the 

world, for instance at (8, 10, 12), the "center" in your RSD will appear as 
(8, 10, 12).  To get the model back to the origin (so that it rotates 
correctly) you need to translate back to (-8, -10, -12).  However, many times 
you will want to use this information, for instance, if you have several 
objects and need to know their relative offset position, such as a helicopter 
and its blades.  You would need to know how high the blades are in the world 
originally, so that you can offset them with respect to the helicopter when 
you're actually drawing them in your program.

The origin of the model's coord system (0,0,0) is the point that is referred 
to when translating the model in your program.  So if I give my model's 
translation vector (.t) in my program the value of (5, 2, 10), the model's 
origin will be at (5, 2, 10), and all the primitives will be drawn around this 


9) How do I assign parents to other objects?

When initializing your object's coordinate system, instead of doing 
GsInitCoordinate2(WORLD, &MyObjectCoord), do GsInitCoordinate2(&MyParentCoord, 

&MyObjectCoord), assuming you already initialized &MyParentCoord with WORLD or 

some other coordinate system.  Each argument is a pointer to type 
GsCOORDINATE2, which includes a matrix that describes the coordinate system 
you are using.  So then, after the initialization is done, all of the offsets 
of your model are with reference to the parent coordinate system.  For 

GsCOORDINATE2 MyParentCoord;
GsCOORDINATE2 MyObjectCoord;

// the coords of an object with MyParentCoord are in the world
GsInitCoordinate2(WORLD, &MyParentCoord);  

// the coords of an object with MyObjectCoord are w.r.t. the parent
GsInitCoordinate2(&MyParentCoord, &MyObjectCoord);

So if you had an GsDOBJ2 handler representing a tank, make its coord2 member 
point to MyParentCoord (the tank is the parent), and if you had a GsDOBJ2 
handler representing the tank turret, make its coord2 member point to 
MyObjectCoord (the tank turret is the child).  Now if the turret is at 
(0,0,0), it will be at the tank model's origin.  You'll probably want to 
tranlate the turret to (0, -1000, 0) or so, depending on your model, and 
everywhere the tank moves (in the world), the tank turret will follow.

10) How do I rotate an object?

First you have to know that all models rotate about the origin (0,0,0) of your 

model's coordinate system (do rsdform -v mymodel.rsd).  This means that 
however your primitives are placed in your RSD, they will rotate around this 
point.  So if the "center" of your model (representing the actual center of 
your model) is not (0,0,0), translate it there first before you rotate it.

Assuming there is an initialized GsCOORDINATE2 Coord structure (belonging the 
object which I am rotating), and I want to rotate the object (RotX, RotY, 

MATRIX TempMatrix;
SVECTOR RotVector;

// this makes a vector
RotVector.vx = RotX;
RotVector.vy = RotY;
RotVector.vz = RotZ;

// this turns a vector into a matrix, so that I can multiply
RotMatrix(&RotVector, &TempMatrix);

// multiply original coord matrix by "rotation" matrix
MulMatrix0(&Coord.coord, &TempMatrix, &Coord.coord);

// object should be redrawn now since it changed
Coord.flg = 0;

Note: Rotation this way may distort your model if your model is not very 

11) How do you advance an object in the direction it's facing?

Assuming that your model starts out pointing in the +z direction, and you want 

to advance U units, and that your object has a GsCOORDINATE2 Coord struct:

SVECTOR StartVector;
SVECTOR CurrentDir;

// assume origin points exactly towards +z direction
StartVector.vx = 0;
StartVector.vy = 0;
StartVector.vz = ONE;

// multiply original orientation (start vector) by current orientation matrix, 

to get the current direction vector
ApplyMatrixSV(&Coord.coord, &StartVector, &CurrentDir);

// add a multiple (units) of the current direction to the current translation
Coord.coord.t[0] += (U * CurrentDir.vx) / ONE;
Coord.coord.t[1] += (U * CurrentDir.vy) / ONE;
Coord.coord.t[2] += (U * CurrentDir.vz) / ONE;

// the object should be updated now
Coord.flg = 0;

Note: You could use 1 instead of ONE=4096, and then not divide later on by 
ONE, but you'd get considerable error if you don't "pump up" your start vector 

to considerable size because of the integer precision. 

9) What's a standard size for a model?

Typical sizes are about 500.0 to 2000.0 in each dimension.  

10) How small/big can I make my model?

If a model is too small (meaning its vertex coordinates are small numbers, 
like 1s or 10s), errors of the playstation fixed-integer rotation and scaling 
(matrix computations) will be too large and the model will distort.

If a model is too large

8) I don't see my object!  Where is it?

First, see if you're actually sorting it with GsSortObject4() -- of course, 
there's some stuff you have to do before you can actually sort it, like 
calling GsGetLws(), GsSetLightMatrix(), and GsSetLsMatrix().  You should also 
make sure the loading of the model was done right, too.

Second, see if the scale is big enough.  Modelers tend to save out RSD models 
in the -2.0 to 2.0 range, which is pretty small for a standard playstation 
model.  Scale it up with rsdform -s 512 512 512 mymodel.rsd, to give it a size 

big enough to see at standard viewing distances, which are 500.0 to 1000.0 
units away.

7) I want to have an object with several moving parts (a model for each part) 
and have each part move independently. What do I have to do to get this to 

Since each model must move independently, you should first center each RSD 
model by setting its "center" to (0,0,0).  For instance, This is so that each 
object will rotate properly about its "center".

12) What's the difference between GsVIEW2 and GsRVIEW2?

) Is it true that the colors specified for an object's polygon is 24-bit, 
whereas images used for textures on models may only be 4-, 8-, or 16-bit?

) I've tried to draw TMD lines or sprites as documented in the File Format 
document, but they don't seem to be working.

Even though they're documented, 3d lines and sprites cannot be used on the 

) I've also tried to use double sided polygons with no success.

Again, double-sided polys are not supported on the Yaroze.  

) How do TIMs get linked up with objects?

When you do the rsdlink command, your TMD gets info about the textures you are 

using for the mapping to the object(s) from the TIM files referenced by your 
object.  Make sure that if these textures change at all, such as tpage 
location or clut location, that you redo rsdlink.

) Do you have to texture map TIMs onto each individual polygon, as in RSDTool, 

or is there a way to "wrap" a texture around groups of polygons.

There doesn't seem to be any tools out right now to do this, although the next 

version of RSDTool was supposed to incorporate this feature.

) Why are my objects all "flat", even when I rotate them?

You forgot to set the coordinate system of your object, i.e., make your 
GsDOBJ2 object handler coordinate pointer (.coord2) point to a validly 
initialized GsCOORDINATE2 struct. 

) Are there any *simple* modelers out there, that don't triangulate like 

) How do I convert a 3D coordinate to a 2D coordinate?


void InitTransProj(void);
void TransProj(VECTOR *pos, short *x, short *y);

static GsCOORDINATE2 trans;

//      init trans proj coord
void InitTransProj()
        GsInitCoordinate2(WORLD, &trans);

//      Trans Proj - convert 3d x,y,z to 2d screen x,y
void TransProj(VECTOR *pos, short *x, short *y)
        MATRIX mat;
        VECTOR v;

        trans.coord.t[0] = pos->vx;
        trans.coord.t[1] = pos->vy;
        trans.coord.t[2] = pos->vz;
        trans.flg = 0;

        GsGetLs(&trans, &mat);

        ApplyMatrixLV(&mat, pos, &v);

        if(mat.t[2]) {
                *x = ProjectionDistance * v.vx / mat.t[2];
                *y = ProjectionDistance * v.vy / mat.t[2];
        } else {
                *x = 0;
                *y = 0;


Contributed by Steve Hunt 


) What's this 0x00000000 stuff mean?                        

This is a hex value, which is 32 bits, meaning 8 hex digits corresponds  to 32 

binary digits (4 bits per hex digit). The PSX has a 32-bit  address space, 
meaning all operations with memory are done with 8-digit  hex values. Some 
other addresses are 4 hex digits = 16 bits, like device  memory, but most 
things are done with 8-digit hex values.

 ) What's the difference between uchar and ushort and ulong?                   


The "u" stands for unsigned, so any values you stick in the variable  can't be 

negative. This gives you twice the numbers you can get from  "signed" 
variables char, short, and long. Unsigned variables are ideal  for memory 
addresses, though, since they are never negative -- uchar  gives you 8 bits of 

storage, or addresses from 0x00 to 0xff, ushort  gives you 16 bits of storage, 

or addresses from 0x0000 to 0xffff, and  ulong gives you 32 bits of storage, 
or addresses from 0x00000000 to  0xffffffff. 

) Why do I have to load data at 0x80090000? What about those other addresses 
mentioned in the manual?

For the yaroze system, the only valid memory-mapped addresses (meaning if you 
stick stuff at these locations, it gets "mapped" to the actual playstation 
RAM) are 0x80000000 to 0x801fffff. This is exactly 2  megabytes, or 2,097,152 
(2 * 2 ^ 20) bytes, to be exact. The other  locations are not used on the 
yaroze.  The only valid space for us is 0x80090000 to 0x801fff00 (1,507,072 
bytes), since the rest is being used for the system. That's why data is 
usually started at 0x80090000, and  added upwards. Your program may be loaded 
anywhere in this space, depending on where you tell your compiler to load it, 
but it's usually  loaded up towards the top. There has to be enough space 
upwards for the program itself (code and heap), plus the amount the stack will 

grow.  The program's stack usually starts at the top of our usable space, 
which is  0x801fff00, and grows down until it collides with the loaded program 

 (this is bad). That's why it's up to the programmer to figure out how  much 
his stack will grow, and tell the compiler to place the program  low enough in 

memory so that the stack doesn't end up running into it.

Typical Setup:


  (hope the stack and heap don't collide!)

  PROGRAM CODE (stays same size)
  DATA 3
  DATA 2
  DATA 1 (0x80090000)
  OTHER OS GOODIES (0x80000000)
You can set the PROGRAM STACK and PROGRAM CODE in your compiler and the DATA 1 

- DATA N in your yaroze batch file.

) What's fixed point?

Fixed point is an alternative to floating point, and is quicker since it 
actually uses integer hardware and not any special floating-point hardware.  
It is actually a trick done with integers, and tends not to be quite as 
accurate as true floating point operations, so you have to watch it when 
rotating and scaling models, and make sure they're not getting distorted.

The playstation uses 12-bit fixed point, meaning there's 12 bits of a short 
(16-bit) integer allocated to the decimal portion of a number (3 bits are used 

for the integer part, and 1 for the sign).  These numbers are the values that 
will represent the vertices and normals in 3D space within a TMD file.  The 
details aren't important unless you plan to change the attributes of a model 
in real-time, which involves fiddling with the byte values of the TMD in 

See the following web page for more info on fixed point:

) Can I do floating point?

) How do I get C++ to work?


) How efficient is C++ on the playstation?

) How efficient is using 16x16 pixel tiles (with GsBG) as opposed to using 
sprites (with GsSPRITE) as backgrounds?

) How can I make my games quicker, taking into account playstation hardware?

a) Make use of the DCACHE in functions that you call very often; see Scott 
Evans' (SCEE) DCACHE article.

b) Declare variables static in functions that you call very often, so fewer 
local variables need to be pushed and popped.

) What are some suggestions to make my 2D graphics a little faster?

) What are some suggestions to make my 3D graphics a little faster?

a) First and foremost -- keep polygon count low.  With the tools available 
this is sometimes difficult, since it seems modelers like to triangulate when 
saving out. 

b) Make several versions of objects at different "resolutions", and sort 
higher polygon objects when those objects are closer to the camera, and lower 
polygon objects when they are farther away.

) Why does saving to DXF from modelers make so many more polygons?  What can I 

do to avoid this?

) Is it more important that I make fewer objects or fewer polygons?


) What can I do with Codewarrior that I can't do with Siocons?

a) Automatic makefiles
b) GUI coding (not suggested)
c) GUI debug 
d) Use MWDebugIO functions, which allow you to create, open,
and close files on your PC 

) What can I do with Siocons that I can't do with Codewarrior?

a) Download memory directly to a PC file (DSAVE[])

) Is there any differences in writing code for Codewarrior versus writing code 

for Siocons?

) What's the best setup?

One way to develop for Yaroze is to use Codewarrior to "make" your projects 
and the PSComUtil to download batch files, since it's mostly point and click.  

I have found the Codewarrior IDE very disturbing, though, so I choose to use 
an outside editor such as Microsoft DevStudio, or some shareware code editor.  

You can leave the files that you edit in the Codewarrior project, and just 
bring Codewarrior into focus and click "make" when you want to build your 
project to be downloaded to the yaroze.

Some other people have suggested forgetting Codewarrior altogether, using the 
makefile capabilities of MS DevStudio and integrating DJGPP(GCC) with it.  See 

Steve Dunn's (SCEE) home page.

Also, check out the front end gnu programs that are available (in the 
utilities listing of this FAQ).

) How about some simple Codewarrior (MWDebugIO) example code for creating, 
opening, reading, and writing files to the PC?

) What kinds of problems are there with Metrowerk's MWDebugIO library?

) Why is PSComUtil failing?

If you get
"Connection Failed. Status -1
Transport Send Data. Status 101812
Transport Poll Rx Status. Status 101812
The PlayStation has generated a Hardware Interrupt exception at instruction 
address 0x0."

Probably means that Pscomutil is still resident in memory.  Check your task 
manager and delete the process.  For some reason, even if you exit PSComUtil, 
it still stays resident in memory sometimes.


) How do I make sounds play? What programs have to be run?

Say I want to use 3 .wav files, a.wav, b.wav, and c.wav. First you do 
"aiff2vag a.wav b.wav c.wav" to create .vag's out of the .wav's. Then  you 
have to type "mkvab -f sounds.def a.vag b.vag c.vag -o sounds.vab"  where 
sounds.vab is the output .vab and sounds.def is your definition file. What's 
that? It's a file you need to provide to make a vab. The  vab can contain 
programs, and for each program, a tone. You set it up so  that there's a .vag 
for each tone. You have to set this by hand via the  .def file. To see other 
people's .def files for their programs, type  "mkvab -r person.vab -o 
person.def" where person.vab is their vab, and  person.def is the output .def 
that you want to look at. In the .def file  is where you associate programs 
and tones. A program can have one or more  tones, but the way it is usually 
set up is that there's a program for each  sound, and each program only 
contains one tone, the .vag that you specify.  Sometimes people use maybe two 
programs and say ten different tones, and  maybe 4 tones in the first program 
and 6 tones in the second program, where  each tone is associated with a vag. 
I don't know why, though. Maybe someone  can answer this for me. Anyway, 
suppose you set up your .def so that program  0 has two tones, a.vag and 
b.vag, and program 1 has one tone, c.vag. So to  play the sound, you do 
"SsUtKeyOn(vabid, prog, tone, note, fine,  voll, volr);", where prog is the 
the program for the sound you want to play as  specified in your .def file, 
such as prog 0, and tone is the tone of that prog as  specified in your .def 
file, such as tone 0 or tone 1. The note is the pitch to play the sound. At 0, 

it's normal. Increasing the pitch is like going up the keys of a piano. The 
fine parameter is just fine pitch. And voll and volr is the left and right 
volumes. But what about vabid? Well, when you call SsVabTransfer(), you get 
returned a vab id. This is the vab that is being used for your sound calls. 
The vab got loaded into sound memory when you called SsVabTransfer(), where 
you have to specify the VH and VB type files that have been loaded into main 
memory from siocons. How did they get into main memory in the first place? 
Well, all you have to do is split up your vab you made, sounds.vab, with 
"vabsplit sounds.vab". Then you got the files sounds.vh and sounds.vb, which 
you just load into the psx memory via siocons. Using the syntax of 
SsVabTransfer(), you just transfer them into sound memory, and you're ready to 

make sound calls.  


1) In the green manual, RotMatrix(MATRIX *m, SVECTOR *r) should actually be 
RotMatrix(SVECTOR *r, MATRIX *m)


1) What Yaroze tutorials are available?

Ira Rainey's Sprite Tutorial (SCEE)

James Chow's help docs (SCEE)

Peter Passmore's 3D Tutorial (SCEE)

Robert Swan's accompaniment to above tutorial (SCEE) - see other downloads too

Jamin Frederick's Sprite Tutorial (SCEA)

Nelson Santos' Ping - beginner game with docs

2) What are some useful general-purpose yaroze utilities?

**SCEE member sites:

Memory Viewer - graphically view Yaroze RAM, 0x80000000 to 0x801fffff

Analog PAD diagnostics - displays analog PAD values

DOS yaroze tools for people who don't like windows

ARS (Action Replay File Server) - lets you do i/o with yaroze at 20x the 
speed;  NOTE: you need Datel Action Replay for this

NiceARS - ARS implemented in windows NT;  NOTE: you need Datel Action Replay 
for this

RsdAnim - "...a PC (Win95) hosted keyframe animator for Playstation RSD format 

3D models...."

Binary Conversion Tool - converts data files to C source binaries

Sound Effects Player - lets you test sounds on yaroze 

C++ Library - wrappers around standard pslib function calls

Yaroze Master - makes editing and using makefiles a snap on Win95/NT

Lightwave to RSD converter - convert from LOB to RSD

Starfield Library - function calls to easily make a 3d starfield

GCC C++ - Win32 compiler for your C++ code, even if you don't have Codewarrior

Crossroads - freeware 3D file converter (Win32)

Convert - freeware DOS audio file converter 

PAK - compression utility for data uploads (incomplete?)

Linux Tools

Amiga Tools

Unix Tools

Utilities for Atari ST sprites

TMD Viewer - includes depth cuing and object/viewpoint manipulation

CRNCHPLY - reduces redundant PLY data
CRNCHPL - same as above, but without DOS4GW.EXE 
MEMEDIT - edit the contents of any file on your second memory card
DATAMAN - manages data download offsets

Memory Card Dump

Stereoscopic Vision

Dump Address - creates .h and batch files for your Yaroze datafiles
Palette Ripper - extracts Cluts from PCX files. Useful for light and palette 
Vertex Extractor - Extracts vertex and normal data from TMD files. Useful for 
animated 3D objects

**SCEA member sites:

VRAM and TIM viewer

PSXsock - enables TCP/IP connection of Yaroze (Win95/NT)

Unix Tools

Psx IDE - front end to gcc for Win95/NT

WAD Builder - compression utility for Yaroze data/code

Joystick Routines
Sprite Animation
(libraries and example code)

Card save module - functions to save to memory card
Font module - lets you use pretty, custom fonts
Menu module - lets you easily make a menu system

Address Arranger - automatically arranges your data addresses for downloading
Sprite Assembler - clips a sprite from a TIM and resaves it
TIM Manipulator - fiddle with specific TIM attributes
Screen Grabber - grabs the screen and stores as a file

PPTMDView - TMD/RSD viewer for Mac

Font Library - fonts and special effects

GsBG Library - lets you do tiled backgrounds

3) Where is there some useful technical info?

**SCEE member sites:

Scott Evans' Technical Notes

Some intro demos and tidbits: dynamic TMDs, lines, sprites, gradients, split 
screen (Robert Swan, Downloads section)

Various technical info

Using DevStudio with GCC

General matrix and MIPS info, graphics links

Shiny Toruses

3D Studio file format

Motion Capture

TMD file format

Exception Handling

Macintosh help

C++ for Yaroze

**SCEA member sites:

Multiple CLUTs 
Misc Tricks 
Fixed Point

Using the Yaroze with C++

C++ class examples

Some programming tips 

Some answered FAQs

VSync() Diagram

Tidbit on speeding up DOS SIOCONS programs

Macintosh resources

Some info on SSUtKeyOn()

Docs describing api

4) Where are some other interesting sites?

Personal profiles of participating Yaroze members

Yaroze Game Reviews

Net Yaroze Times

Club Yaroze

Underground Yaroze (no longer updated)

5) Are there any chat sessions going on? 

Yaroze Chat in Auditorium on SCEA web page (every Saturday 9:00pm EST)

James Rutherford's chat page (schedule posted)

ICQ Chat Group

6) What yaroze contests are there?  Who can participate?

UK Game Developer 98 -- SCEE Yaroze only

) Is there any way to read from a CD other than the Yaroze boot disk, and is 
it allowed?

) Can I run yaroze programs on a regular playstation?  Do I still need to 

) What are some cool 2D special effects?

) What are some cool 3D special effects?

) How do I get PAL games from SCEE to work in NTSC?

) What is ARG and Pro Action Replay?

) How much is Pro Action Replay, and where do I get it?