X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pages%2Fblog-0009.html-inc;h=2e202e79e222745e30148733ba74569908ecbd32;hb=a05e5d4499fb58198e463162d0385e8a156e1f03;hp=627ed292c15d739d206752e4e6eeea332da27460;hpb=638b5b9759c7dcb4de4c0a88c766e9f9dd650348;p=sdlgit%2FSDL-Site.git diff --git a/pages/blog-0009.html-inc b/pages/blog-0009.html-inc index 627ed29..2e202e7 100644 --- a/pages/blog-0009.html-inc +++ b/pages/blog-0009.html-inc @@ -1,6 +1,81 @@

-Why and How Frozen Bubble is going to CPAN +Providing direct memory access to SDL_Surface's pixels

-
A single drop,
causes the ocean to swell

So 5 weeks ago, SDL Perl was broken. It had been for several years. After the last release SDL Perl works ... somewhat. The quick releases that you have seen have been work-arounds, fixes and refactoring. This is not bad for a few weeks of work but, there is a point where code smell and technical debt is too huge to fix with out redesigning. This is that point.

Since the redesigning will take time and effort it will be good to have a leg up. This leg up is Frozen Bubble 2.20. Frozen Bubble employs a lot of C and Perl hacks to cover up for SDL Perl's lacking. This will help in a sense fast forward the code status to 2008. Since Frozen Bubble is helping us out, we can go one step forward and help it out!

So Alias (Adam Kennedy) and I have started work on making Frozen Bubble CPAN accessible. Frozen Bubble is a well know game and making it cross-platform will bring lots of attention and hopefully contributions to SDL Perl.

In Alias's earlier post about this he mentioned about making a splash and some other stuff. I will talk about how and where we will be accomplishing this task.

First we will be tracking Frozen Bubble on the new SDL Perl Trac website. This site will be similar to Padre's Trac site. As a bonus for people looking to help out in SDL Perl I have separated tasks by perceived difficulty. This will help to breakdown harder task too.

For example for Frozen Bubble the two major bumps we have run into so far are:

Migrating the SDL Perl workarounds: Ticket #3
Making the Build System Portable: Ticket #7

The first one will be difficult as it involves XS. So I will break it down into easier tasks with specific instruction which can then hopefully be picked up by interested contributers. The second one there is sort of a forte of Adam so I will leave it up to him. This is the process I am proposing make hard tickets, break them down.

This will generate a lot of easy tickets that will hopefully be synchronized.  If you are interested in this please give me a shout on #sdl irc.perl.org or the mailing list at sdl-devel@perl.org and I will get you registered.

--yapgh



\ 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