source: abuse/trunk/src/demo.cpp @ 481

Last change on this file since 481 was 481, checked in by Sam Hocevar, 11 years ago

Fuck the history, I'm renaming all .hpp files to .h for my own sanity.

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