pingus-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pingus-CVS] CVS: Games/Pingus/src demo_session.cxx,NONE,1.1 demo_sessio


From: grumbel
Subject: [Pingus-CVS] CVS: Games/Pingus/src demo_session.cxx,NONE,1.1 demo_session.hxx,NONE,1.1 server_event.cxx,NONE,1.1 server_event.hxx,NONE,1.1 xml_pdf.cxx,NONE,1.1 xml_pdf.hxx,NONE,1.1 Makefile.am,1.112,1.113 action_button.cxx,1.13,1.14 demo_player.cxx,1.4,1.5 demo_player.hxx,1.5,1.6 demo_recorder.cxx,1.5,1.6 demo_recorder.hxx,1.5,1.6 game_session.hxx,1.10,1.11 pingu.cxx,1.30,1.31 pingu_holder.cxx,1.12,1.13 pingu_holder.hxx,1.10,1.11 pingus_main.cxx,1.20,1.21 server.cxx,1.19,1.20 server.hxx,1.9,1.10 true_server.cxx,1.13,1.14 true_server.hxx,1.8,1.9 xml_helper.cxx,1.21,1.22
Date: 3 Oct 2002 01:02:14 -0000

Update of /usr/local/cvsroot/Games/Pingus/src
In directory dark:/tmp/cvs-serv29162

Modified Files:
        Makefile.am action_button.cxx demo_player.cxx demo_player.hxx 
        demo_recorder.cxx demo_recorder.hxx game_session.hxx pingu.cxx 
        pingu_holder.cxx pingu_holder.hxx pingus_main.cxx server.cxx 
        server.hxx true_server.cxx true_server.hxx xml_helper.cxx 
Added Files:
        demo_session.cxx demo_session.hxx server_event.cxx 
        server_event.hxx xml_pdf.cxx xml_pdf.hxx 
Log Message:
implemented demo recorder and player, still unfinished, but works with a little 
copy&paste...

--- NEW FILE: demo_session.cxx ---
//  $Id: demo_session.cxx,v 1.1 2002/10/03 01:02:12 grumbel Exp $
//
//  Pingus - A free Lemmings clone
//  Copyright (C) 2002 Ingo Ruhnke <address@hidden>
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

#include "xml_pdf.hxx"
#include "true_server.hxx"
#include "world.hxx"
#include "demo_player.hxx"
#include "demo_session.hxx"

DemoSession::DemoSession(const std::string& filename)
{
  // Load Demo file
  pdf    = new XMLPDF(filename);

  // Create server
  server = new TrueServer(pdf->get_plf());

  demo_player = new DemoPlayer(server, pdf);
}

DemoSession::~DemoSession()
{
  delete server;
  delete pdf;
}

/** Draw this screen */
bool
DemoSession::draw (GraphicContext& gc)
{
  server->get_world()->draw(gc);
}

/** Pass a delta to the screen */
void
DemoSession::update (const GameDelta& delta)
{
  // FIXME: Duplicate all timing code here?!
  server->update();
  demo_player->update();
}

/* EOF */

--- NEW FILE: demo_session.hxx ---
//  $Id: demo_session.hxx,v 1.1 2002/10/03 01:02:12 grumbel Exp $
// 
//  Pingus - A free Lemmings clone
//  Copyright (C) 2002 Ingo Ruhnke <address@hidden>
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
// 
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

#ifndef HEADER_PINGUS_DEMO_SESSION_HXX
#define HEADER_PINGUS_DEMO_SESSION_HXX

#include "screen.hxx"

class Server;
class XMLPDF;

/** A DemoSession is analog to a GameSession, but instead of loading a
    level and letting the player play a game, a demo file will be
    loaded and the level will be played automatically. */
class DemoSession : public Screen
{
private:
  XMLPDF*     pdf;
  Server*     server;
  DemoPlayer* demo_player;
public:
  /** @param filename the complete filename of the demo file */
  DemoSession(const std::string& filename);
  ~DemoSession();

  /** Draw this screen */
  bool draw (GraphicContext& gc);

  /** Pass a delta to the screen */
  void update (const GameDelta& delta);
  
private:
  DemoSession (const DemoSession&);
  DemoSession& operator= (const DemoSession&);
};

#endif

/* EOF */

--- NEW FILE: server_event.cxx ---
//  $Id: server_event.cxx,v 1.1 2002/10/03 01:02:12 grumbel Exp $
//
//  Pingus - A free Lemmings clone
//  Copyright (C) 2002 Ingo Ruhnke <address@hidden>
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

#include <assert.h>
#include "string_converter.hxx"
#include "pingus_error.hxx"
#include "server.hxx"
#include "world.hxx"
#include "pingu_holder.hxx"
#include "server_event.hxx"

ServerEvent::ServerEvent()
{
}

ServerEvent::ServerEvent(xmlDocPtr doc, xmlNodePtr cur)
{
  if (XMLhelper::equal_str(cur->name, "armageddon"))
    {
      type = ARMAGEDDON_EVENT;
      std::string time_stamp_str;

      assert(XMLhelper::get_prop(cur, "time", time_stamp_str));
      from_string(time_stamp_str, time_stamp);
    }
  else if (XMLhelper::equal_str(cur->name, "pingu-action"))
    {
      type = PINGU_ACTION_EVENT;
      std::string time_stamp_str;
      std::string pingu_id_str;
      std::string pingu_action_str;

      assert(XMLhelper::get_prop(cur, "time",   time_stamp_str));
      assert(XMLhelper::get_prop(cur, "id",     pingu_id_str));
      assert(XMLhelper::get_prop(cur, "action", pingu_action_str));

      from_string(time_stamp_str, time_stamp);
      from_string(pingu_id_str,   pingu_id);
      pingu_action = Actions::action_from_string(pingu_action_str);
    }
  else
    {
      PingusError::raise(std::string("ServerEvent: Parse error: Unknown event: 
")
                         + reinterpret_cast<const char*>(cur->name));
    }
}

void
ServerEvent::write_xml(std::ostream& xml)
{
  switch(type)
    {
    case ARMAGEDDON_EVENT:
      xml << "  <armageddon time=\"" << to_string(time_stamp) << "\"/>" << 
std::endl;
      break;
    case PINGU_ACTION_EVENT:
      xml << "  <pingu-action time=\"" << to_string(time_stamp) << "\" id=\"" 
<< pingu_id 
          << "\" action=\"" << Actions::action_to_string(pingu_action) << 
"\"/>" << std::endl;
      break;
    default:
      assert(!"Unknown type");
    }
}

ServerEvent
ServerEvent::make_armageddon_event(int t)
{
  ServerEvent event;
  event.type       = ARMAGEDDON_EVENT;
  event.time_stamp = t;
  return event;
}

ServerEvent
ServerEvent::make_pingu_action_event(int t, int id, Actions::ActionName action)
{
  ServerEvent event;
  event.type         = PINGU_ACTION_EVENT;
  event.time_stamp   = t;
  event.pingu_id     = id;
  event.pingu_action = action;
  return event;
}

void
ServerEvent::send(Server* server)
{
  switch(type)
    {
    case ARMAGEDDON_EVENT:
      server->send_armageddon_event();
      break;
    case PINGU_ACTION_EVENT:
      {
        Pingu* pingu = server->get_world()->get_pingu_p()->get_pingu(pingu_id);
        if (pingu)
          {
            server->send_pingu_action_event(pingu,
                                            pingu_action);
          }
        else
          {
            std::cout << "ServerEvent: DemoFile inconsistent with world" << 
std::endl;
          }
      }
      break;
    default:
      assert(!"Unknown type");
    }
}

/* EOF */

--- NEW FILE: server_event.hxx ---
//  $Id: server_event.hxx,v 1.1 2002/10/03 01:02:12 grumbel Exp $
// 
//  Pingus - A free Lemmings clone
//  Copyright (C) 2002 Ingo Ruhnke <address@hidden>
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
// 
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

#ifndef HEADER_PINGUS_SERVER_EVENT_HXX
#define HEADER_PINGUS_SERVER_EVENT_HXX

#include <iostream>
#include "xml_helper.hxx"
#include "pingu_enums.hxx"

class Server;

/** This class represents an event that the Server can recieve from
    the client. Only actions and armageddon are here, the rest happens
    Client internal and the server knows nothing about it (scrolling,
    pause, fastforward, etc.) FIXME: this is only half true... */
class ServerEvent
{
public:
  enum Type { ARMAGEDDON_EVENT,
              PINGU_ACTION_EVENT };

  /** The type of event */
  Type type;

  /** the time at which the event should take place */
  int time_stamp;
  
  // stuff for pingu_action_event

  /** Id of the pingu which should get the actions */
  int pingu_id;
  
  /** action name */
  Actions::ActionName pingu_action;
  
  ServerEvent();

  /** Construct an server event from an xml subtree */
  ServerEvent(xmlDocPtr doc, xmlNodePtr cur);

  void write_xml(std::ostream& xml);

  /** Send this event to the server */
  void send(Server*);

  // Pseudo constructors
  static ServerEvent make_armageddon_event(int time);
  static ServerEvent make_pingu_action_event(int t, int id, Actions::ActionName 
action);
};

#endif

/* EOF */

--- NEW FILE: xml_pdf.cxx ---
//  $Id: xml_pdf.cxx,v 1.1 2002/10/03 01:02:12 grumbel Exp $
//
//  Pingus - A free Lemmings clone
//  Copyright (C) 2002 Ingo Ruhnke <address@hidden>
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

#include "xml_helper.hxx"
#include "pingus_error.hxx"
#include "plf.hxx"
#include "path_manager.hxx"
#include "xml_pdf.hxx"

XMLPDF::XMLPDF(const std::string& filename)
  : plf(0)
{
  xmlDocPtr doc = xmlParseFile(filename.c_str());
  if (doc == NULL)
    PingusError::raise("XMLPDF: Couldn't open \"" + filename + "\"");

  xmlNodePtr cur = doc->ROOT;
  
  if (XMLhelper::equal_str(cur->name, "pingus-demo"))
    {
      cur = cur->children;
      cur = XMLhelper::skip_blank(cur);

      while(cur)
        {
          std::cout << "Token: " << cur->name << std::endl;

          if (XMLhelper::equal_str(cur->name, "level"))
            {
              if (!XMLhelper::node_list_get_string(doc, cur->children, 1, 
levelname))
                {
                  std::cout << "XMLPDF: parse error at levelname" << std::endl;
                }
              std::cout << "Level: " << levelname << std::endl;
            }
          else if (XMLhelper::equal_str(cur->name, "events"))
            {
              xmlNodePtr child_cur = cur->children;
              child_cur = XMLhelper::skip_blank(child_cur);

              while(child_cur)
                {
                  events.push_back(ServerEvent(doc, child_cur));
                  child_cur = child_cur->next;
                  child_cur = XMLhelper::skip_blank(child_cur);
                }
            }
          else
            {
              std::cout << "XMLPDF: Unhandled tag: " << cur->name << std::endl;
            }

          cur = cur->next;
          cur = XMLhelper::skip_blank(cur);
        }
    }
  else
    {
      PingusError::raise("XMLPDF: Not a pingus-demo file");
    }

  xmlFreeDoc(doc);

  std::reverse(events.begin(), events.end());

  if (levelname.empty())
    PingusError::raise("XMLPDF: No level given");

  plf = PLF::create(path_manager.complete("levels/" + levelname));

  std::cout << "XXXXXXXXX Read Demo file: " << std::endl;
  write_xml(std::cout);
}

XMLPDF::~XMLPDF()
{
  delete plf;
}

void
XMLPDF::write_xml(std::ostream& xml)
{
  xml << "<pingus-demo>\n"
      << "  <level>" << levelname << "</level>\n"
      << "  <events>\n";

  for(std::vector<ServerEvent>::iterator i = events.begin();
      i != events.end();
      ++i)
    i->write_xml(xml);
  
  xml << "  </events>\n";
}

/** @return a pointer to the level structure */
PLF*
XMLPDF::get_plf()
{
  return plf;
}

/** @return the levelname */
std::string 
XMLPDF::get_levelname()
{
  return levelname;
}

/** Returns a reference to the events of this demo */
std::vector<ServerEvent> 
XMLPDF::get_events()
{
  return events;
}

/* EOF */

--- NEW FILE: xml_pdf.hxx ---
//  $Id: xml_pdf.hxx,v 1.1 2002/10/03 01:02:12 grumbel Exp $
// 
//  Pingus - A free Lemmings clone
//  Copyright (C) 2002 Ingo Ruhnke <address@hidden>
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
// 
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

#ifndef HEADER_PINGUS_XML_PDF_HXX
#define HEADER_PINGUS_XML_PDF_HXX

#include <string>
#include <vector>
#include <iostream>

#include "server_event.hxx"

class PLF;

/** XMLPDF stands for Pingus Demo File, it contains all the infos
    necesarry to play a pingus demo recording */
class XMLPDF
{
private:
  PLF* plf;
  std::string levelname;
  std::vector<ServerEvent> events;
public:
  XMLPDF(const std::string& filename);
  ~XMLPDF();

  /** @return a pointer to the level structure */
  PLF* get_plf();

  /** @return the levelname */
  std::string get_levelname();

  /** Returns a reference to the events of this demo */
  std::vector<ServerEvent> get_events();

  void write_xml(std::ostream& xml);

private:
  XMLPDF (const XMLPDF&);
  XMLPDF& operator= (const XMLPDF&);
};

#endif

/* EOF */

Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/Games/Pingus/src/Makefile.am,v
retrieving revision 1.112
retrieving revision 1.113
diff -u -d -r1.112 -r1.113
--- Makefile.am 2 Oct 2002 12:54:17 -0000       1.112
+++ Makefile.am 3 Oct 2002 01:02:12 -0000       1.113
@@ -116,6 +116,8 @@
 demo_player.hxx \
 demo_recorder.cxx \
 demo_recorder.hxx \
+demo_session.hxx \
+demo_session.cxx \
 direction.cxx \
 direction.hxx \
 display.cxx \
@@ -258,6 +260,8 @@
 screen_ptr.cxx \
 server.cxx \
 server.hxx \
+server_event.hxx \
+server_event.cxx \
 smallmap.cxx \
 smallmap.hxx \
 smallmap_image.cxx \
@@ -313,6 +317,8 @@
 xml_helper.cxx \
 xml_helper.hxx \
 xml_plf.cxx \
-xml_plf.hxx
+xml_plf.hxx \
+xml_pdf.hxx \
+xml_pdf.cxx
 
 ## EOF ##

Index: action_button.cxx
===================================================================
RCS file: /usr/local/cvsroot/Games/Pingus/src/action_button.cxx,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- action_button.cxx   14 Sep 2002 19:06:33 -0000      1.13
+++ action_button.cxx   3 Oct 2002 01:02:12 -0000       1.14
@@ -241,7 +241,7 @@
 {
   if (pressed)
     {
-      server->set_armageddon();
+      server->send_armageddon_event();
     }
   else
     {

Index: demo_player.cxx
===================================================================
RCS file: /usr/local/cvsroot/Games/Pingus/src/demo_player.cxx,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- demo_player.cxx     14 Sep 2002 23:40:35 -0000      1.4
+++ demo_player.cxx     3 Oct 2002 01:02:12 -0000       1.5
@@ -19,13 +19,18 @@
 
 #include <iostream>
 #include <fstream>
+#include "server.hxx"
 #include "pingus_error.hxx"
 #include "demo_player.hxx"
+#include "xml_helper.hxx"
 #include "my_gettext.hxx"
+#include "xml_pdf.hxx"
 
 using namespace std;
 
-DemoPlayer::DemoPlayer()
+DemoPlayer::DemoPlayer(Server* s, XMLPDF* pdf)
+  : server(s),
+    events(pdf->get_events())
 {
 }
 
@@ -33,49 +38,25 @@
 {
 }
 
-std::string 
-DemoPlayer::get_levelname()
-{
-  return levelname;
-}
-
 void
-DemoPlayer::load(const std::string& arg_filename)
+DemoPlayer::update()
 {
-  const int buffer_size = 256;
-  char buffer[buffer_size];
-  std::string filename;
-  std::ifstream in;
-  
-  filename = arg_filename;
-
-  in.open(filename.c_str());
-
-  if (!in)
-    PingusError::raise(_("DemoPlayer: Couldn't load ") + filename);
-
-  in >> levelname; 
-  in.get(); // \n ueberlesen
-  std::cout << "DemoPlayer: LevelName=" << levelname << std::endl;
-
-  while(!(in.getline(buffer, buffer_size).eof()))
+  if (!events.empty())
     {
-      cout << "Readline: " << buffer << endl;
-      event_queue.push(PingusEvent(buffer));
-      std::cout << "Parsed: " << event_queue.back().game_time << ":" << 
event_queue.back().str << std::endl;
-    }
-}
-
-const PingusEvent& 
-DemoPlayer::peek_event()
-{
-  return event_queue.front();
-}
+      ServerEvent event = events.back();
+      if (event.time_stamp == server->get_time())
+       {
+         std::cout << "Sending: ";
+         event.write_xml(std::cout);
 
-void
-DemoPlayer::dequeue_event()
-{
-  event_queue.pop();
+         event.send(server);
+         events.pop_back();
+       }
+      else if (event.time_stamp < server->get_time())
+       {
+         std::cout << "DemoPlayer Bug: We missed a timestamp: " << 
event.time_stamp << std::endl;
+       }
+    }
 }
 
 /* EOF */

Index: demo_player.hxx
===================================================================
RCS file: /usr/local/cvsroot/Games/Pingus/src/demo_player.hxx,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- demo_player.hxx     27 Sep 2002 11:26:43 -0000      1.5
+++ demo_player.hxx     3 Oct 2002 01:02:12 -0000       1.6
@@ -20,32 +20,23 @@
 #ifndef HEADER_PINGUS_DEMO_PLAYER_HXX
 #define HEADER_PINGUS_DEMO_PLAYER_HXX
 
-#include <queue>
+#include <vector>
+#include "server_event.hxx"
 
-#include "server.hxx"
+class Server;
+class XMLPDF;
 
 class DemoPlayer
 {
 private:
-  std::queue<PingusEvent> event_queue;
-  std::string levelname;
+  Server* server;
+  std::vector<ServerEvent> events;
 
 public:
-  DemoPlayer();
+  DemoPlayer(Server* s, XMLPDF* pdf);
   ~DemoPlayer();
-
-
-  void load(const std::string&);
-
-  std::string get_levelname();
-
-  const PingusEvent& peek_event();
-
-  void dequeue_event();
-
-  bool empty() { 
-    return event_queue.empty(); 
-  }
+  
+  void update();
   
 private:
   DemoPlayer (const DemoPlayer&);

Index: demo_recorder.cxx
===================================================================
RCS file: /usr/local/cvsroot/Games/Pingus/src/demo_recorder.cxx,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- demo_recorder.cxx   16 Aug 2002 15:13:59 -0000      1.5
+++ demo_recorder.cxx   3 Oct 2002 01:02:12 -0000       1.6
@@ -28,10 +28,9 @@
 #include <config.h>
 #include "my_gettext.hxx"
 
-
 using namespace std;
 
-DemoRecorder::DemoRecorder() : is_recording(false)
+DemoRecorder::DemoRecorder()
 {
 }
 
@@ -47,8 +46,6 @@
   //std::cout << "Demo filename: " + filename << std::endl;
   console << "Recording demo to: " << filename << std::endl;
   
-  is_recording = true;
-
   std::cout << "DemoRecorder: levelname = " << levelname << std::endl;
   out.open(filename.c_str());
 
@@ -56,15 +53,6 @@
 
   if (!out)
     PingusError::raise(_("DemoRecorder: Couldn't open: ") + filename);
-}
-
-void
-DemoRecorder::queue_event(const string& event)
-{
-  if (is_recording) {
-    out << event << std::endl;
-    std::cout << "Recorded: " << event << std::endl;
-  }
 }
 
 string 

Index: demo_recorder.hxx
===================================================================
RCS file: /usr/local/cvsroot/Games/Pingus/src/demo_recorder.hxx,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- demo_recorder.hxx   27 Sep 2002 11:26:43 -0000      1.5
+++ demo_recorder.hxx   3 Oct 2002 01:02:12 -0000       1.6
@@ -24,35 +24,23 @@
 #include <fstream>
 #include <string>
 
-///
 class DemoRecorder
 {
 private:
-  ///
   std::ofstream out;
-  ///
   std::string   filename;
-  ///
-  bool     is_recording;
 
-  ///
   std::string get_date();
 public:
-  ///
   DemoRecorder();
-  ///
   ~DemoRecorder();
 
-  ///
-  void queue_event(const std::string&);
-  ///
   void set_levelname(const std::string&);
   
 private:
   DemoRecorder (const DemoRecorder&);
   DemoRecorder& operator= (const DemoRecorder&);
-}///
-;
+};
 
 #endif
 

Index: game_session.hxx
===================================================================
RCS file: /usr/local/cvsroot/Games/Pingus/src/game_session.hxx,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- game_session.hxx    2 Oct 2002 12:54:18 -0000       1.10
+++ game_session.hxx    3 Oct 2002 01:02:12 -0000       1.11
@@ -27,6 +27,7 @@
 class Server;
 class PLF;
 class PingusGameSessionResult;
+class DemoPlayer;
 
 /** You can use this class to start up a game session, which consist
     of a single level. */
@@ -44,10 +45,6 @@
 
   /// The client
   Client* client;
-
-  /** Create a XMLPLf or a PLFPLF, depending on the file extension,
-      the called must delete the returned PLF object */
-  PLF* create_plf (std::string filename);
 
   unsigned int last_redraw;
   unsigned int last_update;

Index: pingu.cxx
===================================================================
RCS file: /usr/local/cvsroot/Games/Pingus/src/pingu.cxx,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- pingu.cxx   2 Oct 2002 19:20:19 -0000       1.30
+++ pingu.cxx   3 Oct 2002 01:02:12 -0000       1.31
@@ -38,17 +38,17 @@
 
 // Init a pingu at the given position while falling
 Pingu::Pingu (int arg_id, const Vector& arg_pos, int owner)
-            : action(0),
-              countdown_action (0),
-              wall_action(0),
-              fall_action(0),
-              id(arg_id),
-              action_time(-1),
-              owner_id(owner),
-              status(PS_ALIVE),
-             pos_x(arg_pos.x),
-             pos_y(arg_pos.y),
-              velocity(new Vector(0, 0, 0))
+  : action(0),
+    countdown_action (0),
+    wall_action(0),
+    fall_action(0),
+    id(arg_id),
+    action_time(-1),
+    owner_id(owner),
+    status(PS_ALIVE),
+    pos_x(arg_pos.x),
+    pos_y(arg_pos.y),
+    velocity(new Vector(0, 0, 0))
 {
   direction.left ();
   set_action(Faller);
@@ -125,78 +125,78 @@
     {    
       switch (act->get_activation_mode()) {
   
-        case INSTANT:
+      case INSTANT:
   
-          if (act->get_type() == action->get_type()) 
-           {
-             pout(PINGUS_DEBUG_ACTIONS) << "Pingu: Already have action" << 
std::endl;
-             ret_val = false;
-           } 
-          else if (action->change_allowed(act->get_type()))
-           {
-             pout(PINGUS_DEBUG_ACTIONS) << "setting instant action" << 
std::endl;
-             act->set_pingu(this);
-             set_action(act);
-             ret_val = true;
-           }
-          else
-           {
-             pout(PINGUS_DEBUG_ACTIONS) << "change from action " << 
action->get_name () << " not allowed" << std::endl;
-             ret_val = false;
-           }
-          break;
+       if (act->get_type() == action->get_type()) 
+         {
+           pout(PINGUS_DEBUG_ACTIONS) << "Pingu: Already have action" << 
std::endl;
+           ret_val = false;
+         } 
+       else if (action->change_allowed(act->get_type()))
+         {
+           pout(PINGUS_DEBUG_ACTIONS) << "setting instant action" << std::endl;
+           act->set_pingu(this);
+           set_action(act);
+           ret_val = true;
+         }
+       else
+         {
+           pout(PINGUS_DEBUG_ACTIONS) << "change from action " << 
action->get_name () << " not allowed" << std::endl;
+           ret_val = false;
+         }
+       break;
                 
-        case WALL_TRIGGERED:
+      case WALL_TRIGGERED:
     
-          if (wall_action && wall_action->get_type() == act->get_type())
-           {
-             pout(PINGUS_DEBUG_ACTIONS) << "Not using wall action, we have 
already" << std::endl;
-             ret_val = false;
-           }
-          else
-           {
-             pout(PINGUS_DEBUG_ACTIONS) << "Setting wall action" << std::endl;
-             wall_action = act;
-             ret_val = true;
-           }
-          break;
+       if (wall_action && wall_action->get_type() == act->get_type())
+         {
+           pout(PINGUS_DEBUG_ACTIONS) << "Not using wall action, we have 
already" << std::endl;
+           ret_val = false;
+         }
+       else
+         {
+           pout(PINGUS_DEBUG_ACTIONS) << "Setting wall action" << std::endl;
+           wall_action = act;
+           ret_val = true;
+         }
+       break;
     
-        case FALL_TRIGGERED:
+      case FALL_TRIGGERED:
   
-          if (fall_action && fall_action->get_type() == act->get_type())
-           {
-             pout(PINGUS_DEBUG_ACTIONS) << "Not using fall action, we have 
already" << std::endl;
-             ret_val = false;
-           }
-          else
-           {
-             pout(PINGUS_DEBUG_ACTIONS) << "Setting fall action" << std::endl;
-             fall_action = act;
-             ret_val = true;
-           }
-          break;
+       if (fall_action && fall_action->get_type() == act->get_type())
+         {
+           pout(PINGUS_DEBUG_ACTIONS) << "Not using fall action, we have 
already" << std::endl;
+           ret_val = false;
+         }
+       else
+         {
+           pout(PINGUS_DEBUG_ACTIONS) << "Setting fall action" << std::endl;
+           fall_action = act;
+           ret_val = true;
+         }
+       break;
 
-        case COUNTDOWN_TRIGGERED:
+      case COUNTDOWN_TRIGGERED:
   
-          if (countdown_action && countdown_action->get_type() == 
act->get_type())
-           {
-             pout(PINGUS_DEBUG_ACTIONS) << "Not using countdown action, we 
have already" << std::endl;
-             ret_val = false;
-             break;
-           }
+       if (countdown_action && countdown_action->get_type() == act->get_type())
+         {
+           pout(PINGUS_DEBUG_ACTIONS) << "Not using countdown action, we have 
already" << std::endl;
+           ret_val = false;
+           break;
+         }
       
-          pout(PINGUS_DEBUG_ACTIONS) << "Setting countdown action" << 
std::endl;
-          // We set the action and start the countdown
-          action_time = act->activation_time();
-          countdown_action = act;
-          ret_val = true;
-          break;
+       pout(PINGUS_DEBUG_ACTIONS) << "Setting countdown action" << std::endl;
+       // We set the action and start the countdown
+       action_time = act->activation_time();
+       countdown_action = act;
+       ret_val = true;
+       break;
          
-        default:
-          pout(PINGUS_DEBUG_ACTIONS) << "unknown action activation_mode" << 
std::endl;     
-          assert(0);
-          ret_val = false;
-          break;
+      default:
+       pout(PINGUS_DEBUG_ACTIONS) << "unknown action activation_mode" << 
std::endl;     
+       assert(0);
+       ret_val = false;
+       break;
       }
     }
 

Index: pingu_holder.cxx
===================================================================
RCS file: /usr/local/cvsroot/Games/Pingus/src/pingu_holder.cxx,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- pingu_holder.cxx    2 Oct 2002 19:20:19 -0000       1.12
+++ pingu_holder.cxx    3 Oct 2002 01:02:12 -0000       1.13
@@ -123,6 +123,19 @@
     }
 }
 
+Pingu*
+PinguHolder::get_pingu(int id)
+{
+  for(std::list<Pingu*>::iterator pingu = pingus.begin(); 
+      pingu != pingus.end(); 
+      ++pingu)
+    {
+      if ((*pingu)->get_id() == id)
+       return *pingu;
+    }
+  return 0;
+}
+
 float
 PinguHolder::get_z_pos() const
 {

Index: pingu_holder.hxx
===================================================================
RCS file: /usr/local/cvsroot/Games/Pingus/src/pingu_holder.hxx,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- pingu_holder.hxx    2 Oct 2002 19:20:19 -0000       1.10
+++ pingu_holder.hxx    3 Oct 2002 01:02:12 -0000       1.11
@@ -63,6 +63,10 @@
       Pingu */
   Pingu* create_pingu(const Vector& pos, int owner_id);
 
+  /** Get a pingu by id 
+   @return the pingu with the id, or 0 if not found */
+  Pingu* get_pingu(int id);
+
   float get_z_pos() const;
 
   std::list<Pingu*>::iterator  begin () { return pingus.begin (); }

Index: pingus_main.cxx
===================================================================
RCS file: /usr/local/cvsroot/Games/Pingus/src/pingus_main.cxx,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- pingus_main.cxx     1 Oct 2002 23:10:41 -0000       1.20
+++ pingus_main.cxx     3 Oct 2002 01:02:12 -0000       1.21
@@ -66,6 +66,7 @@
 #include "message_box.hxx"
 #include "audio.hxx"
 #include "game_session.hxx"
+#include "demo_session.hxx"
 #include "debug.hxx"
 #include "editor/editor.hxx"
 #include "boost/smart_ptr.hpp"
@@ -857,10 +858,14 @@
            }
        }    
     }
-  else
+  else if (start_editor)
     { // Start an empty editor workspace
       if (start_editor)
        ScreenManager::instance()->push_screen(Editor::instance (), false);
+    }
+  else if (!demo_file.empty())
+    {
+      ScreenManager::instance()->push_screen(new DemoSession (demo_file));
     }
 
   // show the main menu, the rest of the game is spawn from there

Index: server.cxx
===================================================================
RCS file: /usr/local/cvsroot/Games/Pingus/src/server.cxx,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- server.cxx  2 Oct 2002 19:20:19 -0000       1.19
+++ server.cxx  3 Oct 2002 01:02:12 -0000       1.20
@@ -19,6 +19,7 @@
 
 #include <algorithm>
 #include <iostream>
+#include <fstream>
 #include <stdio.h>
 #include "system.hxx"
 #include "pingu.hxx"
@@ -93,6 +94,33 @@
 
 Server::~Server ()
 {
+  // Here we write down the demo file
+  // FIXME: syntax will be different in the final version, this is just a 
quick hack
+  std::string date_str;
+  
+  {
+    char buffer[32];
+    time_t curtime;
+    struct tm *loctime;
+    curtime = time (NULL);
+    loctime = localtime(&curtime);
+    strftime(buffer, 32, "%Y%m%d-%H%M%S", loctime);
+
+    date_str = buffer;
+    
+    date_str = System::get_statdir() + "demos/" + date_str + ".xml";
+  }
+
+  std::cout << "Writing demo to: " << date_str << std::endl;
+
+  std::ofstream xml(date_str.c_str());
+  
+  xml << "<pingus-events>" << std::endl;
+  for(std::vector<ServerEvent>::iterator i = events.begin();
+      i != events.end();
+      ++i)
+    i->write_xml(xml);
+  xml << "</pingus-events>" << std::endl;
 }
 
 World*
@@ -104,41 +132,15 @@
 void
 Server::update()
 {
-  /*  static PingusEvent event;
-  
-  if (!demo_mode) {
-    return;
-  }
-  
-  if (get_next_event) 
-    {
-      // Getting next event from file
-      get_next_event = false;    
-      //event = demo_in->get_next_event();
-    }
-  
-  // Check if the time for the event is right
-  if (GameTime::get_time() == event.game_time)
-    {
-      process_event(event.str);
-      get_next_event = true;
-    } 
-  else if (GameTime::get_time() >= event.game_time) 
-    {
-      // BUG: If this is reached the demo code is buggy
-      std::cout << "Demo out of sync!: " 
-               << "GameTime: " << GameTime::get_time()
-               << " EventTime: " << event.game_time
-               << std::endl;
-      get_next_event = true;
-    }
-  */
 }
 
 void
 Server::send_armageddon_event()
 {
+  armageddon = true;
   world->armageddon();
+
+  events.push_back(ServerEvent::make_armageddon_event(get_time()));
 }
 
 void
@@ -153,6 +155,8 @@
          action_holder.push_action(action);
        }
     }
+
+  events.push_back(ServerEvent::make_pingu_action_event(get_time(), 
pingu->get_id(), action));
 }
 
 bool
@@ -175,6 +179,12 @@
 Server::get_action_holder()
 {
   return &action_holder;
+}
+
+int
+Server::get_time()
+{
+  return get_world()->get_game_time()->get_ticks();
 }
 
 /* EOF */

Index: server.hxx
===================================================================
RCS file: /usr/local/cvsroot/Games/Pingus/src/server.hxx,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- server.hxx  2 Oct 2002 19:20:19 -0000       1.9
+++ server.hxx  3 Oct 2002 01:02:12 -0000       1.10
@@ -20,6 +20,8 @@
 #ifndef HEADER_PINGUS_SERVER_HXX
 #define HEADER_PINGUS_SERVER_HXX
 
+#include <vector>
+#include "server_event.hxx"
 #include "action_holder.hxx"
 
 class Pingu;
@@ -52,6 +54,7 @@
 class Server
 {
 protected:
+  std::vector<ServerEvent> events;
   World* world;
   ActionHolder action_holder;
   bool demo_mode;
@@ -59,6 +62,7 @@
 
   bool get_next_event;
   bool finished;
+  bool armageddon;
 
 public:
   Server(PLF*);
@@ -72,10 +76,11 @@
   virtual bool get_pause() = 0;
   virtual void set_pause(bool) = 0;
 
-  virtual void set_armageddon () =0;
-  virtual bool get_armageddon () =0;
+  virtual bool get_armageddon () { return armageddon; }
 
   virtual PLF* get_plf () =0;
+
+  int get_time();
 
   World* get_world();
   ActionHolder* get_action_holder();

Index: true_server.cxx
===================================================================
RCS file: /usr/local/cvsroot/Games/Pingus/src/true_server.cxx,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- true_server.cxx     1 Oct 2002 21:48:32 -0000       1.13
+++ true_server.cxx     3 Oct 2002 01:02:12 -0000       1.14
@@ -97,13 +97,6 @@
   return plf;
 }
 
-void
-TrueServer::set_armageddon ()
-{
-  armageddon = true;
-  world->armageddon ();
-}
-
 bool
 TrueServer::get_armageddon ()
 {

Index: true_server.hxx
===================================================================
RCS file: /usr/local/cvsroot/Games/Pingus/src/true_server.hxx,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- true_server.hxx     1 Oct 2002 21:48:32 -0000       1.8
+++ true_server.hxx     3 Oct 2002 01:02:12 -0000       1.9
@@ -30,7 +30,6 @@
   bool pause;
   unsigned int  last_time;
   float delta;
-  bool armageddon;
 
   /** Reference to the PLF for this level, this must not be deleted */
   PLF* plf;
@@ -48,7 +47,6 @@
   void set_pause(bool);
   bool get_pause();
 
-  void set_armageddon ();
   bool get_armageddon ();
   
 private: 

Index: xml_helper.cxx
===================================================================
RCS file: /usr/local/cvsroot/Games/Pingus/src/xml_helper.cxx,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- xml_helper.cxx      1 Oct 2002 23:10:41 -0000       1.21
+++ xml_helper.cxx      3 Oct 2002 01:02:12 -0000       1.22
@@ -33,7 +33,7 @@
 xmlNodePtr
 XMLhelper::skip_blank (xmlNodePtr cur)
 {
-  if (xmlIsBlankNode(cur))
+  if (cur && xmlIsBlankNode(cur))
     return cur->next;
   else
     return cur;





reply via email to

[Prev in Thread] Current Thread [Next in Thread]