[Top][All Lists]

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

Description Document, v.01

From: John August
Subject: Description Document, v.01
Date: Sat, 3 Apr 2004 23:47:27 +1000
User-agent: Mutt/1.0.1i


Here's a first, very draft, version of the documentation. Rather than
pointing to questions, you can see in the document references in
[square brackets], along with text like "its not clear" and "I don't
understand" which underline questions.

OK, I am ignorant about the subtleties of Object Orient Programming, and
C++ in particular ! I sorta get it, but be kind ...

Feedback would be nice, but otherwise I'll articulate actual questions
in a week or so.


The enemy advances, we retreat.
The enemy retreats, we advance.
The enemy stops, we harrass.
The enemy tires, we attack.

Mao Tse-Tung, The Principles of Guerilla Warfare 

Pingus, a code description / narrative v.01

# Getting information

Quite apart from gdb, strace (and perhaps, DRT), a good way to get an idea
of what pingus does when it starts is to use the command line :

./pingus --debug actions 

# Introduction

We categorise pingus operations into several stages :

1. Setting up the screen from the description files. [some coverage]

2. Having the scenario run, involving :

   -generating pingus [some]
   -developing those pingus [some]
   -noting whether they have died or exited, finishing the level [nothing]

3. User interaction

   -cosmetic interaction (action boxes highlighting when the mouse is
    over them; the target pingu highlighting with a box around it) [none]
   -cursor state (being set to one of the left actions) [none]
   -setting a characteristic to a pingu [none]
   -game level operations : pause, exit [none]
   -setting up the buttons and using ClanLib [some]

# Update

Every active object in the background, and every pingu, has a method 
Update(). This is called by the main program for every such object in
order to advance the game.

[needs more detail]

# Setting up the screen

In order to set up a screen, you have the background, the buttons on the
left, the buttons at the bottom (fast, pause, exit) and the pingu generator.

pingus_main.cxx is where the interesting action starts.  The
coordinating routine is PingusMain::start_game () ;

First there is initial setup and registration.  After identifying the
level file to load, pingus instantiates the class :

new StartScreen(PLFResMgr::load_plf_from_filename(levelfile)),

Which sets up the screen with the given "levelfile", an xml description of
that level. (There are also .plf files, pingus level files, which might be
used in 0.6.1)

This load_plf_from_filename provides a pointer to that file, and deals with

The class GUIScreen is a Screen with a GUI manager. StartScreen is an 
object of the GUIScreen type, and an instance is generated by the code

start_screen.cxx contains a description of the StartScreen object, the
corresponding method to the code above [I think] is repeated below :

StartScreen::StartScreen(PLFHandle arg_plf)
  : plf(arg_plf)
  StartScreenComponent* comp = new StartScreenComponent(plf);
  gui_manager->add(new StartScreenOkButton(this));
  gui_manager->add(new StartScreenAbortButton(this));

I'm not sure how the arg_plf relates to plf, or how the "true" in the
call relates to plf(arg_plf) , but note that calls are made to
StartScreenComponent, StartScreenOkButton and StartScreenAbortButton.

StartScreenComponent is a GUI component that represents the background of
the StartScreen; it would seem that this is a string of references from
the setup file which coordinates what finer-detail elements appear on 
the StartScreenComponent.

The relevant StartScreenComponent method appears to be :

StartScreenComponent::StartScreenComponent(PLFHandle p)
  : plf(p)
  background = Sprite("menu/startscreenbg", "core");
  time_str = GameTime::ticks_to_realtime_string(plf->get_time());

But I'm not sure how the PLFHandle (presumably, Pingus Level File Handle)
is dealt with by the code below. Perhaps only when the screen is generated ?


An important part of startup is to load in the worldmap in
worldmap/level_dot.cxx, called from [?] [what does level_dot mean?]

Files in the worldmap and worldobs directory are called as part of the
process of parsing the level description file.

Worldobjs includes active objects, such as a conveyor belt and spike.
Worldmap are the routines which set up the world.

This is part of a later file, 


calls worldmap/manager.cxx 

# Parsing the xml file 

[where this section fits in, and where it is called from, is not known ]

XMLPLF::parse_file() [xml_plf.cxx] coordinates the main parsing of the xml file.
It does things like load up the action bar from the <action-list> segment of
the xml description.

It is itself called by XMLPLF:XMLPLF in the same file, which is itself called
from PLF::create [plf.cxx], and this is called from [?]

# Pingus development and actions

The Class PinguHolder has a list of all pingus, including those dead and
alive.  Code in worldobjs/entrance.cxx, which runs the entrance, calls
Pingu* pingu = world->get_pingus()->create_pingu(data->pos,
data->owner_id); from the routine Entrance::create_pingu () in order to
create pingus.

The method Entrance::create_pingu () is itself called from
Entrance::update () when a pingu is ready.

Each pingu is in one of several states (blocker, walker, climber) etc, which
are contained in the "actions" directory.

When the Update method for a given pingu is called, it calls the Update
method in the corresponding action file.

We consider the Walker case as an example.  A comment for the Walker::Update()
code, contained in actions/walker.cxx, is repeated below :

/* How should this code work?

  1) Check that the Pingu stands still on ground, if not turn it into
  a faller or drown. The reason we do so, is that we catch situations
  where a digger or a similar action removed the ground under the

  2) If pingu is still on ground, we can preprare the next step

  3) Check if up-hill or down-hill is required

In order to perform the above activity, the code checks what is present
one pixel to five pixels below the pingu; if not solid, it calls
pingu->set_action(Actions::Faller); and becomes a faller.

If a step is made, the code calls pingu->set_pos; an example when the x and y
locations are set is : pingu->set_pos(pingu->get_x() + pingu->direction,
pingu->get_y() - possible_y_step);

Each pingu action has a draw method, which draws the particular case of
pingu - walking left, walking right, and also incorporates any additions
to the graphic.

It is clear how a walker turns into a faller; it is not clear how a faller
turns into a floater - there is no reference to Floater in the faller.cxx
code, apart from a graphic add-on.

# User inputs

[The link between these inputs and the way that clicks change states in
the program is not yet known]

In gui/screen_manager.cxx, ScreenManager::display () calls 
input_controller = new Input::Controller(controller_file); in order to
instantiate a controller.

The routine above calls Countroller::Controller (line 48) in

This routine checks through the xml file, and generates buttons based on
its content. Line 69 starts a while loop, which checks each of the cases
and calls PointerFactory, ScrollerFactory or ButtonFactory as appropriate.

But here we concentrate on ButtonFactory; for instance, line 108 creates
an "action-down", presumably an action on a click.

input/button_factory.cxx contains the routine Button* ButtonFactory::create,
called by line 108 of the previous routine. As we're focusing on a mouse
button, we see that line 51 calls mouse_button.

this is line 99 of the same file, Button* ButtonFactory::mouse_button ;
this routine calls MouseButton(button).

This is contained in input/buttons/mouse_button.cxx . We see from line 35
that it attaches CL_Mouse::sig_button_press and CL_Mouse::sig_button_release.

Importantly, this is the connection between Pingus and the ClanLib driver
for the mouse buttons.

It is in the (ClanLib) file Display/Input/X11/mouse_x11.cpp that the routine
make contact with the underlying XWindow.

The general ClanLib operation runs by polling, and it is necessary to call
the ClanLib update method.

This is found in, for example gui/screen_manager.cxx :

      // Let ClanLib fetch events
      CL_System::keep_alive ();

There is a time delay in dealing with events, as the events are only updated
as rapidly as this is called.

For some reason, the graphics updates without any noticeable time delay -
eg ticks appear on the button boxes, or the button boxes are highlighted.

reply via email to

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