X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pages%2Fblog-0006.html-inc;h=2e202e79e222745e30148733ba74569908ecbd32;hb=c8ad4fe9f211e727310a1ce6d23ffb1d7822d71f;hp=bc1ede2a2121a8f61406c42ed94777a82e4b5b94;hpb=cf23a5dab86667dca8475ee830e684c9944f115f;p=sdlgit%2FSDL-Site.git diff --git a/pages/blog-0006.html-inc b/pages/blog-0006.html-inc index bc1ede2..2e202e7 100644 --- a/pages/blog-0006.html-inc +++ b/pages/blog-0006.html-inc @@ -1,6 +1,81 @@

-Migrating Sol's Tutorial of SDL to SDL_Perl +Providing direct memory access to SDL_Surface's pixels

-
If I have seen further it is only by standing on the shoulders of giants. --Newton



Sol's Tutorials


When I was struggling with SDL C a while ago, someone recommended Sol's Tutorial to me. It had not only help me understand video in SDL, but I believe my code has improved using Sol's code style. I would like to pass these along to fellow SDL_Perl users too. So here is the Ch 02 code of Sol's Tutorial in SDL_Perl. It will be getting more and more Perly as our team hacks on it. There is more to come!


To use this code you need the new Redesigned SDL_Perl Library


Getting SDL Dependencies


Only If you are on Linux (debian/ubuntu) you need the following dependencies:

$ sudo apt-get install libsdl-net1.2-dev libsdl-mixer1.2-dev libsmpeg-dev libsdl1.2-dev libsdl-image1.2-dev libsdl-ttf2.0-dev 

On Windows we recommend using Strawberry Perl. It comes with SDL-1.2.13 header files and libs included.

Both Windows and Linux needs to install Alien::SDL

$ cpan Alien::SDL
** Add sudo to this for Linux

Getting Bleeding SDL


The bleeding SDL is on github. Click download on this site .

Extract it and cd into the folder run
$ cpan . 
** The dot is needed
** in Linux you may need to do sudo

Then you can run this script by doing

$ perl examples/sols/ch02.pl 
\ No newline at end of file +

In an attempt to make pixel access easier on SDL_Surface pixels. I have started work on SDLx::Surface. So far I have only start on the 32 bpp surfaces.


+

The general idea is to make Pointer Values (PV) of each pixel in the surface and place them into a 2D matrix. First I make pointer values like this:


+
SV * get_pixel32 (SDL_Surface *surface, int x, int y)
+{
+ //Convert the pixels to 32 bit 
+ Uint32 *pixels = (Uint32 *)surface->pixels; 
+
+ //Get the requested pixel  
+ Uint32* u_ptr =  pixels + ( y * surface->w ) + x ; 
+
+        SV* sv = newSVpv("a",1); //Make a temp SV* value on the go
+        SvCUR_set(sv, sizeof(Uint32)); //Specify the new CUR length
+ SvLEN_set(sv, sizeof(Uint32)); //Specify the LEN length
+        SvPV_set(sv,(char*)u_ptr); // set the actual pixel's pointer as the memory space to use
+
+ return sv; //make a modifiable reference using u_ptr's place as the memory :)
+
+}
+

+

Next I loop through all the pixels and put them in a 2D array format, shown below:

AV * construct_p_matrix ( SDL_Surface *surface )
+{
+    AV * matrix = newAV();
+     int i, j;
+     for(  i =0 ; i < surface->w; i++)
+      {
+        AV * matrix_row = newAV();
+        for( j =0 ; j < surface->h; j++)
+        {
+           av_push(matrix_row, get_pixel32(surface, i,j) );
+        }
+        av_push(matrix, newRV_noinc((SV*) matrix_row) );
+      }
+
+ return matrix;
+}
+

+

You can see the complete here.


+

In Perl I can do a get access on this pixel using:


+
+
my $surf32_matrix = SDLx::Surface::pixel_array($screen_surface);
+   print unpack 'b*', $surf32_matrix->[0][0]; # pixel value at x = 0 and y =0
+#OUTPUT:
+# 11111111000000000000000000000000
+

+

The structure of the PV is using Devel::Peek is :


+
print Dump $surf32_matrix->[0][0];
+#OUTPUT:
+#SV = PV(0xed0dbc) at 0xeb5344
+#  REFCNT = 1
+#  FLAGS = (POK,pPOK)
+#  PV = 0x9e04ac "\0\0\377\0"
+#  CUR = 4
+#  LEN = 4
+

+

The problem is in setting the value of this pointer value. I have tried the following things with no success:


+
if ( SDL::Video::MUSTLOCK($screen_surface) ) {
+    return if ( SDL::Video::lock_surface($screen_surface) < 0 ); #required for pixel operations
+}
+
+#USING pack
+
+my $green = pack 'b*', '11111111000000000000000000000000';
+substr( $surf32_matrix->[0][0], 0, 8 * 4, $green); #no change
+#substr( $surf32_matrix->[0][0], 0, 8 * 4, 0xFF000000); segfault
+substr( ${$surf32_matrix->[0][0]}, 0, 8 * 4, 0xFF000000); #no change
+#$surf32_matrix->[0][0] = $green; SEGFAULT's cannot write to memory
+${$surf32_matrix->[0][0]} = $green; #no change
+
+
+SDL::Video::unlock_surface($screen_surface)
+  if ( SDL::Video::MUSTLOCK($screen_surface) );
+

+

You can see an example here.


+

Any help will be greatly appreciated.

+


+

\ No newline at end of file