Displaying TextThe beginingI started my experiments by trying to display text. All of the examples I found were for Yaroze or something similar that we don't have access to in the lab (but I found the libs on some of the sites if you want them for your use). I found one example that was written in assembly. The only problem with this one was that it had an external file (which was included in the program at compile time) that it used for the font graphic data, and I could not get file access working so as to read in the file at runtime in a C program, since I know of no way to link a binary file with a C program at compile time. So, I wrote a short program that converted the FONT.BIN that came with the assembly program into a .h file that I could include in a C program. The resulting file is fontdata.h. Porting the assemblyThe first thing I tried to do was port the assembly code over to C. I did this as an ugly hack using lots of global variables and a 1<->1 conversion from .asm code to C code. That code is availible here : printGPU_asm.c. I ended up making a few changes from how the original program did the drawing... the original program used a 4-bit clut (Color Lookup Table), where each of the pixels in the texture buffer took up 4 bits (instead of 16bits), and it looked up the associated color from a table. Unfortunately, I was not able to get this to work. I believe it was because of a problem loading the clut into memory. I decided to just change the character graphics to larger 15bit values and ignore using the clut.Cleaning up the assemblyThen, I cleaned up the program, drastically decreasing the size and (hopefully) efficiency, yielding this. Lastly, I converted the code to a form that uses a struct similar to the examples provided, which may, or may not, make more sense, depending on how your brain works. This code is what is probably the most useable, since it also provides a framework for an easy way to implement sprites. That code is here : printGPU_sprite.c. You can also download a precompiled .exe : printGPU_sprite.exe.I also took the important code out and it is availible as just a .c and .h file you can link with your programs : printGPU.c, printGPU.h. How printing text worksIn order to use this code in your own programs, you need to do 4 things:
The printGPU function steps through each of the characters in the string, finds the appropriate texture coordinates for the character, and draws 2 8x8 sprites to the output coordinates in order to copy the 8x16 character graphic. Text - Sprites - GPU Status - MSVC++ - Postmortem Displaying Arbitrary SpritesBy looking in the GPU reference, I was able to find the codes and syntax of the commands to draw sprites. I set up a struct like this :typedef struct { PsxUInt8 r,g,b,code; PsxUInt16 x,y; PsxUInt8 u,v; PsxUInt16 clut; } SPRITE;That takes the parameters need to draw a sprite. r, g, and b are obviously the colors to draw with. code is one of :
Defining the texture pageTo define the texture page you're drawing sprites from, you use the GPU command 0xe1. The bit-layout of the command is (take from gpu.txt|1f-18|17-0b|0a |09 |08 07|06 05|04|03 02 01 00| |0xe1 | |dfe|dtd|tp |abr |ty|tx | tx 0-f X*64 texture page x coord ty 0 0 texture page y coord 1 256 abr 0 0.5xB+0.5 xF Semi transparency mode 1 1.0xB+1.0 xF 2 1.0xB-1.0 xF 3 1.0xB+0.25xF tp 0 4bit CLUT 1 8bit CLUT 2 15bit direct dtd 0 Ditter off 1 Ditter on dfe 0 Draw to display area prohibited 1 Draw to display area allowedI pretty much ignore arb, dtd, and dfe, leaving them as what they were in the gpuInit() function. So, if we had our texture sitting in memory at (512,0) and we're using 15-bit direct for our sprites, as I did in my font drawing, we would call: GPU_cw(0xe1000708); This value can be assembled using bit-wise functions like this: void setDrawMode(PsxUInt16 tx, PsxUInt16 ty, PsxUInt8 abr, PsxUInt8 tp, PsxUInt8 dtd, PsxUInt8 dfe) { PsxUInt32 command; if (ty!=0) { ty = 1; } tx = tx >> 6; // Divide by 64 command = (0xe1 << 0x18) | (dfe << 0x0a) | (dtd << 9) | (tp << 7) | (abr << 5) | (ty << 4) | tx; GPU_cw(command); } Text - Sprites - GPU Status - MSVC++ - Postmortem Displaying GPU statusWhile programming and debugging, I was running into some really weird problems (it seems to be a bug in mem2vram, but I haven't verified it yet), so I wrote a function that verbosely displays the status of the GPU. It takes the result of GetGPUStatus() and displays the text equivalent of the 20 fields returned. This code is included in all of the above files, in a function called DisplayStatus().Text - Sprites - GPU Status - MSVC++ - Postmortem Developing in the MSVC++ IDEBeing that I have yet to find a better C/C++ environment than MS's Visual C++, I immediately configured it to allow me to compile and run PSX apps from within the IDE. If you're interested in doing this, it really only takes 4 steps:
If you are using Windows NT, 2K, 2K3, or XP, you can set these environment variables under Control Panel | System | Advanced | Environment Variables, or something like that. Otherwise, you want to up the memory for command.com. In Win9x, you can put something like this in your autoexec.bat file: SET COMSPEC=C:\COMMAND.COM /E:8192Or (probably the easiest way out of all of these), make one batch file that has all of these commands you want to run like this. And then in MSVC++ have the script run this: C:\COMMAND.COM /E:8192 /C WORKER.BAT $(InputName)You may need to replace "C:\command.com" with "C:\cmd.exe" or "c:\windows\system32\cmd.exe" Text - Sprites - GPU Status - MSVC++ - Postmortem What I learned
|