Rev 20 | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line | 
|---|---|---|---|
| 1 | pmbaty | 1 | #include "depth.h" | 
        
| 2 | |||
| 20 | pmbaty | 3 | #include "brender/brender.h" | 
        
| 1 | pmbaty | 4 | #include "displays.h" | 
        
| 5 | #include "errors.h" | 
        ||
| 6 | #include "globvars.h" | 
        ||
| 7 | #include "globvrkm.h" | 
        ||
| 8 | #include "globvrpb.h" | 
        ||
| 9 | #include "harness/hooks.h" | 
        ||
| 10 | #include "harness/trace.h" | 
        ||
| 11 | #include "pd/sys.h" | 
        ||
| 12 | #include "replay.h" | 
        ||
| 13 | #include "spark.h" | 
        ||
| 14 | #include "trig.h" | 
        ||
| 15 | #include "utility.h" | 
        ||
| 16 | #include "world.h" | 
        ||
| 17 | #include <math.h> | 
        ||
| 18 | #include <stdlib.h> | 
        ||
| 19 | |||
| 20 | tDepth_effect gDistance_depth_effects[4];  | 
        ||
| 21 | int gSky_on;  | 
        ||
| 22 | int gDepth_cueing_on;  | 
        ||
| 23 | tDepth_effect_type gSwap_depth_effect_type; | 
        ||
| 24 | br_scalar gSky_height; | 
        ||
| 25 | br_scalar gSky_x_multiplier; | 
        ||
| 26 | br_scalar gSky_width; | 
        ||
| 27 | br_scalar gSky_y_multiplier; | 
        ||
| 28 | tU32 gLast_depth_change; | 
        ||
| 29 | br_scalar gOld_yon; | 
        ||
| 30 | br_pixelmap* gWater_shade_table;  | 
        ||
| 31 | br_material* gHorizon_material;  | 
        ||
| 32 | br_model* gRearview_sky_model;  | 
        ||
| 33 | int gFog_shade_table_power;  | 
        ||
| 34 | br_actor* gRearview_sky_actor;  | 
        ||
| 35 | int gAcid_shade_table_power;  | 
        ||
| 36 | int gWater_shade_table_power;  | 
        ||
| 37 | br_model* gForward_sky_model;  | 
        ||
| 38 | br_actor* gForward_sky_actor;  | 
        ||
| 39 | int gDepth_shade_table_power;  | 
        ||
| 40 | br_pixelmap* gFog_shade_table;  | 
        ||
| 41 | int gSwap_depth_effect_start;  | 
        ||
| 42 | br_pixelmap* gDepth_shade_table;  | 
        ||
| 43 | tSpecial_volume* gLast_camera_special_volume;  | 
        ||
| 44 | br_pixelmap* gAcid_shade_table;  | 
        ||
| 45 | int gSwap_depth_effect_end;  | 
        ||
| 46 | br_pixelmap* gSwap_sky_texture;  | 
        ||
| 47 | br_angle gOld_fov; | 
        ||
| 48 | br_angle gSky_image_width; | 
        ||
| 49 | br_angle gSky_image_height; | 
        ||
| 50 | br_angle gSky_image_underground; | 
        ||
| 51 | |||
| 52 | // IDA: int __usercall Log2@<EAX>(int pNumber@<EAX>) | 
        ||
| 53 | int Log2(int pNumber) {  | 
        ||
| 54 | int i;  | 
        ||
| 55 | int bits[16];  | 
        ||
| 56 | LOG_TRACE("(%d)", pNumber);  | 
        ||
| 57 | |||
| 58 | bits[0] = 1;  | 
        ||
| 59 | bits[1] = 2;  | 
        ||
| 60 | bits[2] = 4;  | 
        ||
| 61 | bits[3] = 8;  | 
        ||
| 62 | bits[4] = 16;  | 
        ||
| 63 | bits[5] = 32;  | 
        ||
| 64 | bits[6] = 64;  | 
        ||
| 65 | bits[7] = 128;  | 
        ||
| 66 | bits[8] = 256;  | 
        ||
| 67 | bits[9] = 512;  | 
        ||
| 68 | bits[10] = 1024;  | 
        ||
| 69 | bits[11] = 2048;  | 
        ||
| 70 | bits[12] = 4096;  | 
        ||
| 71 | bits[13] = 0x2000;  | 
        ||
| 72 | bits[14] = 0x4000;  | 
        ||
| 73 | bits[15] = 0x8000;  | 
        ||
| 74 | for (i = COUNT_OF(bits) - 1; i >= 0; --i) {  | 
        ||
| 75 | if ((bits[i] & pNumber) != 0) {  | 
        ||
| 76 | return i;  | 
        ||
| 77 |         } | 
        ||
| 78 |     } | 
        ||
| 79 | return 0;  | 
        ||
| 80 | } | 
        ||
| 81 | |||
| 82 | // IDA: br_scalar __cdecl CalculateWrappingMultiplier(br_scalar pValue, br_scalar pYon) | 
        ||
| 83 | br_scalar CalculateWrappingMultiplier(br_scalar pValue, br_scalar pYon) {  | 
        ||
| 84 |     br_scalar k; | 
        ||
| 85 |     br_scalar trunc_k; | 
        ||
| 86 | int int_k;  | 
        ||
| 87 | LOG_TRACE("(%f, %f)", pValue, pYon);  | 
        ||
| 88 | |||
| 89 | k = pYon * 1.3f * TAU / pValue;  | 
        ||
| 90 | int_k = (int)k;  | 
        ||
| 91 | if (k - int_k <= .5f) {  | 
        ||
| 92 | trunc_k = int_k;  | 
        ||
| 93 | } else {  | 
        ||
| 94 | trunc_k = int_k + 1.f;  | 
        ||
| 95 |     } | 
        ||
| 96 | return trunc_k / TAU * pValue;  | 
        ||
| 97 | } | 
        ||
| 98 | |||
| 99 | // IDA: br_scalar __usercall DepthCueingShiftToDistance@<ST0>(int pShift@<EAX>) | 
        ||
| 100 | br_scalar DepthCueingShiftToDistance(int pShift) {  | 
        ||
| 101 | LOG_TRACE("(%d)", pShift);  | 
        ||
| 102 | NOT_IMPLEMENTED();  | 
        ||
| 103 | } | 
        ||
| 104 | |||
| 105 | // IDA: void __usercall FogAccordingToGPSCDE(br_material *pMaterial@<EAX>) | 
        ||
| 106 | void FogAccordingToGPSCDE(br_material* pMaterial) {  | 
        ||
| 107 |     //int start; // Pierre-Marie Baty -- unused variable | 
        ||
| 108 |     //int end; // Pierre-Marie Baty -- unused variable | 
        ||
| 109 | LOG_TRACE("(%p)", pMaterial);  | 
        ||
| 110 | NOT_IMPLEMENTED();  | 
        ||
| 111 | } | 
        ||
| 112 | |||
| 113 | // IDA: void __cdecl FrobFog() | 
        ||
| 114 | void FrobFog(void) {  | 
        ||
| 115 |     //int i; // Pierre-Marie Baty -- unused variable | 
        ||
| 116 |     //br_material* mat; // Pierre-Marie Baty -- unused variable | 
        ||
| 117 | LOG_TRACE("()");  | 
        ||
| 118 | NOT_IMPLEMENTED();  | 
        ||
| 119 | } | 
        ||
| 120 | |||
| 121 | // IDA: void __usercall InstantDepthChange(tDepth_effect_type pType@<EAX>, br_pixelmap *pSky_texture@<EDX>, int pStart@<EBX>, int pEnd@<ECX>) | 
        ||
| 122 | void InstantDepthChange(tDepth_effect_type pType, br_pixelmap* pSky_texture, int pStart, int pEnd) {  | 
        ||
| 123 | LOG_TRACE("(%d, %p, %d, %d)", pType, pSky_texture, pStart, pEnd);  | 
        ||
| 124 | |||
| 125 | if (pType == -1) {  | 
        ||
| 126 | pStart = 3;  | 
        ||
| 127 | pEnd = 3;  | 
        ||
| 128 |     } | 
        ||
| 129 | |||
| 130 | gProgram_state.current_depth_effect.sky_texture = pSky_texture;  | 
        ||
| 131 | gHorizon_material->colour_map = pSky_texture;  | 
        ||
| 132 | BrMaterialUpdate(gHorizon_material, BR_MATU_ALL);  | 
        ||
| 133 | gProgram_state.current_depth_effect.type = pType;  | 
        ||
| 134 | gProgram_state.current_depth_effect.start = pStart;  | 
        ||
| 135 | gProgram_state.current_depth_effect.end = pEnd;  | 
        ||
| 136 | gProgram_state.default_depth_effect.type = pType;  | 
        ||
| 137 | gProgram_state.default_depth_effect.start = pStart;  | 
        ||
| 138 | gProgram_state.default_depth_effect.end = pEnd;  | 
        ||
| 139 | } | 
        ||
| 140 | |||
| 141 | // IDA: br_scalar __cdecl Tan(br_scalar pAngle) | 
        ||
| 142 | br_scalar Tan(br_scalar pAngle) {  | 
        ||
| 143 | LOG_TRACE("(%f)", pAngle);  | 
        ||
| 144 | |||
| 145 | return sinf(BrAngleToRadian(pAngle)) / cosf(BrAngleToRadian(pAngle));  | 
        ||
| 146 | } | 
        ||
| 147 | |||
| 148 | // IDA: br_scalar __usercall EdgeU@<ST0>(br_angle pSky@<EAX>, br_angle pView@<EDX>, br_angle pPerfect@<EBX>) | 
        ||
| 149 | br_scalar EdgeU(br_angle pSky, br_angle pView, br_angle pPerfect) {  | 
        ||
| 150 |     br_scalar a; | 
        ||
| 151 |     br_scalar b; | 
        ||
| 152 |     br_scalar c; | 
        ||
| 153 | LOG_TRACE("(%d, %d, %d)", pSky, pView, pPerfect);  | 
        ||
| 154 | |||
| 155 | a = cosf(BrAngleToRadian(pPerfect));  | 
        ||
| 156 | b = sinf(BrAngleToRadian(pView));  | 
        ||
| 157 | c = cosf(BrAngleToRadian(pView));  | 
        ||
| 158 | return b * a * a / (BrAngleToRadian(pSky) * (1.f + c));  | 
        ||
| 159 | } | 
        ||
| 160 | |||
| 161 | // IDA: void __usercall MungeSkyModel(br_actor *pCamera@<EAX>, br_model *pModel@<EDX>) | 
        ||
| 162 | void MungeSkyModel(br_actor* pCamera, br_model* pModel) {  | 
        ||
| 163 | br_camera* camera_data;  | 
        ||
| 164 |     br_scalar horizon_half_height; | 
        ||
| 165 |     br_scalar horizon_half_width; | 
        ||
| 166 |     br_scalar horizon_half_diag; | 
        ||
| 167 |     br_scalar tan_half_fov; | 
        ||
| 168 |     br_scalar sky_distance; | 
        ||
| 169 |     //br_angle half_hori_fov; // Pierre-Marie Baty -- unused variable | 
        ||
| 170 |     br_angle half_diag_fov; | 
        ||
| 171 |     tU8 nbands; | 
        ||
| 172 |     tU8 band; | 
        ||
| 173 |     tU8 vertex; | 
        ||
| 174 |     tU8 stripe; | 
        ||
| 175 |     br_scalar edge_u; | 
        ||
| 176 |     br_scalar narrow_u; | 
        ||
| 177 |     br_angle min_angle; | 
        ||
| 178 |     br_angle angle_range; | 
        ||
| 179 |     br_angle angle; | 
        ||
| 180 | LOG_TRACE("(%p, %p)", pCamera, pModel);  | 
        ||
| 181 | |||
| 182 | camera_data = pCamera->type_data;  | 
        ||
| 183 | tan_half_fov = Tan(camera_data->field_of_view / 2);  | 
        ||
| 184 | sky_distance = camera_data->yon_z - 1.f;  | 
        ||
| 185 | horizon_half_width = sky_distance * tan_half_fov;  | 
        ||
| 186 | horizon_half_height = horizon_half_width * camera_data->aspect;  | 
        ||
| 187 | horizon_half_diag = sqrtf(horizon_half_height * horizon_half_height + horizon_half_width * horizon_half_width);  | 
        ||
| 188 | half_diag_fov = BrRadianToAngle(atan2f(horizon_half_diag, sky_distance));  | 
        ||
| 189 | edge_u = EdgeU(gSky_image_width, 2 * half_diag_fov, BR_ANGLE_DEG(10));  | 
        ||
| 190 | narrow_u = edge_u / 2.f;  | 
        ||
| 191 | gSky_width = horizon_half_width * 2.f;  | 
        ||
| 192 | gSky_height = horizon_half_height * 2.f;  | 
        ||
| 193 | gSky_x_multiplier = CalculateWrappingMultiplier(gSky_width, camera_data->yon_z);  | 
        ||
| 194 | gSky_y_multiplier = CalculateWrappingMultiplier(gSky_height, camera_data->yon_z);  | 
        ||
| 195 | |||
| 196 | for (vertex = 0; vertex < 88; vertex += 4) {  | 
        ||
| 197 | pModel->vertices[vertex].map.v[0] = -edge_u;  | 
        ||
| 198 |     } | 
        ||
| 199 | for (vertex = 1; vertex < 88; vertex += 4) {  | 
        ||
| 200 | pModel->vertices[vertex].map.v[0] = -narrow_u;  | 
        ||
| 201 |     } | 
        ||
| 202 | for (vertex = 2; vertex < 88; vertex += 4) {  | 
        ||
| 203 | pModel->vertices[vertex].map.v[0] = narrow_u;  | 
        ||
| 204 |     } | 
        ||
| 205 | for (vertex = 3; vertex < 88; vertex += 4) {  | 
        ||
| 206 | pModel->vertices[vertex].map.v[0] = edge_u;  | 
        ||
| 207 |     } | 
        ||
| 208 | for (vertex = 0; vertex < 88; vertex += 4) {  | 
        ||
| 209 | pModel->vertices[vertex].p.v[0] = -horizon_half_diag;  | 
        ||
| 210 |     } | 
        ||
| 211 | for (vertex = 1; vertex < 88; vertex += 4) {  | 
        ||
| 212 | pModel->vertices[vertex].p.v[0] = -(horizon_half_diag / 2.f);  | 
        ||
| 213 |     } | 
        ||
| 214 | for (vertex = 2; vertex < 88; vertex += 4) {  | 
        ||
| 215 | pModel->vertices[vertex].p.v[0] = horizon_half_diag / 2.f;  | 
        ||
| 216 |     } | 
        ||
| 217 | for (vertex = 3; vertex < 88; vertex += 4) {  | 
        ||
| 218 | pModel->vertices[vertex].p.v[0] = horizon_half_diag;  | 
        ||
| 219 |     } | 
        ||
| 220 | PossibleService();  | 
        ||
| 221 | angle_range = -gSky_image_underground - (-BR_ANGLE_DEG(90) - half_diag_fov);  | 
        ||
| 222 | for (band = 0; band < 2u; band++) {  | 
        ||
| 223 | vertex = 4 * band;  | 
        ||
| 224 | angle = -BR_ANGLE_DEG(90) - half_diag_fov + angle_range * band / 2;  | 
        ||
| 225 | pModel->vertices[vertex].p.v[1] = sinf(BrAngleToRadian(angle)) * sky_distance;  | 
        ||
| 226 | pModel->vertices[vertex].p.v[2] = -cosf(BrAngleToRadian(angle)) * sky_distance;  | 
        ||
| 227 |     } | 
        ||
| 228 | min_angle = -gSky_image_underground;  | 
        ||
| 229 | angle_range = gSky_image_height;  | 
        ||
| 230 | nbands = 18;  | 
        ||
| 231 | for (band = 0; band < nbands; band++) {  | 
        ||
| 232 | vertex = 4 * band + 8;  | 
        ||
| 233 | pModel->vertices[vertex].p.v[1] = sinf(BrAngleToRadian(min_angle + angle_range * band / nbands)) * sky_distance;  | 
        ||
| 234 | pModel->vertices[vertex].p.v[2] = -cosf(BrAngleToRadian(min_angle + angle_range * band / nbands)) * sky_distance;  | 
        ||
| 235 |     } | 
        ||
| 236 | min_angle = gSky_image_height - gSky_image_underground;  | 
        ||
| 237 | angle_range = half_diag_fov + BR_ANGLE_DEG(90) - (gSky_image_height - gSky_image_underground);  | 
        ||
| 238 | for (band = 0; band <= 1u; band++) {  | 
        ||
| 239 | vertex = 4 * band + 80;  | 
        ||
| 240 | angle = min_angle + angle_range * band;  | 
        ||
| 241 | pModel->vertices[vertex].p.v[1] = sinf(BrAngleToRadian(angle)) * sky_distance;  | 
        ||
| 242 | pModel->vertices[vertex].p.v[2] = -cosf(BrAngleToRadian(angle)) * sky_distance;  | 
        ||
| 243 |     } | 
        ||
| 244 | PossibleService();  | 
        ||
| 245 | for (band = 0; band <= 21u; ++band) {  | 
        ||
| 246 | vertex = 4 * band;  | 
        ||
| 247 | for (stripe = 1; stripe < 4u; ++stripe) {  | 
        ||
| 248 | pModel->vertices[vertex + stripe].p.v[1] = pModel->vertices[vertex].p.v[1];  | 
        ||
| 249 | pModel->vertices[vertex + stripe].p.v[2] = pModel->vertices[vertex].p.v[2];  | 
        ||
| 250 |         } | 
        ||
| 251 |     } | 
        ||
| 252 | |||
| 253 | BrModelUpdate(pModel, BR_MODU_ALL & ~BR_MODU_VERTEX_NORMALS);  | 
        ||
| 254 | } | 
        ||
| 255 | |||
| 256 | // IDA: br_model* __usercall CreateHorizonModel@<EAX>(br_actor *pCamera@<EAX>) | 
        ||
| 257 | br_model* CreateHorizonModel(br_actor* pCamera) {  | 
        ||
| 258 |     //tU8 nbands; // Pierre-Marie Baty -- unused variable | 
        ||
| 259 |     tU8 band; | 
        ||
| 260 |     tU8 vertex; | 
        ||
| 261 |     tU8 stripe; | 
        ||
| 262 | br_model* model;  | 
        ||
| 263 | LOG_TRACE("(%p)", pCamera);  | 
        ||
| 264 | |||
| 265 | model = BrModelAllocate(NULL, 88, 126);  | 
        ||
| 266 | model->flags |= BR_MODF_KEEP_ORIGINAL;  | 
        ||
| 267 | for (band = 0; band < 21; band++) {  | 
        ||
| 268 | for (stripe = 0; stripe < 3; stripe++) {  | 
        ||
| 269 | model->faces[6 * band + 2 * stripe].vertices[0] = stripe + 4 * band + 0;  | 
        ||
| 270 | model->faces[6 * band + 2 * stripe].vertices[1] = stripe + 4 * band + 1;  | 
        ||
| 271 | model->faces[6 * band + 2 * stripe].vertices[2] = stripe + 4 * band + 5;  | 
        ||
| 272 | model->faces[6 * band + 2 * stripe + 1].vertices[0] = stripe + 4 * band + 0;  | 
        ||
| 273 | model->faces[6 * band + 2 * stripe + 1].vertices[1] = stripe + 4 * band + 5;  | 
        ||
| 274 | model->faces[6 * band + 2 * stripe + 1].vertices[2] = stripe + 4 * band + 4;  | 
        ||
| 275 | model->faces[6 * band + 2 * stripe + 0].smoothing = 1;  | 
        ||
| 276 | model->faces[6 * band + 2 * stripe + 1].smoothing = 1;  | 
        ||
| 277 | model->faces[6 * band + 2 * stripe + 0].material = NULL;  | 
        ||
| 278 | model->faces[6 * band + 2 * stripe + 1].material = NULL;  | 
        ||
| 279 |         } | 
        ||
| 280 |     } | 
        ||
| 281 | for (vertex = 0; vertex < 12; vertex++) {  | 
        ||
| 282 | model->vertices[vertex].map.v[1] = 0.9999999f;  | 
        ||
| 283 |     } | 
        ||
| 284 | for (vertex = 80; vertex < 88; vertex++) {  | 
        ||
| 285 | model->vertices[vertex].map.v[1] = 0.f;  | 
        ||
| 286 |     } | 
        ||
| 287 | for (band = 1; band < 18; band++) {  | 
        ||
| 288 | model->vertices[4 * band + 8].map.v[1] = (float)(18 - band) / 18.f;  | 
        ||
| 289 | for (stripe = 1; stripe < 4; stripe++) {  | 
        ||
| 290 | model->vertices[4 * band + 8 + stripe].map.v[1] = model->vertices[4 * band + 8].map.v[1];  | 
        ||
| 291 |         } | 
        ||
| 292 |     } | 
        ||
| 293 | return model;  | 
        ||
| 294 | } | 
        ||
| 295 | |||
| 296 | // IDA: void __usercall LoadDepthTable(char *pName@<EAX>, br_pixelmap **pTable@<EDX>, int *pPower@<EBX>) | 
        ||
| 297 | void LoadDepthTable(char* pName, br_pixelmap** pTable, int* pPower) {  | 
        ||
| 298 |     tPath_name the_path; | 
        ||
| 299 | int i;  | 
        ||
| 300 | int j;  | 
        ||
| 301 |     tU8 temp; | 
        ||
| 302 | LOG_TRACE("(\"%s\", %p, %p)", pName, pTable, pPower);  | 
        ||
| 303 | |||
| 304 | #define PTABLE_PIXEL_AT(X, Y) ((tU8*)((*pTable)->pixels))[(X) + (Y) * (*pTable)->row_bytes] | 
        ||
| 305 | |||
| 306 | PathCat(the_path, gApplication_path, "SHADETAB");  | 
        ||
| 307 | PathCat(the_path, the_path, pName);  | 
        ||
| 308 | *pTable = DRPixelmapLoad(the_path);  | 
        ||
| 309 | if (*pTable == NULL) {  | 
        ||
| 310 | FatalError(kFatalError_LoadDepthCueShadeTable);  | 
        ||
| 311 |     } | 
        ||
| 312 | *pPower = Log2((*pTable)->height);  | 
        ||
| 313 | for (i = 0; i < (*pTable)->width; i++) {  | 
        ||
| 314 | for (j = 0; j < (*pTable)->height / 2; j++) {  | 
        ||
| 315 | temp = PTABLE_PIXEL_AT(i, j);  | 
        ||
| 316 | PTABLE_PIXEL_AT(i, j) = PTABLE_PIXEL_AT(i, ((*pTable)->height - j - 1));  | 
        ||
| 317 | PTABLE_PIXEL_AT(i, ((*pTable)->height - j - 1)) = temp;  | 
        ||
| 318 |         } | 
        ||
| 319 |     } | 
        ||
| 320 | |||
| 321 | #undef PTABLE_PIXEL_AT | 
        ||
| 322 | } | 
        ||
| 323 | |||
| 324 | // IDA: void __cdecl InitDepthEffects() | 
        ||
| 325 | void InitDepthEffects(void) {  | 
        ||
| 326 |     tPath_name the_path; | 
        ||
| 327 | int i;  | 
        ||
| 328 | int j;  | 
        ||
| 329 | |||
| 330 | LoadDepthTable("DEPTHCUE.TAB", &gDepth_shade_table, &gDepth_shade_table_power);  | 
        ||
| 331 | LoadDepthTable("FOG.TAB", &gFog_shade_table, &gFog_shade_table_power);  | 
        ||
| 332 | LoadDepthTable("ACIDFOG.TAB", &gAcid_shade_table, &gAcid_shade_table_power);  | 
        ||
| 333 | LoadDepthTable("BLUEGIT.TAB", &gWater_shade_table, &gWater_shade_table_power);  | 
        ||
| 334 | GenerateSmokeShades();  | 
        ||
| 335 | PathCat(the_path, gApplication_path, "MATERIAL");  | 
        ||
| 336 | PathCat(the_path, the_path, "HORIZON.MAT");  | 
        ||
| 337 | gHorizon_material = BrMaterialLoad(the_path);  | 
        ||
| 338 | if (gHorizon_material == NULL) {  | 
        ||
| 339 | FatalError(kFatalError_FindSkyMaterial_S, "HORIZON.MAT"); // 2nd argument added  | 
        ||
| 340 |     } | 
        ||
| 341 | gHorizon_material->index_blend = BrPixelmapAllocate(BR_PMT_INDEX_8, 256, 256, NULL, 0);  | 
        ||
| 20 | pmbaty | 342 | |
| 343 |     // HACK: moved below loop | 
        ||
| 344 |     // BrTableAdd(gHorizon_material->index_blend); | 
        ||
| 1 | pmbaty | 345 | for (i = 0; i < 256; i++) {  | 
        
| 346 | for (j = 0; j < 256; j++) {  | 
        ||
| 347 | *((tU8*)gHorizon_material->index_blend->pixels + 256 * i + j) = j;  | 
        ||
| 348 |         } | 
        ||
| 349 |     } | 
        ||
| 20 | pmbaty | 350 |     // HACK: this should be above the for loop. Haven't been able to figure out how this is working in OG, as changes made to the pixelmap | 
        
| 351 |     // don't update the stored copy without calling `BrTableUpdate`. | 
        ||
| 352 | BrTableAdd(gHorizon_material->index_blend);  | 
        ||
| 353 | |||
| 1 | pmbaty | 354 | gHorizon_material->flags |= BR_MATF_PERSPECTIVE;  | 
        
| 355 | BrMaterialAdd(gHorizon_material);  | 
        ||
| 356 | gForward_sky_model = CreateHorizonModel(gCamera);  | 
        ||
| 357 | gRearview_sky_model = CreateHorizonModel(gRearview_camera);  | 
        ||
| 358 | BrModelAdd(gForward_sky_model);  | 
        ||
| 359 | BrModelAdd(gRearview_sky_model);  | 
        ||
| 360 | gForward_sky_actor = BrActorAllocate(BR_ACTOR_MODEL, NULL);  | 
        ||
| 361 | gForward_sky_actor->model = gForward_sky_model;  | 
        ||
| 362 | gForward_sky_actor->material = gHorizon_material;  | 
        ||
| 363 | gForward_sky_actor->render_style = BR_RSTYLE_NONE;  | 
        ||
| 364 | BrActorAdd(gUniverse_actor, gForward_sky_actor);  | 
        ||
| 365 | gRearview_sky_actor = BrActorAllocate(BR_ACTOR_MODEL, NULL);  | 
        ||
| 366 | gRearview_sky_actor->model = gRearview_sky_model;  | 
        ||
| 367 | gRearview_sky_actor->material = gHorizon_material;  | 
        ||
| 368 | gRearview_sky_actor->render_style = BR_RSTYLE_NONE;  | 
        ||
| 369 | BrActorAdd(gUniverse_actor, gRearview_sky_actor);  | 
        ||
| 370 | gLast_camera_special_volume = 0;  | 
        ||
| 371 | } | 
        ||
| 372 | |||
| 373 | // IDA: void __usercall DoDepthByShadeTable(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_pixelmap *pShade_table@<EBX>, int pShade_table_power@<ECX>, int pStart, int pEnd) | 
        ||
| 374 | void DoDepthByShadeTable(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_pixelmap* pShade_table, int pShade_table_power, int pStart, int pEnd) {  | 
        ||
| 375 | tU8* render_ptr;  | 
        ||
| 376 | tU8* shade_table_pixels;  | 
        ||
| 377 | tU16* depth_ptr;  | 
        ||
| 378 |     tU16 depth_value; | 
        ||
| 379 |     tU16 too_near; | 
        ||
| 380 | int depth_shift_amount;  | 
        ||
| 381 |     //int depth_start; // Pierre-Marie Baty -- unused variable | 
        ||
| 382 | int y;  | 
        ||
| 383 | int x;  | 
        ||
| 384 | int depth_line_skip;  | 
        ||
| 385 | int render_line_skip;  | 
        ||
| 386 | LOG_TRACE("(%p, %p, %p, %d, %d, %d)", pRender_buffer, pDepth_buffer, pShade_table, pShade_table_power, pStart, pEnd);  | 
        ||
| 387 | |||
| 388 | too_near = 0xffff - (1 << pStart);  | 
        ||
| 389 | shade_table_pixels = pShade_table->pixels;  | 
        ||
| 390 | depth_shift_amount = pShade_table_power + 8 - pStart - pEnd;  | 
        ||
| 391 | render_ptr = (tU8*)pRender_buffer->pixels + pRender_buffer->base_x + pRender_buffer->base_y * pRender_buffer->row_bytes;  | 
        ||
| 392 | depth_ptr = pDepth_buffer->pixels;  | 
        ||
| 393 | render_line_skip = pRender_buffer->row_bytes - pRender_buffer->width;  | 
        ||
| 394 | depth_line_skip = pDepth_buffer->row_bytes / 2 - pRender_buffer->width;  | 
        ||
| 395 | |||
| 396 | if (depth_shift_amount <= 0) {  | 
        ||
| 397 | if (depth_shift_amount >= 0) {  | 
        ||
| 398 | for (y = 0; y < pRender_buffer->height; ++y) {  | 
        ||
| 399 | for (x = 0; x < pRender_buffer->width; ++x) {  | 
        ||
| 400 | if (*depth_ptr != 0xFFFF) {  | 
        ||
| 401 | depth_value = *depth_ptr - too_near;  | 
        ||
| 402 | if (depth_value < -(int16_t)too_near) {  | 
        ||
| 403 | *render_ptr = shade_table_pixels[(depth_value & 0xFF00) + *render_ptr];  | 
        ||
| 404 |                         } | 
        ||
| 405 |                     } | 
        ||
| 406 | ++render_ptr;  | 
        ||
| 407 | ++depth_ptr;  | 
        ||
| 408 |                 } | 
        ||
| 409 | render_ptr += render_line_skip;  | 
        ||
| 410 | depth_ptr += depth_line_skip;  | 
        ||
| 411 |             } | 
        ||
| 412 | } else {  | 
        ||
| 413 | for (y = 0; pRender_buffer->height > y; ++y) {  | 
        ||
| 414 | for (x = 0; pRender_buffer->width > x; ++x) {  | 
        ||
| 415 | if (*depth_ptr != 0xFFFF) {  | 
        ||
| 416 | depth_value = *depth_ptr - too_near;  | 
        ||
| 417 | if (depth_value < -(int16_t)too_near) {  | 
        ||
| 418 | *render_ptr = shade_table_pixels[*render_ptr + ((depth_value >> (pEnd - (pShade_table_power + 8 - pStart))) & 0xFF00)];  | 
        ||
| 419 |                         } | 
        ||
| 420 |                     } | 
        ||
| 421 | ++render_ptr;  | 
        ||
| 422 | ++depth_ptr;  | 
        ||
| 423 |                 } | 
        ||
| 424 | render_ptr += render_line_skip;  | 
        ||
| 425 | depth_ptr += depth_line_skip;  | 
        ||
| 426 |             } | 
        ||
| 427 |         } | 
        ||
| 428 | } else {  | 
        ||
| 429 | for (y = 0; pRender_buffer->height > y; ++y) {  | 
        ||
| 430 | for (x = 0; pRender_buffer->width > x; ++x) {  | 
        ||
| 431 | if (*depth_ptr != 0xFFFF) {  | 
        ||
| 432 | depth_value = *depth_ptr - too_near;  | 
        ||
| 433 | if (depth_value < -(int16_t)too_near) {  | 
        ||
| 434 | *render_ptr = shade_table_pixels[*render_ptr + ((depth_value << depth_shift_amount) & 0xFF00)];  | 
        ||
| 435 |                     } | 
        ||
| 436 |                 } | 
        ||
| 437 | ++render_ptr;  | 
        ||
| 438 | ++depth_ptr;  | 
        ||
| 439 |             } | 
        ||
| 440 | render_ptr += render_line_skip;  | 
        ||
| 441 | depth_ptr += depth_line_skip;  | 
        ||
| 442 |         } | 
        ||
| 443 |     } | 
        ||
| 444 | } | 
        ||
| 445 | |||
| 446 | // IDA: void __usercall ExternalSky(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>, br_matrix34 *pCamera_to_world@<ECX>) | 
        ||
| 447 | void ExternalSky(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world) {  | 
        ||
| 448 | int dst_x;  | 
        ||
| 449 | int src_x;  | 
        ||
| 450 | int dx;  | 
        ||
| 451 | int hori_y;  | 
        ||
| 452 | int top_y;  | 
        ||
| 453 | int hori_pixels;  | 
        ||
| 454 |     //br_angle yaw; // Pierre-Marie Baty -- unused variable | 
        ||
| 455 |     br_angle hori_sky; | 
        ||
| 456 |     //br_angle pitch; // Pierre-Marie Baty -- unused variable | 
        ||
| 457 |     br_angle vert_sky; | 
        ||
| 458 | br_camera* camera;  | 
        ||
| 459 |     br_scalar tan_half_fov; | 
        ||
| 460 |     br_scalar tan_half_hori_fov; | 
        ||
| 461 |     br_scalar tan_half_hori_sky; | 
        ||
| 462 |     br_scalar hshift; | 
        ||
| 463 |     br_scalar tan_pitch; | 
        ||
| 464 |     tU8 top_col; | 
        ||
| 465 |     tU8 bot_col; | 
        ||
| 466 | int bot_height;  | 
        ||
| 467 |     //int repetitions; // Pierre-Marie Baty -- unused variable | 
        ||
| 468 | br_pixelmap* col_map;  | 
        ||
| 469 | LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);  | 
        ||
| 470 | |||
| 471 | dst_x = 0;  | 
        ||
| 472 | col_map = gHorizon_material->colour_map;  | 
        ||
| 473 | camera = (br_camera*)pCamera->type_data;  | 
        ||
| 474 | tan_half_fov = Tan(camera->field_of_view / 2);  | 
        ||
| 475 | tan_half_hori_fov = tan_half_fov * camera->aspect;  | 
        ||
| 476 | |||
| 477 | vert_sky = BrRadianToAngle(atan2(pCamera_to_world->m[2][0], pCamera_to_world->m[2][2]));  | 
        ||
| 478 | hori_sky = BrRadianToAngle(atan2(col_map->width * tan_half_hori_fov / (double)pRender_buffer->width, 1));  | 
        ||
| 479 | |||
| 480 | tan_half_hori_sky = -BrFixedToFloat(vert_sky) / BrFixedToFloat(BR_ANGLE_DEG(360) / (int)(1.0f / BrFixedToFloat(2 * hori_sky) + 0.5f));  | 
        ||
| 481 | |||
| 482 | dx = col_map->width * tan_half_hori_sky;  | 
        ||
| 483 | while (dx < 0) {  | 
        ||
| 484 | dx += col_map->width;  | 
        ||
| 485 |     } | 
        ||
| 486 | while (dx > col_map->width) {  | 
        ||
| 487 | dx -= col_map->width;  | 
        ||
| 488 |     } | 
        ||
| 489 | |||
| 490 | hshift = col_map->height - gSky_image_underground * col_map->height / gSky_image_height;  | 
        ||
| 491 | tan_pitch = sqrtf(pCamera_to_world->m[2][0] * pCamera_to_world->m[2][0] + pCamera_to_world->m[2][2] * pCamera_to_world->m[2][2]);  | 
        ||
| 492 | hori_y = -(pCamera_to_world->m[2][1]  | 
        ||
| 493 |                  / tan_pitch | 
        ||
| 494 | / tan_half_fov * pRender_buffer->height / 2.0f)  | 
        ||
| 495 | - hshift;  | 
        ||
| 496 | |||
| 497 | while (dst_x < pRender_buffer->width) {  | 
        ||
| 498 | hori_pixels = col_map->width - dx;  | 
        ||
| 499 | if (hori_pixels > pRender_buffer->width - dst_x) {  | 
        ||
| 500 | hori_pixels = pRender_buffer->width - dst_x;  | 
        ||
| 501 |         } | 
        ||
| 502 | src_x = dx - col_map->origin_x;  | 
        ||
| 503 | DRPixelmapRectangleCopy(pRender_buffer, dst_x - pRender_buffer->origin_x, hori_y, col_map, src_x, -col_map->origin_y, hori_pixels, col_map->height);  | 
        ||
| 504 | dx = 0;  | 
        ||
| 505 | dst_x += hori_pixels;  | 
        ||
| 506 |     } | 
        ||
| 507 | |||
| 508 | top_y = hori_y + pRender_buffer->origin_y;  | 
        ||
| 509 | if (top_y > 0) {  | 
        ||
| 510 | top_col = ((tU8*)col_map->pixels)[0];  | 
        ||
| 511 | DRPixelmapRectangleFill(pRender_buffer, -pRender_buffer->origin_x, -pRender_buffer->origin_y, pRender_buffer->width, top_y, top_col);  | 
        ||
| 512 |     } | 
        ||
| 513 | bot_height = pRender_buffer->height - pRender_buffer->origin_y - hori_y - col_map->height;  | 
        ||
| 514 | if (bot_height > 0) {  | 
        ||
| 515 | bot_col = ((tU8*)col_map->pixels)[col_map->row_bytes * (col_map->height - 1)];  | 
        ||
| 516 | DRPixelmapRectangleFill(pRender_buffer, -pRender_buffer->origin_x, hori_y + col_map->height, pRender_buffer->width, bot_height, bot_col);  | 
        ||
| 517 |     } | 
        ||
| 518 | } | 
        ||
| 519 | |||
| 520 | #define ACTOR_CAMERA(ACTOR) ((br_camera*)((ACTOR)->type_data)) | 
        ||
| 521 | |||
| 522 | // IDA: void __usercall DoHorizon(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>, br_matrix34 *pCamera_to_world@<ECX>) | 
        ||
| 523 | void DoHorizon(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world) {  | 
        ||
| 524 |     br_angle yaw; | 
        ||
| 525 | br_actor* actor;  | 
        ||
| 526 | LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);  | 
        ||
| 527 | |||
| 528 | yaw = BrRadianToAngle(atan2f(pCamera_to_world->m[2][0], pCamera_to_world->m[2][2]));  | 
        ||
| 529 | if (!gProgram_state.cockpit_on && !(gAction_replay_mode && gAction_replay_camera_mode)) {  | 
        ||
| 530 | return;  | 
        ||
| 531 |     } | 
        ||
| 532 | if (gRendering_mirror) {  | 
        ||
| 533 | actor = gRearview_sky_actor;  | 
        ||
| 534 | } else {  | 
        ||
| 535 | actor = gForward_sky_actor;  | 
        ||
| 536 | if (ACTOR_CAMERA(gCamera)->field_of_view != gOld_fov || ACTOR_CAMERA(gCamera)->yon_z != gOld_yon) {  | 
        ||
| 537 | gOld_fov = ACTOR_CAMERA(gCamera)->field_of_view;  | 
        ||
| 538 | gOld_yon = ACTOR_CAMERA(gCamera)->yon_z;  | 
        ||
| 539 | MungeSkyModel(gCamera, gForward_sky_model);  | 
        ||
| 540 |         } | 
        ||
| 541 |     } | 
        ||
| 542 | BrMatrix34RotateY(&actor->t.t.mat, yaw);  | 
        ||
| 543 | BrVector3Copy(&actor->t.t.translate.t, (br_vector3*)pCamera_to_world->m[3]);  | 
        ||
| 544 | gHorizon_material->map_transform.m[0][0] = 1.f;  | 
        ||
| 545 | gHorizon_material->map_transform.m[0][1] = 0.f;  | 
        ||
| 546 | gHorizon_material->map_transform.m[1][0] = 0.f;  | 
        ||
| 547 | gHorizon_material->map_transform.m[1][1] = 1.f;  | 
        ||
| 548 | gHorizon_material->map_transform.m[2][0] = -BrFixedToFloat(yaw) / BrFixedToFloat(gSky_image_width);  | 
        ||
| 549 | gHorizon_material->map_transform.m[2][1] = 0.f;  | 
        ||
| 550 | BrMaterialUpdate(gHorizon_material, BR_MATU_ALL);  | 
        ||
| 551 | actor->render_style = BR_RSTYLE_FACES;  | 
        ||
| 552 | BrZbSceneRenderAdd(actor);  | 
        ||
| 553 | actor->render_style = BR_RSTYLE_NONE;  | 
        ||
| 554 | } | 
        ||
| 555 | |||
| 556 | // IDA: void __usercall DoDepthCue(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>) | 
        ||
| 557 | void DoDepthCue(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer) {  | 
        ||
| 558 | LOG_TRACE("(%p, %p)", pRender_buffer, pDepth_buffer);  | 
        ||
| 559 | |||
| 560 |     DoDepthByShadeTable( | 
        ||
| 561 |         pRender_buffer, | 
        ||
| 562 |         pDepth_buffer, | 
        ||
| 563 |         gDepth_shade_table, | 
        ||
| 564 |         gDepth_shade_table_power, | 
        ||
| 565 | gProgram_state.current_depth_effect.start,  | 
        ||
| 566 | gProgram_state.current_depth_effect.end);  | 
        ||
| 567 | } | 
        ||
| 568 | |||
| 569 | // IDA: void __usercall DoFog(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>) | 
        ||
| 570 | void DoFog(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer) {  | 
        ||
| 571 | LOG_TRACE("(%p, %p)", pRender_buffer, pDepth_buffer);  | 
        ||
| 572 | |||
| 573 |     DoDepthByShadeTable( | 
        ||
| 574 |         pRender_buffer, | 
        ||
| 575 |         pDepth_buffer, | 
        ||
| 576 |         gFog_shade_table, | 
        ||
| 577 |         gFog_shade_table_power, | 
        ||
| 578 | gProgram_state.current_depth_effect.start,  | 
        ||
| 579 | gProgram_state.current_depth_effect.end);  | 
        ||
| 580 | } | 
        ||
| 581 | |||
| 582 | // IDA: void __usercall DepthEffect(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>, br_matrix34 *pCamera_to_world@<ECX>) | 
        ||
| 583 | void DepthEffect(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world) {  | 
        ||
| 584 | LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);  | 
        ||
| 585 | |||
| 586 | if (gProgram_state.current_depth_effect.type == eDepth_effect_darkness) {  | 
        ||
| 587 | DoDepthCue(pRender_buffer, pDepth_buffer);  | 
        ||
| 588 |     } | 
        ||
| 589 | if (gProgram_state.current_depth_effect.type == eDepth_effect_fog) {  | 
        ||
| 590 | DoFog(pRender_buffer, pDepth_buffer);  | 
        ||
| 591 |     } | 
        ||
| 592 | } | 
        ||
| 593 | |||
| 594 | // IDA: void __usercall DepthEffectSky(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>, br_matrix34 *pCamera_to_world@<ECX>) | 
        ||
| 595 | void DepthEffectSky(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world) {  | 
        ||
| 596 | LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);  | 
        ||
| 597 | |||
| 598 | if (gProgram_state.current_depth_effect.sky_texture != NULL  | 
        ||
| 599 | && (gLast_camera_special_volume == NULL || gLast_camera_special_volume->sky_col < 0)) {  | 
        ||
| 600 | DoHorizon(pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);  | 
        ||
| 601 |     } | 
        ||
| 602 | } | 
        ||
| 603 | |||
| 604 | // IDA: void __usercall DoWobbleCamera(br_actor *pCamera@<EAX>) | 
        ||
| 605 | void DoWobbleCamera(br_actor* pCamera) {  | 
        ||
| 606 | float f_time;  | 
        ||
| 607 | static br_scalar mag00 = 0.02f;  | 
        ||
| 608 | static br_scalar mag01 = 0.02f;  | 
        ||
| 609 | static br_scalar mag02 = 0.02f;  | 
        ||
| 610 | static br_scalar mag10 = 0.15f;  | 
        ||
| 611 | static br_scalar mag11 = 0.05f;  | 
        ||
| 612 | static br_scalar mag12 = 0.02f;  | 
        ||
| 613 | static br_scalar mag20 = 0.f;  | 
        ||
| 614 | static br_scalar mag21 = 0.f;  | 
        ||
| 615 | static br_scalar mag22 = 0.f;  | 
        ||
| 616 | static float period00 = 3000.f;  | 
        ||
| 617 | static float period01 = 3000.f;  | 
        ||
| 618 | static float period02 = 4000.f;  | 
        ||
| 619 | static float period10 = 2200.f;  | 
        ||
| 620 | static float period11 = 3300.f;  | 
        ||
| 621 | static float period12 = 3100.f;  | 
        ||
| 622 | static float period20 = 2800.f;  | 
        ||
| 623 | static float period21 = 2500.f;  | 
        ||
| 624 | static float period22 = 3900.f;  | 
        ||
| 625 | LOG_TRACE("(%p)", pCamera);  | 
        ||
| 626 | |||
| 627 | f_time = (float)PDGetTotalTime();  | 
        ||
| 628 | pCamera->t.t.mat.m[0][0] += FastScalarSin(fmod(f_time / period00 * 360.f, 360.f)) * mag00;  | 
        ||
| 629 | pCamera->t.t.mat.m[0][1] += FastScalarSin(fmod(f_time / period01 * 360.f, 360.f)) * mag01;  | 
        ||
| 630 | pCamera->t.t.mat.m[0][2] += FastScalarSin(fmod(f_time / period02 * 360.f, 360.f)) * mag02;  | 
        ||
| 631 | pCamera->t.t.mat.m[1][0] += FastScalarSin(fmod(f_time / period10 * 360.f, 360.f)) * mag10;  | 
        ||
| 632 | pCamera->t.t.mat.m[1][1] += FastScalarSin(fmod(f_time / period11 * 360.f, 360.f)) * mag11;  | 
        ||
| 633 | pCamera->t.t.mat.m[1][2] += FastScalarSin(fmod(f_time / period12 * 360.f, 360.f)) * mag12;  | 
        ||
| 634 | pCamera->t.t.mat.m[2][0] += FastScalarSin(fmod(f_time / period20 * 360.f, 360.f)) * mag20;  | 
        ||
| 635 | pCamera->t.t.mat.m[2][1] += FastScalarSin(fmod(f_time / period21 * 360.f, 360.f)) * mag21;  | 
        ||
| 636 | pCamera->t.t.mat.m[2][2] += FastScalarSin(fmod(f_time / period22 * 360.f, 360.f)) * mag22;  | 
        ||
| 637 | } | 
        ||
| 638 | |||
| 639 | // IDA: void __usercall DoDrugWobbleCamera(br_actor *pCamera@<EAX>) | 
        ||
| 640 | void DoDrugWobbleCamera(br_actor* pCamera) {  | 
        ||
| 641 | float f_time;  | 
        ||
| 642 | static br_scalar mag00 = 0.03f;  | 
        ||
| 643 | static br_scalar mag01 = 0.03f;  | 
        ||
| 644 | static br_scalar mag02 = 0.03f;  | 
        ||
| 645 | static br_scalar mag10 = 0.2f;  | 
        ||
| 646 | static br_scalar mag11 = 0.07f; // Pierre-Marie Baty -- missing float suffix  | 
        ||
| 647 | static br_scalar mag12 = 0.03f;  | 
        ||
| 648 | static br_scalar mag20 = 0.02f;  | 
        ||
| 649 | static br_scalar mag21 = 0.03f;  | 
        ||
| 650 | static br_scalar mag22 = 0.01f;  | 
        ||
| 651 | static float period00 = 550.f;  | 
        ||
| 652 | static float period01 = 700.f;  | 
        ||
| 653 | static float period02 = 200.f;  | 
        ||
| 654 | static float period10 = 100.f;  | 
        ||
| 655 | static float period11 = 1300.f;  | 
        ||
| 656 | static float period12 = 500.f;  | 
        ||
| 657 | static float period20 = 800.f;  | 
        ||
| 658 | static float period21 = 1500.f;  | 
        ||
| 659 | static float period22 = 300.f;  | 
        ||
| 660 | LOG_TRACE("(%p)", pCamera);  | 
        ||
| 661 | |||
| 662 | f_time = (float)PDGetTotalTime();  | 
        ||
| 663 | pCamera->t.t.mat.m[0][0] += FastScalarSin(fmod(f_time / period00 * 360.f, 360.f)) * mag00;  | 
        ||
| 664 | pCamera->t.t.mat.m[0][1] += FastScalarSin(fmod(f_time / period01 * 360.f, 360.f)) * mag01;  | 
        ||
| 665 | pCamera->t.t.mat.m[0][2] += FastScalarSin(fmod(f_time / period02 * 360.f, 360.f)) * mag02;  | 
        ||
| 666 | pCamera->t.t.mat.m[1][0] += FastScalarSin(fmod(f_time / period10 * 360.f, 360.f)) * mag10;  | 
        ||
| 667 | pCamera->t.t.mat.m[1][1] += FastScalarSin(fmod(f_time / period11 * 360.f, 360.f)) * mag11;  | 
        ||
| 668 | pCamera->t.t.mat.m[1][2] += FastScalarSin(fmod(f_time / period12 * 360.f, 360.f)) * mag12;  | 
        ||
| 669 | pCamera->t.t.mat.m[2][0] += FastScalarSin(fmod(f_time / period20 * 360.f, 360.f)) * mag20;  | 
        ||
| 670 | pCamera->t.t.mat.m[2][1] += FastScalarSin(fmod(f_time / period21 * 360.f, 360.f)) * mag21;  | 
        ||
| 671 | pCamera->t.t.mat.m[2][2] += FastScalarSin(fmod(f_time / period22 * 360.f, 360.f)) * mag22;  | 
        ||
| 672 | } | 
        ||
| 673 | |||
| 674 | // IDA: void __usercall DoSpecialCameraEffect(br_actor *pCamera@<EAX>, br_matrix34 *pCamera_to_world@<EDX>) | 
        ||
| 675 | void DoSpecialCameraEffect(br_actor* pCamera, br_matrix34* pCamera_to_world) {  | 
        ||
| 676 | LOG_TRACE("(%p, %p)", pCamera, pCamera_to_world);  | 
        ||
| 677 | |||
| 678 | if (gOn_drugs) {  | 
        ||
| 679 | DoDrugWobbleCamera(pCamera);  | 
        ||
| 680 | } else {  | 
        ||
| 681 | gLast_camera_special_volume = FindSpecialVolume((br_vector3*)pCamera_to_world->m[3], gLast_camera_special_volume);  | 
        ||
| 682 | if (gLast_camera_special_volume != NULL) {  | 
        ||
| 683 | if (gLast_camera_special_volume->camera_special_effect_index == 0) {  | 
        ||
| 684 | DoWobbleCamera(pCamera);  | 
        ||
| 685 |             } | 
        ||
| 686 |         } | 
        ||
| 687 |     } | 
        ||
| 688 | } | 
        ||
| 689 | |||
| 690 | // IDA: void __cdecl LessDepthFactor() | 
        ||
| 691 | void LessDepthFactor(void) {  | 
        ||
| 692 | char s[256];  | 
        ||
| 693 | LOG_TRACE("()");  | 
        ||
| 694 | |||
| 695 | if (gProgram_state.current_depth_effect.start > 3) {  | 
        ||
| 696 | gProgram_state.current_depth_effect.start--;  | 
        ||
| 697 |     } | 
        ||
| 698 | sprintf(s, "Depth start reduced to %d", gProgram_state.current_depth_effect.start);  | 
        ||
| 21 | pmbaty | 699 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -1, s);  | 
        
| 1 | pmbaty | 700 | gProgram_state.default_depth_effect.start = gProgram_state.current_depth_effect.start;  | 
        
| 701 | } | 
        ||
| 702 | |||
| 703 | // IDA: void __cdecl MoreDepthFactor() | 
        ||
| 704 | void MoreDepthFactor(void) {  | 
        ||
| 705 | char s[256];  | 
        ||
| 706 | LOG_TRACE("()");  | 
        ||
| 707 | |||
| 708 | if (gProgram_state.current_depth_effect.start < 14) {  | 
        ||
| 709 | gProgram_state.current_depth_effect.start++;  | 
        ||
| 710 |     } | 
        ||
| 711 | sprintf(s, "Depth start increased to %d", gProgram_state.current_depth_effect.start);  | 
        ||
| 21 | pmbaty | 712 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -1, s);  | 
        
| 1 | pmbaty | 713 | gProgram_state.default_depth_effect.start = gProgram_state.current_depth_effect.start;  | 
        
| 714 | } | 
        ||
| 715 | |||
| 716 | // IDA: void __cdecl LessDepthFactor2() | 
        ||
| 717 | void LessDepthFactor2(void) {  | 
        ||
| 718 | char s[256];  | 
        ||
| 719 | LOG_TRACE("()");  | 
        ||
| 720 | |||
| 721 | if (gProgram_state.current_depth_effect.end < 14) {  | 
        ||
| 722 | gProgram_state.current_depth_effect.end++;  | 
        ||
| 723 |     } | 
        ||
| 724 | sprintf(s, "Depth end reduced to %d", gProgram_state.current_depth_effect.end);  | 
        ||
| 21 | pmbaty | 725 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -1, s);  | 
        
| 1 | pmbaty | 726 | gProgram_state.default_depth_effect.end = gProgram_state.current_depth_effect.end;  | 
        
| 727 | } | 
        ||
| 728 | |||
| 729 | // IDA: void __cdecl MoreDepthFactor2() | 
        ||
| 730 | void MoreDepthFactor2(void) {  | 
        ||
| 731 | char s[256];  | 
        ||
| 732 | LOG_TRACE("()");  | 
        ||
| 733 | |||
| 734 | if (gProgram_state.current_depth_effect.end > 0) {  | 
        ||
| 735 | gProgram_state.current_depth_effect.end--;  | 
        ||
| 736 |     } | 
        ||
| 737 | sprintf(s, "Depth end increased to %d", gProgram_state.current_depth_effect.end);  | 
        ||
| 21 | pmbaty | 738 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -1, s);  | 
        
| 1 | pmbaty | 739 | gProgram_state.default_depth_effect.end = gProgram_state.current_depth_effect.end;  | 
        
| 740 | } | 
        ||
| 741 | |||
| 742 | // IDA: void __cdecl AssertYons() | 
        ||
| 743 | void AssertYons(void) {  | 
        ||
| 744 | br_camera* camera_ptr;  | 
        ||
| 745 | int i;  | 
        ||
| 746 | LOG_TRACE("()");  | 
        ||
| 747 | |||
| 748 | for (i = 0; i < COUNT_OF(gCamera_list); ++i) {  | 
        ||
| 749 | camera_ptr = gCamera_list[i]->type_data;  | 
        ||
| 750 | camera_ptr->yon_z = gYon_multiplier * gCamera_yon;  | 
        ||
| 751 |     } | 
        ||
| 752 | } | 
        ||
| 753 | |||
| 754 | // IDA: void __cdecl IncreaseYon() | 
        ||
| 755 | void IncreaseYon(void) {  | 
        ||
| 756 | br_camera* camera_ptr;  | 
        ||
| 757 | int i;  | 
        ||
| 758 | char s[256];  | 
        ||
| 759 | LOG_TRACE("()");  | 
        ||
| 760 | |||
| 761 | gCamera_yon = gCamera_yon + 5.f;  | 
        ||
| 762 | AssertYons();  | 
        ||
| 763 | camera_ptr = gCamera_list[1]->type_data;  | 
        ||
| 764 | i = (int)camera_ptr->yon_z;  | 
        ||
| 765 | sprintf(s, GetMiscString(kMiscString_YonIncreasedTo_D), i);  | 
        ||
| 21 | pmbaty | 766 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, s);  | 
        
| 1 | pmbaty | 767 | } | 
        
| 768 | |||
| 769 | // IDA: void __cdecl DecreaseYon() | 
        ||
| 770 | void DecreaseYon(void) {  | 
        ||
| 771 | br_camera* camera_ptr;  | 
        ||
| 772 | int i;  | 
        ||
| 773 | char s[256];  | 
        ||
| 774 | LOG_TRACE("()");  | 
        ||
| 775 | |||
| 776 | gCamera_yon = gCamera_yon - 5.f;  | 
        ||
| 777 | if (gCamera_yon < 5.f) {  | 
        ||
| 778 | gCamera_yon = 5.f;  | 
        ||
| 779 |     } | 
        ||
| 780 | AssertYons();  | 
        ||
| 781 | camera_ptr = gCamera_list[1]->type_data;  | 
        ||
| 782 | i = (int)camera_ptr->yon_z;  | 
        ||
| 783 | sprintf(s, GetMiscString(kMiscString_YonDecreasedTo_D), i);  | 
        ||
| 21 | pmbaty | 784 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, s);  | 
        
| 1 | pmbaty | 785 | } | 
        
| 786 | |||
| 787 | // IDA: void __cdecl SetYon(br_scalar pYon) | 
        ||
| 788 | void SetYon(br_scalar pYon) {  | 
        ||
| 789 | int i;  | 
        ||
| 790 | br_camera* camera_ptr;  | 
        ||
| 791 | LOG_TRACE("(%d)", pYon);  | 
        ||
| 792 | |||
| 793 | if (pYon < 5.0f) {  | 
        ||
| 794 | pYon = 5.0f;  | 
        ||
| 795 |     } | 
        ||
| 796 | |||
| 797 | for (i = 0; i < COUNT_OF(gCamera_list); i++) {  | 
        ||
| 798 | if (gCamera_list[i]) {  | 
        ||
| 799 | camera_ptr = gCamera_list[i]->type_data;  | 
        ||
| 800 | camera_ptr->yon_z = pYon;  | 
        ||
| 801 |         } | 
        ||
| 802 |     } | 
        ||
| 803 | gCamera_yon = pYon;  | 
        ||
| 804 | } | 
        ||
| 805 | |||
| 806 | // IDA: br_scalar __cdecl GetYon() | 
        ||
| 807 | br_scalar GetYon(void) {  | 
        ||
| 808 | LOG_TRACE("()");  | 
        ||
| 809 | |||
| 810 | return gCamera_yon;  | 
        ||
| 811 | } | 
        ||
| 812 | |||
| 813 | // IDA: void __cdecl IncreaseAngle() | 
        ||
| 814 | void IncreaseAngle(void) {  | 
        ||
| 815 | br_camera* camera_ptr;  | 
        ||
| 816 | int i;  | 
        ||
| 817 | char s[256];  | 
        ||
| 818 | LOG_TRACE("()");  | 
        ||
| 819 | |||
| 820 | for (i = 0; i < COUNT_OF(gCamera_list); i++) {  | 
        ||
| 821 | camera_ptr = gCamera_list[i]->type_data;  | 
        ||
| 822 | camera_ptr->field_of_view += 0x1c7; // 2.4993896484375 degrees  | 
        ||
| 823 | if (camera_ptr->field_of_view > 0x78e3) { // 169.9969482421875 degrees  | 
        ||
| 824 | camera_ptr->field_of_view = 0x78e3;  | 
        ||
| 825 |         } | 
        ||
| 826 | #ifdef DETHRACE_FIX_BUGS | 
        ||
| 20 | pmbaty | 827 | sprintf(s, "Camera angle increased to %f", (float)BrAngleToDegrees(camera_ptr->field_of_view));  | 
        
| 1 | pmbaty | 828 | #else | 
        
| 829 | sprintf(s, "Camera angle increased to %d", gProgram_state.current_depth_effect.end);  | 
        ||
| 830 | #endif | 
        ||
| 21 | pmbaty | 831 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -1, s);  | 
        
| 1 | pmbaty | 832 |     } | 
        
| 833 | } | 
        ||
| 834 | |||
| 835 | // IDA: void __cdecl DecreaseAngle() | 
        ||
| 836 | void DecreaseAngle(void) {  | 
        ||
| 837 | br_camera* camera_ptr;  | 
        ||
| 838 | int i;  | 
        ||
| 839 | char s[256];  | 
        ||
| 840 | LOG_TRACE("()");  | 
        ||
| 841 | |||
| 842 | for (i = 0; i < COUNT_OF(gCamera_list); i++) {  | 
        ||
| 843 | camera_ptr = gCamera_list[i]->type_data;  | 
        ||
| 844 | camera_ptr->field_of_view -= 0x1c7; // 2.4993896484375 degrees  | 
        ||
| 845 | if (camera_ptr->field_of_view < 0x71c) { // 9.99755859375 degrees  | 
        ||
| 846 | camera_ptr->field_of_view = 0x71c;  | 
        ||
| 847 |         } | 
        ||
| 848 | #ifdef DETHRACE_FIX_BUGS | 
        ||
| 20 | pmbaty | 849 | sprintf(s, "Camera angle decreased to %f", (float)BrAngleToDegrees(camera_ptr->field_of_view));  | 
        
| 1 | pmbaty | 850 | #else | 
        
| 851 | sprintf(s, "Camera angle decreased to %d", gProgram_state.current_depth_effect.end);  | 
        ||
| 852 | #endif | 
        ||
| 21 | pmbaty | 853 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -1, s);  | 
        
| 1 | pmbaty | 854 |     } | 
        
| 855 | } | 
        ||
| 856 | |||
| 857 | // IDA: void __cdecl ToggleDepthMode() | 
        ||
| 858 | void ToggleDepthMode(void) {  | 
        ||
| 859 | LOG_TRACE("()");  | 
        ||
| 860 | |||
| 861 | switch (gProgram_state.current_depth_effect.type) {  | 
        ||
| 862 | case eDepth_effect_none:  | 
        ||
| 863 | InstantDepthChange(eDepth_effect_darkness, gProgram_state.current_depth_effect.sky_texture, 8, 0);  | 
        ||
| 21 | pmbaty | 864 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -1, "Darkness mode");  | 
        
| 1 | pmbaty | 865 | break;  | 
        
| 866 | case eDepth_effect_darkness:  | 
        ||
| 867 | InstantDepthChange(eDepth_effect_none, gProgram_state.current_depth_effect.sky_texture, 0, 0);  | 
        ||
| 868 | InstantDepthChange(eDepth_effect_fog, gProgram_state.current_depth_effect.sky_texture, 10, 0);  | 
        ||
| 21 | pmbaty | 869 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -1, "Fog mode");  | 
        
| 1 | pmbaty | 870 | break;  | 
        
| 871 | case eDepth_effect_fog:  | 
        ||
| 872 | InstantDepthChange(eDepth_effect_none, gProgram_state.current_depth_effect.sky_texture, 0, 0);  | 
        ||
| 21 | pmbaty | 873 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -1, "Depth effects disabled");  | 
        
| 1 | pmbaty | 874 | break;  | 
        
| 875 |     } | 
        ||
| 876 | gProgram_state.default_depth_effect.type = gProgram_state.current_depth_effect.type;  | 
        ||
| 877 | } | 
        ||
| 878 | |||
| 879 | // IDA: int __cdecl GetSkyTextureOn() | 
        ||
| 880 | int GetSkyTextureOn(void) {  | 
        ||
| 881 | LOG_TRACE("()");  | 
        ||
| 882 | |||
| 883 | return gSky_on;  | 
        ||
| 884 | } | 
        ||
| 885 | |||
| 886 | // IDA: void __usercall SetSkyTextureOn(int pOn@<EAX>) | 
        ||
| 887 | void SetSkyTextureOn(int pOn) {  | 
        ||
| 888 | br_pixelmap* tmp;  | 
        ||
| 889 | LOG_TRACE("(%d)", pOn);  | 
        ||
| 890 | |||
| 891 | if (pOn != gSky_on) {  | 
        ||
| 892 | tmp = gProgram_state.current_depth_effect.sky_texture;  | 
        ||
| 893 | gProgram_state.current_depth_effect.sky_texture = gSwap_sky_texture;  | 
        ||
| 894 | gProgram_state.default_depth_effect.sky_texture = gSwap_sky_texture;  | 
        ||
| 895 | gSwap_sky_texture = tmp;  | 
        ||
| 896 | |||
| 897 | if (gHorizon_material) {  | 
        ||
| 898 | if (gSwap_sky_texture) {  | 
        ||
| 899 | gHorizon_material->colour_map = gSwap_sky_texture;  | 
        ||
| 900 | BrMaterialUpdate(gHorizon_material, -1);  | 
        ||
| 901 |             } | 
        ||
| 902 |         } | 
        ||
| 903 |     } | 
        ||
| 904 | gSky_on = pOn;  | 
        ||
| 905 | } | 
        ||
| 906 | |||
| 907 | // IDA: void __cdecl ToggleSkyQuietly() | 
        ||
| 908 | void ToggleSkyQuietly(void) {  | 
        ||
| 909 | br_pixelmap* temp;  | 
        ||
| 910 | LOG_TRACE("()");  | 
        ||
| 911 | |||
| 912 | temp = gProgram_state.current_depth_effect.sky_texture;  | 
        ||
| 913 | gProgram_state.current_depth_effect.sky_texture = gSwap_sky_texture;  | 
        ||
| 914 | gSwap_sky_texture = temp;  | 
        ||
| 915 | gProgram_state.default_depth_effect.sky_texture = gProgram_state.current_depth_effect.sky_texture;  | 
        ||
| 916 | if (gHorizon_material) {  | 
        ||
| 917 | if (gProgram_state.current_depth_effect.sky_texture) {  | 
        ||
| 918 | gHorizon_material->colour_map = gProgram_state.current_depth_effect.sky_texture;  | 
        ||
| 919 | BrMaterialUpdate(gHorizon_material, 0x7FFFu);  | 
        ||
| 920 |         } | 
        ||
| 921 |     } | 
        ||
| 922 | } | 
        ||
| 923 | |||
| 924 | // IDA: void __cdecl ToggleSky() | 
        ||
| 925 | void ToggleSky(void) {  | 
        ||
| 926 | LOG_TRACE("()");  | 
        ||
| 20 | pmbaty | 927 | NOT_IMPLEMENTED();  | 
        
| 1 | pmbaty | 928 | } | 
        
| 929 | |||
| 930 | // IDA: int __cdecl GetDepthCueingOn() | 
        ||
| 931 | int GetDepthCueingOn(void) {  | 
        ||
| 932 | LOG_TRACE("()");  | 
        ||
| 933 | return gDepth_cueing_on;  | 
        ||
| 934 | } | 
        ||
| 935 | |||
| 936 | // IDA: void __usercall SetDepthCueingOn(int pOn@<EAX>) | 
        ||
| 937 | void SetDepthCueingOn(int pOn) {  | 
        ||
| 938 | LOG_TRACE("(%d)", pOn);  | 
        ||
| 939 | if (pOn != gDepth_cueing_on && gHorizon_material) {  | 
        ||
| 940 | InstantDepthChange(gSwap_depth_effect_type, gProgram_state.current_depth_effect.sky_texture, gSwap_depth_effect_start, gSwap_depth_effect_end);  | 
        ||
| 941 | gSwap_depth_effect_type = gProgram_state.current_depth_effect.type;  | 
        ||
| 942 | gSwap_depth_effect_start = gProgram_state.current_depth_effect.start;  | 
        ||
| 943 | gSwap_depth_effect_end = gProgram_state.current_depth_effect.end;  | 
        ||
| 944 |     } | 
        ||
| 945 | gDepth_cueing_on = pOn;  | 
        ||
| 946 | } | 
        ||
| 947 | |||
| 948 | // IDA: void __cdecl ToggleDepthCueingQuietly() | 
        ||
| 949 | void ToggleDepthCueingQuietly(void) {  | 
        ||
| 950 |     tDepth_effect_type temp_type; | 
        ||
| 951 | int temp_start;  | 
        ||
| 952 | int temp_end;  | 
        ||
| 953 | LOG_TRACE("()");  | 
        ||
| 954 | |||
| 955 | temp_type = gProgram_state.current_depth_effect.type;  | 
        ||
| 956 | temp_start = gProgram_state.current_depth_effect.start;  | 
        ||
| 957 | temp_end = gProgram_state.current_depth_effect.end;  | 
        ||
| 958 |     InstantDepthChange( | 
        ||
| 959 |         gSwap_depth_effect_type, | 
        ||
| 960 | gProgram_state.current_depth_effect.sky_texture,  | 
        ||
| 961 |         gSwap_depth_effect_start, | 
        ||
| 962 | gSwap_depth_effect_end);  | 
        ||
| 963 | gSwap_depth_effect_type = temp_type;  | 
        ||
| 964 | gSwap_depth_effect_start = temp_start;  | 
        ||
| 965 | gSwap_depth_effect_end = temp_end;  | 
        ||
| 966 | } | 
        ||
| 967 | |||
| 968 | // IDA: void __cdecl ToggleDepthCueing() | 
        ||
| 969 | void ToggleDepthCueing(void) {  | 
        ||
| 970 | LOG_TRACE("()");  | 
        ||
| 20 | pmbaty | 971 | NOT_IMPLEMENTED();  | 
        
| 1 | pmbaty | 972 | } | 
        
| 973 | |||
| 974 | // IDA: void __cdecl ChangeDepthEffect() | 
        ||
| 975 | void ChangeDepthEffect(void) {  | 
        ||
| 976 |     //br_scalar x1; // Pierre-Marie Baty -- unused variable | 
        ||
| 977 |     //br_scalar x2; // Pierre-Marie Baty -- unused variable | 
        ||
| 978 |     //br_scalar y1; // Pierre-Marie Baty -- unused variable | 
        ||
| 979 |     //br_scalar y2; // Pierre-Marie Baty -- unused variable | 
        ||
| 980 |     //br_scalar z1; // Pierre-Marie Baty -- unused variable | 
        ||
| 981 |     //br_scalar z2; // Pierre-Marie Baty -- unused variable | 
        ||
| 982 |     //br_scalar distance; // Pierre-Marie Baty -- unused variable | 
        ||
| 983 |     //tSpecial_volume* special_volume; // Pierre-Marie Baty -- unused variable | 
        ||
| 984 | LOG_TRACE("()");  | 
        ||
| 20 | pmbaty | 985 | STUB_ONCE();  | 
        
| 1 | pmbaty | 986 | } | 
        
| 987 | |||
| 988 | // IDA: void __cdecl MungeForwardSky() | 
        ||
| 989 | void MungeForwardSky(void) {  | 
        ||
| 990 | LOG_TRACE("()");  | 
        ||
| 991 | } | 
        ||
| 992 | |||
| 993 | // IDA: void __cdecl MungeRearviewSky() | 
        ||
| 994 | void MungeRearviewSky(void) {  | 
        ||
| 995 | LOG_TRACE("()");  | 
        ||
| 996 | |||
| 997 | if (gSky_image_width != 0) {  | 
        ||
| 998 | MungeSkyModel(gRearview_camera, gRearview_sky_model);  | 
        ||
| 999 |     } | 
        ||
| 1000 | } |