NAME

SDL::App::FPS - a parent class for FPS (framerate centric) applications

SYNOPSIS

Subclass SDL::App::FPS and override some methods:

	package SDL::App::MyFPS;
	use Exporter;
	use strict;
	use SDL::App::FPS;

	use vars qw/@ISA/;
	@ISA = qw/SDL::App::FPS/;

        # override the method draw_frame with something to draw
	sub draw_frame
          {
	  my ($self,$current_time,$lastframe_time,$current_fps) = @_;
          }

        # override the event handler to handle events interesting to you
	sub handle_event
	  {
	  my ($self,$event} = shift;
 
	  }

Then write a small script using SDL::App::MyFPS like this:

#!/usr/bin/perl -w

use strict;
use SDL::App::MyFPS;

# fill in here options or use Getopt::Long for command line
my $options = { };

my $app = SDL::App::MyFPS->new( $options );
$app->main_loop();

That's all!

DESCRIPTION

This package provides you with a base class to write your own SDL Perl applications.

SUBCLASSING

It is a good idea to store additional data under $self-{name_of_subclass}>, this way it does not interfere with changes in the base class.

Do not access the data in the baseclass directly, always use the accessor methods!

METHODS

The following methods should be overridden to make a usefull application:

draw_frame()

Responsible for drawing the current frame. It's first two parameters, the time (in ticks) at the start of the current frame, and the time at the start of the last frame. These times are warped according to time_warp(), see there for an explanation on how this works.

The third parameter is the current framerate, averaged. You can use this to reduce dynamically the complexity of the scene to achieve a faster FPS if it falls below a certain threshold.

handle_event()

Responsible for handling a single event. Gets one parameter, $event, the SDL::Event object. Check the event type with $event->type() and then take the appropriate action.

Should return 1 to quit the application (if necc.), and 0 to keep it running.

The following methods can be overriden if so desired:

pre_init_handler()

Called by new() just before the creating the SDL application and window.

post_init_handler()

Called by new() just after the creating the SDL application and window.

quit_handler()

Called by main_loop() just before the application is exiting.

The following methods need not be overriden except in very special cases:

new()
$app = SDL::App::FSL->new($options);

Create a new application, init the SDL subsystem, create a window, starts the frame rate monitoring and the application time-warped clock.

Get's a hash ref with options, the following options are supported:

	width     the width of the application window in pixel
	height    the width of the application window in pixel
	depth     the depth of the screen (colorspace) in bits
	max_fps   maximum number of FPS to do (save CPU cycles)
	cap_fps   use a better model to cap the FPS to the desired
		  rate (default), set to 0 to disable - but you don't want
                  to do this - trust me)

Please note that to the resulution of the timer the maximum achivable FPS with capping is about 200 FPS even with an empty draw routine. Of course, my machine could do about 50000 FPS; but then it hogs 100% of the CPU. Thus the framerate capping might not be accurate and cap the rate at a much lower rate than you want. However, only max_fps > 100 is affected, anything below 100 works usually as intended.

new() calls pre_init_handler() before creating the SDL application, and post_init_handler() afterwards. So you can override thess two for your own desires.

quit()

Set a flag to quit the application at the end of the current frame. Can be called in draw_frame(), for instance.

pause()
$app->pause();
$app->pause(SDL_KEYDOWN);

Pauses the application until the next event occurs. Given an optional event type (like SDL_KEYDOWN), it will wait until this event happens. All other events will be ignored, with the exception of SDL_QUIT.

fullscreen()

Toggle the application's fullscreen status.

width()
my $w = $self->width();

Return the current width of the applications surface.

height()
my $w = $self->height();

Return the current height of the applications surface.

update()
$self->update($rect);

Call the SDL::App's update method.

app()
my $sdl_app = $self->app();

Return a pointer to the SDL application object. Usefull for calling it's methods.

main_loop()
$app->main_loop();

The main loop of the application, only returns when an SDL_QUIT event occured, or the user event handler (see handle_event) returned true.

handle_events()

Checks for events and hands all of them to event_handler for user handling. The only event it handles directly is SDL_QUIT. Returns 0 for keeping the application running, and > 0 for quit.

create_window

Initialized the SDL subsysten and creates the window.

option()
print $app->option('max_fps'),"\n";	# get
$app->option('max_fps',40);		# set to 40

Get/sets an option defined by the key (name) and an optional value.

freeze_time_warp_ramp()
$app->freeze_time_warp_ramp();

Disables any ramping of the time warp that might be in effect.

freeze_time()
$app->freeze_time();

Sets the time warp factor to 0, effectively stopping the warped clock. Note that the real clock still ticks and frames are still drawn, so you can overlay some menu/animation over a static (froozen in time) background. Of course it might be more efficient to save the current drawn frame as image and stop the drawing if the not-changing background altogether.

thaw_time()
$app->thaw_time();

Sets the time warp factor back to what it was before freeze_time() was called. Does nothing when the clock is not frozen.

ramp_time_warp
$app->ramp_time_warp($target_factor,$time_to_ramp);

Set a tagret time warp factor and a time it will take to get to this factor. The time warp (see time_warp()) will then be gradually adjusted to the target factor. $time_to_ramp is in ms (aka 1000 == one second).

It is sometimes a good idea to read out the current time warp and ramp it to a specific factor, like so:

$time_warp = $app->time_warp();
$app->ramp_time_warp($time_warp * 2, 1000);

But you need to restrict this somehow, otherwise the clock might be speed up or slowed down to insanely high or low speeds. So sometimes it is just better to do this:

sub enable_slow_motion
  {
  # no matter how fast clock now is, slow it down to a fixed value
  $app->ramp_time_warp(0.5, 1000);
  }

When ramp_time_warp() is called without arguments, and ramping is in effect, it returns a list consisting of:

target factor		# to where we ramp
time to ramp		# how long it takes (ticks)
current time warp	# where are currently
start time warp		# from where we ramp (factor)
start time warp time	# from where we ramp (real time ticks)

When no ramping is in effect, it returns an empty list or undef.

You can disable/stop the time warping by setting a new time warp factor directly like so:

my $t = $app->time_warp(); $app->time_warp($t);

Or easier:

$app->freeze_time_warp();
time_warp
$app->time_warp(2);		# fast forward

Get or set the current time warp, e.g. the factor how fast the time passes. The new time warp will be effective from the next frame onwards.

Please note that setting a time warp factor will disable time warp ramping.

time_is_ramping
if ($app->time_is_ramping())
  {
  }

Returns true if the time warp factor is currently beeing ramped, e.g. chaning.

time_is_frozen
if ($app->time_is_frozen())
  {
  }

Return true if the time is currently frozen, e.g. the clock is standing still.

frames()

Return number of frames drawn since start of app.

start_time()

Return the time when the application started in ticks.

current_fps()

Return current number of frames per second, averaged over the last 1000ms.

max_fps()

Return maximum number of frames per second we ever achieved.

min_fps()

Return minimum number of frames per second we ever achieved.

now()

Return current time at the start of the frame in ticks, unwarped. See current_time for a warped version. This is usefull for tracking the real time clock as opposed to the warped application clock.

current_time()

Return current time at the start of this frame (the same as it is passed to draw_frame(). This time will be warped by time_warp, e.g a time_warp of 2 makes it go twice as fast as GetTicks(). Note that the returned value will only change at the start of each frame.

lastframe_time()

Return time at the start of the last frame. See current_time(). The same value is passed to draw_frame().

next_frame

Updates the FPS monitoring process, the frame counter, the average frame rate, and then calls draw_frame().

AUTHORS

(c) Tels <http://bloodgate.com/>

SEE ALSO

SDL::App and SDL.