File: HardwareSetup.cpp

package info (click to toggle)
descent3 1.5.0%2Bds-2
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid
  • size: 35,256 kB
  • sloc: cpp: 416,147; ansic: 3,233; sh: 10; makefile: 8
file content (163 lines) | stat: -rw-r--r-- 5,025 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
* Descent 3 
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdlib.h>
#include <string.h>
#include "3d.h"
#include "pserror.h"
#include "HardwareInternal.h"
#include "renderer.h"

// User-specified aspect ratio, stored as w/h
static float sAspect = 0.0f;

// initialize the 3d system
void g3_Init(void) { atexit(g3_Close); }

// close down the 3d system
void g3_Close(void) {}

// allows the user to specify an aspect ratio that overrides the renderer's
// The parameter is the w/h of the screen pixels
void g3_SetAspectRatio(float aspect) { sAspect = aspect; }
// returns the user-specified aspect ratio used to override the renderer's
float g3_GetAspectRatio() { return sAspect; }

void g3_GetViewPortMatrix(float *viewMat) {
  // extract the viewport data from the renderer
  int viewportWidth, viewportHeight;
  int viewportX, viewportY;
  rend_GetProjectionScreenParameters(viewportX, viewportY, viewportWidth, viewportHeight);

  float viewportWidthOverTwo = ((float)viewportWidth) * 0.5f;
  float viewportHeightOverTwo = ((float)viewportHeight) * 0.5f;

  // setup the matrix
  memset(viewMat, 0, sizeof(float) * 16);
  viewMat[0] = viewportWidthOverTwo;
  viewMat[5] = -viewportHeightOverTwo;
  viewMat[12] = viewportWidthOverTwo + (float)viewportX;
  viewMat[13] = viewportHeightOverTwo + (float)viewportY;
  viewMat[10] = viewMat[15] = 1.0f;
}

void g3_GetProjectionMatrix(float zoom, float *projMat) {
  // get window size
  int viewportWidth, viewportHeight;
  rend_GetProjectionParameters(&viewportWidth, &viewportHeight);

  // compute aspect ratio for this ViewPort
  float screenAspect = rend_GetAspectRatio();
  if (sAspect != 0.0f) {
    // check for user override
    screenAspect = screenAspect * 4.0f / 3.0f / sAspect;
  }
  float s = screenAspect * ((float)viewportWidth) / ((float)viewportHeight);

  // setup the matrix
  memset(projMat, 0, sizeof(float) * 16);

  // calculate 1/tan(fov)
  float oOT = 1.0f / zoom;

  // fill in the matrix
  projMat[0] = oOT;
  projMat[5] = oOT * s;
  projMat[10] = 1.0f;
  projMat[11] = 1.0f;
  projMat[14] = -1.0f;
}

// start the frame
void g3_StartFrame(vector *view_pos, matrix *view_matrix, float zoom) {
  // initialize the viewport transform
  g3_GetViewPortMatrix((float *)gTransformViewPort);
  g3_GetProjectionMatrix(zoom, (float *)gTransformProjection);
  g3_GetModelViewMatrix(view_pos, view_matrix, (float *)gTransformModelView);
  g3_UpdateFullTransform();

  // get window size
  rend_GetProjectionParameters(&Window_width, &Window_height);

  // Set vars for projection
  Window_w2 = ((float)Window_width) * 0.5f;
  Window_h2 = ((float)Window_height) * 0.5f;

  // Compute aspect ratio for this window
  float screen_aspect = rend_GetAspectRatio();
  if (sAspect != 0.0f) {
    // check for user override
    screen_aspect = screen_aspect * 4.0f / 3.0f / sAspect;
  }
  float s = screen_aspect * (float)Window_height / (float)Window_width;

  if (s <= 0.0f) // JEFF: Should this have been 1.0f?
  {
    // scale x
    Matrix_scale.x = s;
    Matrix_scale.y = 1.0f;
  } else {
    Matrix_scale.y = 1.0f / s;
    Matrix_scale.x = 1.0f;
  }

  Matrix_scale.z = 1.0f;

  // Set the view variables
  View_position = *view_pos;
  View_zoom = zoom;
  Unscaled_matrix = *view_matrix;

  // Compute matrix scale for zoom and aspect ratio
  if (View_zoom <= 1.0f) {
    // zoom in by scaling z
    Matrix_scale.z = Matrix_scale.z * View_zoom;
  } else {
    // zoom out by scaling x and y
    float oOZ = 1.0f / View_zoom;
    Matrix_scale.x = Matrix_scale.x * oOZ;
    Matrix_scale.y = Matrix_scale.y * oOZ;
  }

  // Scale the matrix elements
  View_matrix.rvec = Unscaled_matrix.rvec * Matrix_scale.x;
  View_matrix.uvec = Unscaled_matrix.uvec * Matrix_scale.y;
  View_matrix.fvec = Unscaled_matrix.fvec * Matrix_scale.z;

  // Reset the list of free points
  InitFreePoints();

  // Reset the far clip plane
  g3_ResetFarClipZ();
}

// this doesn't do anything, but is here for completeness
void g3_EndFrame(void) {
  // make sure temp points are free
  CheckTempPoints();
}

// get the current view position
void g3_GetViewPosition(vector *vp) { *vp = View_position; }

void g3_GetViewMatrix(matrix *mat) { *mat = View_matrix; }

void g3_GetUnscaledMatrix(matrix *mat) { *mat = Unscaled_matrix; }

// Gets the matrix scale vector
void g3_GetMatrixScale(vector *matrix_scale) { *matrix_scale = Matrix_scale; }