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

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

core: Get rid of mostly useless headers, move endianness handling to
common.h (and rewrite functions so that they do not need the SDL headers)
and move a few functions out of sdlport's video.cpp. These functions
were in the original video.cpp (which reappears) and shouldn't be part
of the SDL port.

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