source: abuse/tags/pd/abuse/src/demo.c @ 528

Last change on this file since 528 was 49, checked in by Sam Hocevar, 15 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 6.1 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/*
192      fade_in(cash.img(cash.reg("art/help.spe","sell6",SPEC_IMAGE,1)),8);
193      milli_wait(2000);
194      fade_out(8);
195*/
196      delete record_file;
197      l_difficulty=initial_difficulty;
198      the_game->set_state(MENU_STATE);
199      eh->push_event(new event(ID_NULL,NULL));
200
201      view *v=player_list;
202      for (;v;v=v->next)  // reset all the players
203      { if (v->focus) { v->reset_player(); v->focus->set_aistate(0); } }     
204      delete current_level;
205      current_level=NULL;
206      the_game->reset_keymap();
207      base->input_state=INPUT_PROCESSING;
208
209
210    } break;
211  }
212
213  switch (new_state)
214  {
215    case RECORDING :
216    { return start_recording(filename); } break;
217    case PLAYING :
218    { return start_playing(filename); } break;
219    case NORMAL :
220    { state=NORMAL; } break;
221  }
222 
223  return 1;
224}
225
226int demo_manager::save_packet(void *packet, int packet_size)   // returns non 0 if actually saved
227{
228  if (state==RECORDING)
229  {
230    ushort ps=lstl(packet_size);
231    if (record_file->write(&ps,2)!=2 ||
232        record_file->write(packet,packet_size)!=packet_size)
233    {
234      set_state(NORMAL);
235      return 0;
236    }
237    return 1;
238  } else return 0;
239}
240
241int demo_manager::get_packet(void *packet, int &packet_size)   // returns non 0 if actually loaded
242{
243  if (state==PLAYING)
244  {
245    ushort ps;
246    if (record_file->read(&ps,2)!=2)
247    {
248      set_state(NORMAL);
249      return 0;
250    }
251    ps=lstl(ps);
252
253    if (record_file->read(packet,ps)!=ps)
254    {
255      set_state(NORMAL);
256      return 0;
257    }
258
259    packet_size=ps;
260    return 1;
261  }
262  return 0;
263}
264
Note: See TracBrowser for help on using the repository browser.