Un-ignored: the dev drive is the ground truth the restoration and emulator work constantly reference (DPL3/LIBDPL + VRENDER i860 renderer source, BT/RP live+dev game trees, VGL_LABS pod boot, scene/audio content). Kept in-repo for the pod-owner community. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
112 lines
19 KiB
C++
112 lines
19 KiB
C++
|
|
#define divpl5_xshift 6
|
|
#define divpl5_yshift 7
|
|
|
|
#define X 0
|
|
#define Y 1
|
|
|
|
typedef struct s_bininfo {
|
|
int bin_minx;
|
|
int bin_miny;
|
|
int bin_maxx;
|
|
int bin_maxy;
|
|
} bininfo;
|
|
|
|
typedef struct s_preplane {
|
|
float x23;
|
|
float x31;
|
|
float x12;
|
|
float C;
|
|
} preplane;
|
|
|
|
|
|
/*{{{ datastructures for binitizing*/
|
|
/* *********************************
|
|
|
|
what are the best datastructures for binitizing ?
|
|
|
|
they need working out in conjunction with the DMA engine
|
|
protocol
|
|
|
|
the DMA engine takes, per bin, an array of 64-bit words, organised as
|
|
|
|
address:count|opcode
|
|
|
|
the address is where the IGC data resides, the count is the no of
|
|
64-bit words in the IGC packet. The packet could be typically a
|
|
triangle, a partial triangle, a sphere or a chunk of end-of-frame data
|
|
triangles are 30-40 32-bit words long.
|
|
|
|
a screen may be anything from 512 to 1280 pixels wide, which is from 8
|
|
to 64 bins wide, typically 10 (NTSC) - awkward, needs * rather than <<
|
|
|
|
a typical bin data looks like
|
|
|
|
address:count
|
|
address:count
|
|
address:count
|
|
...
|
|
address:count
|
|
|
|
in contiguous memory locations. How to assemble these live with
|
|
minimal mallocing?
|
|
|
|
YEAH - good one hardware guys. The macro language supports a GOTO;
|
|
so we simply malloc chunks of say 32 64-bit words, and the last one
|
|
contains GOTO next chunk. So we never need to memcpy. In fact in the
|
|
steady-state we never need to malloc.
|
|
|
|
So if we have to render a triangle, we have to put its IGC data into
|
|
memory, then reference this data from multiple bin lists. All rendered
|
|
triangles can be put into a huge pool (double-buffered), which is
|
|
just incremented.
|
|
|
|
So we have the structures in place - how do we binitize?
|
|
|
|
Lets render a triangle -
|
|
|
|
pre --> enable voodoo 1
|
|
edge 4
|
|
edge 4
|
|
edge 4
|
|
z compare 4
|
|
z replace 4
|
|
lum 4
|
|
spec 4
|
|
scalar_stuff 1
|
|
p -->
|
|
|
|
We need to place pre:42 (pre:21?) into all the bins the triangle overlaps
|
|
For each bin we need a head chunk, and a tail chunk. Each chunk contains a
|
|
count (so I know where to put the next triangle).
|
|
|
|
I think I am starting to understand how to do this ...
|
|
|
|
*/
|
|
/*}}} */
|
|
|
|
#define BIN_FULL (254*2*4) /* when index==this, chain into next chunk */
|
|
|
|
typedef struct s_binchunk {
|
|
/* force this to be 1/2 page long */
|
|
int DMA_opcodes[(BIN_FULL>>2)+2]; /* force dbl-alignment, 64 triangles worth */
|
|
int usage; /* in 32-bit words, always dbl-bumped */
|
|
struct s_binchunk *next; /* only used for housekeeping */
|
|
} binchunk;
|
|
|
|
|
|
typedef struct s_screenbin {
|
|
binchunk *head;
|
|
binchunk *tail;
|
|
} screenbin;
|
|
|
|
typedef struct s_coeffchunk {
|
|
/* force this to be 65536 bytes long */
|
|
int IGC_opcodes[65532>>2];
|
|
struct s_coeffchunk *next; /* only used for housekeeping */
|
|
} coeffchunk;
|
|
|
|
|
|
#define COEFF_FULL (65532-512) /* when bytes>=this, chain into next chunk */
|
|
|