Subversion Repositories Games.Carmageddon

Rev

Rev 1 | Rev 20 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "depth.h"
  2.  
  3. #include "brender.h"
  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);
  342.     BrTableAdd(gHorizon_material->index_blend);
  343.     for (i = 0; i < 256; i++) {
  344.         for (j = 0; j < 256; j++) {
  345.             *((tU8*)gHorizon_material->index_blend->pixels + 256 * i + j) = j;
  346.         }
  347.     }
  348.     gHorizon_material->flags |= BR_MATF_PERSPECTIVE;
  349.     BrMaterialAdd(gHorizon_material);
  350.     gForward_sky_model = CreateHorizonModel(gCamera);
  351.     gRearview_sky_model = CreateHorizonModel(gRearview_camera);
  352.     BrModelAdd(gForward_sky_model);
  353.     BrModelAdd(gRearview_sky_model);
  354.     gForward_sky_actor = BrActorAllocate(BR_ACTOR_MODEL, NULL);
  355.     gForward_sky_actor->model = gForward_sky_model;
  356.     gForward_sky_actor->material = gHorizon_material;
  357.     gForward_sky_actor->render_style = BR_RSTYLE_NONE;
  358.     BrActorAdd(gUniverse_actor, gForward_sky_actor);
  359.     gRearview_sky_actor = BrActorAllocate(BR_ACTOR_MODEL, NULL);
  360.     gRearview_sky_actor->model = gRearview_sky_model;
  361.     gRearview_sky_actor->material = gHorizon_material;
  362.     gRearview_sky_actor->render_style = BR_RSTYLE_NONE;
  363.     BrActorAdd(gUniverse_actor, gRearview_sky_actor);
  364.     gLast_camera_special_volume = 0;
  365. }
  366.  
  367. // 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)
  368. void DoDepthByShadeTable(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_pixelmap* pShade_table, int pShade_table_power, int pStart, int pEnd) {
  369.     tU8* render_ptr;
  370.     tU8* shade_table_pixels;
  371.     tU16* depth_ptr;
  372.     tU16 depth_value;
  373.     tU16 too_near;
  374.     int depth_shift_amount;
  375.     //int depth_start; // Pierre-Marie Baty -- unused variable
  376.     int y;
  377.     int x;
  378.     int depth_line_skip;
  379.     int render_line_skip;
  380.     LOG_TRACE("(%p, %p, %p, %d, %d, %d)", pRender_buffer, pDepth_buffer, pShade_table, pShade_table_power, pStart, pEnd);
  381.  
  382.     too_near = 0xffff - (1 << pStart);
  383.     shade_table_pixels = pShade_table->pixels;
  384.     depth_shift_amount = pShade_table_power + 8 - pStart - pEnd;
  385.     render_ptr = (tU8*)pRender_buffer->pixels + pRender_buffer->base_x + pRender_buffer->base_y * pRender_buffer->row_bytes;
  386.     depth_ptr = pDepth_buffer->pixels;
  387.     render_line_skip = pRender_buffer->row_bytes - pRender_buffer->width;
  388.     depth_line_skip = pDepth_buffer->row_bytes / 2 - pRender_buffer->width;
  389.  
  390.     if (depth_shift_amount <= 0) {
  391.         if (depth_shift_amount >= 0) {
  392.             for (y = 0; y < pRender_buffer->height; ++y) {
  393.                 for (x = 0; x < pRender_buffer->width; ++x) {
  394.                     if (*depth_ptr != 0xFFFF) {
  395.                         depth_value = *depth_ptr - too_near;
  396.                         if (depth_value < -(int16_t)too_near) {
  397.                             *render_ptr = shade_table_pixels[(depth_value & 0xFF00) + *render_ptr];
  398.                         }
  399.                     }
  400.                     ++render_ptr;
  401.                     ++depth_ptr;
  402.                 }
  403.                 render_ptr += render_line_skip;
  404.                 depth_ptr += depth_line_skip;
  405.             }
  406.         } else {
  407.             for (y = 0; pRender_buffer->height > y; ++y) {
  408.                 for (x = 0; pRender_buffer->width > x; ++x) {
  409.                     if (*depth_ptr != 0xFFFF) {
  410.                         depth_value = *depth_ptr - too_near;
  411.                         if (depth_value < -(int16_t)too_near) {
  412.                             *render_ptr = shade_table_pixels[*render_ptr + ((depth_value >> (pEnd - (pShade_table_power + 8 - pStart))) & 0xFF00)];
  413.                         }
  414.                     }
  415.                     ++render_ptr;
  416.                     ++depth_ptr;
  417.                 }
  418.                 render_ptr += render_line_skip;
  419.                 depth_ptr += depth_line_skip;
  420.             }
  421.         }
  422.     } else {
  423.         for (y = 0; pRender_buffer->height > y; ++y) {
  424.             for (x = 0; pRender_buffer->width > x; ++x) {
  425.                 if (*depth_ptr != 0xFFFF) {
  426.                     depth_value = *depth_ptr - too_near;
  427.                     if (depth_value < -(int16_t)too_near) {
  428.                         *render_ptr = shade_table_pixels[*render_ptr + ((depth_value << depth_shift_amount) & 0xFF00)];
  429.                     }
  430.                 }
  431.                 ++render_ptr;
  432.                 ++depth_ptr;
  433.             }
  434.             render_ptr += render_line_skip;
  435.             depth_ptr += depth_line_skip;
  436.         }
  437.     }
  438. }
  439.  
  440. // IDA: void __usercall ExternalSky(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>, br_matrix34 *pCamera_to_world@<ECX>)
  441. void ExternalSky(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world) {
  442.     int dst_x;
  443.     int src_x;
  444.     int dx;
  445.     int hori_y;
  446.     int top_y;
  447.     int hori_pixels;
  448.     //br_angle yaw; // Pierre-Marie Baty -- unused variable
  449.     br_angle hori_sky;
  450.     //br_angle pitch; // Pierre-Marie Baty -- unused variable
  451.     br_angle vert_sky;
  452.     br_camera* camera;
  453.     br_scalar tan_half_fov;
  454.     br_scalar tan_half_hori_fov;
  455.     br_scalar tan_half_hori_sky;
  456.     br_scalar hshift;
  457.     br_scalar tan_pitch;
  458.     tU8 top_col;
  459.     tU8 bot_col;
  460.     int bot_height;
  461.     //int repetitions; // Pierre-Marie Baty -- unused variable
  462.     br_pixelmap* col_map;
  463.     LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);
  464.  
  465.     dst_x = 0;
  466.     col_map = gHorizon_material->colour_map;
  467.     camera = (br_camera*)pCamera->type_data;
  468.     tan_half_fov = Tan(camera->field_of_view / 2);
  469.     tan_half_hori_fov = tan_half_fov * camera->aspect;
  470.  
  471.     vert_sky = BrRadianToAngle(atan2(pCamera_to_world->m[2][0], pCamera_to_world->m[2][2]));
  472.     hori_sky = BrRadianToAngle(atan2(col_map->width * tan_half_hori_fov / (double)pRender_buffer->width, 1));
  473.  
  474.     tan_half_hori_sky = -BrFixedToFloat(vert_sky) / BrFixedToFloat(BR_ANGLE_DEG(360) / (int)(1.0f / BrFixedToFloat(2 * hori_sky) + 0.5f));
  475.  
  476.     dx = col_map->width * tan_half_hori_sky;
  477.     while (dx < 0) {
  478.         dx += col_map->width;
  479.     }
  480.     while (dx > col_map->width) {
  481.         dx -= col_map->width;
  482.     }
  483.  
  484.     hshift = col_map->height - gSky_image_underground * col_map->height / gSky_image_height;
  485.     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]);
  486.     hori_y = -(pCamera_to_world->m[2][1]
  487.                  / tan_pitch
  488.                  / tan_half_fov * pRender_buffer->height / 2.0f)
  489.         - hshift;
  490.  
  491.     while (dst_x < pRender_buffer->width) {
  492.         hori_pixels = col_map->width - dx;
  493.         if (hori_pixels > pRender_buffer->width - dst_x) {
  494.             hori_pixels = pRender_buffer->width - dst_x;
  495.         }
  496.         src_x = dx - col_map->origin_x;
  497.         DRPixelmapRectangleCopy(pRender_buffer, dst_x - pRender_buffer->origin_x, hori_y, col_map, src_x, -col_map->origin_y, hori_pixels, col_map->height);
  498.         dx = 0;
  499.         dst_x += hori_pixels;
  500.     }
  501.  
  502.     top_y = hori_y + pRender_buffer->origin_y;
  503.     if (top_y > 0) {
  504.         top_col = ((tU8*)col_map->pixels)[0];
  505.         DRPixelmapRectangleFill(pRender_buffer, -pRender_buffer->origin_x, -pRender_buffer->origin_y, pRender_buffer->width, top_y, top_col);
  506.     }
  507.     bot_height = pRender_buffer->height - pRender_buffer->origin_y - hori_y - col_map->height;
  508.     if (bot_height > 0) {
  509.         bot_col = ((tU8*)col_map->pixels)[col_map->row_bytes * (col_map->height - 1)];
  510.         DRPixelmapRectangleFill(pRender_buffer, -pRender_buffer->origin_x, hori_y + col_map->height, pRender_buffer->width, bot_height, bot_col);
  511.     }
  512. }
  513.  
  514. #define ACTOR_CAMERA(ACTOR) ((br_camera*)((ACTOR)->type_data))
  515.  
  516. // IDA: void __usercall DoHorizon(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>, br_matrix34 *pCamera_to_world@<ECX>)
  517. void DoHorizon(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world) {
  518.     br_angle yaw;
  519.     br_actor* actor;
  520.     LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);
  521.  
  522.     yaw = BrRadianToAngle(atan2f(pCamera_to_world->m[2][0], pCamera_to_world->m[2][2]));
  523.     if (!gProgram_state.cockpit_on && !(gAction_replay_mode && gAction_replay_camera_mode)) {
  524.         return;
  525.     }
  526.     if (gRendering_mirror) {
  527.         actor = gRearview_sky_actor;
  528.     } else {
  529.         actor = gForward_sky_actor;
  530.         if (ACTOR_CAMERA(gCamera)->field_of_view != gOld_fov || ACTOR_CAMERA(gCamera)->yon_z != gOld_yon) {
  531.             gOld_fov = ACTOR_CAMERA(gCamera)->field_of_view;
  532.             gOld_yon = ACTOR_CAMERA(gCamera)->yon_z;
  533.             MungeSkyModel(gCamera, gForward_sky_model);
  534.         }
  535.     }
  536.     BrMatrix34RotateY(&actor->t.t.mat, yaw);
  537.     BrVector3Copy(&actor->t.t.translate.t, (br_vector3*)pCamera_to_world->m[3]);
  538.     gHorizon_material->map_transform.m[0][0] = 1.f;
  539.     gHorizon_material->map_transform.m[0][1] = 0.f;
  540.     gHorizon_material->map_transform.m[1][0] = 0.f;
  541.     gHorizon_material->map_transform.m[1][1] = 1.f;
  542.     gHorizon_material->map_transform.m[2][0] = -BrFixedToFloat(yaw) / BrFixedToFloat(gSky_image_width);
  543.     gHorizon_material->map_transform.m[2][1] = 0.f;
  544.     BrMaterialUpdate(gHorizon_material, BR_MATU_ALL);
  545.     actor->render_style = BR_RSTYLE_FACES;
  546.     BrZbSceneRenderAdd(actor);
  547.     actor->render_style = BR_RSTYLE_NONE;
  548. }
  549.  
  550. // IDA: void __usercall DoDepthCue(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>)
  551. void DoDepthCue(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer) {
  552.     LOG_TRACE("(%p, %p)", pRender_buffer, pDepth_buffer);
  553.  
  554.     DoDepthByShadeTable(
  555.         pRender_buffer,
  556.         pDepth_buffer,
  557.         gDepth_shade_table,
  558.         gDepth_shade_table_power,
  559.         gProgram_state.current_depth_effect.start,
  560.         gProgram_state.current_depth_effect.end);
  561. }
  562.  
  563. // IDA: void __usercall DoFog(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>)
  564. void DoFog(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer) {
  565.     LOG_TRACE("(%p, %p)", pRender_buffer, pDepth_buffer);
  566.  
  567.     DoDepthByShadeTable(
  568.         pRender_buffer,
  569.         pDepth_buffer,
  570.         gFog_shade_table,
  571.         gFog_shade_table_power,
  572.         gProgram_state.current_depth_effect.start,
  573.         gProgram_state.current_depth_effect.end);
  574. }
  575.  
  576. // IDA: void __usercall DepthEffect(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>, br_matrix34 *pCamera_to_world@<ECX>)
  577. void DepthEffect(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world) {
  578.     LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);
  579.  
  580.     if (gProgram_state.current_depth_effect.type == eDepth_effect_darkness) {
  581.         DoDepthCue(pRender_buffer, pDepth_buffer);
  582.     }
  583.     if (gProgram_state.current_depth_effect.type == eDepth_effect_fog) {
  584.         DoFog(pRender_buffer, pDepth_buffer);
  585.     }
  586. }
  587.  
  588. // IDA: void __usercall DepthEffectSky(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>, br_matrix34 *pCamera_to_world@<ECX>)
  589. void DepthEffectSky(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world) {
  590.     LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);
  591.  
  592.     if (gProgram_state.current_depth_effect.sky_texture != NULL
  593.         && (gLast_camera_special_volume == NULL || gLast_camera_special_volume->sky_col < 0)) {
  594.         DoHorizon(pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);
  595.     }
  596. }
  597.  
  598. // IDA: void __usercall DoWobbleCamera(br_actor *pCamera@<EAX>)
  599. void DoWobbleCamera(br_actor* pCamera) {
  600.     float f_time;
  601.     static br_scalar mag00 = 0.02f;
  602.     static br_scalar mag01 = 0.02f;
  603.     static br_scalar mag02 = 0.02f;
  604.     static br_scalar mag10 = 0.15f;
  605.     static br_scalar mag11 = 0.05f;
  606.     static br_scalar mag12 = 0.02f;
  607.     static br_scalar mag20 = 0.f;
  608.     static br_scalar mag21 = 0.f;
  609.     static br_scalar mag22 = 0.f;
  610.     static float period00 = 3000.f;
  611.     static float period01 = 3000.f;
  612.     static float period02 = 4000.f;
  613.     static float period10 = 2200.f;
  614.     static float period11 = 3300.f;
  615.     static float period12 = 3100.f;
  616.     static float period20 = 2800.f;
  617.     static float period21 = 2500.f;
  618.     static float period22 = 3900.f;
  619.     LOG_TRACE("(%p)", pCamera);
  620.  
  621.     f_time = (float)PDGetTotalTime();
  622.     pCamera->t.t.mat.m[0][0] += FastScalarSin(fmod(f_time / period00 * 360.f, 360.f)) * mag00;
  623.     pCamera->t.t.mat.m[0][1] += FastScalarSin(fmod(f_time / period01 * 360.f, 360.f)) * mag01;
  624.     pCamera->t.t.mat.m[0][2] += FastScalarSin(fmod(f_time / period02 * 360.f, 360.f)) * mag02;
  625.     pCamera->t.t.mat.m[1][0] += FastScalarSin(fmod(f_time / period10 * 360.f, 360.f)) * mag10;
  626.     pCamera->t.t.mat.m[1][1] += FastScalarSin(fmod(f_time / period11 * 360.f, 360.f)) * mag11;
  627.     pCamera->t.t.mat.m[1][2] += FastScalarSin(fmod(f_time / period12 * 360.f, 360.f)) * mag12;
  628.     pCamera->t.t.mat.m[2][0] += FastScalarSin(fmod(f_time / period20 * 360.f, 360.f)) * mag20;
  629.     pCamera->t.t.mat.m[2][1] += FastScalarSin(fmod(f_time / period21 * 360.f, 360.f)) * mag21;
  630.     pCamera->t.t.mat.m[2][2] += FastScalarSin(fmod(f_time / period22 * 360.f, 360.f)) * mag22;
  631. }
  632.  
  633. // IDA: void __usercall DoDrugWobbleCamera(br_actor *pCamera@<EAX>)
  634. void DoDrugWobbleCamera(br_actor* pCamera) {
  635.     float f_time;
  636.     static br_scalar mag00 = 0.03f;
  637.     static br_scalar mag01 = 0.03f;
  638.     static br_scalar mag02 = 0.03f;
  639.     static br_scalar mag10 = 0.2f;
  640.     static br_scalar mag11 = 0.07f; // Pierre-Marie Baty -- missing float suffix
  641.     static br_scalar mag12 = 0.03f;
  642.     static br_scalar mag20 = 0.02f;
  643.     static br_scalar mag21 = 0.03f;
  644.     static br_scalar mag22 = 0.01f;
  645.     static float period00 = 550.f;
  646.     static float period01 = 700.f;
  647.     static float period02 = 200.f;
  648.     static float period10 = 100.f;
  649.     static float period11 = 1300.f;
  650.     static float period12 = 500.f;
  651.     static float period20 = 800.f;
  652.     static float period21 = 1500.f;
  653.     static float period22 = 300.f;
  654.     LOG_TRACE("(%p)", pCamera);
  655.  
  656.     f_time = (float)PDGetTotalTime();
  657.     pCamera->t.t.mat.m[0][0] += FastScalarSin(fmod(f_time / period00 * 360.f, 360.f)) * mag00;
  658.     pCamera->t.t.mat.m[0][1] += FastScalarSin(fmod(f_time / period01 * 360.f, 360.f)) * mag01;
  659.     pCamera->t.t.mat.m[0][2] += FastScalarSin(fmod(f_time / period02 * 360.f, 360.f)) * mag02;
  660.     pCamera->t.t.mat.m[1][0] += FastScalarSin(fmod(f_time / period10 * 360.f, 360.f)) * mag10;
  661.     pCamera->t.t.mat.m[1][1] += FastScalarSin(fmod(f_time / period11 * 360.f, 360.f)) * mag11;
  662.     pCamera->t.t.mat.m[1][2] += FastScalarSin(fmod(f_time / period12 * 360.f, 360.f)) * mag12;
  663.     pCamera->t.t.mat.m[2][0] += FastScalarSin(fmod(f_time / period20 * 360.f, 360.f)) * mag20;
  664.     pCamera->t.t.mat.m[2][1] += FastScalarSin(fmod(f_time / period21 * 360.f, 360.f)) * mag21;
  665.     pCamera->t.t.mat.m[2][2] += FastScalarSin(fmod(f_time / period22 * 360.f, 360.f)) * mag22;
  666. }
  667.  
  668. // IDA: void __usercall DoSpecialCameraEffect(br_actor *pCamera@<EAX>, br_matrix34 *pCamera_to_world@<EDX>)
  669. void DoSpecialCameraEffect(br_actor* pCamera, br_matrix34* pCamera_to_world) {
  670.     LOG_TRACE("(%p, %p)", pCamera, pCamera_to_world);
  671.  
  672.     if (gOn_drugs) {
  673.         DoDrugWobbleCamera(pCamera);
  674.     } else {
  675.         gLast_camera_special_volume = FindSpecialVolume((br_vector3*)pCamera_to_world->m[3], gLast_camera_special_volume);
  676.         if (gLast_camera_special_volume != NULL) {
  677.             if (gLast_camera_special_volume->camera_special_effect_index == 0) {
  678.                 DoWobbleCamera(pCamera);
  679.             }
  680.         }
  681.     }
  682. }
  683.  
  684. // IDA: void __cdecl LessDepthFactor()
  685. void LessDepthFactor(void) {
  686.     char s[256];
  687.     LOG_TRACE("()");
  688.  
  689.     if (gProgram_state.current_depth_effect.start > 3) {
  690.         gProgram_state.current_depth_effect.start--;
  691.     }
  692.     sprintf(s, "Depth start reduced to %d", gProgram_state.current_depth_effect.start);
  693.     NewTextHeadupSlot(4, 0, 500, -1, s);
  694.     gProgram_state.default_depth_effect.start = gProgram_state.current_depth_effect.start;
  695. }
  696.  
  697. // IDA: void __cdecl MoreDepthFactor()
  698. void MoreDepthFactor(void) {
  699.     char s[256];
  700.     LOG_TRACE("()");
  701.  
  702.     if (gProgram_state.current_depth_effect.start < 14) {
  703.         gProgram_state.current_depth_effect.start++;
  704.     }
  705.     sprintf(s, "Depth start increased to %d", gProgram_state.current_depth_effect.start);
  706.     NewTextHeadupSlot(4, 0, 500, -1, s);
  707.     gProgram_state.default_depth_effect.start = gProgram_state.current_depth_effect.start;
  708. }
  709.  
  710. // IDA: void __cdecl LessDepthFactor2()
  711. void LessDepthFactor2(void) {
  712.     char s[256];
  713.     LOG_TRACE("()");
  714.  
  715.     if (gProgram_state.current_depth_effect.end < 14) {
  716.         gProgram_state.current_depth_effect.end++;
  717.     }
  718.     sprintf(s, "Depth end reduced to %d", gProgram_state.current_depth_effect.end);
  719.     NewTextHeadupSlot(4, 0, 500, -1, s);
  720.     gProgram_state.default_depth_effect.end = gProgram_state.current_depth_effect.end;
  721. }
  722.  
  723. // IDA: void __cdecl MoreDepthFactor2()
  724. void MoreDepthFactor2(void) {
  725.     char s[256];
  726.     LOG_TRACE("()");
  727.  
  728.     if (gProgram_state.current_depth_effect.end > 0) {
  729.         gProgram_state.current_depth_effect.end--;
  730.     }
  731.     sprintf(s, "Depth end increased to %d", gProgram_state.current_depth_effect.end);
  732.     NewTextHeadupSlot(4, 0, 500, -1, s);
  733.     gProgram_state.default_depth_effect.end = gProgram_state.current_depth_effect.end;
  734. }
  735.  
  736. // IDA: void __cdecl AssertYons()
  737. void AssertYons(void) {
  738.     br_camera* camera_ptr;
  739.     int i;
  740.     LOG_TRACE("()");
  741.  
  742.     for (i = 0; i < COUNT_OF(gCamera_list); ++i) {
  743.         camera_ptr = gCamera_list[i]->type_data;
  744.         camera_ptr->yon_z = gYon_multiplier * gCamera_yon;
  745.     }
  746. }
  747.  
  748. // IDA: void __cdecl IncreaseYon()
  749. void IncreaseYon(void) {
  750.     br_camera* camera_ptr;
  751.     int i;
  752.     char s[256];
  753.     LOG_TRACE("()");
  754.  
  755.     gCamera_yon = gCamera_yon + 5.f;
  756.     AssertYons();
  757.     camera_ptr = gCamera_list[1]->type_data;
  758.     i = (int)camera_ptr->yon_z;
  759.     sprintf(s, GetMiscString(kMiscString_YonIncreasedTo_D), i);
  760.     NewTextHeadupSlot(4, 0, 2000, -4, s);
  761. }
  762.  
  763. // IDA: void __cdecl DecreaseYon()
  764. void DecreaseYon(void) {
  765.     br_camera* camera_ptr;
  766.     int i;
  767.     char s[256];
  768.     LOG_TRACE("()");
  769.  
  770.     gCamera_yon = gCamera_yon - 5.f;
  771.     if (gCamera_yon < 5.f) {
  772.         gCamera_yon = 5.f;
  773.     }
  774.     AssertYons();
  775.     camera_ptr = gCamera_list[1]->type_data;
  776.     i = (int)camera_ptr->yon_z;
  777.     sprintf(s, GetMiscString(kMiscString_YonDecreasedTo_D), i);
  778.     NewTextHeadupSlot(4, 0, 2000, -4, s);
  779. }
  780.  
  781. // IDA: void __cdecl SetYon(br_scalar pYon)
  782. void SetYon(br_scalar pYon) {
  783.     int i;
  784.     br_camera* camera_ptr;
  785.     LOG_TRACE("(%d)", pYon);
  786.  
  787.     if (pYon < 5.0f) {
  788.         pYon = 5.0f;
  789.     }
  790.  
  791.     for (i = 0; i < COUNT_OF(gCamera_list); i++) {
  792.         if (gCamera_list[i]) {
  793.             camera_ptr = gCamera_list[i]->type_data;
  794.             camera_ptr->yon_z = pYon;
  795.         }
  796.     }
  797.     gCamera_yon = pYon;
  798. }
  799.  
  800. // IDA: br_scalar __cdecl GetYon()
  801. br_scalar GetYon(void) {
  802.     LOG_TRACE("()");
  803.  
  804.     return gCamera_yon;
  805. }
  806.  
  807. // IDA: void __cdecl IncreaseAngle()
  808. void IncreaseAngle(void) {
  809.     br_camera* camera_ptr;
  810.     int i;
  811.     char s[256];
  812.     LOG_TRACE("()");
  813.  
  814.     for (i = 0; i < COUNT_OF(gCamera_list); i++) {
  815.         camera_ptr = gCamera_list[i]->type_data;
  816.         camera_ptr->field_of_view += 0x1c7;       // 2.4993896484375 degrees
  817.         if (camera_ptr->field_of_view > 0x78e3) { // 169.9969482421875 degrees
  818.             camera_ptr->field_of_view = 0x78e3;
  819.         }
  820. #ifdef DETHRACE_FIX_BUGS
  821.         sprintf(s, "Camera angle increased to %f", (float)BrAngleToDegree(camera_ptr->field_of_view));
  822. #else
  823.         sprintf(s, "Camera angle increased to %d", gProgram_state.current_depth_effect.end);
  824. #endif
  825.         NewTextHeadupSlot(4, 0, 500, -1, s);
  826.     }
  827. }
  828.  
  829. // IDA: void __cdecl DecreaseAngle()
  830. void DecreaseAngle(void) {
  831.     br_camera* camera_ptr;
  832.     int i;
  833.     char s[256];
  834.     LOG_TRACE("()");
  835.  
  836.     for (i = 0; i < COUNT_OF(gCamera_list); i++) {
  837.         camera_ptr = gCamera_list[i]->type_data;
  838.         camera_ptr->field_of_view -= 0x1c7;      // 2.4993896484375 degrees
  839.         if (camera_ptr->field_of_view < 0x71c) { // 9.99755859375 degrees
  840.             camera_ptr->field_of_view = 0x71c;
  841.         }
  842. #ifdef DETHRACE_FIX_BUGS
  843.         sprintf(s, "Camera angle decreased to %f", (float)BrAngleToDegree(camera_ptr->field_of_view));
  844. #else
  845.         sprintf(s, "Camera angle decreased to %d", gProgram_state.current_depth_effect.end);
  846. #endif
  847.         NewTextHeadupSlot(4, 0, 500, -1, s);
  848.     }
  849. }
  850.  
  851. // IDA: void __cdecl ToggleDepthMode()
  852. void ToggleDepthMode(void) {
  853.     LOG_TRACE("()");
  854.  
  855.     switch (gProgram_state.current_depth_effect.type) {
  856.     case eDepth_effect_none:
  857.         InstantDepthChange(eDepth_effect_darkness, gProgram_state.current_depth_effect.sky_texture, 8, 0);
  858.         NewTextHeadupSlot(4, 0, 500, -1, "Darkness mode");
  859.         break;
  860.     case eDepth_effect_darkness:
  861.         InstantDepthChange(eDepth_effect_none, gProgram_state.current_depth_effect.sky_texture, 0, 0);
  862.         InstantDepthChange(eDepth_effect_fog, gProgram_state.current_depth_effect.sky_texture, 10, 0);
  863.         NewTextHeadupSlot(4, 0, 500, -1, "Fog mode");
  864.         break;
  865.     case eDepth_effect_fog:
  866.         InstantDepthChange(eDepth_effect_none, gProgram_state.current_depth_effect.sky_texture, 0, 0);
  867.         NewTextHeadupSlot(4, 0, 500, -1, "Depth effects disabled");
  868.         break;
  869.     }
  870.     gProgram_state.default_depth_effect.type = gProgram_state.current_depth_effect.type;
  871. }
  872.  
  873. // IDA: int __cdecl GetSkyTextureOn()
  874. int GetSkyTextureOn(void) {
  875.     LOG_TRACE("()");
  876.  
  877.     return gSky_on;
  878. }
  879.  
  880. // IDA: void __usercall SetSkyTextureOn(int pOn@<EAX>)
  881. void SetSkyTextureOn(int pOn) {
  882.     br_pixelmap* tmp;
  883.     LOG_TRACE("(%d)", pOn);
  884.  
  885.     if (pOn != gSky_on) {
  886.         tmp = gProgram_state.current_depth_effect.sky_texture;
  887.         gProgram_state.current_depth_effect.sky_texture = gSwap_sky_texture;
  888.         gProgram_state.default_depth_effect.sky_texture = gSwap_sky_texture;
  889.         gSwap_sky_texture = tmp;
  890.  
  891.         if (gHorizon_material) {
  892.             if (gSwap_sky_texture) {
  893.                 gHorizon_material->colour_map = gSwap_sky_texture;
  894.                 BrMaterialUpdate(gHorizon_material, -1);
  895.             }
  896.         }
  897.     }
  898.     gSky_on = pOn;
  899. }
  900.  
  901. // IDA: void __cdecl ToggleSkyQuietly()
  902. void ToggleSkyQuietly(void) {
  903.     br_pixelmap* temp;
  904.     LOG_TRACE("()");
  905.  
  906.     temp = gProgram_state.current_depth_effect.sky_texture;
  907.     gProgram_state.current_depth_effect.sky_texture = gSwap_sky_texture;
  908.     gSwap_sky_texture = temp;
  909.     gProgram_state.default_depth_effect.sky_texture = gProgram_state.current_depth_effect.sky_texture;
  910.     if (gHorizon_material) {
  911.         if (gProgram_state.current_depth_effect.sky_texture) {
  912.             gHorizon_material->colour_map = gProgram_state.current_depth_effect.sky_texture;
  913.             BrMaterialUpdate(gHorizon_material, 0x7FFFu);
  914.         }
  915.     }
  916. }
  917.  
  918. // IDA: void __cdecl ToggleSky()
  919. void ToggleSky(void) {
  920.     LOG_TRACE("()");
  921.  
  922.     SetSkyTextureOn(!GetSkyTextureOn());
  923.     if (gProgram_state.current_depth_effect.sky_texture != NULL) {
  924.         NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(kMiscString_SkyTextureOn));
  925.     } else if (gSwap_sky_texture != NULL) {
  926.         NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(kMiscString_SkyTextureOff));
  927.     } else {
  928.         NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(kMiscString_ThereIsNoSkyTextureForThisRace));
  929.     }
  930. }
  931.  
  932. // IDA: int __cdecl GetDepthCueingOn()
  933. int GetDepthCueingOn(void) {
  934.     LOG_TRACE("()");
  935.     return gDepth_cueing_on;
  936. }
  937.  
  938. // IDA: void __usercall SetDepthCueingOn(int pOn@<EAX>)
  939. void SetDepthCueingOn(int pOn) {
  940.     LOG_TRACE("(%d)", pOn);
  941.     if (pOn != gDepth_cueing_on && gHorizon_material) {
  942.         InstantDepthChange(gSwap_depth_effect_type, gProgram_state.current_depth_effect.sky_texture, gSwap_depth_effect_start, gSwap_depth_effect_end);
  943.         gSwap_depth_effect_type = gProgram_state.current_depth_effect.type;
  944.         gSwap_depth_effect_start = gProgram_state.current_depth_effect.start;
  945.         gSwap_depth_effect_end = gProgram_state.current_depth_effect.end;
  946.     }
  947.     gDepth_cueing_on = pOn;
  948. }
  949.  
  950. // IDA: void __cdecl ToggleDepthCueingQuietly()
  951. void ToggleDepthCueingQuietly(void) {
  952.     tDepth_effect_type temp_type;
  953.     int temp_start;
  954.     int temp_end;
  955.     LOG_TRACE("()");
  956.  
  957.     temp_type = gProgram_state.current_depth_effect.type;
  958.     temp_start = gProgram_state.current_depth_effect.start;
  959.     temp_end = gProgram_state.current_depth_effect.end;
  960.     InstantDepthChange(
  961.         gSwap_depth_effect_type,
  962.         gProgram_state.current_depth_effect.sky_texture,
  963.         gSwap_depth_effect_start,
  964.         gSwap_depth_effect_end);
  965.     gSwap_depth_effect_type = temp_type;
  966.     gSwap_depth_effect_start = temp_start;
  967.     gSwap_depth_effect_end = temp_end;
  968. }
  969.  
  970. // IDA: void __cdecl ToggleDepthCueing()
  971. void ToggleDepthCueing(void) {
  972.     LOG_TRACE("()");
  973.  
  974.     SetDepthCueingOn(!GetDepthCueingOn());
  975.     if (gProgram_state.current_depth_effect.type != eDepth_effect_none) {
  976.         NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(kMiscString_DepthCueingOn));
  977.     } else if (gSwap_depth_effect_type != eDepth_effect_none) {
  978.         NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(kMiscString_DepthCueingOff));
  979.     } else {
  980.         NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(kMiscString_ThereIsNoDepthCueingForThisRace));
  981.     }
  982. }
  983.  
  984. // IDA: void __cdecl ChangeDepthEffect()
  985. void ChangeDepthEffect(void) {
  986.     //br_scalar x1; // Pierre-Marie Baty -- unused variable
  987.     //br_scalar x2; // Pierre-Marie Baty -- unused variable
  988.     //br_scalar y1; // Pierre-Marie Baty -- unused variable
  989.     //br_scalar y2; // Pierre-Marie Baty -- unused variable
  990.     //br_scalar z1; // Pierre-Marie Baty -- unused variable
  991.     //br_scalar z2; // Pierre-Marie Baty -- unused variable
  992.     //br_scalar distance; // Pierre-Marie Baty -- unused variable
  993.     //tSpecial_volume* special_volume; // Pierre-Marie Baty -- unused variable
  994.     LOG_TRACE("()");
  995.  
  996.     gProgram_state.current_depth_effect.type = gProgram_state.default_depth_effect.type;
  997.     gProgram_state.current_depth_effect.sky_texture = gProgram_state.default_depth_effect.sky_texture;
  998.     gProgram_state.current_depth_effect.start = gProgram_state.default_depth_effect.start;
  999.     gProgram_state.current_depth_effect.end = gProgram_state.default_depth_effect.end;
  1000. }
  1001.  
  1002. // IDA: void __cdecl MungeForwardSky()
  1003. void MungeForwardSky(void) {
  1004.     LOG_TRACE("()");
  1005. }
  1006.  
  1007. // IDA: void __cdecl MungeRearviewSky()
  1008. void MungeRearviewSky(void) {
  1009.     LOG_TRACE("()");
  1010.  
  1011.     if (gSky_image_width != 0) {
  1012.         MungeSkyModel(gRearview_camera, gRearview_sky_model);
  1013.     }
  1014. }
  1015.