chunk.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. // Chunk.cpp
  19. // Project: Nostril (aka Postal)
  20. //
  21. // History:
  22. // 05/13/97 JMI Started.
  23. //
  24. // 05/15/97 JMI Added alpha'ing of blood on the ground.
  25. //
  26. // 05/22/97 JMI Changed blood alpha level to 60 (was 70).
  27. //
  28. // 05/22/97 JMI Can support several types of 'chunks'.
  29. //
  30. // 05/26/97 JMI Changed bullet casing color to 7 (gray) was 3
  31. // (dark yellow).
  32. //
  33. // 06/17/97 JMI Converted all occurrences of rand() to GetRand() and
  34. // srand() to SeedRand().
  35. //
  36. // 08/18/97 JMI Now uses its own internal GetRand() and has randomization
  37. // arguments to Setup() so the caller can still control the
  38. // the randomization.
  39. //
  40. // 08/25/97 JMI Setup() was mod'ing m_dRot before adding in the random
  41. // sway value causing it to sometimes exceed 359. Fixed.
  42. //
  43. // 09/08/97 JMI Added Kevlar type for pieces of kevlar vest that
  44. // splatter off of dudes with vest.
  45. //
  46. // 09/08/97 JMI Took out CHUNK_* macros to verify/make-sure they're not
  47. // used.
  48. //
  49. //////////////////////////////////////////////////////////////////////////////
  50. //
  51. // This CThing-derived class will represent pieces of bloody yee (or chunks)
  52. // that fly off a recently damaged, complex organism or something.
  53. //
  54. //////////////////////////////////////////////////////////////////////////////
  55. #define CHUNK_CPP
  56. #include "RSPiX.h"
  57. #include "chunk.h"
  58. #include "reality.h"
  59. // This class defines its own GetRand()
  60. #undef GetRand
  61. #undef GetRandom
  62. #define GetRand CChunk::GetChunkRand
  63. #define GetRandom CChunk::GetChunkRand
  64. ////////////////////////////////////////////////////////////////////////////////
  65. // Macros/types/etc.
  66. ////////////////////////////////////////////////////////////////////////////////
  67. // Gets a random between -range / 2 and range / 2.
  68. #define RAND_SWAY(sway) ((CChunk::GetChunkRand() % sway) - sway / 2)
  69. // Level at which to alpha blood on the ground.
  70. #define ALPHA_LEVEL 60
  71. ////////////////////////////////////////////////////////////////////////////////
  72. // Variables/data
  73. ////////////////////////////////////////////////////////////////////////////////
  74. // Note that this is never reseeded b/c this is just an 'effect'
  75. // that does not and SHOULD not affect game play as it can be
  76. // turned off.
  77. long CChunk::ms_lGetRandomSeed = 0; // Seed for GetRand[om]().
  78. // Chunk info for each type.
  79. CChunk::TypeInfo CChunk::ms_atiChunks[CChunk::NumTypes] =
  80. { // u8ColorIndex, sLen
  81. { 1, 4, }, // Blood.
  82. { 7, 3, }, // BulletCasing.
  83. { 2, 4, }, // Shell.
  84. { 7, 4, }, // Kevlar.
  85. };
  86. ////////////////////////////////////////////////////////////////////////////////
  87. // Suspend object
  88. ////////////////////////////////////////////////////////////////////////////////
  89. void CChunk::Suspend(void)
  90. {
  91. m_sSuspend++;
  92. }
  93. ////////////////////////////////////////////////////////////////////////////////
  94. // Resume object
  95. ////////////////////////////////////////////////////////////////////////////////
  96. void CChunk::Resume(void)
  97. {
  98. m_sSuspend--;
  99. }
  100. ////////////////////////////////////////////////////////////////////////////////
  101. // Update object
  102. ////////////////////////////////////////////////////////////////////////////////
  103. void CChunk::Update(void)
  104. {
  105. long lCurTime = m_pRealm->m_time.GetGameTime();
  106. double dSeconds = (lCurTime - m_lPrevTime) / 1000.0;
  107. m_lPrevTime = lCurTime;
  108. double dDist = m_dVel * dSeconds;
  109. m_dX += COSQ[(short)m_dRot] * dDist;
  110. m_dZ -= SINQ[(short)m_dRot] * dDist;
  111. double dVertDeltaVel = g_dAccelerationDueToGravity * dSeconds;
  112. m_dVertVel += dVertDeltaVel;
  113. m_dY += (m_dVertVel - dVertDeltaVel / 2) * dSeconds;
  114. // If we have hit terrain . . .
  115. if (m_pRealm->GetHeight(m_dX, m_dZ) >= m_dY)
  116. {
  117. short sX2d, sY2d;
  118. // Map from 3d to 2d coords.
  119. Map3Dto2D(m_dX, m_dY, m_dZ, &sX2d, &sY2d);
  120. switch (m_type)
  121. {
  122. case Blood:
  123. {
  124. RImage* pim = m_pRealm->m_phood->m_pimBackground;
  125. if ( sX2d >= 0 && sY2d >= 0
  126. && sX2d < pim->m_sWidth
  127. && sY2d < pim->m_sHeight)
  128. {
  129. // Pixel. 8bpp only!
  130. U8* pu8Dst = pim->m_pData + sX2d + sY2d * pim->m_lPitch;
  131. *pu8Dst = rspBlendColor( // Alpha color/index.
  132. ALPHA_LEVEL, // Alpha level.
  133. m_pRealm->m_phood->m_pmaTransparency, // Multialpha.
  134. m_sprite.m_u8Color, // Src color/index to blend.
  135. *pu8Dst); // Dst color/index to blend.
  136. }
  137. break;
  138. }
  139. case BulletCasing:
  140. case Shell:
  141. #if 0 // Looks bad.
  142. rspPlot(
  143. (U8)251,
  144. m_pRealm->m_phood->m_pimBackground,
  145. sX2d,
  146. sY2d);
  147. rspLine(
  148. m_sprite.m_u8Color,
  149. m_pRealm->m_phood->m_pimBackground,
  150. sX2d,
  151. sY2d,
  152. sX2d + RAND_SWAY(BLOOD_SWAY),
  153. sY2d + RAND_SWAY(BLOOD_SWAY),
  154. NULL);
  155. #endif
  156. break;
  157. }
  158. // We're done.
  159. delete this;
  160. }
  161. }
  162. ////////////////////////////////////////////////////////////////////////////////
  163. // Render object
  164. ////////////////////////////////////////////////////////////////////////////////
  165. void CChunk::Render(void)
  166. {
  167. // Map from 3d to 2d coords
  168. Map3Dto2D(m_dX, m_dY, m_dZ, &m_sprite.m_sX2, &m_sprite.m_sY2);
  169. m_sprite.m_sX2End = m_sprite.m_sX2 + RAND_SWAY(m_sLen);
  170. m_sprite.m_sY2End = m_sprite.m_sY2 + RAND_SWAY(m_sLen);
  171. // Priority is based on bottom edge of sprite on X/Z plane.
  172. m_sprite.m_sPriority = m_dZ;
  173. // Layer should be based on info we get from attribute map.
  174. m_sprite.m_sLayer = CRealm::GetLayerViaAttrib(m_pRealm->GetLayer((short) m_dX, (short) m_dZ));
  175. // Update sprite in scene
  176. m_pRealm->m_scene.UpdateSprite(&m_sprite);
  177. }
  178. ////////////////////////////////////////////////////////////////////////////////
  179. // Setup object.
  180. ////////////////////////////////////////////////////////////////////////////////
  181. short CChunk::Setup( // Returns 0 if successfull, non-zero otherwise
  182. short sX, // In: New x coord
  183. short sY, // In: New y coord
  184. short sZ, // In: New z coord
  185. double dRot, // In: Initial direction.
  186. short sRandRotSway, // In: Random sway on rotation or zero.
  187. double dVel, // In: Initial velocity.
  188. short sRandVelSway, // In: Random sway on velocity or zero.
  189. double dVertVel, // In: Initial vertical velocity.
  190. short sRandVertVelSway, // In: Random sway on velocity or zero.
  191. Type type) // In: Type of chunk.
  192. {
  193. short sResult = 0;
  194. // Use specified position
  195. m_dX = (double)sX;
  196. m_dY = (double)sY;
  197. m_dZ = (double)sZ;
  198. m_dVel = dVel;
  199. m_dVertVel = dVertVel;
  200. // Apply randomizations.
  201. if (sRandRotSway)
  202. {
  203. m_dRot = rspMod360(dRot + RAND_SWAY(sRandRotSway) );
  204. }
  205. else
  206. {
  207. m_dRot = rspMod360(dRot);
  208. }
  209. if (sRandVelSway)
  210. {
  211. m_dVel += RAND_SWAY(sRandVelSway);
  212. }
  213. if (sRandVertVelSway)
  214. {
  215. m_dVertVel += RAND_SWAY(sRandVertVelSway);
  216. }
  217. m_lPrevTime = m_pRealm->m_time.GetGameTime();
  218. m_type = type;
  219. ASSERT(type < NumTypes);
  220. m_sprite.m_u8Color = ms_atiChunks[type].u8ColorIndex;
  221. m_sLen = ms_atiChunks[type].sLen;
  222. return sResult;
  223. }
  224. ////////////////////////////////////////////////////////////////////////////////
  225. // EOF
  226. ////////////////////////////////////////////////////////////////////////////////