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

-Updates and Design Decisions +Providing direct memory access to SDL_Surface's pixels

-

Storm clouds loom,
Thunder cracks,
Lightning blinds,
Farmers rejoice.

Some quick updates:
After someone bugged me to update the Ohloh site for SDL perl, I finally got around to doing it.


Some good news:
v2.2.2.11 seems to be doing a good job considering it has been started to be picked up Debian, Mandriva and other packager maintainers. The stats are currently at [PASS(11) FAIL(6) NA(1) UNKNOWN(35)].

Some OK news:
As you can see we have some fails occurring in the smoke tests. This is occurring due to the test on Mixer.pm. Mixer.pm depends on a sound card being available to the user running the test. This can be fixed by adjusting the test to check for sound cards before it runs but I am at a lost on how to do that.
In regards to the unknowns occurring it is due to the *nixes and macs not having SDL libs installed. The will be fixed when Alien::SDL downloads and compiles sources.

Some not-so-great news:
Currently the XS code simplification work requires redesign and there are several different ways of redesigning. This may break backwards compatibility, hopefully we can work around this. Soon we will present the two arguments for the designs in the mailing list.


Until next time here is  a hint of something coming soon (credits go to garu):


--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