Skip to content

Commit

Permalink
1st commit
Browse files Browse the repository at this point in the history
  • Loading branch information
eilara committed Feb 25, 2012
0 parents commit 1b414d4
Show file tree
Hide file tree
Showing 61 changed files with 9,195 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Betweener.xs
@@ -0,0 +1,12 @@

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"

MODULE = SDLx::Betweener PACKAGE = SDLx::Betweener

INCLUDE: src/xs/Timeline.xs
INCLUDE: src/xs/Tween.xs

MODULE = SDLx::Betweener PACKAGE = SDLx::Betweener
5 changes: 5 additions & 0 deletions Changes
@@ -0,0 +1,5 @@
Revision history for Perl extension SDLx-Betweener.

0.01 Tue Feb 7 20:16:58 2012
- original version

40 changes: 40 additions & 0 deletions Makefile.PL
@@ -0,0 +1,40 @@

use strict;
use ExtUtils::MakeMaker;
use Alien::SDL;


my $lib = 'betweener';
my $test = 'betweener_unit_tests';
my $cpp_path = 'src/cpp';
my $lib_ar = "$cpp_path/lib$lib\$(LIB_EXT)";
my $cc = 'g++';

WriteMakefile(
NAME => 'SDLx::Betweener',
VERSION_FROM => 'lib/SDLx/Betweener.pm',
PREREQ_PM => {
'Alien::SDL' => '1.430',
'SDL' => '2.536',
'Moose' => '2.0402',
},
CC => $cc,
LD => '$(CC)',
($] >= 5.005 ?
(ABSTRACT => 'SDL Perl XS Tweening Library',
AUTHOR => 'eilara <ran.eilam@gmail.com>') : ()),
LIBS => Alien::SDL->config('libs', '-lm'),
DEFINE => '', # e.g., '-DHAVE_SOMETHING'
INC => Alien::SDL->config('cflags'). ' -I. -Isrc/cpp -Isrc/cpp_xs',
OBJECT => '$(O_FILES)',
'MYEXTLIB' => $lib_ar,
# clean => {'FILES' => ''},
);


sub MY::postamble {
'
$(MYEXTLIB): src/Makefile
cd src && $(MAKE) $(PASSTHRU)
';
}
43 changes: 43 additions & 0 deletions README
@@ -0,0 +1,43 @@
SDLx::Betweener version 0.01
============================

Will replace SDLx-Tween because it is better.

STATUS

Alpha: only simplest tween and starfield work.

TODO

* start/stop actions on tween with destroyed timelines crash, should
give error message
* float setters should check and convert value if int by accident
* direct setter value can be upgraded to string and you will never
see any tween updates, peek and warn if SV nature changes?
* add set_duration
* template specialization on proxies not method overloading

INSTALLATION

To install this module type the following:

perl Makefile.PL
make
make test
make install

DEPENDENCIES

This module requires these other modules and libraries:

SDL

COPYRIGHT AND LICENCE

Copyright (C) 2012 by Ran Eilam

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.10.1 or,
at your option, any later version of Perl 5 you may have available.


45 changes: 45 additions & 0 deletions eg/01-circle.pl
@@ -0,0 +1,45 @@
#!/usr/bin/perl

package SDLx::Betweener::eg_01::Circle;
use Moose;
has radius => (is => 'rw', default => 0);

package main;
use strict;
use warnings;
use FindBin qw($Bin);
use lib ("$Bin/..", "$Bin/../lib", "$Bin/../blib/arch", "$Bin/../blib/lib");
use SDL;
use SDLx::App;
use SDLx::Betweener;

my $circle = SDLx::Betweener::eg_01::Circle->new;

my $app = SDLx::App->new(
title => 'Circle With Tweened Radius',
width => 640,
height => 480,
eoq => 1,
);

my $tweener = SDLx::Betweener->new(app => $app);

my $tween = $tweener->tween_int(
t => 3_000,
to => 200,
on => {radius => $circle},
ease => 'p4_in_out',
bounce => 1,
forever => 1,
);

$app->add_show_handler(sub {
$app->draw_rect(undef, 0x000000FF);
$app->draw_circle_filled([320, 200], $circle->radius, 0x3300DDFF);
$app->draw_circle([320, 200], $circle->radius, 0xDD3311FF);
$app->update;
});

$tween->start;
$app->run;

63 changes: 63 additions & 0 deletions eg/02-starfield.pl
@@ -0,0 +1,63 @@
#!/usr/bin/perl

package main;
use strict;
use warnings;
use FindBin qw($Bin);
use lib ("$Bin/..", "$Bin/../lib", "$Bin/../blib/arch", "$Bin/../blib/lib");
use Math::Trig;
use SDL::GFX::Primitives;
use SDLx::App;
use SDLx::Betweener;

my $STAR_COUNT = 20000;

my $app = SDLx::App->new(
title => 'Starfield',
width => 640,
height => 480,
eoq => 1,
);

my $tweener = SDLx::Betweener->new(app => $app);

my ($first_star, $prev_star, @tweens);

my $i; while($i++ < $STAR_COUNT) {
my $theta = rand(2 * pi);
my $to = [cos($theta)*640 + 320, sin($theta)*480 + 240];
my $star = [[320,200], undef, undef];
my $tween = $tweener->tween_path(
t => (int(rand 8_000) + 1000),
to => $to,
on => $star->[0],
ease => 'exponential_in',
forever => 1,
);
$star->[1] = $tween;

if ($first_star) { $prev_star->[2] = $star }
else { $first_star = $star }

$prev_star = $star;
push @tweens, $tween;
}

my $show_handler = sub {
my $star = $first_star;
$app->draw_rect(undef, 0x000000FF);
my ($x, $y);
while ($star) {
($x, $y) = @{$star->[0]};
SDL::GFX::Primitives::pixel_color($app, $x, $y, 0xFFFFFFFF);
$star = $star->[2];
}
$app->update;
};

$app->add_show_handler($show_handler);

$_->start for @tweens;

$app->run;

149 changes: 149 additions & 0 deletions lib/SDLx/Betweener.pm
@@ -0,0 +1,149 @@
package SDLx::Betweener;

use 5.010001;
use strict;
use warnings;
use SDL;
use SDLx::Betweener::Timeline;

our $VERSION = '0.01';

require XSLoader;
XSLoader::load('SDLx::Betweener', $VERSION);

use constant { TWEEN_INT => 0, TWEEN_FLOAT => 1, TWEEN_PATH => 2 };
my @Tween_Lookup = qw(_tween_int _tween_float _tween_path);

use constant { DIRECT_PROXY => 1, CALLBACK_PROXY => 2, METHOD_PROXY => 3 };
my %Proxy_Lookup = do { my $i = 1; map { $_ => $i++ } qw(ARRAY CODE HASH)};

use constant { LINEAR_PATH => 0, CIRCULAR_PATH => 1 };
my %Path_Lookup = do { my $i = 0; map { $_ => $i++ } qw(
linear circular
)};

my @Ease_Names = qw(
linear
p2_in p2_out p2_in_out
p3_in p3_out p3_in_out
p4_in p4_out p4_in_out
p5_in p5_out p5_in_out
sine_in sine_out sine_in_out
circular_in circular_out circular_in_out
exponential_in exponential_out exponential_in_out
elastic_in elastic_out elastic_in_out
back_in back_out back_in_out
bounce_in bounce_out bounce_in_out
);
my %Ease_Lookup = do { my $i = 0; map { $_ => $i++ } @Ease_Names };
sub Ease_Names { @Ease_Names }

sub new {
my ($class, %args) = @_;
my $timeline = SDLx::Betweener::Timeline->new;
my $move_handler = sub { $timeline->tick(SDL::get_ticks) };
$args{app}->add_move_handler($move_handler) if $args{app};
return bless {
timeline => $timeline,
move_handler => $move_handler,
%args,
}, $class;
}

sub DESTROY {
my $self = shift;
$self->{app}->remove_move_handler($self->{move_handler})
if $self->{app};
}

sub tick {
my ($self, $now) = @_;
$now = SDL::get_ticks unless defined $now;
$self->{timeline}->tick($now);
}

sub tween_int {
my ($self, %args) = @_;
return $self->tween(TWEEN_INT, %args);
}

sub tween_float {
my ($self, %args) = @_;
return $self->tween(TWEEN_FLOAT, %args);
}

sub tween_path {
my ($self, %args) = @_;
return $self->tween(TWEEN_PATH, %args);
}

sub tween {
my ($self, $type, %args) = @_;
my $builder = $Tween_Lookup[$type];
my $on = $args{on} || die 'No "on" given';
my $on_type = ref($on) || die '"on" must be ref';
$on = [$on] if $on_type eq 'SCALAR'; # normalize for direct proxy
my $t = $args{t} || die 'No "t" for duration given';
my $proxy = $Proxy_Lookup{ref $on} || die "unknown proxy type: $on";
my $ease = $Ease_Lookup{$args{ease} || 'linear'};

# these 2 only used for 1d tweens
my ($from, $to);

# these 2 only used for TWEEN_PATH type
my $path = $args{path}? $Path_Lookup{$args{path}->[0] || die 'no path type'}
: LINEAR_PATH;
my $path_args;

# these tweens need from/to syntax sugar
if (($type == TWEEN_INT || $type == TWEEN_FLOAT) ||
($type == TWEEN_PATH && $path == LINEAR_PATH)) {

# try to get 'from/to' from range
($args{from}, $args{to}) = @{ $args{range} } if $args{range};
# must have "to" by now
$to = $args{to};
die 'No "to" defined' unless defined $to;
$from = $args{from};

if (defined $from) {
$on = $on->[0] if
$proxy == DIRECT_PROXY && @$on == 1;
} else {
# if we have no 'from' lets try to get it from the proxy
if ($proxy == DIRECT_PROXY) {
if (@$on == 1) {
$on = $on->[0];
$from = $$on;
} else {
$from = $on;
}
} elsif ($proxy == METHOD_PROXY) {
my $method = [keys %$on]->[0];
$from = [values %$on]->[0]->$method;
} elsif ($proxy == CALLBACK_PROXY)
{ die 'No "from" given for callback proxy' }
}

$path_args = {from=>$from, to=>$to} if $type == TWEEN_PATH;

} else { # then we are building a non linear path tween
$path_args = $args{path}->[1];
}

$on = [%$on] if $proxy == METHOD_PROXY;

return $self->{timeline}->$builder(
$proxy,
$on,
$t,
($type == TWEEN_PATH? ($path, $path_args): ($from, $to)),
$ease,
$args{forever} || 0,
$args{repeat} || 1,
$args{bounce} || 0,
$args{reverse} || 0,
);
}

1;
8 changes: 8 additions & 0 deletions lib/SDLx/Betweener/Timeline.pm
@@ -0,0 +1,8 @@
package SDLx::Betweener::Timeline;

use strict;
use warnings;

use SDLx::Betweener;

1;
10 changes: 10 additions & 0 deletions lib/SDLx/Betweener/Tween.pm
@@ -0,0 +1,10 @@
package SDLx::Betweener::Tween;

use strict;
use warnings;
use SDL;

use SDLx::Betweener;

1;

0 comments on commit 1b414d4

Please sign in to comment.