Optimized blit functions.
authorDan Olson <theoddone33@icculus.org>
Sun, 3 Jan 2010 05:08:19 +0000 (21:08 -0800)
committerDan Olson <theoddone33@icculus.org>
Sun, 3 Jan 2010 05:08:19 +0000 (21:08 -0800)
pyhexen/vid.py

index 63ebcae..6204f2c 100644 (file)
@@ -1,6 +1,7 @@
 import pygame
 import struct
 import wad
+import numpy
 
 class VidException(Exception):
        pass
@@ -9,13 +10,13 @@ class Video:
        def __init__(self, wad):
                self.palette = []
                self.wad = wad
-               self.tinttab = self.wad.CacheLumpName ('TINTTAB')
+               self.tinttab = map(ord, self.wad.CacheLumpName ('TINTTAB'))
                
        # Stuff from I_* in the C code.
        def SetPalette(self, data):
                self.palette = []
                for i in range (0, 768, 3):
-                       rgb = [ord(x) for x in data[i:i+3]]
+                       rgb = map (ord, data[i:i+3])
                        self.palette.append(rgb)
                self.screen.set_palette(self.palette)
                
@@ -25,32 +26,46 @@ class Video:
        # Stuff from V_* in the C code.
        def __blitRaw (self, data, w, h):
                screen = pygame.surfarray.pixels2d (self.screen)
-               for y in range(0, h):
-                       for x in range (0, w):
-                               screen[x,y] = ord (data[y * w + x])
+               img = map (ord, data)
+               for y in xrange(h):
+                       start = y * w
+                       end = start + w
+                       screen[0:w,y] = img[start:end]
                
-       def __blitPatch(self, data, x, y, trans = lambda a, b: a):
+       def __blitPatch(self, data, x, y, trans = None):
                (width, height) = struct.unpack_from ('<hh', data, 0)
                (left_offset, top_offset) = struct.unpack_from('<hh', data, 4)
                
+               # Transform data into a usable form, seeing as it came from a file.
+               img = map (ord, data)
+               
                # Adjust pos
                x = x - left_offset
                y = y - top_offset
 
-               # Crazy column/patch thing to buffer
+               # Blit the patch to the screen per-column
                screen = pygame.surfarray.pixels2d (self.screen)
-               for x_ofs in range (0, width):
+
+               blit = lambda s0,s1,x0,y0,y1: img[s0:s1]
+               
+               if trans != None:
+                       blit = lambda s0,s1,x0,y0,y1: map(trans, img[s0:s1], screen[x0,y0:y1])
+               
+               for x_ofs in xrange (width):
                        col_ofs = struct.unpack_from ('<i', data, 8 + 4 * x_ofs)[0]
-                       topdelta = ord (data[col_ofs + 0])
+                       dst_x = x + x_ofs
                        # Step through the posts in a column
-                       while topdelta != 255:
-                               length = ord (data[col_ofs + 1])
-                               source_ofs = col_ofs + 3
-                               topdelta = topdelta + y
-                               for y_ofs in range (0, length):
-                                       screen[x + x_ofs, topdelta + y_ofs] = trans(ord (data[source_ofs + y_ofs]),screen[x + x_ofs, topdelta + y_ofs])
-                               col_ofs = col_ofs + length + 4
-                               topdelta = ord (data[col_ofs + 0])
+                       while True:
+                               topdelta = img[col_ofs + 0]
+                               if topdelta == 255:
+                                       break
+                               length = img[col_ofs + 1]
+                               s0 = col_ofs + 3
+                               s1 = s0 + length
+                               y0 = topdelta + y
+                               y1 = y0 + length
+                               screen[dst_x,y0:y1] = blit(s0,s1,dst_x,y0,y1)
+                               col_ofs += length + 4
                                
        def Init(self):
                pygame.init()
@@ -65,11 +80,11 @@ class Video:
                self.__blitPatch (lump, x, y)
                                
        def DrawFuzzPatch(self, x, y, lump):
-               transparent = lambda a, b: ord (self.tinttab[a + b * 256])
+               transparent = lambda a, b: self.tinttab[a + b * 256]
                self.__blitPatch (lump, x, y, transparent)
                
        def DrawShadowedPatch(self, x, y, lump):
-               shadow = lambda a,b: ord (self.tinttab[b * 256])
+               shadow = lambda a,b: self.tinttab[b * 256]
                self.__blitPatch (lump, x + 2, y + 2, shadow)
                self.__blitPatch (lump, x, y)
                
\ No newline at end of file