-
Notifications
You must be signed in to change notification settings - Fork 24
/
manual.html
268 lines (239 loc) · 10.6 KB
/
manual.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
<html>
<style>
.tocindent { margin-left: 20px; }
</style>
<body>
<h1>Omgifol manual</h1>
<p><em>Note: this is ridiculously incomplete.</em>
</p>
<table border="0" id="toc"><tr id="toctitle"><td align="center">
<b>Table of contents</b> <script type="text/javascript">showTocToggle("show","hide")</script></td></tr><tr id="tocinside"><td>
<div class="tocline"><a href="#Installation">1 Installation</a><br /></div>
<div class="tocline"><a href="#Using_Omgifol">2 Using Omgifol</a><br /></div>
<div class="tocline"><a href="#WAD_objects">3 WAD objects</a><br /></div>
<div class="tocindent">
<a href="#Loading_from_WAD_files">3.1 Loading from WAD files</a><br />
<a href="#Writing_to_WAD_files">3.2 Writing to WAD files</a><br />
<a href="#Accessing_lumps">3.3 Accessing lumps</a><br />
<div class="tocindent">
<a href="#Lump_groups">3.3.1 Lump groups</a><br />
</div>
<a href="#Merging">3.4 Merging</a><br />
</div>
<div class="tocline"><a href="#Lumps">4 Lumps</a><br /></div>
<div class="tocindent">
<a href="#Graphic_lumps">4.1 Graphic lumps</a><br />
</div>
<div class="tocline"><a href="#Editors">5 Editors</a><br /></div>
<div class="tocindent">
<a href="#Map_editor">5.1 Map editor</a><br />
<a href="#UDMF_map_editor">5.2 UDMF map editor</a><br />
</div>
</td></tr></table>
<a name="Installation"></a><h2>Installation</h2>
<ol><li> Install Python 3, which can be downloaded from <a href="https://python.org" title="https://python.org">https://python.org</a>
</li><li> Use pip to install Omgifol: <tt>pip install omgifol</tt>
</li><li> Or, if pip is unavailable, extract the "omg" directory in the Omgifol package into <em>pythondir</em>/Lib/site-packages (replace <em>pythondir</em> with the directory where Python is installed).
</li></ol>
<p>Optionally:
</p>
<ol><li> Install the <a href="https://python-pillow.github.io" class="external" title="https://python-pillow.github.io">Pillow library</a><span class="urlexpansion"> (<i>https://python-pillow.github.io</i>)</span>. This is required to import or export images.
</li>
<li> Install the <a href="https://pysoundfile.readthedocs.io" class="external" title="https://pysoundfile.readthedocs.io">PySoundFile library</a><span class="urlexpansion"> (<i>https://pysoundfile.readthedocs.io</i>)</span>. This is required to import or export sound files.
</li>
</ol>
<a name="Using_Omgifol"></a><h2>Using Omgifol</h2>
<p>At the beginning of an interactive session, or as the first line in a Python script file, enter
</p>
<pre> from omg import *
</pre>
<a name="WAD_objects"></a><h2>WAD objects</h2>
<p>A <tt>WAD</tt> is an abstract representation of a WAD file. A <tt>WAD</tt> object can load content from a WAD file, or save content to a WAD file, but is entirely memory-resident.
</p>
<a name="Loading_from_WAD_files"></a><h3>Loading from WAD files</h3>
<p>The following are all equivalent:
</p>
<pre> 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)
</pre>
<p>You can load more than one file to the same object:
</p>
<pre> a = WAD()
a.from_file(file1)
a.from_file(file2)
a.from_file(file3)
</pre>
<p>In this case, lumps from <em>file2</em> will overwrite those from <em>file1</em>
with the same name, etc.
</p>
<a name="Writing_to_WAD_files"></a><h3>Writing to WAD files</h3>
<p>If <em>a</em> is a <tt>WAD</tt> instance:
</p>
<pre> a.to_file('some_wad.wad')
</pre>
<a name="Accessing_lumps"></a><h3>Accessing lumps</h3>
<p>Lumps are stored in <em>groups</em>. Each <tt>WAD</tt> holds a number of groups, representing different categories of lumps. Each group is an ordered dictionary; that is, it works just like a Python <tt>collections.OrderedDict</tt> object.
</p><p>All lumps are instances of the <tt>Lump</tt> class; see below for its documentation.
</p><p>To retrieve the sprite called <tt>CYBR1A</tt> from the <tt>WAD</tt> object <em>a</em>, do:
</p>
<pre> a.sprites['CYBR1A']
</pre>
<p>And to replace it with some other lump object called <tt>some_lump</tt>:
</p>
<pre> a.sprites['CYBR1A'] = some_lump
</pre>
<p>To add a new lump, simply do as above with a lump name that does not yet exist.
</p><p>Renaming and deleting is done as follows:
</p>
<pre> a.sprites.rename('CYBR1A', 'NEW_NAME')
del a.sprites['CYBR1A']
</pre>
<a name="Lump_groups"></a><h4>Lump groups</h4>
<p>By default, WADs recognize the following lump groups:
</p>
<pre> 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
udmfmaps Map data (UDMF)
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
</pre>
<p>This scheme can be modified if desired; refer to wad.py for the details.
</p><p>The <tt>maps</tt> and <tt>glmaps</tt> are special. These do not contain lumps, but additional groups of lumps, one for each map. So if you access E1M1:
</p>
<pre> a.maps['E1M1']
</pre>
<p>you will retrieve a group of lumps containing all the map's data. To retrieve
the individual lumps, do:
</p>
<pre> a.maps['E1M1']['SIDEDEFS']
</pre>
<p>etc.
</p>
<a name="Merging"></a><h3>Merging</h3>
<p>To merge two <tt>WAD</tt>s <em>a</em> and <em>b</em>:
</p>
<pre> c = a + b
</pre>
<p>Note that (for efficiency reasons) this only copies references to lumps,
which means that subsequent changes to lumps in <em>a</em> or <em>b</em> will affect the
corresponding lumps in <em>c</em>. To give <em>c</em> its own set of lumps, do:
</p>
<pre> c = (a + b).copy()
</pre>
<p>When lumps in <em>a</em> and <em>b</em> have the same name,
lumps from <em>b</em> will replace those from <em>a</em>.
</p><p>It is also possible to merge individual sections:
</p>
<pre> a.sprites += b.sprites
</pre>
<p>Use with care for sections of different types.
</p><p>Note that some sections do more than just copy over the list of lumps
when they merge. For example, adding two <em>txdefs</em> sections together
will automagically merge the <tt>TEXTURE1</tt>, <tt>TEXTURE2</tt> and <tt>PNAMES</tt> lumps. <tt>txdefs</tt>
also get merged this way when two <tt>WAD</tt> objects are merged on the top level.
</p>
<a name="Lumps"></a><h2>Lumps</h2>
<p>The <tt>Lump</tt> class holds a single lump. The class provides the following data and methods:
</p>
<pre> .data The lump's raw data as a string
.to_file(<em>filename</em>) Save from a file
.from_file(<em>filename</em>) Load from a file
.copy() Return a copy
</pre>
<p>Creating a new lump called 'FOOF' containing the text 'Hello!' and inserting it into a <tt>WAD</tt> <em>w</em> would be done as follows:
</p>
<pre> w.data['FOOF'] = Lump('Hello!')
</pre>
<a name="Graphic_lumps"></a><h3>Graphic lumps</h3>
<p>There are subclasses of <tt>Lump</tt> for different types of lumps. Currently, only these provide special functionality: <tt>Graphic</tt>, <tt>Flat</tt>, and <tt>Sound</tt>.
</p><p><tt>Graphic</tt>, used to represent Doom format graphics, provides the following settable attributes:
</p>
<pre> .offsets (x, y) offsets
.x_offset x offset
.y_offset y offset
.dimensions (width, height)
.width width in pixels
.height height in pixels
</pre>
<p><tt>Graphic</tt> defines the following methods in adddition to those defined by <tt>Lump</tt>:
</p>
<pre> .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
</pre>
<p>For the argument lists used by these functions, refer to the code and the inline documentation in lump.py.
</p><p><tt>Flat</tt> works similarly to <tt>Graphic</tt>, but handles format conversions slightly differently.
</p><p><tt>Sound</tt>, used to represent Doom format sounds, provides the following settable attributes:
</p>
<pre> .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)
</pre>
<p><tt>Sound</tt> defines the following methods in adddition to those defined by <tt>Lump</tt>:
</p>
<pre> .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
</pre>
</p>
<a name="Editors"></a><h2>Editors</h2>
<p><em>Editors</em> 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:
</p>
<ul><li> <tt>Colormap</tt> for the COLORMAP lump
</li><li> <tt>Playpal</tt> for the PLAYPAL lump
</li><li> <tt>Textures</tt> for TEXTURE1/TEXTURE2/PNAMES
</li><li> <tt>MapEditor</tt> for maps
</li><li> <tt>UMapEditor</tt> for maps in UDMF format
</li></ul>
<p>All editors provide the following methods:
</p>
<pre> .to_lump
.from_lump
</pre>
<p>or, if the editor represents more than one lump:
</p>
<pre> .to_lumps
.from_lumps
</pre>
<p>In the latter case, the editor is initialized with a lump group instead of a single lump.
</p>
<a name="Map_editor"></a><h3>Map editor</h3>
<p>Example (moving one vertex one unit):
</p>
<pre> m = MapEditor(wad.maps["E1M1"])
m.vertexes[103].x += 1
wad.maps["E1M1"] = m.to_lumps()
</pre>
<a name="UDMF_map_editor"></a><h3>UDMF map editor</h3>
<p><tt>UMapEditor</tt> works similarly to <tt>MapEditor</tt>, except the attributes of map data are named based on how they appear in the <tt>TEXTMAP</tt> lump itself. See the <a href="https://www.doomworld.com/eternity/engine/stuff/udmf11.txt">UDMF specification</a> for examples.
</p>
<p><tt>UMapEditor</tt> can also import non-UDMF maps, and line specials will automatically be translated to their UDMF equivalents when necessary:
</p>
<pre> # Load and automatically convert a Doom-format map
m = UMapEditor(wad.maps["E1M1"])
# Load a UDMF-format map
m = UMapEditor(wad.udmfmaps["MAP01"])
</pre>
<p>Refer to the source code for more information.</p>
</body>
</html>