source: abuse/branches/pd/macabuse/src/old_demo_code @ 636

Last change on this file since 636 was 49, checked in by Sam Hocevar, 15 years ago
  • Imported original public domain release, for future reference.
File size: 8.9 KB
Line 
1/*
2static void push_demo_event(event &ev)
3{
4  if (ev.type==EV_KEY || ev.type==EV_KEYRELEASE ||
5      ev.type==EV_MOUSE_MOVE || ev.type==EV_MOUSE_BUTTON)
6  {
7    record_total++;
8    record_array=(event **)jrealloc(record_array,sizeof(event *)*record_total,"demo event que");
9    record_array[record_total-1]=new event;
10    memcpy(record_array[record_total-1],&ev,sizeof(ev));
11  }
12}
13
14static void flush_demo_events(bFILE *fp)
15{
16  fp->write_short(record_total);
17  for (int i=0;i<record_total;i++)
18  {
19    event *ev=record_array[i];
20    if (ev->type==EV_KEY)
21    {
22      fp->write_byte(DE_KEY_PRESS);
23      fp->write_byte(2);
24      fp->write_short(ev->key);
25    }
26    else if (ev->type==EV_KEYRELEASE)
27    {
28      fp->write_byte(DE_KEY_RELEASE);
29      fp->write_byte(2);
30      fp->write_short(ev->key);
31    }
32    else if (ev->type==EV_MOUSE_MOVE)
33    {
34      fp->write_byte(DE_MOUSE_MOVE);
35      fp->write_byte(4);
36      fp->write_short(ev->mouse_move.x);
37      fp->write_short(ev->mouse_move.y);
38    } else if (ev->type==EV_MOUSE_BUTTON)
39    {
40      fp->write_byte(DE_MOUSE_BUTTON);
41      fp->write_byte(1);
42      fp->write_byte(ev->mouse_button);
43    }
44    jfree(ev);
45  }
46  record_total=0;
47  if (record_array)
48    jfree(record_array);
49  record_array=NULL;
50}
51
52int set_demo_mode(int mode, char *filename, window_manager *wm)
53{
54  switch (demo_mode)
55  {
56    case DEMO_RECORD :
57    {
58      the_game->show_help("Finished recording");
59      if (demo_file)
60      {
61        flush_demo_events(demo_file);
62        demo_file->write_short(0xffff);    // end of input marker
63        delete demo_file;
64        demo_file=NULL;
65      }   
66    } break;
67
68    case DEMO_PLAY :
69    {
70      if (demo_file)
71      {
72        delete demo_file;
73        demo_file=NULL;
74      }
75
76      if (mode==DEMO_OFF)
77      {
78        the_game->set_state(MENU_STATE);
79        wm->push_event(new event(ID_NULL,NULL));
80      }
81      the_game->reset_keymap();
82      l_difficulty=old_difficulty;
83
84      view *v=player_list;
85      for (;v;v=v->next) { if (v->focus) { v->reset_player(); v->focus->set_aistate(0); } }
86    } break;
87  }
88
89  demo_mode=mode;
90
91  switch (demo_mode)
92  {
93    case DEMO_RECORD :
94    {
95      demo_file=new jFILE(filename,"wb");
96      if (demo_file->open_failure())
97      {
98        the_game->show_help("Unable to open file to record demo");
99        delete demo_file;
100        demo_file=NULL;
101        demo_mode=DEMO_OFF;
102        return 0;
103      } else
104      {
105        char name[100];
106        strcpy(name,current_level->name());
107
108        the_game->load_level(name);
109        demo_file->write("DEMO,VERSION:1",14);
110        demo_file->write_byte(strlen(name)+1);
111        demo_file->write(name,strlen(name)+1);
112       
113        if (DEFINEDP(symbol_value(l_difficulty)))
114        {
115          if (symbol_value(l_difficulty)==l_easy) demo_file->write_byte(0);
116          else if (symbol_value(l_difficulty)==l_medium) demo_file->write_byte(1);
117          else if (symbol_value(l_difficulty)==l_hard) demo_file->write_byte(2);
118          else demo_file->write_byte(3);
119        } else demo_file->write_byte(3);
120
121        demo_tick_on=current_level->tick_counter();
122        last_demo_mx=last_demo_my=last_demo_mbut=0;
123      }
124     
125      if (dev&EDIT_MODE) toggle_edit_mode();
126      player_list->reset_player();
127    } break;
128    case DEMO_PLAY   :   
129    {
130
131      demo_file=open_file(filename,"rb");
132      if (demo_file->open_failure())
133      {
134        the_game->show_help("Unable to open file to play demo");
135        delete demo_file;
136        demo_file=NULL;
137        demo_mode=DEMO_OFF;
138        return 0;
139      } else
140      {
141        events_for_tick=0;
142        char name[100];
143        demo_file->read(name,14);
144        if (!memcmp(name,"DEMO,VERSION:1",14))
145        {
146          demo_file->read(name,demo_file->read_byte());
147          bFILE *test=open_file(name,"rb");        // make sure level is there
148          if (test->open_failure()) { delete test; return 0; }
149          delete test;
150
151          old_difficulty=l_difficulty;
152          switch (demo_file->read_byte())
153          {
154            case 0 :
155            { set_symbol_value(l_difficulty,l_easy); } break;
156            case 1 :
157            { set_symbol_value(l_difficulty,l_medium); } break;
158            case 2 :
159            { set_symbol_value(l_difficulty,l_hard); } break;
160            case 3 :
161            { set_symbol_value(l_difficulty,l_extreme); } break;
162          }
163
164
165          view *v=player_list;
166          for (;v;v=v->next) { if (v->focus) v->reset_player(); }
167
168          the_game->load_level(name);
169          demo_tick_on=current_level->tick_counter()-1;
170          the_game->set_state(RUN_STATE);
171          last_demo_mx=last_demo_my=last_demo_mbut=0;
172
173          for (;v;v=v->next) { if (v->focus) { v->focus->set_aistate(0); } }
174
175        } else
176        {
177          delete demo_file;
178          demo_file=NULL;
179          the_game->show_help("Bad demo version or, not demo file");
180          return 0;
181        }
182      }
183      if (dev&EDIT_MODE) toggle_edit_mode();
184      player_list->reset_player();
185    } break;
186  }
187  return 1;
188}
189
190void load_event(bFILE *fp, window_manager *wm,  event &ev)
191{
192  int type=fp->read_byte();
193  int size=fp->read_byte();
194  wm->set_mouse_position(small_render ? last_demo_mx*2 : last_demo_mx,
195                         small_render ? last_demo_my*2 : last_demo_my);
196  ev.mouse_move.x=last_demo_mx;
197  ev.mouse_move.y=last_demo_my;
198  ev.mouse_button=last_demo_mbut;
199
200  switch (type)
201  {
202    case DE_KEY_PRESS :
203    {
204      ev.type=EV_KEY;
205      ev.key=fp->read_short();
206    } break;
207    case DE_KEY_RELEASE :
208    {
209      ev.type=EV_KEYRELEASE;
210      ev.key=fp->read_short();
211    } break;
212    case DE_MOUSE_MOVE :
213    {
214      ev.type=EV_MOUSE_MOVE;
215      last_demo_mx=fp->read_short();
216      last_demo_my=fp->read_short();
217      wm->set_mouse_position(small_render ? last_demo_mx*2 : last_demo_mx,
218                             small_render ? last_demo_my*2 : last_demo_my);
219    } break;
220    case DE_MOUSE_BUTTON :
221    {
222      ev.type=EV_MOUSE_BUTTON;
223      last_demo_mbut=fp->read_byte();
224      ev.mouse_button=last_demo_mbut;
225    } break;
226    default :
227    {
228      char buf[100];
229      fp->read(buf,size);
230    }
231  } 
232}
233
234void remap_demo_mouse()
235{
236  if (small_render)   // divide mouse by 2 if enlarged rendering is on
237  {
238    last_demo_mx=(last_demo_mx-player_list->cx1)/2+player_list->cx1;
239    last_demo_my=(last_demo_my-player_list->cy1)/2+player_list->cy1;
240  }
241}
242
243void get_event(event &ev, window_manager *wm)
244{
245  switch (demo_mode)
246  {
247    case DEMO_PLAY :
248    {
249      if (current_level)
250      {
251        if (events_for_tick==0)  // no more stored events for this tick, got check for tick change
252        {
253          if (demo_tick_on!=current_level->tick_counter())
254          {
255            while (events_for_tick--)    // just in case program didn't read all of last ticks events
256              load_event(demo_file,wm,ev);
257
258            events_for_tick=demo_file->read_short();
259            if (events_for_tick==0xffff)
260              set_demo_mode(DEMO_OFF,NULL,wm);
261            demo_tick_on=current_level->tick_counter();
262          }
263        }
264
265        if (events_for_tick)
266        {
267          load_event(demo_file,wm,ev);
268          events_for_tick--;
269        }
270        else
271        {
272          dprintf("Forced user event in demo mode! bad, bad..\n");
273          wm->get_event(ev);           // hopefully this will not happen
274        }
275      }
276    } break;
277    case DEMO_RECORD :
278    {
279      if (demo_tick_on!=current_level->tick_counter())
280      {
281        flush_demo_events(demo_file);
282        do
283        {
284          demo_tick_on++;
285          if (demo_tick_on!=current_level->tick_counter())  // store no event ticks
286            demo_file->write_short(0);
287        } while (demo_tick_on!=current_level->tick_counter());
288      }
289      wm->get_event(ev);
290      if (ev.type==EV_MOUSE_MOVE)
291      { last_demo_mx=ev.mouse_move.x;
292        last_demo_my=ev.mouse_move.y;
293        remap_demo_mouse();
294        ev.mouse_move.x=last_demo_mx;
295        ev.mouse_move.y=last_demo_my;
296      } else
297      {
298        ev.mouse_move.x=last_demo_mx;
299        ev.mouse_move.y=last_demo_my;
300        if (ev.type==EV_MOUSE_BUTTON)
301          last_demo_mbut=ev.mouse_button;
302        else ev.mouse_button=last_demo_mbut;
303      }
304
305      if (ev.type==EV_KEY && ev.key==JK_ENTER)
306        set_demo_mode(DEMO_OFF,NULL,wm);
307      else
308        push_demo_event(ev);     
309
310    } break;
311    case DEMO_OFF :
312    { wm->get_event(ev);
313      idle_ticks=0;
314      last_demo_mx=ev.mouse_move.x;
315      last_demo_my=ev.mouse_move.y;
316      last_demo_mbut=ev.mouse_button;
317      remap_demo_mouse();
318/*      wm->mouse_status(last_demo_mx,last_demo_mx,last_demo_mbut);
319      if (ev.type!=EV_MOUSE_MOVE)
320      {
321        ev.mouse_move.x=last_demo_mx;
322        ev.mouse_move.y=last_demo_my;
323      }
324      if (ev.type!=EV_MOUSE_BUTTON)
325        ev.mouse_button=last_demo_mbut;     */
326    } break;
327  }
328}
329
330int event_waiting(window_manager *wm)
331{
332  switch (demo_mode)
333  {
334    case DEMO_RECORD :
335    case DEMO_OFF :
336    { return wm->event_waiting();  } break;
337    case DEMO_PLAY :
338    {
339      if (demo_tick_on!=current_level->tick_counter())
340      {
341        while (events_for_tick)    // just in case program didn't read all of last ticks events
342        {
343          events_for_tick--;
344          event ev;
345          load_event(demo_file,wm,ev);
346        }
347
348        events_for_tick=demo_file->read_short();
349        demo_tick_on=current_level->tick_counter();
350        if (events_for_tick==0xffff)
351          set_demo_mode(DEMO_OFF,NULL,wm);
352      }     
353
354      if (demo_mode==DEMO_PLAY)  // make sure we didn't just end demo
355      {
356        while (wm->event_waiting())  // gobble up any user events
357        {
358          event ev;
359          wm->get_event(ev);         // see if the user is trying to cut off the demo
360          if (ev.type==EV_KEY)
361          set_demo_mode(DEMO_OFF,NULL,wm);
362        }
363        return events_for_tick!=0;
364      } else return wm->event_waiting();
365
366
367    } break;             
368  }
369  return 0;
370}
371
372
373*/
Note: See TracBrowser for help on using the repository browser.