]> icculus.org git repositories - theoddone33/hheretic.git/blob - pyhexen/vid.py
Optimized blit functions.
[theoddone33/hheretic.git] / pyhexen / vid.py
1 import pygame
2 import struct
3 import wad
4 import numpy
5
6 class VidException(Exception):
7         pass
8         
9 class Video:
10         def __init__(self, wad):
11                 self.palette = []
12                 self.wad = wad
13                 self.tinttab = map(ord, self.wad.CacheLumpName ('TINTTAB'))
14                 
15         # Stuff from I_* in the C code.
16         def SetPalette(self, data):
17                 self.palette = []
18                 for i in range (0, 768, 3):
19                         rgb = map (ord, data[i:i+3])
20                         self.palette.append(rgb)
21                 self.screen.set_palette(self.palette)
22                 
23         def WaitVBL (self):
24                 pygame.display.flip()
25                 
26         # Stuff from V_* in the C code.
27         def __blitRaw (self, data, w, h):
28                 screen = pygame.surfarray.pixels2d (self.screen)
29                 img = map (ord, data)
30                 for y in xrange(h):
31                         start = y * w
32                         end = start + w
33                         screen[0:w,y] = img[start:end]
34                 
35         def __blitPatch(self, data, x, y, trans = None):
36                 (width, height) = struct.unpack_from ('<hh', data, 0)
37                 (left_offset, top_offset) = struct.unpack_from('<hh', data, 4)
38                 
39                 # Transform data into a usable form, seeing as it came from a file.
40                 img = map (ord, data)
41                 
42                 # Adjust pos
43                 x = x - left_offset
44                 y = y - top_offset
45
46                 # Blit the patch to the screen per-column
47                 screen = pygame.surfarray.pixels2d (self.screen)
48
49                 blit = lambda s0,s1,x0,y0,y1: img[s0:s1]
50                 
51                 if trans != None:
52                         blit = lambda s0,s1,x0,y0,y1: map(trans, img[s0:s1], screen[x0,y0:y1])
53                 
54                 for x_ofs in xrange (width):
55                         col_ofs = struct.unpack_from ('<i', data, 8 + 4 * x_ofs)[0]
56                         dst_x = x + x_ofs
57                         # Step through the posts in a column
58                         while True:
59                                 topdelta = img[col_ofs + 0]
60                                 if topdelta == 255:
61                                         break
62                                 length = img[col_ofs + 1]
63                                 s0 = col_ofs + 3
64                                 s1 = s0 + length
65                                 y0 = topdelta + y
66                                 y1 = y0 + length
67                                 screen[dst_x,y0:y1] = blit(s0,s1,dst_x,y0,y1)
68                                 col_ofs += length + 4
69                                 
70         def Init(self):
71                 pygame.init()
72                 self.window = pygame.display.set_mode ((320,200), 0, 8)
73                 pygame.display.set_caption('PyHexen')
74                 self.screen = pygame.display.get_surface()
75                 
76         def DrawRawScreen(self, lump):
77                 self.__blitRaw (lump, 320, 200)
78                                 
79         def DrawPatch(self, x, y, lump):
80                 self.__blitPatch (lump, x, y)
81                                 
82         def DrawFuzzPatch(self, x, y, lump):
83                 transparent = lambda a, b: self.tinttab[a + b * 256]
84                 self.__blitPatch (lump, x, y, transparent)
85                 
86         def DrawShadowedPatch(self, x, y, lump):
87                 shadow = lambda a,b: self.tinttab[b * 256]
88                 self.__blitPatch (lump, x + 2, y + 2, shadow)
89                 self.__blitPatch (lump, x, y)
90