#include "common.h" #include "display.h" #include // 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); }