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

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