What's new

Need Plugin-Dev Help!

Spacy

New member
Hi at all.

I've started to develop a N64 Graphics Plugin tht uses Zilmars GFX Specs 1.3 and DirectX9.

I understood Zilmar's specs mostly, but there are really important things that I don't understand:

Where s the polygon data that should be drawn and where are the textures. Some more explanations may be helpfull.

Here is the part of ZIlmar's Specs that I don't understand:
(Of course i know what a HWND is, but what's about "MemoryBswaped" and "HEADER" and the "DPC_xxxx" and "VI_xxx" Registers?
--------------------------------------------------------------
typedef struct {
HWND hWnd; /* Render window */
HWND hStatusBar; /* if render window does not have a status bar then this is NULL */

BOOL MemoryBswaped; // If this is set to TRUE, then the memory has been pre
// bswap on a dword (32 bits) boundry
// eg. the first 8 bytes are stored like this:
// 4 3 2 1 8 7 6 5

BYTE * HEADER; // This is the rom header (first 40h bytes of the rom
// This will be in the same memory format as the rest of the memory.
BYTE * RDRAM;
BYTE * DMEM;
BYTE * IMEM;

DWORD * MI_INTR_REG;

DWORD * DPC_START_REG;
DWORD * DPC_END_REG;
DWORD * DPC_CURRENT_REG;
DWORD * DPC_STATUS_REG;
DWORD * DPC_CLOCK_REG;
DWORD * DPC_BUFBUSY_REG;
DWORD * DPC_PIPEBUSY_REG;
DWORD * DPC_TMEM_REG;

DWORD * VI_STATUS_REG;
DWORD * VI_ORIGIN_REG;
DWORD * VI_WIDTH_REG;
DWORD * VI_INTR_REG;
DWORD * VI_V_CURRENT_LINE_REG;
DWORD * VI_TIMING_REG;
DWORD * VI_V_SYNC_REG;
DWORD * VI_H_SYNC_REG;
DWORD * VI_LEAP_REG;
DWORD * VI_H_START_REG;
DWORD * VI_V_START_REG;
DWORD * VI_V_BURST_REG;
DWORD * VI_X_SCALE_REG;
DWORD * VI_Y_SCALE_REG;

void (*CheckInterrupts)( void );
} GFX_INFO;
 

Cyberman

Moderator
Moderator
Spacy said:
Hi at all.

I've started to develop a N64 Graphics Plugin tht uses Zilmars GFX Specs 1.3 and DirectX9.

I understood Zilmar's specs mostly, but there are really important things that I don't understand:

Where s the polygon data that should be drawn and where are the textures. Some more explanations may be helpfull.

Here is the part of ZIlmar's Specs that I don't understand:
(Of course i know what a HWND is, but what's about "MemoryBswaped" and "HEADER" and the "DPC_xxxx" and "VI_xxx" Registers?
--------------------------------------------------------------
typedef struct {
HWND hWnd; /* Render window */
HWND hStatusBar; /* if render window does not have a status bar then this is NULL */

BOOL MemoryBswaped; // If this is set to TRUE, then the memory has been pre
// bswap on a dword (32 bits) boundry
// eg. the first 8 bytes are stored like this:
// 4 3 2 1 8 7 6 5

BYTE * HEADER; // This is the rom header (first 40h bytes of the rom
// This will be in the same memory format as the rest of the memory.
BYTE * RDRAM;
BYTE * DMEM;
BYTE * IMEM;

DWORD * MI_INTR_REG;

DWORD * DPC_START_REG;
DWORD * DPC_END_REG;
DWORD * DPC_CURRENT_REG;
DWORD * DPC_STATUS_REG;
DWORD * DPC_CLOCK_REG;
DWORD * DPC_BUFBUSY_REG;
DWORD * DPC_PIPEBUSY_REG;
DWORD * DPC_TMEM_REG;

DWORD * VI_STATUS_REG;
DWORD * VI_ORIGIN_REG;
DWORD * VI_WIDTH_REG;
DWORD * VI_INTR_REG;
DWORD * VI_V_CURRENT_LINE_REG;
DWORD * VI_TIMING_REG;
DWORD * VI_V_SYNC_REG;
DWORD * VI_H_SYNC_REG;
DWORD * VI_LEAP_REG;
DWORD * VI_H_START_REG;
DWORD * VI_V_START_REG;
DWORD * VI_V_BURST_REG;
DWORD * VI_X_SCALE_REG;
DWORD * VI_Y_SCALE_REG;

void (*CheckInterrupts)( void );
} GFX_INFO;

I moved this to the appropriate forum .. to get to your question though.

Perhaps examining some of the source code available and examining that carefully. Suggested ones to look at would be Glide64 to start with :)

I haven't twiddled with N64 emulation in a few years so brain is pretty blank at the moment on the specifics.

Cyb
 

blight

New member
the n64 in fact has a software renderer which is loaded with a microcode (ucode) by the program (game).

bswapped indicates if "the memory" has been byteswapped (different kind of platforms store data types in different order: intel processors store the least significant byte of a multi-byte data-type first while PPC/RISC processors usually do it the other way around - this is called the "byte order") - "the memory" is the data pointed to by the HEADER, RDRAM, VI_XX (these might already be bswapped i am not sure), ... pointers. there is a function which is called when the plugin has to process data. it has to interpret the memory, at a location pointed to by some register, like the microcode on the software-rendering-processor in the real n64 would do and act according to the information in that data. the data is made up of display lists which consist of the different kind of commands to draw things. you have to get the vertexes, textures and all the other stuff yourself out of the memory (it's encoded into the display list commands i think)

this is why only professionals write such plugins - and anyone who has written one has to be a pro!
 
Last edited:
OP
Spacy

Spacy

New member
<<this is why only professionals write such plugins - and anyone who has written one has to be a pro!>>

OK, I'm not really a professional. Not in DirectX and not in N64 Developing.

I've been long times in Gameboy Romhacking, so I'm kind of familiar with hardware and Bits and Bytes and so on.

I will still try to make a plugin.

OK, till now, I've looked at much source from other plugins, and I understand how it works (Operation Code Interpreting). GBI.H was very usefull for this ^^

I've got some other probs now:
Is there somewhere a list of all Operations (for ex. G_TRI1, G_CULLDL, G_TEXTURE, G_SETFILLCOLOR, G_FILLRECT, and all the other commands) and what the operations do? At this point, every source I see is made another way, so a list what the Operation-Codes do would be very usefull.

Has someone got such a list or knows where to get it?
 

vleespet

The decent one
I haven't, but I just want to say that I'm happy that you're creating a new plugin. I hope you will complete this job with success. Good luck!
 
OP
Spacy

Spacy

New member
Yeah, thanks a lot :)

I've got some questions about Display Lists (used in ProcessDList):
How is the Display List constructed?

Is the following correct?
<Command> <Paramter1> <Parameter2>

And I still need a list with some Command-Explanations.

Another question:
How can I load the uCode from the ROM (from inside a gfx plugin?)

PS: Please ask if you don't understand something (in my language), because I can't speek realy good english ^_^"

PS²:
Really thanks to everyboda who helps me here a bit :)
 
OP
Spacy

Spacy

New member
Since now, I didn't get which commands I have to execute. In the following, there are (I think) all commands that I can get through display lists. Must I only execute the commands listed at "RDP commands" or have I to execute "DMA" and "IMMEDIATE" commands, too? What's about the last section, the "generated" commands?

I've added an attachment. Is this correct (the second page about plugins!)?

(Here is my fixed table ripped from GBI.h ^_^)
//----------------------------------------------------------------------------------------------------
// ###################
// # Operation Codes #
// ###################

/* DMA commands: */
const BYTE G_SPNOOP = 0; /* handle 0 gracefully */
const BYTE G_MTX = 1;
const BYTE G_RESERVED0 = 2; /* not implemeted */
const BYTE G_MOVEMEM = 3; /* move a block of memory (up to 4 words) to dmem */
const BYTE G_VTX = 4;
const BYTE G_RESERVED1 = 5; /* not implemeted */
const BYTE G_DL = 6;
const BYTE G_RESERVED2 = 7; /* not implemeted */
const BYTE G_RESERVED3 = 8; /* not implemeted */
const BYTE G_SPRITE2D = 9; /* sprite command */

/* IMMEDIATE commands: */
const BYTE G_IMMFIRST = 0xbf; // vorher -65: 0xff-65 !+1!
const BYTE G_TRI1 = (G_IMMFIRST-0);
const BYTE G_CULLDL = (G_IMMFIRST-1);
const BYTE G_POPMTX = (G_IMMFIRST-2);
const BYTE G_MOVEWORD = (G_IMMFIRST-3);
const BYTE G_TEXTURE = (G_IMMFIRST-4);
const BYTE G_SETOTHERMODE_H = (G_IMMFIRST-5);
const BYTE G_SETOTHERMODE_L = (G_IMMFIRST-6);
const BYTE G_ENDDL = (G_IMMFIRST-7);
const BYTE G_SETGEOMETRYMODE = (G_IMMFIRST-8);
const BYTE G_CLEARGEOMETRYMODE = (G_IMMFIRST-9);
const BYTE G_LINE3D = (G_IMMFIRST-10);
const BYTE G_RDPHALF_1 = (G_IMMFIRST-11);
const BYTE G_RDPHALF_2 = (G_IMMFIRST-12);
const BYTE G_RDPHALF_CONT = (G_IMMFIRST-13);

/* RDP commands: */
const BYTE G_NOOP = 0xc0; /* 0 */
const BYTE G_SETCIMG = 0xff; /* -1 */
const BYTE G_SETZIMG = 0xfe; /* -2 */
const BYTE G_SETTIMG = 0xfd; /* -3 */
const BYTE G_SETCOMBINE = 0xfc; /* -4 */
const BYTE G_SETENVCOLOR = 0xfb; /* -5 */
const BYTE G_SETPRIMCOLOR = 0xfa; /* -6 */
const BYTE G_SETBLENDCOLOR = 0xf9; /* -7 */
const BYTE G_SETFOGCOLOR = 0xf8; /* -8 */
const BYTE G_SETFILLCOLOR = 0xf7; /* -9 */
const BYTE G_FILLRECT = 0xf6; /* -10 */
const BYTE G_SETTILE = 0xf5; /* -11 */
const BYTE G_LOADTILE = 0xf4; /* -12 */
const BYTE G_LOADBLOCK = 0xf3; /* -13 */
const BYTE G_SETTILESIZE = 0xf2; /* -14 */
const BYTE G_LOADTLUT = 0xf0; /* -16 */
const BYTE G_RDPSETOTHERMODE = 0xef; /* -17 */
const BYTE G_SETPRIMDEPTH = 0xee; /* -18 */
const BYTE G_SETSCISSOR = 0xed; /* -19 */
const BYTE G_SETCONVERT = 0xec; /* -20 */
const BYTE G_SETKEYR = 0xeb; /* -21 */
const BYTE G_SETKEYGB = 0xea; /* -22 */
const BYTE G_RDPFULLSYNC = 0xe9; /* -23 */
const BYTE G_RDPTILESYNC = 0xe8; /* -24 */
const BYTE G_RDPPIPESYNC = 0xe7; /* -25 */
const BYTE G_RDPLOADSYNC = 0xe6; /* -26 */
const BYTE G_TEXRECTFLIP = 0xe5; /* -27 */
const BYTE G_TEXRECT = 0xe4; /* -28 */

/*
* The following commands are the "generated" RDP commands; the user
* never sees them, the RSP microcode generates them.
*
* The layout of the bits is magical, to save work in the ucode.
* These id's are -56, -52, -54, -50, -55, -51, -53, -49, ...
* edge, shade, texture, zbuff bits: estz
*/
const BYTE G_TRI_FILL = 0xc8; /* fill triangle: 11001000 */
const BYTE G_TRI_SHADE = 0xcc; /* shade triangle: 11001100 */
const BYTE G_TRI_TXTR = 0xca; /* texture triangle: 11001010 */
const BYTE G_TRI_SHADE_TXTR = 0xce; /* shade, texture triangle: 11001110 */
const BYTE G_TRI_FILL_ZBUFF = 0xc9; /* fill, zbuff triangle: 11001001 */
const BYTE G_TRI_SHADE_ZBUFF = 0xcd; /* shade, zbuff triangle: 11001101 */
const BYTE G_TRI_TXTR_ZBUFF = 0xcb; /* texture, zbuff triangle: 11001011 */
const BYTE G_TRI_SHADE_TXTR_ZBUFF = 0xcf; /* shade, txtr, zbuff trngl: 11001111 */

/*
* A TRI_FILL triangle is just the edges. You need to set the DP
* to use primcolor, in order to see anything. (it is NOT a triangle
* that gets rendered in 'fill mode'. Triangles can't be rendered
* in 'fill mode')
*
* A TRI_SHADE is a gouraud triangle that has colors interpolated.
* Flat-shaded triangles (from the software) are still gouraud shaded,
* it's just the colors are all the same and the deltas are 0.
*
* Other triangle types, and combinations are more obvious.
*/
//----------------------------------------------------------------------------------------------------
 

Orkin

d1R3c764 & g1|\|64 m4|<3R
Yes, you must emulate the DMA and immediate commands -- those are the RSP commands. The "generated" commands are those that the real RSP on the N64 generates, and passes along to the RDP for rasterization. You don't need to worry about these.

The syntax for the commands doesn't really follow any pattern, other than the command opcode is held in the highest-order byte in the first 32-bit word of the command. You can look through GBI.H to see how the parameters are encoded for each command. Also, keep in mind that the comand sets and opcodes change between ucodes...

The DPC and VI registers contain info on the current state of the VI, and the Display Processor. You don't need to worry about the DPC registers, since you're essentially by-passing it by HLEing the RSP, but the VI registers are usefull for telling the current size of the N64 display.

Your chart isn't quite correct...a video plugin's job starts two steps higher than that, but we also skip the RDP altogether, and go straight to the graphics API. Most of the video plugin's job is HLEing the RSP, the RDP part is relatively small (although it also presents some of the more difficult problems).
 
Last edited:
OP
Spacy

Spacy

New member
Nice, the basics are done, super mario 64 logo and world is shown untransformed (for testing purposes, I added a y-axis rotation).

There's just one prob:
I'm 15 years old, and I didn't hat matrices in school till now ^^"
I read the basics from a school-book of my brother, but I need a litle bit information about vertex transformation and rotation, scaling and all this stuff.
Does someone know where to get informations about that?

PS:
@Orkin:
respect, really good plugin ;)
but one prob: gln64 is asking for a ucode in mario kart 64 us (i think it was v1.0)
Have you got probs there too?
 

Trotterwatch

New member
but one prob: gln64 is asking for a ucode in mario kart 64 us (i think it was v1.0)
Have you got probs there too?

Manually set it to F3DEX - this was just a small accidental ommission from the plugin AFAIK.
 

Orkin

d1R3c764 & g1|\|64 m4|<3R
Yeah...the problem with Mario Kart is a stupid mistake on my part...I rewrote the ucode detection in v0.4.1, and forgot to check for F3DEX v0.95 (the version Mario Kart uses).

There are many sources on the Internet that explain 3D matrix transformations, so looking around and reading up on it would be a big help. You really don't need to worry much about what the matrices are doing, just load what the ROM sends you, and transform the vertices with it.

One thing to watch out for is the odd way the N64 stores matrices. I recommend that you look at another plugin's source for help there (don't look at glN64's, it's written in assembler and difficult to read).
 
OP
Spacy

Spacy

New member
Right, glN64's Matrix load functions are not understandeable for me ^^"

I'm looking forward to a new version of glN64 with a correct ucode detection, so I don't habe to set it always during playing.

The name I've chosen for my plugin is:
Shine 64

I had 2 other names before, but after a time I didn't liked them ^^

At the moment I don't have any time for coding, because I've got practical training (still 1,5 weeks more) and after that other things are waiting.

I think I will be able to continue when my practical training is done.

Thanks for all the help ^_^
 

decription

New member
Best of luck to you, I'm happy to help in anyway possible. You remind me of Glide64 and how it was built my a young author with help from this board. Besides checking the glide sources perhaps looking through some really old Glide64 topics could help. Much of the code is posted in the thread as are countless other ideas and brilliant thoughts.
 

Top