Subversion Repositories Games.Carmageddon

Rev

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

  1. #include "depth.h"
  2.  
  3. #include "brender/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.  
  343.     // HACK: moved below loop
  344.     // BrTableAdd(gHorizon_material->index_blend);
  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.     }
  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.  
  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);
  699.     NewTextHeadupSlot(4, 0, 500, -1, s);
  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);
  712.     NewTextHeadupSlot(4, 0, 500, -1, s);
  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);
  725.     NewTextHeadupSlot(4, 0, 500, -1, s);
  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);
  738.     NewTextHeadupSlot(4, 0, 500, -1, s);
  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);
  766.     NewTextHeadupSlot(4, 0, 2000, -4, s);
  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);
  784.     NewTextHeadupSlot(4, 0, 2000, -4, s);
  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
  827.         sprintf(s, "Camera angle increased to %f", (float)BrAngleToDegrees(camera_ptr->field_of_view));
  828. #else
  829.         sprintf(s, "Camera angle increased to %d", gProgram_state.current_depth_effect.end);
  830. #endif
  831.         NewTextHeadupSlot(4, 0, 500, -1, s);
  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
  849.         sprintf(s, "Camera angle decreased to %f", (float)BrAngleToDegrees(camera_ptr->field_of_view));
  850. #else
  851.         sprintf(s, "Camera angle decreased to %d", gProgram_state.current_depth_effect.end);
  852. #endif
  853.         NewTextHeadupSlot(4, 0, 500, -1, s);
  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);
  864.         NewTextHeadupSlot(4, 0, 500, -1, "Darkness mode");
  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);
  869.         NewTextHeadupSlot(4, 0, 500, -1, "Fog mode");
  870.         break;
  871.     case eDepth_effect_fog:
  872.         InstantDepthChange(eDepth_effect_none, gProgram_state.current_depth_effect.sky_texture, 0, 0);
  873.         NewTextHeadupSlot(4, 0, 500, -1, "Depth effects disabled");
  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("()");
  927.     NOT_IMPLEMENTED();
  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("()");
  971.     NOT_IMPLEMENTED();
  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("()");
  985.     STUB_ONCE();
  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. }
  1001.