Quake BSP renderer for PS1
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

131 lines
3.8 KiB

#include "common.h"
#include "display.h"
#include <inline_c.h>
// Define display/draw environments for double buffering
static DISPENV disp[2];
static DRAWENV draw[2];
static int db;
u_long ot[2][OTLEN]; // Ordering tables, two arrays for double buffering. These are basically the buckets for bucket sorting of polygons.
// You can also see them as "layers" in the modern 3D graphics sense, but they serve a more immediate role for polygon ordering.
// Layer 0 is free for overlays, as polygons at depth 0 will be clipped.
char primbuff[2][65536]; // Primitive buffer, just a raw buffer of bytes to use as a pool for primitives
char *nextpri;
const MATRIX identity = {
ONE, 0, 0,
0, ONE, 0,
0, 0, ONE,
0, 0, 0,
};
// Transform to change the coordinate system from PS1 Default (Y down, Z forward) to Quake (Z up, Y forward)
const MATRIX quake_swizzle = {
ONE, 0, 0,
0, 0, -ONE,
0, ONE, 0,
0, 0, 0,
};
MATRIX light_cols = {
ONE, 0, 0,
ONE, 0, 0,
ONE, 0, 0
};
MATRIX light_dirs = {
ONE, 0, 0,
0, 0, 0,
0, 0, 0
};
// Scale X coordinates to correct the aspect ratio for the chosen resolution
VECTOR aspect_scale = { SCREENWIDTH * ONE / 320 , ONE, ONE };
void display_init()
{
// This not only resets the GPU but it also installs the library's
// ISR subsystem to the kernel
ResetGraph(0);
SetVideoMode(MODE_NTSC);
// Define display environments, first on top and second on bottom
SetDefDispEnv(&disp[0], 0, 0, SCREENWIDTH, SCREENHEIGHT);
SetDefDispEnv(&disp[1], 0, SCREENHEIGHT, SCREENWIDTH, SCREENHEIGHT);
// Define drawing environments, first on bottom and second on top
SetDefDrawEnv(&draw[0], 0, SCREENHEIGHT, SCREENWIDTH, SCREENHEIGHT);
SetDefDrawEnv(&draw[1], 0, 0, SCREENWIDTH, SCREENHEIGHT);
// Set and enable clear color
setRGB0(&draw[0], 49, 77, 121);
setRGB0(&draw[1], 49, 77, 121);
draw[0].isbg = 1;
draw[0].dtd = 1;
draw[1].isbg = 1;
draw[1].dtd = 1;
// Clear double buffer counter
db = 0;
// Apply the GPU environments
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
// Load test font
FntLoad(960, 448);
// Open up a test font text stream
FntOpen(0, 8, SCREENWIDTH, SCREENHEIGHT, 0, 200);
// TODO: OT initialization
// Initialize GTE
InitGeom();
gte_SetGeomOffset(SCREENWIDTH >> 1, SCREENHEIGHT >> 1);
gte_SetGeomScreen(180); // Screen depth for FOV control. Determines the distance of the camera to the near plane.
}
void display_start()
{
ClearOTagR(ot[db], OTLEN);
gte_SetBackColor(48, 48, 48); // Ambient light color
gte_SetColorMatrix(&light_cols); // Light color (up to three different lights)
MATRIX proj_matrix = quake_swizzle; // Swizzle coordinates so that everything is in Quake coordinate system (Z up)
ScaleMatrixL(&proj_matrix, &aspect_scale); // Apply aspect ratio correction for the current resolution
MATRIX view_matrix;
SVECTOR trot = { -cam_rot.vx, -cam_rot.vy, -cam_rot.vz, 0 }; // Inverse camera rotation (in Quake coordinates)
VECTOR tpos = { -cam_pos.vx, -cam_pos.vy, -cam_pos.vz }; // Inverse camera position (in Quake coordinates)
RotMatrixQ(&trot, &view_matrix); // Set camera rotation part of the view matrix
ApplyMatrixLV(&view_matrix, &tpos, &tpos); // Apply camera rotation to camera position
TransMatrix(&view_matrix, &tpos); // Apply transformed position to the translation part of the view matrix
// Compose view and projection matrices to obtain a combined view-projection matrix
CompMatrixLV(&proj_matrix, &view_matrix, &view_matrix);
}
void display_finish()
{
// Flip buffer index
db = !db;
// Wait for all drawing to complete
DrawSync(0);
// Wait for vertical sync to cap the logic to 60fps (or 50 in PAL mode)
// and prevent screen tearing
VSync(0);
// Switch pages
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
// Enable display output, ResetGraph() disables it by default
SetDispMask(1);
}