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

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

lisp: populate LispSymbol? with symbol-related methods.

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: l_difficulty->SetValue(l_easy); break;
176    case 1: l_difficulty->SetValue(l_medium); break;
177    case 2: l_difficulty->SetValue(l_hard); break;
178    case 3: l_difficulty->SetValue(l_extreme); break;
179  }
180
181  state=PLAYING;
182  reset_game();
183
184
185
186  return 1;
187}
188
189int demo_manager::set_state(demo_state new_state, char *filename)
190{
191  if (new_state==state) return 1;
192
193  switch (state)
194  {
195    case RECORDING :
196    { delete record_file; } break;
197    case PLAYING :
198    {
199/*
200      fade_in(cache.img(cache.reg("art/help.spe","sell6",SPEC_IMAGE,1)),8);
201      milli_wait(2000);
202      fade_out(8);
203*/
204      delete record_file;
205      l_difficulty = initial_difficulty;
206      the_game->set_state(MENU_STATE);
207      wm->push_event(new event(ID_NULL,NULL));
208
209      view *v=player_list;
210      for (;v;v=v->next)  // reset all the players
211      { if (v->focus) { v->reset_player(); v->focus->set_aistate(0); } }
212      delete current_level;
213      current_level=NULL;
214      the_game->reset_keymap();
215      base->input_state=INPUT_PROCESSING;
216
217
218    } break;
219    default :
220      break;
221  }
222
223  switch (new_state)
224  {
225    case RECORDING :
226    { return start_recording(filename); } break;
227    case PLAYING :
228    { return start_playing(filename); } break;
229    case NORMAL :
230    { state=NORMAL; } break;
231  }
232
233  return 1;
234}
235
236int demo_manager::save_packet(void *packet, int packet_size)   // returns non 0 if actually saved
237{
238  if (state==RECORDING)
239  {
240    uint16_t ps=lstl(packet_size);
241    if (record_file->write(&ps,2)!=2 ||
242    record_file->write(packet,packet_size)!=packet_size)
243    {
244      set_state(NORMAL);
245      return 0;
246    }
247    return 1;
248  } else return 0;
249}
250
251int demo_manager::get_packet(void *packet, int &packet_size)   // returns non 0 if actually loaded
252{
253  if (state==PLAYING)
254  {
255    uint16_t ps;
256    if (record_file->read(&ps,2)!=2)
257    {
258      set_state(NORMAL);
259      return 0;
260    }
261    ps=lstl(ps);
262
263    if (record_file->read(packet,ps)!=ps)
264    {
265      set_state(NORMAL);
266      return 0;
267    }
268
269    packet_size=ps;
270    return 1;
271  }
272  return 0;
273}
274
Note: See TracBrowser for help on using the repository browser.