source: abuse/branches/lol/src/demo.cpp @ 732

Last change on this file since 732 was 732, checked in by Sam Hocevar, 8 years ago

build: SDL2 compilation fixes.

File size: 6.4 KB
RevLine 
[56]1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
[715]4 *  Copyright (c) 2005-2013 Sam Hocevar <sam@hocevar.net>
[56]5 *
6 *  This software was released into the Public Domain. As with most public
[555]7 *  domain software, no warranty is made or implied by Crack dot Com, by
8 *  Jonathan Clark, or by Sam Hocevar.
[56]9 */
10
[732]11#if HAVE_CONFIG_H
[555]12#   include "config.h"
13#endif
[56]14
[512]15#include "common.h"
16
[724]17#include "lisp/lisp.h"
[88]18
[724]19#include "imlib/specs.h"
20#include "imlib/window.h"
21#include "imlib/dprint.h"
22
[481]23#include "dev.h"
24#include "clisp.h"
25#include "netface.h"
[724]26#include "game.h"
27#include "demo.h"
[2]28
29demo_manager demo_man;
[682]30ivec2 last_demo_mpos;
[658]31int last_demo_mbut;
[2]32extern base_memory_struct *base;   // points to shm_addr
33extern int idle_ticks;
34
35extern void net_receive();
36extern void net_send(int force);
[709]37extern void fade_in(AImage *im, int steps);
[2]38extern void fade_out(int steps);
39
[643]40void get_event(Event &ev)
[124]41{ wm->get_event(ev);
[2]42  switch (ev.type)
43  {
44    case EV_KEY :
45    {
46      if (demo_man.state==demo_manager::PLAYING)
[124]47        demo_man.set_state(demo_manager::NORMAL);
[2]48      else if (ev.key==JK_ENTER && demo_man.state==demo_manager::RECORDING)
49      {
50        demo_man.set_state(demo_manager::NORMAL);
[124]51    the_game->show_help("Finished recording");
[2]52      }
53    } break;
54  }
55
[658]56  last_demo_mpos = ev.mouse_move;
57  last_demo_mbut = ev.mouse_button;
[2]58  idle_ticks=0;
59}
60
[106]61int event_waiting()
[645]62{ return wm->IsPending(); }
[2]63
64
[716]65int demo_manager::start_recording(char const *filename)
[2]66{
[691]67  if (!g_current_level) return 0;
[2]68
69  record_file=open_file(filename,"wb");
70  if (record_file->open_failure()) { delete record_file; return 0; }
71
[712]72  String const name = g_current_level->GetName();
[2]73
[712]74  the_game->load_level(name.C());
[715]75  record_file->write((void const *)"DEMO,VERSION:2", 14);
[712]76  record_file->write_uint8(name.Count() + 1);
77  record_file->write(name.C(), name.Count() + 1);
[124]78
[712]79  uint8_t difficulty = 3;
[2]80  if (DEFINEDP(symbol_value(l_difficulty)))
81  {
[712]82    if (symbol_value(l_difficulty) == l_easy)
83      difficulty = 0;
84    else if (symbol_value(l_difficulty) == l_medium)
85      difficulty = 1;
86    else if (symbol_value(l_difficulty) == l_hard)
87      difficulty = 2;
88  }
89  record_file->write_uint8(difficulty);
[2]90
[712]91  state = RECORDING;
[124]92
[2]93  reset_game();
94
95  return 1;
96}
97
98void demo_manager::do_inputs()
99{
100  switch (state)
101  {
102    case RECORDING :
103    {
104      base->packet.packet_reset();       // reset input buffer
105      view *p=player_list;               // get current inputs
[494]106      for (; p; p=p->next)
[2]107        if (p->local_player())
108          p->get_input();
109
[17]110      base->packet.write_uint8(SCMD_SYNC);
111      base->packet.write_uint16(make_sync());
[2]112      demo_man.save_packet(base->packet.packet_data(),base->packet.packet_size());
113      process_packet_commands(base->packet.packet_data(),base->packet.packet_size());
114
115    } break;
116    case PLAYING :
117    {
[17]118      uint8_t buf[1500];
[2]119      int size;
120      if (get_packet(buf,size))              // get starting inputs
121      {
[657]122        process_packet_commands(buf, size);
[682]123        ivec2 mouse = the_game->GameToMouse(ivec2(player_list->pointer_x,
[657]124                                                  player_list->pointer_y),
125                                            player_list);
[703]126        wm->SetMousePos(mouse);
[2]127      }
128      else
129      {
[124]130    set_state(NORMAL);
131    return ;
[2]132      }
133    } break;
[4]134    default :
135      break;
[2]136  }
137}
138
139void demo_manager::reset_game()
140{
141  if (dev&EDIT_MODE) toggle_edit_mode();
142  the_game->set_state(RUN_STATE);
143
144  view *v=player_list;
[676]145  for (; v; v=v->next) { if (v->m_focus) v->reset_player(); }
[2]146
[682]147  last_demo_mpos = ivec2(0, 0);
[658]148  last_demo_mbut = 0;
[691]149  g_current_level->set_tick_counter(0);
[2]150
151}
152
[716]153int demo_manager::start_playing(char const *filename)
[2]154{
[17]155  uint8_t sig[15];
[2]156  record_file=open_file(filename,"rb");
[124]157  if (record_file->open_failure()) { delete record_file; return 0; }
[2]158  char name[100],nsize,diff;
159  if (record_file->read(sig,14)!=14        ||
160      memcmp(sig,"DEMO,VERSION:2",14)!=0   ||
161      record_file->read(&nsize,1)!=1       ||
162      record_file->read(name,nsize)!=nsize ||
163      record_file->read(&diff,1)!=1)
164  { delete record_file; return 0; }
165
166  char tname[100],*c;
167  strcpy(tname,name);
168  c=tname;
169  while (*c) { if (*c=='\\') *c='/'; c++; }
170
[643]171  bFILE *probe=open_file(tname,"rb");   // see if the level still exists?
[2]172  if (probe->open_failure()) { delete record_file; delete probe; return 0; }
173  delete probe;
[124]174
[2]175  the_game->load_level(tname);
[484]176  initial_difficulty = l_difficulty;
[2]177
178  switch (diff)
179  {
[484]180    case 0: l_difficulty->SetValue(l_easy); break;
181    case 1: l_difficulty->SetValue(l_medium); break;
182    case 2: l_difficulty->SetValue(l_hard); break;
183    case 3: l_difficulty->SetValue(l_extreme); break;
[2]184  }
185
186  state=PLAYING;
187  reset_game();
188
189
190
191  return 1;
192}
193
[716]194int demo_manager::set_state(demo_state new_state, char const *filename)
[2]195{
196  if (new_state==state) return 1;
197
198  switch (state)
199  {
[124]200    case RECORDING :
[2]201    { delete record_file; } break;
202    case PLAYING :
203    {
204/*
[123]205      fade_in(cache.img(cache.reg("art/help.spe","sell6",SPEC_IMAGE,1)),8);
[686]206      Timer now; now.Wait(2.f);
[2]207      fade_out(8);
208*/
209      delete record_file;
[484]210      l_difficulty = initial_difficulty;
[2]211      the_game->set_state(MENU_STATE);
[707]212      wm->Push(Event(ID_NULL, NULL));
[2]213
214      view *v=player_list;
[494]215      for (; v; v=v->next)  // reset all the players
[676]216      { if (v->m_focus) { v->reset_player(); v->m_focus->set_aistate(0); } }
[691]217      delete g_current_level;
218      g_current_level=NULL;
[2]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  }
[124]237
[2]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 ||
[124]247    record_file->write(packet,packet_size)!=packet_size)
[2]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.