pyhexen progress
authorDan Olson <theoddone33@icculus.org>
Fri, 27 Nov 2009 11:40:44 +0000 (03:40 -0800)
committerDan Olson <theoddone33@icculus.org>
Fri, 27 Nov 2009 11:40:44 +0000 (03:40 -0800)
build.py [new file with mode: 0644]
dumpwad.py
pyhexen.py [new file with mode: 0644]
pyhexen/__init__.py
pyhexen/patch.py [deleted file]
pyhexen/vid.py [new file with mode: 0644]
pyhexen/wad.py

diff --git a/build.py b/build.py
new file mode 100644 (file)
index 0000000..aa3049c
--- /dev/null
+++ b/build.py
@@ -0,0 +1,65 @@
+
+import sys
+import os
+import os.path
+
+SDL_SRCS = [ 'sdl/i_sdl.c' ]
+
+GL_SRCS = [
+       'opengl/ogl_clip.c',
+       'opengl/ogl_draw.c',
+       'opengl/ogl_font.c',
+       'opengl/ogl_rend.c',
+       'opengl/ogl_rl.c',
+       'opengl/ogl_sky.c',
+       'opengl/ogl_tex.c',
+       'opengl/m_bams.c'
+       ]
+
+BASE_SRCS = [
+       'base/i_linux.c',
+       'base/oss.c',
+       'base/i_sound.c',
+       'base/am_map.c',
+       'base/ct_chat.c',
+       'base/d_net.c',
+       'base/f_finale.c',
+       'base/g_game.c',
+       'base/d_main.c',
+       'base/info.c',
+       'base/in_lude.c',
+       'base/mn_menu.c',
+       'base/m_misc.c',
+       'base/p_ceilng.c',
+       'base/p_doors.c',
+       'base/p_enemy.c',
+       'base/p_floor.c',
+       'base/p_inter.c',
+       'base/p_lights.c',
+       'base/p_map.c',
+       'base/p_maputl.c',
+       'base/p_mobj.c',
+       'base/p_plats.c',
+       'base/p_pspr.c',
+       'base/p_setup.c',
+       'base/p_sight.c',
+       'base/p_spec.c',
+       'base/p_switch.c',
+       'base/p_telept.c',
+       'base/p_tick.c',
+       'base/p_user.c',
+       'base/r_bsp.c',
+       'base/r_data.c',
+       'base/r_draw.c',
+       'base/r_main.c',
+       'base/r_plane.c',
+       'base/r_segs.c',
+       'base/r_things.c',
+       'base/sb_bar.c',
+       'base/sounds.c',
+       'base/tables.c',
+       'base/v_video.c',
+       'base/w_wad.c',
+       'base/z_zone.c'
+]
+
index bebaa8e..502ad8b 100644 (file)
@@ -9,5 +9,5 @@ myWad.InitMultipleFiles (sys.argv[1:])
 
 print ("Dumping wad contents...")
 
-for (handle, pos, len, name) in myWad.lumps:
-       print ("Found '%s' ('%s' offset %d, length %d)" % (name, handle.name, pos, len))
+for (handle, pos, length, name) in myWad.lumps:
+       print ("Found '%s' ('%s' offset %d, length %d)" % (name, handle.name, pos, length))
diff --git a/pyhexen.py b/pyhexen.py
new file mode 100644 (file)
index 0000000..d35199d
--- /dev/null
@@ -0,0 +1,25 @@
+import sys
+import pyhexen
+import pygame
+from pygame.locals import *
+
+def input(events):
+       for event in events:
+               if event.type == QUIT:
+                       sys.exit(0)
+
+wad = pyhexen.wad.WadReader()
+wad.InitMultipleFiles (['heretic.wad'])
+
+vid = pyhexen.vid.Video()
+vid.Init()
+
+vid.SetPalette (wad.CacheLumpName('PLAYPAL'))
+vid.DrawRawScreen (wad.CacheLumpName('TITLE'))
+vid.DrawPatch (4, 160, wad.CacheLumpName('ADVISOR'))
+
+vid.WaitVBL ()
+
+while True:
+       input (pygame.event.get())
+
index e69de29..ee8aa56 100644 (file)
@@ -0,0 +1,2 @@
+import pyhexen.wad
+import pyhexen.vid
diff --git a/pyhexen/patch.py b/pyhexen/patch.py
deleted file mode 100644 (file)
index 70a4230..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-
-from struct import *
-
-class PatchDesc:
-       patch_t = '<hhhh8i'
-       patch_t_size = calcsize (patch_t)
diff --git a/pyhexen/vid.py b/pyhexen/vid.py
new file mode 100644 (file)
index 0000000..6023a98
--- /dev/null
@@ -0,0 +1,74 @@
+import pygame
+import struct
+import string
+
+class VidException(Exception):
+       pass
+       
+class Video:
+       def __init__(self):
+               self.palette = []
+               
+       # 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]]
+                       self.palette.append(rgb)
+               self.screen.set_palette(self.palette)
+               
+       def WaitVBL (self):
+               pygame.display.flip()
+               
+       # 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])
+               
+       def __blitPatch(self, data, x, y, trans = lambda x: x):
+               (width, height) = struct.unpack_from ('<hh', data, 0)
+               (left_offset, top_offset) = struct.unpack_from('<hh', data, 4)
+               column_offsets =  struct.unpack_from('<8i', data, 8)
+               
+               # Adjust pos
+               x = x - left_offset
+               y = y - top_offset
+
+               # Crazy column/patch thing to buffer
+               screen = pygame.surfarray.pixels2d (self.screen)
+               for x_ofs in range (0, width):
+                       col_ofs = struct.unpack_from ('<i', data, 8 + 4 * x_ofs)[0]
+                       topdelta = ord (data[col_ofs + 0])
+                       # Step through the posts in a column
+                       while topdelta != 255:
+                               length = ord (data[col_ofs + 1])
+                               source_ofs = col_ofs + 3
+                               for y_ofs in range (0, length):
+                                       screen[x + x_ofs, topdelta + y_ofs] = trans(ord (data[source_ofs + y_ofs]))
+                               col_ofs = col_ofs + length + 4
+                               topdelta = ord (data[col_ofs + 0])
+                               
+       def Init(self):
+               pygame.init()
+               self.window = pygame.display.set_mode ((320,200), 0, 8)
+               pygame.display.set_caption('PyHexen')
+               self.screen = pygame.display.get_surface()
+               
+       def DrawRawScreen(self, lump):
+               # Horribly inefficent for now.
+               self.__blitRaw (lump, 320, 200)
+                               
+       def DrawPatch(self, x, y, lump):
+               # Horribly inefficent for now.
+               self.__blitPatch (lump, x, y)
+                               
+       def DrawFuzzPatch(self, x, y, lump):
+               # Stub
+               self.DrawPatch(x,y,lump)
+               
+       def DrawShadowedPatch(self,x,y,lump):
+               # Stub
+               self.DrawPatch(x,y,lump)
+               
\ No newline at end of file
index 55bde1e..517d141 100644 (file)
@@ -15,6 +15,7 @@ class WadDesc:
 class WadReader:
        def __init__(self):
                self.lumps = []
+               self.lumpcache = []
 
        def __del__(self):
                for (handle, pos, size, name) in self.lumps:
@@ -22,8 +23,12 @@ class WadReader:
                                handle.close()
 
        def AddFile(self, filename):
+               "Add a single file to the wad database"
                (base, ext) = os.path.splitext (filename)
-               fileHandle = open (filename, 'rb')
+               try:
+                       fileHandle = open (filename, 'rb')
+               except IOError:
+                       raise WadException ("Could not open '%s'" % filename)
 
                lumpinfo = []
                if ext.lower() == '.wad':
@@ -45,18 +50,23 @@ class WadReader:
                # Dump the info into our table of accumulated crap.
                for (pos, length, name) in lumpinfo:
                        self.lumps.append ((fileHandle, pos, length, name.rstrip('\x00')))
+                       self.lumpcache.append ((False, ''))
 
        def InitMultipleFiles (self, filenames):
+               "Add multiple files to the wad database"
                for f in filenames:
                        self.AddFile (f)
 
        def InitFile (self, filename):
+               "Add a single file to the wad database"
                self.AddFile (f)
 
        def NumLumps (self):
+               "Return the number of lumps in the wad database"
                return len (self.lumps)
 
        def CheckNumForName (self, name):
+               "Check if a specific lump name exists in the wad database, returning its index or -1 if it was not found"
                searchName = name.upper()[:8]
                for (x, y) in enumerate (reversed(self.lumps)):
                        (handle, pos, length, name) = y
@@ -65,23 +75,38 @@ class WadReader:
                return -1
 
        def GetNumForName (self, name):
+               "Get the lump index of a specific lump name, or throw an exception if it was not found"
                index = self.CheckNumForName (name)
                if index == -1:
                        raise WadException ("%s not found!" % name)
                return index
 
        def LumpLength (self, lump):
+               "Return the size of a specific lump index"
+               if lump < 0 or lump > len(self.lumps):
+                       raise WadException ('Invalid lump number %d requested' % lump)
                (handle, pos, length, name) = self.lumps[lump]
                return length
 
        def ReadLump (self, lump):
+               "Return the data associated with a specific lump index"
+               if lump < 0 or lump > len(self.lumps):
+                       raise WadException ('Invalid lump number %d requested' % lump)
                (handle, pos, length, name) = self.lumps[lump]
                handle.seek (pos)
                return handle.read (length)
 
-       def CacheLumpNum (self, lump, tag):
-               pass
-
-       def CacheLumpName (self, name, tag):
+       def CacheLumpNum (self, lump, tag=None):
+               "Cache and return the data associated with a specific lump index"
+               if lump < 0 or lump > len(self.lumps):
+                       raise WadException ('Invalid lump number %d requested' % lump)
+               (cached, data) = self.lumpcache[lump]
+               if not cached:
+                       data = self.ReadLump (lump)
+                       self.lumpcache[lump] = (True, data)
+               return data
+
+       def CacheLumpName (self, name, tag=None):
+               "Cache and return the data associated with a specific lump name"
                return self.CacheLumpNum (self.GetNumForName (name), tag)