pax_global_header 0000666 0000000 0000000 00000000064 13243701254 0014513 g ustar 00root root 0000000 0000000 52 comment=ae7300dfc6edba52eb45fe74d4d07fc6e325c5bf omgifol-0.4.0/ 0000775 0000000 0000000 00000000000 13243701254 0013150 5 ustar 00root root 0000000 0000000 omgifol-0.4.0/.gitignore 0000664 0000000 0000000 00000000050 13243701254 0015133 0 ustar 00root root 0000000 0000000 *.pyc __pycache__ build dist *.egg-info omgifol-0.4.0/CHANGES 0000664 0000000 0000000 00000002646 13243701254 0014153 0 ustar 00root root 0000000 0000000 0.4.0 (2018/02/22) add support for importing/exporting/editing sound effect lumps add 'Thing' and 'Linedef' members to MapEditor class (aliases to the thing and linedef classes used by the current map format) add support for data stored inside map header lumps (e.g. FraggleScript) add ability for WAD and WadIO classes to use empty space in WAD file, if possible ('use_free' argument in relevant methods) enforce maximum size for patch lumps remove some old chr() calls for Python 3 users fix previously broken WAD.load method fix palette index 0 in patches becoming transparent when exporting fix some lumps falsely being loaded as maps (e.g. aaliens.wad "LOADACS", which was followed by a "SCRIPTS" lump and thus detected as a map) 0.3.0 (2017/10/06) add support for Python 3.x (experimental; 3.5.0 or higher recommended) add support for Hexen / ZDoom maps add better map loading (supports names other than ExMx and MAPxx, doesn't mistake MAPINFO for an actual map) add better support for "limit removing" maps add tall patch support add support for importing/exporting RGBA images (converted to the WAD's 256-color palette on import, but can contain true transparency) add better handling of missing map data add draw_sector and misc. helper functions to MapEditor [jmickle66666666] add ability to individually change single flags (by name) with MapEditor fix a colormap generation bug and add Colormap.set_position [jmickle66666666] omgifol-0.4.0/LICENSE 0000664 0000000 0000000 00000002044 13243701254 0014155 0 ustar 00root root 0000000 0000000 Copyright (c) 2005 Fredrik Johansson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. omgifol-0.4.0/demo/ 0000775 0000000 0000000 00000000000 13243701254 0014074 5 ustar 00root root 0000000 0000000 omgifol-0.4.0/demo/drawmaps.py 0000664 0000000 0000000 00000004364 13243701254 0016273 0 ustar 00root root 0000000 0000000 from __future__ import print_function from omg import * import sys from PIL import Image, ImageDraw def drawmap(wad, name, filename, width, format): xsize = width - 8 edit = MapEditor(wad.maps[name]) xmin = ymin = 32767 xmax = ymax = -32768 for v in edit.vertexes: xmin = min(xmin, v.x) xmax = max(xmax, v.x) ymin = min(ymin, -v.y) ymax = max(ymax, -v.y) scale = xsize / float(xmax - xmin) xmax = int(xmax * scale) xmin = int(xmin * scale) ymax = int(ymax * scale) ymin = int(ymin * scale) for v in edit.vertexes: v.x = v.x * scale v.y = -v.y * scale im = Image.new('RGB', ((xmax - xmin) + 8, (ymax - ymin) + 8), (255,255,255)) draw = ImageDraw.Draw(im) edit.linedefs.sort(key=lambda a: not a.two_sided) for line in edit.linedefs: p1x = edit.vertexes[line.vx_a].x - xmin + 4 p1y = edit.vertexes[line.vx_a].y - ymin + 4 p2x = edit.vertexes[line.vx_b].x - xmin + 4 p2y = edit.vertexes[line.vx_b].y - ymin + 4 color = (0, 0, 0) if line.two_sided: color = (144, 144, 144) if line.action: color = (220, 130, 50) draw.line((p1x, p1y, p2x, p2y), fill=color) draw.line((p1x+1, p1y, p2x+1, p2y), fill=color) draw.line((p1x-1, p1y, p2x-1, p2y), fill=color) draw.line((p1x, p1y+1, p2x, p2y+1), fill=color) draw.line((p1x, p1y-1, p2x, p2y-1), fill=color) del draw im.save(filename, format) #import psyco #psyco.full() if (len(sys.argv) < 5): print("\n Omgifol script: draw maps to image files\n") print(" Usage:") print(" drawmaps.py source.wad pattern width format\n") print(" Draw all maps whose names match the given pattern (eg E?M4 or MAP*)") print(" to image files of a given format (PNG, BMP, etc). width specifies the") print(" desired width of the output images.") else: print("Loading %s..." % sys.argv[1]) inwad = WAD() inwad.from_file(sys.argv[1]) width = int(sys.argv[3]) format = sys.argv[4].upper() for name in inwad.maps.find(sys.argv[2]): print("Drawing %s" % name) drawmap(inwad, name, name + "_map" + "." + format.lower(), width, format) omgifol-0.4.0/demo/merge.py 0000664 0000000 0000000 00000001002 13243701254 0015536 0 ustar 00root root 0000000 0000000 from __future__ import print_function import omg, sys if (len(sys.argv) < 3): print("\n Omgifol script: merge WADs\n") print(" Usage:") print(" merge.py input1.wad input2.wad ... [-o output.wad]\n") print(" Default output is merged.wad") else: w = omg.WAD() for a in sys.argv[1:]: if a == "-o": break print("Adding %s..." % a) w += omg.WAD(a) outpath = "merged.wad" if "-o" in sys.argv: outpath = sys.argv[-1] w.to_file(outpath) omgifol-0.4.0/demo/mirror.py 0000664 0000000 0000000 00000002313 13243701254 0015757 0 ustar 00root root 0000000 0000000 from __future__ import print_function from sys import argv from omg import * from omg.mapedit import * def mirror(map): ed = MapEditor(map) for v in ed.vertexes: v.x = -v.x for l in ed.linedefs: l.vx_a, l.vx_b = l.vx_b, l.vx_a for t in ed.things: t.x = -t.x t.angle = (180 - t.angle) % 360 ed.nodes = [] return ed.to_lumps() def main(args): if (len(args) < 2): print(" Omgifol script: mirror maps\n") print(" Usage:") print(" mirror.py input.wad output.wad [pattern]\n") print(" Mirror all maps or those whose name match the given pattern") print(" (eg E?M4 or MAP*).") print(" Note: nodes will have to be rebuilt externally.\n") else: print("Loading %s..." % args[0]) inwad = WAD() outwad = WAD() inwad.from_file(args[0]) pattern = "*" if (len(args) == 3): pattern = args[2] for name in inwad.maps.find(pattern): print("Mirroring %s" % name) outwad.maps[name] = mirror(inwad.maps[name]) print("Saving %s..." % args[1]) outwad.to_file(args[1]) if __name__ == "__main__": main(argv[1:]) omgifol-0.4.0/manual.html 0000664 0000000 0000000 00000024357 13243701254 0015326 0 ustar 00root root 0000000 0000000
Note: this is ridiculously incomplete.
Table of contents |
Optionally:
At the beginning of an interactive session, or as the first line in a Python script file, enter
from omg import *
A WAD is an abstract representation of a WAD file. A WAD object can load content from a WAD file, or save content to a WAD file, but is entirely memory-resident.
The following are all equivalent:
a = WAD('wadfile.wad') a = WAD(from_file='wadfile.wad') f = open('wadfile.wad', 'rb') a = WAD(from_file=f) a = WAD() a.from_file('wadfile.wad') f = open('wadfile.wad', 'rb') a = WAD() a.from_file(f)
You can load more than one file to the same object:
a = WAD() a.from_file(file1) a.from_file(file2) a.from_file(file3)
In this case, lumps from file2 will overwrite those from file1 with the same name, etc.
If a is a WAD instance:
a.to_file('some_wad.wad')
Lumps are stored in groups. Each WAD holds a number of groups, representing different categories of lumps. Each group is an ordered dictionary; that is, it works just like a Python dict (http://docs.python.org/tut/node7.html#SECTION007500000000000000000) object but remembers in which order lumps were inserted.
All lumps are instances of the Lump class; see below for its documentation.
To retrieve the sprite called CYBR1A from the WAD object a, do:
a.sprites['CYBR1A']
And to replace it with some other lump object called some_lump:
a.sprites['CYBR1A'] = some_lump
To add a new lump, simply do as above with a lump name that does not yet exist.
Renaming and deleting is done as follows:
a.sprites.rename('CYBR1A', 'NEW_NAME') del a.sprites['CYBR1A']
By default, WADs recognize the following lump groups:
sprites Sprite graphics (between S and SS markers) patches Wall graphics (between P and PP markers) flats Flat graphics (between F and FF markers) colormaps Boom colormaps (between C markers) ztextures ZDoom textures (between TX markers) maps Map data glmaps GL nodes map data music Music (all lumps named D_*) sounds Sound effects (all lumps named DS* or DP*) txdefs TEXTURE1, TEXTURE2 and PNAMES graphics Titlepic, status bar, miscellaneous graphics data Everything else
This scheme can be modified if desired; refer to wad.py for the details.
The maps and glmaps are special. These do not contain lumps, but additional groups of lumps, one for each map. So if you access E1M1:
a.maps['E1M1']
you will retrieve a group of lumps containing all the map's data. To retrieve the individual lumps, do:
a.maps['E1M1']['SIDEDEFS']
etc.
To merge two WADs a and b:
c = a + b
Note that (for efficiency reasons) this only copies references to lumps, which means that subsequent changes to lumps in a or b will affect the corresponding lumps in c. To give c its own set of lumps, do:
c = (a + b).copy()
When lumps in a and b have the same name, lumps from b will replace those from a.
It is also possible to merge individual sections:
a.sprites += b.sprites
Use with care for sections of different types.
Note that some sections do more than just copy over the list of lumps when they merge. For example, adding two txdefs sections together will automagically merge the TEXTURE1, TEXTURE2 and PNAMES lumps. txdefs also get merged this way when two WAD objects are merged on the top level.
The Lump class holds a single lump. The class provides the following data and methods:
.data The lump's raw data as a string .to_file(filename) Save from a file .from_file(filename) Load from a file .copy() Return a copy
Creating a new lump called 'FOOF' containing the text 'Hello!' and inserting it into a WAD w would be done as follows:
w.data['FOOF'] = Lump('Hello!')
There are subclasses of Lump for different types of lumps. Currently, only these provide special functionality: Graphic, Flat, and Sound.
Graphic, used to represent Doom format graphics, provides the following settable attributes:
.offsets (x, y) offsets .x_offset x offset .y_offset y offset .dimensions (width, height) .width width in pixels .height height in pixels
Graphic defines the following methods in adddition to those defined by Lump:
.from_raw Load from a raw image .to_raw Return the image converted to raw pixels .from_Image Load from a PIL Image instance .to_Image Return the image converted to a PIL image .translate Translate to another palette
For the argument lists used by these functions, refer to the code and the inline documenation in lump.py.
Flat works similarly to Graphic, but handles format conversions slightly differently.
Sound, used to represent Doom format sounds, provides the following settable attributes:
.format Sound effect format (0-3) .length Length of sound in samples .sample_rate Sample rate for digitized sounds (defaults to 11025) .midi_bank MIDI patch bank number (formats 1-2 only) .midi_patch MIDI patch number (formats 1-2 only)
Graphic defines the following methods in adddition to those defined by Lump:
.from_raw Load from a raw sound file .to_raw Return the sound file converted to raw samples .from_file Load from a sound file .to_file Save the sound to a file
Editors are used to edit lumps or lump groups. They represent lump data with high-level objects and structures, and provide methods to modify the data. The following editors have been implemented so far:
All editors provide the following methods:
.to_lump .from_lump
or, if the editor represents more than one lump:
.to_lumps .from_lumps
In the latter case, the editor is initialized with a lump group instead of a single lump.
Example (moving one vertex one unit):
m = MapEditor(wad.maps["E1M1"]) m.vertexes[103].x += 1 wad.maps["E1M1"] = m.to_lumps()
Refer to the source code for more information.