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

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

style: remove trailing spaces, fix copyright statements.

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