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

Last change on this file since 88 was 88, checked in by Sam Hocevar, 12 years ago
  • Remove a few duplicate extern declarations. They belong to header files.
File size: 6.4 KB
RevLine 
[56]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
[88]12#include "game.hpp"
13
[2]14#include "demo.hpp"
15#include "specs.hpp"
16#include "macs.hpp"
17#include "jwindow.hpp"
18#include "jmalloc.hpp"
19#include "dprint.hpp"
20#include "dev.hpp"
21#include "jrand.hpp"
22#include "lisp.hpp"
23#include "clisp.hpp"
24#include "netface.hpp"
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, window_manager *wm)
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(window_manager *wm)
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);
[17]75  record_file->write_uint8(strlen(name)+1);
[2]76  record_file->write(name,strlen(name)+1);
77 
78 
79  if (DEFINEDP(symbol_value(l_difficulty)))
80  {
[17]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);
[2]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
[17]107      base->packet.write_uint8(SCMD_SYNC);
108      base->packet.write_uint16(make_sync());
[2]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    {
[17]115      uint8_t buf[1500];
[2]116      int size;
117      if (get_packet(buf,size))              // get starting inputs
118      {
119        process_packet_commands(buf,size);     
[16]120        int32_t mx,my;
[2]121        the_game->game_to_mouse(player_list->pointer_x,player_list->pointer_y,player_list,mx,my);
122        eh->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;
[4]130    default :
131      break;
[2]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{
[17]151  uint8_t sig[15];
[2]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 :
177    { set_symbol_value(l_difficulty,l_easy); } break;
178    case 1 :
179    { set_symbol_value(l_difficulty,l_medium); } break;
180    case 2 :
181    { set_symbol_value(l_difficulty,l_hard); } break;
182    case 3 :
183    { set_symbol_value(l_difficulty,l_extreme); } break;
184  }
185
186  state=PLAYING;
187  reset_game();
188
189
190
191  return 1;
192}
193
194int demo_manager::set_state(demo_state new_state, char *filename)
195{
196  if (new_state==state) return 1;
197
198  switch (state)
199  {
200    case RECORDING :
201    { delete record_file; } break;
202    case PLAYING :
203    {
204/*
205      fade_in(cash.img(cash.reg("art/help.spe","sell6",SPEC_IMAGE,1)),8);
206      milli_wait(2000);
207      fade_out(8);
208*/
209      delete record_file;
210      l_difficulty=initial_difficulty;
211      the_game->set_state(MENU_STATE);
212      eh->push_event(new event(ID_NULL,NULL));
213
214      view *v=player_list;
215      for (;v;v=v->next)  // reset all the players
216      { if (v->focus) { v->reset_player(); v->focus->set_aistate(0); } }     
217      delete current_level;
218      current_level=NULL;
219      the_game->reset_keymap();
220      base->input_state=INPUT_PROCESSING;
221
222
223    } break;
[4]224    default :
225      break;
[2]226  }
227
228  switch (new_state)
229  {
230    case RECORDING :
231    { return start_recording(filename); } break;
232    case PLAYING :
233    { return start_playing(filename); } break;
234    case NORMAL :
235    { state=NORMAL; } break;
236  }
237 
238  return 1;
239}
240
241int demo_manager::save_packet(void *packet, int packet_size)   // returns non 0 if actually saved
242{
243  if (state==RECORDING)
244  {
[17]245    uint16_t ps=lstl(packet_size);
[2]246    if (record_file->write(&ps,2)!=2 ||
247        record_file->write(packet,packet_size)!=packet_size)
248    {
249      set_state(NORMAL);
250      return 0;
251    }
252    return 1;
253  } else return 0;
254}
255
256int demo_manager::get_packet(void *packet, int &packet_size)   // returns non 0 if actually loaded
257{
258  if (state==PLAYING)
259  {
[17]260    uint16_t ps;
[2]261    if (record_file->read(&ps,2)!=2)
262    {
263      set_state(NORMAL);
264      return 0;
265    }
266    ps=lstl(ps);
267
268    if (record_file->read(packet,ps)!=ps)
269    {
270      set_state(NORMAL);
271      return 0;
272    }
273
274    packet_size=ps;
275    return 1;
276  }
277  return 0;
278}
279
Note: See TracBrowser for help on using the repository browser.