source: golgotha/src/golg/objs/debris.cc

Last change on this file was 80, checked in by Sam Hocevar, 12 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 6.1 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#include "g1_object.hh"
10#include "math/num_type.hh"
11#include "math/pi.hh"
12#include "g1_rand.hh"
13#include "objs/debris.hh"
14#include "saver.hh"
15#include "map.hh"
16#include "g1_render.hh"
17#include "object_definer.hh"
18#include "dll/dll.hh"
19#include "map_man.hh"
20#include "math/pi.hh"
21#include "draw_context.hh"
22#include "r1_clip.hh"
23#include "r1_api.hh"
24
25const i4_float FUNNEL_HEIGHT=7.0;
26const i4_float FUNNEL_RADIUS=1.0;
27const int DATA_VERSION=1;
28const int MAX_VALS=256;
29const i4_float RADIUS=0.01;
30static i4_float rand_val[MAX_VALS];
31static int rand_i;
32inline i4_float fast_rand() { rand_i=(rand_i+1)&(MAX_VALS-1); return rand_val[rand_i]; }
33
34void g1_debris_init()
35{
36  for (int i=0; i<MAX_VALS; i++)
37    rand_val[i] = g1_float_rand(i)*RADIUS;
38  rand_i=0;
39}
40
41g1_object_definer<g1_debris_class> g1_debris_def("debris",
42                                                 g1_object_definition_class::EDITOR_SELECTABLE,
43                                                 g1_debris_init);
44
45
46g1_debris_class::g1_debris_class(g1_object_type id, g1_loader_class *fp)
47  : g1_object_class(id, fp)
48
49  w16 ver,data_size;
50
51  if (fp)
52    fp->get_version(ver,data_size);
53  else
54    ver = 0;
55
56  switch (ver)
57  {
58    case DATA_VERSION:
59      break;
60    default:
61      break;
62  }
63  type = RING_CHUNKS;
64  rad = 0.5;
65  strength = 2.0;
66}
67
68void g1_debris_class::save(g1_saver_class *fp)
69{
70  g1_object_class::save(fp); 
71  fp->start_version(DATA_VERSION); 
72  fp->end_version();
73}
74
75void g1_debris_class::setup(i4_float sx, i4_float sy, i4_float sz, int _type)
76{
77  g1_map_class *map=g1_get_map();
78
79  if (sx<1) sx=1;
80  if (sy<1) sy=1;
81  if (sx>map->width()-1) sx=map->width()-1;
82  if (sy>map->height()-1) sy=map->height()-1;
83
84  x=lx=sx;
85  y=ly=sy;
86  h=lh=sz;
87  type = _type;
88
89  int i;
90  switch (type)
91  {
92    case TORNADO:
93      for (i=0; i<MAX_DEBRIS; i++)
94      {
95        debris[i].x = g1_float_rand(i)*FUNNEL_RADIUS*2.0-FUNNEL_RADIUS;
96        debris[i].y = g1_float_rand(i+2)*FUNNEL_RADIUS*2.0-FUNNEL_RADIUS;
97        debris[i].z = g1_float_rand(i+4)*FUNNEL_HEIGHT;
98        ldebris[i] = debris[i];
99      }
100      break;
101    case RING_CHUNKS:
102      for (i=0; i<MAX_DEBRIS; i++)
103      {
104        debris[i].x = g1_float_rand(i+4)*rad*2.0-rad;
105        debris[i].y = g1_float_rand(i+6)*rad*2.0-rad;
106        debris[i].z = g1_float_rand(i+8)*strength;
107        ldebris[i] = debris[i];
108      }
109      break;
110  }
111  occupy_location();
112  request_think();
113}
114
115
116void g1_debris_class::think()
117{
118  i4_float
119    spin_speed = 0.3,
120    cs = cos(spin_speed)*1.05,
121    sn = sin(spin_speed)*1.05;
122
123  unoccupy_location();
124  int i;
125  switch (type)
126  {
127    case TORNADO:
128      for (i=0; i<MAX_DEBRIS; i++)
129      {
130        ldebris[i] = debris[i];
131        debris[i].z += 0.4;
132        debris[i].x = debris[i].x*cs - debris[i].y*sn + fast_rand();
133        debris[i].y = debris[i].x*sn + debris[i].y*cs + fast_rand();
134        if (debris[i].z>FUNNEL_HEIGHT)
135        {
136          debris[i].x = g1_float_rand(i+0)*2*FUNNEL_RADIUS-FUNNEL_RADIUS;
137          debris[i].y = g1_float_rand(i+1)*2*FUNNEL_RADIUS-FUNNEL_RADIUS;
138          debris[i].z = g1_float_rand(i+2)*0.3;
139          ldebris[i] = debris[i];
140        }
141      }
142      break;
143    case RING_CHUNKS:
144      rad += 0.2;
145      strength *= 0.94;
146      if (rad>10.0)
147      {
148        request_remove();
149        return;
150      }
151      for (i=0; i<MAX_DEBRIS; i++)
152      {
153        ldebris[i] = debris[i];
154        debris[i].z += 0.2;
155        if (debris[i].z>strength)
156        {
157          i4_float th = g1_float_rand(i+0)*2*i4_pi();
158          debris[i].x = cos(th)*rad;
159          debris[i].y = sin(th)*rad;
160          debris[i].z = g1_float_rand(i+8)*0.2;
161          ldebris[i] = debris[i];
162        }
163      }
164      break;
165  }
166  occupy_location();
167  request_think();
168}
169
170void g1_debris_class::draw(g1_draw_context_class *context)
171{   
172  sw32 i,j;
173
174  r1_render_api_class *r_api = g1_render.r_api;
175
176  i4_transform_class tmp,trans = *context->transform;
177  r1_vert      p, vert[3];
178  i4_3d_vector ip;
179
180  vert[0].a=vert[1].a=vert[2].a = 1;
181  vert[0].r=vert[0].g=vert[0].b = 0;
182  vert[1].r=vert[1].g=vert[1].b = 0;
183  vert[2].r=vert[2].g=vert[2].b = 0;
184
185  tmp.translate(x,y,h);
186  trans.multiply(tmp);
187
188  i4_float tx[3],ty[3];
189  i4_bool ok;
190  i4_float fr=g1_render.frame_ratio;
191
192  r_api->set_write_mode(R1_WRITE_COLOR | R1_COMPARE_W | R1_WRITE_W);
193  r_api->set_shading_mode(R1_COLORED_SHADING);
194  r_api->set_alpha_mode(R1_ALPHA_DISABLED);
195  r_api->disable_texture();
196  for (i=0; i<MAX_DEBRIS; i++)
197  {
198    ip.set((debris[i].x-ldebris[i].x)*fr + ldebris[i].x,
199           (debris[i].y-ldebris[i].y)*fr + ldebris[i].y,
200           (debris[i].z-ldebris[i].z)*fr + ldebris[i].z);
201    trans.transform(ip, *p.point());
202    if (!r1_calc_outcode(&p))
203    {
204      p.v.x *= g1_render.scale_x;
205      p.v.y *= g1_render.scale_y;
206      p.w = 1/p.v.z;
207      p.px = p.v.x * p.w;
208      p.py = p.v.y * p.w;
209      ok=i4_T;
210      tx[0] = p.px+fast_rand()-RADIUS/2; ty[0] = p.py-fast_rand();
211      tx[1] = p.px-fast_rand(); ty[1] = p.py+fast_rand();
212      tx[2] = p.px+fast_rand(); ty[2] = p.py+fast_rand();
213      for (j=0; j<3 && ok; j++)
214      {
215        if (tx[j]<=-1.0 || tx[j]>=1.0 || ty[j]<=-1.0 || ty[j]>=1.0)
216          ok = i4_F;
217        else
218        {
219          vert[j].w = p.w;
220          vert[j].v.x = p.v.x; vert[j].v.y = p.v.y; vert[j].v.z = p.v.z;
221         
222          vert[j].px = tx[j]*g1_render.center_x + g1_render.center_x;
223          vert[j].py = ty[j]*g1_render.center_y + g1_render.center_y;
224        }
225      }
226      if (ok)
227        r_api->render_poly(3,vert);
228    }
229  } 
230}
231
Note: See TracBrowser for help on using the repository browser.