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
RevLine 
[56]1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
[494]4 *  Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
[56]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
[512]13#include "common.h"
14
[481]15#include "game.h"
[88]16
[481]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"
[2]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
[106]39void get_event(event &ev)
[124]40{ wm->get_event(ev);
[2]41  switch (ev.type)
42  {
43    case EV_KEY :
44    {
45      if (demo_man.state==demo_manager::PLAYING)
[124]46        demo_man.set_state(demo_manager::NORMAL);
[2]47      else if (ev.key==JK_ENTER && demo_man.state==demo_manager::RECORDING)
48      {
49        demo_man.set_state(demo_manager::NORMAL);
[124]50    the_game->show_help("Finished recording");
[2]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
[106]61int event_waiting()
[2]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);
[17]77  record_file->write_uint8(strlen(name)+1);
[2]78  record_file->write(name,strlen(name)+1);
[124]79
80
[2]81  if (DEFINEDP(symbol_value(l_difficulty)))
82  {
[17]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);
[2]88
[124]89
[2]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
[494]105      for (; p; p=p->next)
[2]106        if (p->local_player())
107          p->get_input();
108
[17]109      base->packet.write_uint8(SCMD_SYNC);
110      base->packet.write_uint16(make_sync());
[2]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    {
[17]117      uint8_t buf[1500];
[2]118      int size;
119      if (get_packet(buf,size))              // get starting inputs
120      {
[124]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);
[2]125      }
126      else
127      {
[124]128    set_state(NORMAL);
129    return ;
[2]130      }
131    } break;
[4]132    default :
133      break;
[2]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;
[494]144  for (; v; v=v->next) { if (v->focus) v->reset_player(); }
[2]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{
[17]153  uint8_t sig[15];
[2]154  record_file=open_file(filename,"rb");
[124]155  if (record_file->open_failure()) { delete record_file; return 0; }
[2]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;
[124]172
[2]173  the_game->load_level(tname);
[484]174  initial_difficulty = l_difficulty;
[2]175
176  switch (diff)
177  {
[484]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;
[2]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  {
[124]198    case RECORDING :
[2]199    { delete record_file; } break;
200    case PLAYING :
201    {
202/*
[123]203      fade_in(cache.img(cache.reg("art/help.spe","sell6",SPEC_IMAGE,1)),8);
[2]204      milli_wait(2000);
205      fade_out(8);
206*/
207      delete record_file;
[484]208      l_difficulty = initial_difficulty;
[2]209      the_game->set_state(MENU_STATE);
[106]210      wm->push_event(new event(ID_NULL,NULL));
[2]211
212      view *v=player_list;
[494]213      for (; v; v=v->next)  // reset all the players
[124]214      { if (v->focus) { v->reset_player(); v->focus->set_aistate(0); } }
[2]215      delete current_level;
216      current_level=NULL;
217      the_game->reset_keymap();
218      base->input_state=INPUT_PROCESSING;
219
220
221    } break;
[4]222    default :
223      break;
[2]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  }
[124]235
[2]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  {
[17]243    uint16_t ps=lstl(packet_size);
[2]244    if (record_file->write(&ps,2)!=2 ||
[124]245    record_file->write(packet,packet_size)!=packet_size)
[2]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  {
[17]258    uint16_t ps;
[2]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.