Permalink
Browse files

added SDLx::Layer, no crashes anymore, SDLx::Layer stores surface and…

… rects, and hashref safely
  • Loading branch information...
1 parent a685a30 commit 6cad5e2cb63095f8febd70103e77fcbd5feae225 Tobias Leich committed Jul 30, 2010
Showing with 352 additions and 141 deletions.
  1. +7 −0 Build.PL
  2. +16 −0 lib/SDLx/Layer.pm
  3. +36 −36 lib/SDLx/LayerManager.pm
  4. +8 −0 src/SDLx/Layer.h
  5. +166 −0 src/SDLx/Layer.xs
  6. +58 −68 src/SDLx/LayerManager.xs
  7. +4 −4 src/SDlx/LayerManager.h
  8. +55 −32 t/sdlx_layermanager.t
  9. +2 −1 typemap
View
7 Build.PL
@@ -202,6 +202,13 @@ my %subsystems = (
},
libraries => [qw( SDL )],
},
+ LayerX => {
+ file => {
+ from => 'src/SDLx/Layer.xs',
+ to => 'lib/SDLx/Layer.xs',
+ },
+ libraries => [qw( SDL SDL_image )],
+ },
AudioSpec => {
file => {
from => 'src/Core/objects/AudioSpec.xs',
View
16 lib/SDLx/Layer.pm
@@ -0,0 +1,16 @@
+package SDLx::Layer;
+use strict;
+use warnings;
+use SDL;
+use SDLx::Surface;
+use SDLx::Sprite;
+use SDL::Events;
+
+our @ISA = qw(Exporter DynaLoader);
+
+use SDL::Internal::Loader;
+internal_load_dlls(__PACKAGE__);
+
+bootstrap SDLx::Layer;
+
+1;
View
72 lib/SDLx/LayerManager.pm
@@ -63,42 +63,42 @@ sub set {
# return \@layers;
#}
-sub blit {
- my $self = shift;
- my $dest = shift;
-
- return 0 unless (scalar @attached_layers || $must_redraw);
-
- my $did_redraw = (scalar @attached_layers || $must_redraw);
-
- #print("$must_redraw\n");
- my ( $mask, $x, $y ) = @{ SDL::Events::get_mouse_state() };
-
- #$snapshot->blit_by($dest) if $must_redraw;
-
- if(scalar @attached_layers || $must_redraw) {
- my $layer_index = 0;
- foreach (@layers) {
- $_->{layer}->draw($dest) unless join( ',', @attached_layers ) =~ m/\b\Q$layer_index\E\b/;
- $layer_index++;
- }
- #$snapshot = SDLx::Sprite->new(width => $dest->w, height => $dest->h);
- $snapshot->blit_by($dest);
- #print("2\n");
- }
-
- foreach (@attached_layers) {
- $layers[$_]->{layer}->draw_xy($dest, $x + @{$attached_distance[$_]}[0], $y + @{$attached_distance[$_]}[1]);
- }
-
- #unless (scalar @attached_layers && defined $snapshot) {
- # $snapshot = SDLx::Sprite->new(width => $self->{dest}->w, height => $self->{dest}->h);
- # $snapshot->blit_by($self->{dest});
- #}
-
- $must_redraw = 0;
- return $did_redraw;
-}
+#sub blit {
+# my $self = shift;
+# my $dest = shift;
+#
+# return 0 unless (scalar @attached_layers || $must_redraw);
+#
+# my $did_redraw = (scalar @attached_layers || $must_redraw);
+#
+# #print("$must_redraw\n");
+# my ( $mask, $x, $y ) = @{ SDL::Events::get_mouse_state() };
+#
+# #$snapshot->blit_by($dest) if $must_redraw;
+#
+# if(scalar @attached_layers || $must_redraw) {
+# my $layer_index = 0;
+# foreach (@layers) {
+# $_->{layer}->draw($dest) unless join( ',', @attached_layers ) =~ m/\b\Q$layer_index\E\b/;
+# $layer_index++;
+# }
+# #$snapshot = SDLx::Sprite->new(width => $dest->w, height => $dest->h);
+# $snapshot->blit_by($dest);
+# #print("2\n");
+# }
+#
+# foreach (@attached_layers) {
+# $layers[$_]->{layer}->draw_xy($dest, $x + @{$attached_distance[$_]}[0], $y + @{$attached_distance[$_]}[1]);
+# }
+#
+# #unless (scalar @attached_layers && defined $snapshot) {
+# # $snapshot = SDLx::Sprite->new(width => $self->{dest}->w, height => $self->{dest}->h);
+# # $snapshot->blit_by($self->{dest});
+# #}
+#
+# $must_redraw = 0;
+# return $did_redraw;
+#}
sub attach {
my $self = shift;
View
8 src/SDLx/Layer.h
@@ -0,0 +1,8 @@
+
+typedef struct SDLx_Layer
+{
+ SDL_Surface *surface;
+ SDL_Rect *clip;
+ SDL_Rect *pos;
+ HV *data;
+} SDLx_Layer;
View
166 src/SDLx/Layer.xs
@@ -0,0 +1,166 @@
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include "ppport.h"
+
+#ifndef aTHX_
+#define aTHX_
+#endif
+
+#include <SDL.h>
+#include "SDLx/Layer.h"
+
+PerlInterpreter * perl = NULL;
+
+MODULE = SDLx::Layer PACKAGE = SDLx::Layer PREFIX = layerx_
+
+SDLx_Layer *
+layerx_new( CLASS, surface, ... )
+ char* CLASS
+ SDL_Surface *surface
+ CODE:
+ RETVAL = (SDLx_Layer *)safemalloc( sizeof(SDLx_Layer) );
+ RETVAL->surface = (SDL_Surface *)safemalloc( sizeof(SDL_Surface) );
+ RETVAL->clip = (SDL_Rect *)safemalloc( sizeof(SDL_Rect) );
+ RETVAL->pos = (SDL_Rect *)safemalloc( sizeof(SDL_Rect) );
+ RETVAL->surface = SDL_ConvertSurface(surface, surface->format, surface->flags);
+ RETVAL->data = (HV *)safemalloc( sizeof(HV) );
+ (RETVAL->pos)->x = 0;
+ (RETVAL->pos)->y = 0;
+ (RETVAL->pos)->w = (RETVAL->surface)->w;
+ (RETVAL->pos)->h = (RETVAL->surface)->h;
+ (RETVAL->clip)->x = 0;
+ (RETVAL->clip)->y = 0;
+ (RETVAL->clip)->w = (RETVAL->surface)->w;
+ (RETVAL->clip)->h = (RETVAL->surface)->h;
+
+ if(SvROK(ST(items - 1)) && SVt_PVHV == SvTYPE(SvRV(ST(items - 1))))
+ {
+ RETVAL->data = (HV *)SvRV(ST(items - 1));
+ items--;
+ }
+ else
+ RETVAL->data = (HV *)NULL;
+
+ if(items > 2)
+ (RETVAL->pos)->x = SvIV(ST(2));
+ if(items > 3)
+ (RETVAL->pos)->y = SvIV(ST(3));
+ if(items > 4)
+ (RETVAL->clip)->x = SvIV(ST(4));
+ if(items > 5)
+ (RETVAL->clip)->y = SvIV(ST(5));
+ if(items > 6)
+ (RETVAL->clip)->w = SvIV(ST(6));
+ if(items > 7)
+ (RETVAL->clip)->h = SvIV(ST(7));
+ OUTPUT:
+ RETVAL
+
+int
+layerx_x( layer )
+ SDLx_Layer *layer
+ CODE:
+ RETVAL = (layer->pos)->x;
+ OUTPUT:
+ RETVAL
+
+int
+layerx_y( layer )
+ SDLx_Layer *layer
+ CODE:
+ RETVAL = (layer->pos)->y;
+ OUTPUT:
+ RETVAL
+
+int
+layerx_w( layer )
+ SDLx_Layer *layer
+ CODE:
+ RETVAL = (layer->clip)->w;
+ OUTPUT:
+ RETVAL
+
+int
+layerx_h( layer )
+ SDLx_Layer *layer
+ CODE:
+ RETVAL = (layer->clip)->h;
+ OUTPUT:
+ RETVAL
+
+SV *
+layerx_surface( layer )
+ SDLx_Layer *layer
+ PREINIT:
+ char* CLASS = "SDL::Surface";
+ CODE:
+ SV *rectref = newSV( sizeof(SDL_Surface *) );
+ void *copyRect = safemalloc( sizeof(SDL_Surface) );
+ memcpy( copyRect, layer->surface, sizeof(SDL_Surface) );
+
+ void** pointers = malloc(2 * sizeof(void*));
+ pointers[0] = (void*)copyRect;
+ pointers[1] = (void*)perl;
+
+ RETVAL = newSVsv(sv_setref_pv(rectref, "SDL::Surface", (void *)pointers));
+ OUTPUT:
+ RETVAL
+
+SV *
+layerx_clip( layer )
+ SDLx_Layer *layer
+ PREINIT:
+ char* CLASS = "SDL::Rect";
+ CODE:
+ SV *rectref = newSV( sizeof(SDL_Rect *) );
+ void *copyRect = safemalloc( sizeof(SDL_Rect) );
+ memcpy( copyRect, layer->clip, sizeof(SDL_Rect) );
+
+ void** pointers = malloc(2 * sizeof(void*));
+ pointers[0] = (void*)copyRect;
+ pointers[1] = (void*)perl;
+
+ RETVAL = newSVsv(sv_setref_pv(rectref, "SDL::Rect", (void *)pointers));
+ OUTPUT:
+ RETVAL
+
+SV *
+layerx_pos( layer )
+ SDLx_Layer *layer
+ PREINIT:
+ char* CLASS = "SDL::Rect";
+ CODE:
+ SV *rectref = newSV( sizeof(SDL_Rect *) );
+ void *copyRect = safemalloc( sizeof(SDL_Rect) );
+ memcpy( copyRect, layer->pos, sizeof(SDL_Rect) );
+
+ void** pointers = malloc(2 * sizeof(void*));
+ pointers[0] = (void*)copyRect;
+ pointers[1] = (void*)perl;
+
+ RETVAL = newSVsv(sv_setref_pv(rectref, "SDL::Rect", (void *)pointers));
+ OUTPUT:
+ RETVAL
+
+HV *
+layerx_data( layer )
+ SDLx_Layer *layer
+ CODE:
+ if((HV *)NULL == layer->data)
+ XSRETURN_UNDEF;
+ else
+ RETVAL = layer->data;
+ OUTPUT:
+ RETVAL
+
+void
+layerx_DESTROY( layer )
+ SDLx_Layer *layer
+ CODE:
+ /*safefree(layer->clip);
+ layer->clip = NULL;
+ safefree(layer->pos);
+ layer->pos = NULL;*/
+ safefree(layer);
+ //layer = NULL;
View
126 src/SDLx/LayerManager.xs
@@ -10,47 +10,7 @@
#include <SDL.h>
#include "SDLx/LayerManager.h"
-#define SDLX_MAX_LAYER_SIZE 256
-
-SV *layers[SDLX_MAX_LAYER_SIZE];
-SV *attached_layers[SDLX_MAX_LAYER_SIZE];
-
-Uint8 _length()
-{
- int i = 0;
- while(i < SDLX_MAX_LAYER_SIZE && layers[i] != NULL)
- {
- i++;
- }
-
- return i;
-}
-
-int _call_method(SV *ref, char *method)
-{
- dSP;
- int count;
- int retval = 0;
-
- ENTER;
- SAVETMPS;
-
- PUSHMARK(SP);
- XPUSHs(ref);
- PUTBACK;
-
- count = call_method(method, G_SCALAR);
-
- SPAGAIN;
- if (count == 1)
- retval = POPi;
- PUTBACK;
-
- FREETMPS;
- LEAVE;
-
- return retval;
-}
+PerlInterpreter * perl = NULL;
MODULE = SDLx::LayerManager PACKAGE = SDLx::LayerManager PREFIX = lmx_
@@ -59,52 +19,45 @@ lmx_new( CLASS, ... )
char* CLASS
CODE:
RETVAL = (SDLx_LayerManager *)safemalloc( sizeof(SDLx_LayerManager) );
- RETVAL->layers = newAV();
+ RETVAL->length = 0;
OUTPUT:
RETVAL
void *
-lmx_add( manager, ... )
+lmx_add( manager, layer )
SDLx_LayerManager *manager
+ SDLx_Layer *layer
CODE:
- int i = 1;
- while( i < items )
- {
- av_push(manager->layers, (SV *)newSVsv(ST(i)));
-
- /*printf("is object: %d\n", sv_isobject((SV *)ST(i)));
- printf("is SDLx::Sprite: %d\n", sv_derived_from((SV *)ST(i), "SDLx::Sprite"));
-
- printf("x is %d\n", _call_method((SV *)ST(i), "x"));
-
- PUSHMARK(SP);
- XPUSHs((SV *)ST(i));
- XPUSHs(sv_2mortal(newSViv(7)));
- PUTBACK;
- call_method("x", G_DISCARD);
-
- printf("x is %d\n", _call_method((SV *)ST(i), "x"));*/
-
- i++;
- }
+ manager->layers[manager->length] = layer;
+ manager->length++;
AV *
lmx_layers( manager )
SDLx_LayerManager *manager
CODE:
- RETVAL = manager->layers;
+ XSRETURN_UNDEF;
OUTPUT:
RETVAL
+
SV *
lmx_layer( manager, index )
SDLx_LayerManager *manager
int index
+ PREINIT:
+ char* CLASS = "SDLx::Layer";
CODE:
- if(index <= av_len(manager->layers))
+ if(index >= 0 && index < manager->length)
{
- RETVAL = *av_fetch(manager->layers, index, 0);
- SvREFCNT_inc(RETVAL);
+ SV *rectref = newSV( sizeof(SDLx_Layer *) );
+ void *copyRect = safemalloc( sizeof(SDLx_Layer) );
+ memcpy( copyRect, (manager->layers)[index], sizeof(SDLx_Layer) );
+
+ void** pointers = malloc(2 * sizeof(void*));
+ pointers[0] = (void*)copyRect;
+ pointers[1] = (void*)perl;
+
+ RETVAL = newSVsv(sv_setref_pv(rectref, "SDLx::Layer", (void *)pointers));
}
else
XSRETURN_UNDEF;
@@ -115,11 +68,48 @@ int
lmx_length( manager )
SDLx_LayerManager *manager
CODE:
- RETVAL = av_len(manager->layers) + 1;
+ RETVAL = manager->length;
OUTPUT:
RETVAL
void
+lmx_blit( manager, dest )
+ SDLx_LayerManager *manager
+ SDL_Surface *dest
+ CODE:
+ //int x, y;
+ //SDL_GetMouseState(&x, &y);
+
+ int index = 0;
+ while(index < manager->length)
+ {
+ //SDLx_Layer *layer = *(manager->layers);
+ SDLx_Layer *layer = (manager->layers)[index];
+
+ SDL_BlitSurface(layer->surface, layer->clip, dest, layer->pos);
+ //SDL_UpdateRect(dest, 0, 0, 0, 0);
+
+ index++;
+ }
+
+ /*
+ my ( $mask, $x, $y ) = @{ SDL::Events::get_mouse_state() };
+
+ if(scalar @attached_layers) {
+ my $layer_index = 0;
+ foreach (@layers) {
+ $_->{layer}->draw($dest) unless join( ',', @attached_layers ) =~ m/\b\Q$layer_index\E\b/;
+ $layer_index++;
+ }
+ $snapshot->blit_by($dest);
+ }
+
+ foreach (@attached_layers) {
+ $layers[$_]->{layer}->draw_xy($dest, $x + @{$attached_distance[$_]}[0], $y + @{$attached_distance[$_]}[1]);
+ }
+ */
+
+void
lmx_DESTROY( manager )
SDLx_LayerManager* manager
CODE:
View
8 src/SDlx/LayerManager.h
@@ -1,8 +1,8 @@
+#include "Layer.h"
+
typedef struct SDLx_LayerManager
{
- void *add;
- SV *layer;
- AV *layers;
- //int length;
+ SDLx_Layer *layers[256];
+ int length;
} SDLx_LayerManager;
View
87 t/sdlx_layermanager.t
@@ -4,13 +4,16 @@ use Test::More;
use SDL;
use SDL::Surface;
use SDL::Rect;
+use SDL::Image;
use SDLx::LayerManager;
+use SDLx::Layer;
use SDLx::Surface;
use SDLx::Sprite;
use SDL::PixelFormat;
use SDL::Video;
use lib 't/lib';
use SDL::TestTool;
+use Data::Dumper;
my $videodriver = $ENV{SDL_VIDEODRIVER};
$ENV{SDL_VIDEODRIVER} = 'dummy' unless $ENV{SDL_RELEASE_TESTING};
@@ -20,40 +23,60 @@ if ( !SDL::TestTool->init(SDL_INIT_VIDEO) ) {
}
my $display = SDL::Video::set_video_mode( 800, 600, 32, SDL_SWSURFACE );
+my $surface = SDL::Image::load('test/data/picture.bmp');
+
+############# SDLx::Layer ###########################################################
+
+my $hash = { id => 7 };
+my $layer = SDLx::Layer->new( $surface, 20, 40, 0, 5, 100, 120, $hash );
+my $layer2 = SDLx::Layer->new( $surface, 60, 60 );
+
+isa_ok( $layer, 'SDLx::Layer', 'SDLx::Layer->new');
+is ( $layer->x, 20, 'SDLx::Layer->x' );
+is ( $layer->y, 40, 'SDLx::Layer->y' );
+is ( $layer->w, 100, 'SDLx::Layer->w' );
+is ( $layer->h, 120, 'SDLx::Layer->h' );
+isa_ok( $layer->surface, 'SDL::Surface', 'SDLx::Layer->surface' );
+is ( $layer->surface->w, 180, 'SDLx::Layer->surface->w' );
+is ( $layer->surface->h, 200, 'SDLx::Layer->surface->h' );
+isa_ok( $layer->clip, 'SDL::Rect', 'SDLx::Layer->clip' );
+is ( $layer->clip->x, 0, 'SDLx::Layer->clip->x' );
+is ( $layer->clip->y, 5, 'SDLx::Layer->clip->y' );
+is ( $layer->clip->w, 100, 'SDLx::Layer->clip->w' );
+is ( $layer->clip->h, 120, 'SDLx::Layer->clip->h' );
+isa_ok( $layer->pos, 'SDL::Rect', 'SDLx::Layer->pos' );
+is ( $layer->pos->x, 20, 'SDLx::Layer->pos->x' );
+is ( $layer->pos->y, 40, 'SDLx::Layer->pos->y' );
+is ( $layer->pos->w, 180, 'SDLx::Layer->pos->w' );
+is ( $layer->pos->h, 200, 'SDLx::Layer->pos->h' );
+isa_ok( $layer->data, 'HASH', 'SDLx::Layer->data' );
+is ( $layer2->data, undef, 'SDLx::Layer->data' );
+is ( $layer->data->{id}, 7, 'SDLx::Layer->data->{}' );
+
+
+############ SDLx::LayerManager #####################################################
my $manager = SDLx::LayerManager->new();
+isa_ok( $manager, 'SDLx::LayerManager', 'SDLx::LayerManager->new' );
+is( $manager->length, 0, 'SDLx::LayerManager->length');
+ $manager->add( $layer ); pass( 'SDLx::LayerManager->add' );
+ $manager->add( $layer2 ); pass( 'SDLx::LayerManager->add' );
+is( $manager->length, 2, 'SDLx::LayerManager->length');
+isa_ok( $manager->layer(0), 'SDLx::Layer', 'SDLx::LayerManager->layer' );
+isa_ok( $manager->layer(1), 'SDLx::Layer', 'SDLx::LayerManager->layer' );
+is( $manager->layer(2), undef, 'SDLx::LayerManager->layer' );
+is( $manager->layer(-3), undef, 'SDLx::LayerManager->layer' );
+is( $manager->layer(0)->h, 120, 'SDLx::LayerManager->layer->h' );
+isa_ok( $manager->layer(0)->surface, 'SDL::Surface', 'SDLx::LayerManager->layer->surface' );
+is( $manager->layer(0)->surface->w, 180, 'SDLx::LayerManager->layer->surface->w' );
+
+#isa_ok( $manager->layers, 'ARRAY', '[layers] returns an ARRAY' );
+#is( $manager->layer(0)->x, 10, '[layer(0)->x] is 10' );
+# $manager->layer(0)->x(42); pass( '[layer(0)->x(42)] set to 42' );
+#is( $manager->layer(0)->x, 42, '[layer(0)->x] is 42 now' );
+ $manager->blit($display); pass( '[blit] ran' );
+SDL::Video::update_rect($display, 0, 0, 0, 0);
-isa_ok( $manager, 'SDLx::LayerManager' , '[new] returns SDLx::LayerManager');
-
-is( $manager->length, 0 , '[length] is zero');
-
-my $sprite1 =
- SDLx::Sprite->new( image => 'test/data/picture.bmp', x => 10, y => 20 );
-my $sprite2 =
- SDLx::Sprite->new( image => 'test/data/picture.bmp', x => 60, y => 70 );
-my $sprite3 =
- SDLx::Sprite->new( image => 'test/data/picture.bmp', x => 10, y => 120 );
-
-$manager->add( $sprite1 );
-
-is( $manager->length, 1, '[length] is one');
-
-isa_ok( $manager->layers, 'ARRAY', '[layers] returns an ARRAY' );
-isa_ok( $manager->layer(0), 'SDLx::Sprite', '[layer(0)] gives us the SDLx::Sprite' );
-is( $manager->layer(1), undef, '[layer(1)] returns undef' );
-is( $manager->layer(0)->x, 10, '[layer(0)->x] is 10 by default' );
- $manager->layer(0)->x(42); pass( '[layer(0)->x(42)] set to 42' );
-is( $manager->layer(0)->x, 42, '[layer(0)->x] is 42 now' );
-
-
-
-
-
-
-
-
-#$manager->blit($display);
-#SDL::Video::update_rect( $display, 0, 0, 0, 0 );
#is( $manager->get_layer_by_position( 20, 130 ), 2 );
@@ -65,7 +88,7 @@ is( $manager->layer(0)->x, 42, '[layer(0)->x] is 42 now' );
#my @layers_ahead = $manager->get_layers_ahead_layer(0);
#is_deeply( \@layers_ahead, [ 1, 2 ] );
-sleep(1);
+sleep(2);
if ($videodriver) {
$ENV{SDL_VIDEODRIVER} = $videodriver;
View
3 typemap
@@ -55,7 +55,8 @@ Mix_Music * O_OBJECT
SDL_GLattr T_IV
SDLPango_Context * O_OBJECT
sdlx_timer * O_OBJECT
-SDLx_LayerManager * O_OBJECT
+SDLx_LayerManager * O_OBJECT
+SDLx_Layer * O_OBJECT
SDLPango_Alignment T_UV
int * T_PTR
int ** T_PTR

0 comments on commit 6cad5e2

Please sign in to comment.