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

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

imlib: use vec2i for image::size and unroll all necessary changes
everywhere else in the code.

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