source: abuse/tags/pd/macabuse/src/demo.c @ 49

Last change on this file since 49 was 49, checked in by Sam Hocevar, 11 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 6.2 KB
Line 
1#include "demo.hpp"
2#include "specs.hpp"
3#include "macs.hpp"
4#include "jwindow.hpp"
5#include "game.hpp"
6#include "jmalloc.hpp"
7#include "dprint.hpp"
8#include "dev.hpp"
9#include "jrand.hpp"
10#include "lisp.hpp"
11#include "clisp.hpp"
12#include "netface.hpp"
13
14
15demo_manager demo_man;
16extern window_manager *eh;
17int last_demo_mx,last_demo_my,last_demo_mbut;
18extern base_memory_struct *base;   // points to shm_addr
19extern int idle_ticks;
20
21extern void net_receive();
22extern void net_send(int force);
23extern void fade_in(image *im, int steps);
24extern void fade_out(int steps);
25
26void get_event(event &ev, window_manager *wm)
27{ wm->get_event(ev);
28  switch (ev.type)
29  {
30    case EV_KEY :
31    {
32      if (demo_man.state==demo_manager::PLAYING)
33        demo_man.set_state(demo_manager::NORMAL);   
34      else if (ev.key==JK_ENTER && demo_man.state==demo_manager::RECORDING)
35      {
36        demo_man.set_state(demo_manager::NORMAL);
37        the_game->show_help("Finished recording");
38      }
39    } break;
40  }
41
42  last_demo_mx=ev.mouse_move.x;
43  last_demo_my=ev.mouse_move.y;
44  last_demo_mbut=ev.mouse_button;
45  idle_ticks=0;
46}
47
48int event_waiting(window_manager *wm)
49{ return wm->event_waiting(); }
50
51
52int demo_manager::start_recording(char *filename)
53{
54  if (!current_level) return 0;
55
56  record_file=open_file(filename,"wb");
57  if (record_file->open_failure()) { delete record_file; return 0; }
58
59  char name[100];
60  strcpy(name,current_level->name());
61
62  the_game->load_level(name);
63  record_file->write("DEMO,VERSION:2",14);
64  record_file->write_byte(strlen(name)+1);
65  record_file->write(name,strlen(name)+1);
66 
67 
68  if (DEFINEDP(symbol_value(l_difficulty)))
69  {
70    if (symbol_value(l_difficulty)==l_easy) record_file->write_byte(0);
71    else if (symbol_value(l_difficulty)==l_medium) record_file->write_byte(1);
72    else if (symbol_value(l_difficulty)==l_hard) record_file->write_byte(2);
73    else record_file->write_byte(3);
74  } else record_file->write_byte(3);
75 
76
77  state=RECORDING;
78
79  reset_game();
80
81  return 1;
82}
83
84void demo_manager::do_inputs()
85{
86  switch (state)
87  {
88    case RECORDING :
89    {
90      base->packet.packet_reset();       // reset input buffer
91      view *p=player_list;               // get current inputs
92      for (;p;p=p->next)
93        if (p->local_player())
94          p->get_input();
95
96      base->packet.write_byte(SCMD_SYNC);
97      base->packet.write_short(make_sync());
98      demo_man.save_packet(base->packet.packet_data(),base->packet.packet_size());
99      process_packet_commands(base->packet.packet_data(),base->packet.packet_size());
100
101    } break;
102    case PLAYING :
103    {
104      uchar buf[1500];
105      int size;
106      if (get_packet(buf,size))              // get starting inputs
107      {
108        process_packet_commands(buf,size);     
109        long mx,my;
110        the_game->game_to_mouse(player_list->pointer_x,player_list->pointer_y,player_list,mx,my);
111        eh->set_mouse_position(small_render ? mx*2 : mx, small_render ? my*2 : my);
112      }
113      else
114      {
115        set_state(NORMAL);
116        return ;
117      }
118    } break;
119  }
120}
121
122void demo_manager::reset_game()
123{
124  if (dev&EDIT_MODE) toggle_edit_mode();
125  the_game->set_state(RUN_STATE);
126  rand_on=0;
127
128  view *v=player_list;
129  for (;v;v=v->next) { if (v->focus) v->reset_player(); }
130
131  last_demo_mx=last_demo_my=last_demo_mbut=0;
132  current_level->set_tick_counter(0);
133
134}
135
136int demo_manager::start_playing(char *filename)
137{
138  uchar sig[15];
139  record_file=open_file(filename,"rb");
140  if (record_file->open_failure()) { delete record_file; return 0; } 
141  char name[100],nsize,diff;
142  if (record_file->read(sig,14)!=14        ||
143      memcmp(sig,"DEMO,VERSION:2",14)!=0   ||
144      record_file->read(&nsize,1)!=1       ||
145      record_file->read(name,nsize)!=nsize ||
146      record_file->read(&diff,1)!=1)
147  { delete record_file; return 0; }
148
149  char tname[100],*c;
150  strcpy(tname,name);
151  c=tname;
152  while (*c) { if (*c=='\\') *c='/'; c++; }
153
154  bFILE *probe=open_file(tname,"rb");   // see if the level still exsist?
155  if (probe->open_failure()) { delete record_file; delete probe; return 0; }
156  delete probe;
157 
158  the_game->load_level(tname);
159  initial_difficulty=l_difficulty;
160
161  switch (diff)
162  {
163    case 0 :
164    { set_symbol_value(l_difficulty,l_easy); } break;
165    case 1 :
166    { set_symbol_value(l_difficulty,l_medium); } break;
167    case 2 :
168    { set_symbol_value(l_difficulty,l_hard); } break;
169    case 3 :
170    { set_symbol_value(l_difficulty,l_extreme); } break;
171  }
172
173  state=PLAYING;
174  reset_game();
175
176
177
178  return 1;
179}
180
181int demo_manager::set_state(demo_state new_state, char *filename)
182{
183  if (new_state==state) return 1;
184
185  switch (state)
186  {
187    case RECORDING :
188    { delete record_file; } break;
189    case PLAYING :
190    {
191      switch_mode(VMODE_640x480);
192
193      fade_in(cash.img(cash.reg("art/help.spe","sell6",SPEC_IMAGE,1)),8);
194      milli_wait(2000);
195      fade_out(8);
196
197      screen->clear();
198      switch_mode(VMODE_320x200);
199     
200
201      delete record_file;
202      l_difficulty=initial_difficulty;
203      the_game->set_state(MENU_STATE);
204      eh->push_event(new event(ID_NULL,NULL));
205
206      view *v=player_list;
207      for (;v;v=v->next)  // reset all the players
208      { if (v->focus) { v->reset_player(); v->focus->set_aistate(0); } }     
209      delete current_level;
210      current_level=NULL;
211      the_game->reset_keymap();
212      base->input_state=INPUT_PROCESSING;
213
214
215    } break;
216  }
217
218  switch (new_state)
219  {
220    case RECORDING :
221    { return start_recording(filename); } break;
222    case PLAYING :
223    { return start_playing(filename); } break;
224    case NORMAL :
225    { state=NORMAL; } break;
226  }
227 
228  return 1;
229}
230
231int demo_manager::save_packet(void *packet, int packet_size)   // returns non 0 if actually saved
232{
233  if (state==RECORDING)
234  {
235    ushort ps=lstl(packet_size);
236    if (record_file->write(&ps,2)!=2 ||
237        record_file->write(packet,packet_size)!=packet_size)
238    {
239      set_state(NORMAL);
240      return 0;
241    }
242    return 1;
243  } else return 0;
244}
245
246int demo_manager::get_packet(void *packet, int &packet_size)   // returns non 0 if actually loaded
247{
248  if (state==PLAYING)
249  {
250    ushort ps;
251    if (record_file->read(&ps,2)!=2)
252    {
253      set_state(NORMAL);
254      return 0;
255    }
256    ps=lstl(ps);
257
258    if (record_file->read(packet,ps)!=ps)
259    {
260      set_state(NORMAL);
261      return 0;
262    }
263
264    packet_size=ps;
265    return 1;
266  }
267  return 0;
268}
269
Note: See TracBrowser for help on using the repository browser.