source: golgotha/src/golg/demo.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 11 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: 8.5 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 "file/file.hh"
10#include "tick_count.hh"
11#include "lisp/lisp.hh"
12#include "lisp/li_init.hh"
13#include "g1_object.hh"
14#include "objs/stank.hh"
15#include "player.hh"
16#include "objs/field_camera.hh"
17#include "human.hh"
18#include "saver.hh"
19#include "map.hh"
20#include "map_man.hh"
21#include "level_load.hh"
22#include "app/app.hh"
23#include "g1_speed.hh"
24#include "file/sub_section.hh"
25
26/*
27
28example script:
29'((action_mode)   300
30
31  (strategy_mode)
32  (set_camera_pos x y) 10
33
34  (action_mode)   
35  (wait_till_near_camera "main_base" 10)
36
37  (camera_mode)
38  (set_current_camera "main_base1")
39
40  (pan_to_camera "main_base2")
41 
42
43
44
45
46(wait 1000)
47(
48
49commands
50
51(action_mode)
52
53(strategy_mode)    ; overhead view
54(set_camera_pos x y) ; should be called when in stretgy mode to the position in world space
55
56(strategy_toggle)  ; radar map toggle
57(wait_till_near_camera "camera_name" min_distance)
58(set_current_camera "camera_name")
59
60 */
61
62static int demo_last_tick=0;
63static i4_file_class *record_file=0;
64static int wait_ticks=0;
65static float camera_dist=0;
66
67
68static void flush_time()
69{
70  if (record_file && g1_tick_counter-demo_last_tick)
71  {
72    record_file->printf(" %d\n", g1_tick_counter-demo_last_tick);
73    demo_last_tick=g1_tick_counter;
74  }
75}
76
77static i4_bool copy_file(const i4_const_str &f1, const i4_const_str &f2)
78{
79  i4_file_class *in=i4_open(f1);
80  if (!in)
81    return i4_F;
82
83  i4_file_class *out=i4_open(f2, I4_WRITE);
84  if (!out)
85  {
86    delete in;
87    return i4_F;
88  }
89  w8 buf[4096];
90  int done=0;
91  while (!done)
92  {
93    int s=in->read(buf, sizeof(buf));
94    if (out->write(buf, s)!=s)
95      return i4_F;
96
97    if (s!=sizeof(buf))
98      done=1;
99  }
100  delete in;
101  delete out;
102  return i4_T;
103}
104
105static int current_demo_num=0;
106
107static li_object *record_toggle(li_object *o, li_environment *env)
108{
109  if (record_file)
110  {
111    flush_time();
112    record_file->printf(")\n");
113    delete record_file;
114    record_file=0;
115    g1_human->record_end();
116
117
118
119    // find a free demo name we can save to
120    current_demo_num=0;
121    char demo_name[200], found=1;
122    do
123    {
124      sprintf(demo_name, "demos/demo%02d.level", current_demo_num);
125
126      i4_file_status_struct rs;
127      if (i4_get_status(demo_name, rs))
128        current_demo_num++;
129      else
130        found=0;
131
132    } while (found);
133   
134
135    i4_file_class *out=i4_open(demo_name, I4_WRITE);
136    i4_file_class *in=i4_open("demos/tmp_level.level");
137
138    i4_file_class *sdata[3];
139    sdata[0]=i4_open("demos/tmp_script.scm");
140    sdata[1]=i4_open("demos/tmp_inputs.gdm");
141    sdata[2]=i4_open("demos/tmp_resources.scm");
142   
143    char *snames[3]={"script", "inputs", "resources"};
144
145   
146    i4_insert_sections(in, out, 3, sdata, snames);
147    delete in;
148    delete out;
149    delete sdata[0];
150    delete sdata[1];
151    delete sdata[2];
152
153    i4_unlink("demos/tmp_script.scm");
154    i4_unlink("demos/tmp_level.level");
155    i4_unlink("demos/tmp_inputs.gdm");
156    i4_unlink("demos/tmp_resources.scm");   
157  }
158  else if (g1_map_is_loaded())
159  {
160    i4_mkdir("demos");
161
162    i4_str *res_file=g1_get_res_filnename(g1_get_map()->get_filename());
163    if (!copy_file(*res_file, "demos/tmp_resources.scm"))
164      return 0;
165
166    i4_file_class *out=i4_open("demos/tmp_level.level", I4_WRITE);
167    if (!out)
168    {
169      i4_warning("Couldn't save initial demo level state!");
170      return 0;
171    }
172
173
174    g1_saver_class *save=new g1_saver_class(out);
175    g1_get_map()->save(save, G1_MAP_ALL);
176    if (save->begin_data_write())
177      g1_get_map()->save(save, G1_MAP_ALL);
178    delete save;
179    g1_load_level("demos/tmp_level.level", 0);
180   
181    record_file=i4_open("demos/tmp_script.scm", I4_WRITE);
182
183    record_file->printf("(play_script\n"
184                        "  (action_mode)\n");
185    g1_human->record_start("demos/tmp_inputs.gdm");
186
187    demo_last_tick=g1_tick_counter;
188  }
189
190  return 0;
191}
192
193void g1_demo_script_add(char *command)
194{
195  if (record_file)
196  {
197    flush_time();
198    record_file->printf("  %s", command);
199  }
200}
201
202
203
204static li_object_pointer demo_script;
205static g1_object_class *wait_camera=0;
206
207
208static li_object *end_demo(li_object *o, li_environment *env)
209{
210  if (record_file)
211    record_toggle(0,0);
212
213  if (demo_script.get())
214  {
215    demo_script=0;
216    g1_human->playback_end();
217  }
218  return 0;
219}
220
221static li_object *play_script(li_object *o, li_environment *env)
222{
223  demo_script=o;
224  wait_ticks=0;
225  camera_dist=0;
226  wait_camera=0;
227  return 0;
228}
229
230
231static li_object *load_level(li_object *o, li_environment *env)
232{
233  i4_bool load_res=li_get_bool(li_second(o,env),env);
234  char *fn=li_get_string(li_first(o,env),env);
235
236  if (!g1_load_level(fn, load_res, 0))
237  {
238    i4_warning("Couldn't load level file %s", fn);
239    return 0;
240  }
241
242  return li_true_sym;
243}
244
245
246static li_object *playback_input(li_object *o, li_environment *env)
247
248  char *fn=li_get_string(li_first(o,env),env);
249  i4_file_class *fp=i4_open(fn);
250  if (!g1_human->playback_start(fp))
251  {
252    i4_warning("Couldn't load stream");
253    return li_nil;
254  }
255  else
256    return li_true_sym;
257}
258
259static li_object *play_demo(li_object *o, li_environment *env)
260{
261  if (o)
262    current_demo_num=li_get_int(li_car(o,env),env);
263 
264  char demo_name[200];
265  sprintf(demo_name, "demos/demo%02d.level", current_demo_num);
266
267  if (g1_load_level(demo_name, 1))
268  {
269    i4_loader_class *lfp=i4_open_save_file(i4_open(demo_name));
270    if (lfp)
271    {
272      w32 off, size;
273      if (lfp->get_section_info("inputs", off, size))
274        g1_human->playback_start(new i4_sub_section_file(i4_open(demo_name), off, size));
275
276
277      if (lfp->get_section_info("script", off, size))
278      {
279        i4_file_class *fp=new i4_sub_section_file(i4_open(demo_name), off,size);
280        li_load(fp);
281        delete fp;
282      }
283
284
285      delete lfp;
286    }
287  }
288
289  return 0;
290}
291
292
293i4_bool g1_playing_demo()
294{
295  if (!g1_map_is_loaded())
296    return i4_F;
297
298  if (wait_ticks || demo_script.get())
299    return i4_T;
300  else
301    return i4_F;
302}
303
304void g1_demo_tick()
305{
306  if (wait_camera)
307  {
308    g1_object_class *c=g1_player_man.get_local()->get_commander();
309    if (!c)
310      wait_camera=0;
311    else if ((c->x-wait_camera->x)*(c->x-wait_camera->x)+
312        (c->y-wait_camera->y)*(c->y-wait_camera->y)+
313        (c->h-wait_camera->h)*(c->h-wait_camera->h) < camera_dist*camera_dist)
314      wait_camera=0;
315  }             
316  else if (wait_ticks)
317    wait_ticks--;
318  else
319  {
320    li_object *script_start=demo_script.get();
321    li_object *script=script_start;
322
323    while (!wait_camera && !wait_ticks && script)
324    {
325     
326      li_object *o=li_car(script, 0);     
327      if (o->type()==LI_INT)
328        wait_ticks=li_get_int(o, 0);
329      else
330        li_eval(o);
331
332      if (script_start!=demo_script.get())    // we loaded another script
333        script=0;
334
335      if (script)
336         script=li_cdr(script, 0);
337    }
338
339    if (script_start==demo_script.get())
340      demo_script=script;
341  }
342}
343
344static li_object *wait_near(li_object *o, li_environment *env)
345{
346  wait_camera=g1_find_named_camera(li_get_string(li_eval(li_first(o,env),env),env));
347  camera_dist=li_get_float(li_eval(li_second(o,env), env),env);
348
349  return 0;
350}
351
352static li_object *quit_demo(li_object *o, li_environment *env)
353{
354  if (g1_playing_demo())
355  {
356    end_demo(0,0);
357    i4_current_app->quit();
358  }
359
360  return 0;
361}
362
363static li_object *set_game_hz(li_object *o, li_environment *env)
364{
365  G1_HZ=li_get_int(li_car(o,env),env);
366  return 0;
367}
368
369
370li_automatic_add_function(quit_demo, "quit_demo");
371li_automatic_add_function(end_demo, "end_demo");
372li_automatic_add_function(play_demo, "play_demo");
373li_automatic_add_function(record_toggle, "record_toggle");
374li_automatic_add_function(wait_near, "wait_till_near_camera");
375
376li_automatic_add_function(set_game_hz, "set_game_hz");
377li_automatic_add_function(load_level, "load_level");
378li_automatic_add_function(playback_input, "playback_input");
379li_automatic_add_function(play_script, "play_script");
Note: See TracBrowser for help on using the repository browser.