(Ñ) by Vladimir Kladov, 2004
Starting from version 2.4, EmuZWin supports 256 color games. This idea was first implemented in DOS-based Spectrum emulator, the Sp256. You can get it and first 12 games made for playing in 256 colors mode by this link: http://www.emulatronia.com/emusdaqui/spec256/download-eng.htm .
And to allow you to convert more games to 256 colors mode, an embedded power GFX-editor added into the EmuzWin, and this short instruction is how to use it to do this work. Hope, this will help.
How it works
Before start converting your lovely Speccy game to 256 colors mode,
you should know a bit how this is implemented at all.
As this is said on the site of original Sp256 emulator: this is done
implementing so-named parallel GFX_Z80 processor, and parallel GFX_Memory, having for each
data/registry bit of the original Spectrum machine a correspondent data byte. This allows
to have 256 separate colors for each screen pixel, rather then 16 ones, and only 2 of 16
colors for each character placement 8x8 pixels.
While the main Z80 machine is emulated, the GFX machine executes
correspondent operations but in its own addresses, and with its own data, where 8 bytes of
GFX machine corresponds to each 8 bits of each byte in normal Z80 machine. The main
difference of 256 colors mode is following: you see not the Spectrum video buffer but
video buffer of the parallel GFX-Spectrum.
For the first view this seems not too hard to find parts of images
drawn on screen (sprites) and to add desired colors to it, and voila - the game become 256
colors! No needs to patch the game itself, hack it (not trivial task for
non-professional), have problems with license (just do not publish game snapshot, provide
only GFX-memory image e.g.). But some things are important:
And, you should have some experience with simple computer graphic design applications (The MS Paintbrush is enough, though knowledge of the Adobe Photoshop or other similar graphic editor is better). Also, you should understand Spectrum memory model (at least such things as ROM bank, RAM bank, hexadecimal digits, memory address, XOR operation and other should not terror your brain :) ). And, be ready to use the Debugger (also embedded in the EmuZWin emulator): sometimes it is necessary to understand which data are drawn in the videobuffer and how those data are transofrmed, too. Though in most cases patching the original game is not requered (and is not welcome).
Step 1.
First, provide a snapshot of the game you want to convert in some general snapshot format (SNA, Z80 are good idea), in some initial state. Tape (e.g. TAP or TZX) image is not good idea: while tape is loaded, GFX data are overriden and disappear. It is much better to get such ready to use snapshot from the World of Spectrum site or from other good known place on the Web. But if you can not, just load tape and then game is ready, save a snapshot.
Step 2.
Now, pause the game (though this is not must) and in the EmuZWin
main menu call Effects|256 Colors. This turns game into 256 Colors mode,
and the display screen becomes (usually) totally black :).
This does not matter. In 256 Colors mode, not the original Spectrum video buffer is shown
but the screen of parallel GFX machine one. You will see something in this mode only when
you provide something to be shown, adding some color information changing GFX memory
content.
Later, while converting game to 256 Colors and while playing, it is
always safe to switch between 256 Colors mode and usual 16 Colors: once game were switched
to 256 Colors mode, it is always emulated by special 256-emulation code, so GFX data
always are actual as the game were always running in 256 Colors.
Step 3.
Now, Tools|GFX Editor and two additional panels, GFX
Memory and GFX Registers in the Debugger are
available (to turn these two, in the Debugger right click on disassembly panel to pop up a
menu, and check appropriate items there).
The first recommended operation is to expand usual Spectrum memory to
GFX memory by a rule: bit 0 in usual memory to byte 00 in GFX Memory (black color in
standard GFX Palette), and bit 1 - to byte FF (while color mixed with foreground
attribute, by default). To do this, use white paper toolbar icon in the GFX Editor (button
Clear GFX Memory).
Then, use the GFX Editor to find out where in memory sprites are
located. Use AutoWidth mode (turned on by default) and resize it by width to match sprites
visually. Certainly, be sure that you find the initial stable location of the sprite, not
an intermediate buffer of screen area there it could be moved. Try overdraw some pixels of
a sprite, run game and ensure that you go right way. Do not paint over mask which could
look very like to a sprite itself (but in most cases, contains less details though).
To convert a game to 256 Colors you should locate all the sprites and
add color information to all of them. Test game playing it as far as possible (use cheat
pokes, slow game to 50% speed, time 2 seconds back to overpass hard parts of a game, test
with no cheats too as well as possible etc.). While designing graphics, you may decide to
modify palette used, change some GFX emulation options, add backgrounds etc. I very hope
that GFX Editor is power enough to allow for you doing all what you want, and at least you
can copy selection to another graphic editor to do what you imagine but GFX Editor can not
do, and then paste modified graphics back to GFX memory.
Common rules.
You can save 256 Colors game as a usual snapshot (e.g. SNA or Z80) and in such case all necessary additional files are saved too. These are:
Final steps.
Before finishing the game you may be want to add some backgrounds
there. Background file in raw format has 64000 bytes length and actually is a rectangle
320x200 bytes, where each byte is an index in the palette. Only a (centered) rectangle
256x192 pixels is used, and top 4 and bottom 4 lines, as well as left 32 and right 32
columns are not used. Leave pixels which should never be drawn from the background image,
equal to 00. And even if a background pixel is not 00, it is overriden by any actual GFX
data from the GFX video buffer.
An utility bmp2rawbk256.exe provided in this archive. Use it to convert
bitmap to a background file.
If you provide a single background which is used for all the time while
playing the game, just name it game.B00. If you provide several background images for some
different cases or/and want for a certain background toappear only on some conditions
satisfied, add so named "background probe conditions" to the configuration (game.CFG,
you also can edit it directly from the GFX Editor). See format of CFG-file to get know how
to do this.
And, one more special effect is possible. You can provide several
palettes (game.Pnn), each for a correspondent background. And when a
background is applied, a correspondent palette too, so you can take an effect e.g. when
each room in the game has its own lightning and colors, and increase total amount of
colors used in the game, above a value 256.
.CFG - 256 Colors configuration explained.
Configuration strings (default values are shown):
GFXLeveledXOR=0
GFXLeveledOR=0
GFXLeveledAND=0
GFXScreenXORBuffered=0
UpColorsMixed=64
DownColorsMixed=0
UpMixChgBright=0
DownMixChgBright=0
UseBrightInMix=0
UpMixPaper=0
DownMixPaper=0
BkMixed=0
BkMixBkAttr=0
BkOverFF=1
GFXLeveledXOR: while XORing two GFX bytes, MAX function used to get
result. Actually, for xor only A xor A gives 00, in all other cases A xor B = max(A,B)
when this option is on.
GFXLeveledOR: while ORing two GFX bytes, MAX function used to get result
when this option is on.
GFXLeveledAND: while ANDing two GFX bytes, MIN function used to get
result: A and B = min(A,B) when this option is on.
GFXScreenXORBuffered: if 1, special sequence [XOR A,(HL);LD (HL),A]
when HL is between 4000H and 57FFH is recognized as xor with screen. In such case,
previous GFX data is stored in special buffer together with data (in GFX.A) used to xor
it. If such operation is executed again for such address, then for those XOR-data in
GFX.A, which are the same, just previous GFX data value is restored.
UpColorsMixed: if 0, there are no mixing at all for up colors in the
palette. By default, up 64 colors (with indeces from 192 to 255) are mixed with usual
attribute. Maximum value (plus DownColorsMixed) is 128.
DownColorsMixed: if 0, there are no mixing at all for down colors in the
palette. By default, only up 64 colors (with indeces from 192 to 255) are mixed with usual
attribute and no down colors are mixed. Maximum value for UpColorsMixed+DownColors
is 128.
UpMixChgBright: 0..100 percents (default 0), defines which part of mixed result
is affected by the bright of an attribute rather then by its color.
DownMixChgBright: the same as above but for down mixed colors bank.
UseBrightInMix: By default, only 3 lower bits in the attribute byte
correspondent to a foreground color are used for mixing last 64 colors in the palette. If
1, then brightness bit also used to mix with.
UpMixPaper: by default, mixing is done always with attribute ink color.
Setting this option to 1 provides mixing with a paper color only - for upper mixed colors
bank.
DownMixPaper: the same as UpMixPaper, but for down mixed colors bank.
BkMixed: if 1, then colors in the background with indeces under DownColorsMixed
and above UpColorsMixed are are mixed with the attribute.
BkMixBkAttr: if 1, and BkMixed=1, then background pixels with indeces
under DownColorsMixed and above UpColorsMixed are mixed
with back attribute rather then with fore attribute.
BkOverFF: background pixels are overriding also FF value from GFX, but
not in case when a correspondent attribute has fore color 7 (white).
Also, a number of lines can be there which define probes for background. Those must have following format:
NN: addr [ & mask1, mask2, ..., maskN ] = [ byte1, byte2, ..., byteN ] [; addr [ masks ] = [ bytes ] ]...
where:
NN - background number (at least two decimal digits, e.g. 00 for
background number 0);
addr - decimal or hexadecimal probe address (e.g. 4000H or 16384); any
memory address can be used to check data from 0000h to FFFFh (currently selected banks
only checked).
& masks - a list of comma separated bytes used as masks while probing
following bytes; This list is not necessary (if omitted, all FFh masks are used).
bytes - a list of comma separated bytes, which are compared with
correspondent memory bytes at address addr, addr+1, ..., addr+N-1 correspondently to
byte1, byte2, ..., byteN. If masks available those are masking correspondent memory bytes
before comparing with bytes (e.g., if 98H is probed with mask FEH, both values 98H and 99H
at that memory are satisfying).
All the sequences listed (semicolon separated) in one line are defining one probe which is
satisfying only if all the masked comparisons are satisfied. There is possible a situation
when several probes are satisfying correspondent to different backgrounds. In such case a
background selected correspondent to the longest probe among winning (i.e. having more
bytes to compare), and among all winning probes of the same length - the first one.
See also description of Bmp2RawBk256.exe utility, which allows to convert bitmap (.BMP) to raw background image (.Bnn) or even to create palette (.Pnn).
GFX Editor hints and tricks.
I hope that this tool will satisfy your desires. If not, you can select some area and copy it to the clipboard, then paste into another graphic editor (Paintbrush), do what you want there, copy it from there, go to the GFX Editor, then paste modified data to the selection again. Or you can use copy/paste just to reproduce some GFX data in several locations. Or, just to flip it vertically (but be careful if not only color values are important but color indeces too: the same color can be found in the palette several times, and while pasting only the first satisfying by its R, G, B values is used to be inserted).
Usually, left click (Pen, Brush, Fill, Gradient Line) use fore color, whereas right click use back color (or changes colors order, as for Ctrl+Brush or Gradient Line).
When you selected some tool, try pressing CTRL or SHIFT key - you can obtain additional capabilities. E.g.:
You can easy select tool pressing keyboard key (P - Pen, B - Brush, E - Eye Dropper, etc. - see toolbar hints).
If you unpress black face on the left toolbar (View Usual &Memory (16 colors)), you will see GFX memory only. This mode is not useful to find out sprites which have no yet GFX colors, but allows to see better what you have already in GFX memory. And, when use tools Fill and Magic in such mode, content of usual memory has no effect at all.
The left toolbar is mainly for utilities and main editing modes. Try the all its buttons to check out what you can do. Use Clear GFX Memory button to initialize entire or selected part of GFX memory (usually expanding bit 0 to color 00, bit 1 to color FF). Click GFX Configuration to edit GFX Configuration on fly without reloading the game. Etc.
The Undo stack actually is not restricted. Except a size of temp files used on your hard disk (10Mbytes is far enough to save entire GFX memory at least 20 times if you change it totally). But when you reset Spectrum, or load another snapshot undo stack is cleared. And, if you changed something after Undo, Redo operation becomes unavailable for changes already undoned.
For games storing its sprites together with masks byte-by-byte, try mode View All/Even/Odd bytes.
To find sprites faster, use GFX Sprite Finder.
Use grid to markup sprite bounds for yourself. To re-adjust grid size or change its vertical anchoring, just turn it off and then click Grid button on toolbar again, and a dialog allowing to adjust Grid will appear.
(C) by Vladimir Kladov, 2004