Automatic creation MASK for sprites Bezugly Andrew (Ticklish
Jim / BIS), 1997 _________________________________________ Hi
all, who decided to spend it-Nogo your time reading this little
article. Its theme, I think it will be of interesting to all
those who are involved in capacity-games, whether artist or
pro-mist. So ... Mask for the sprite. How many seychasmozhno
find vserazlichnyh sprite re-daktorov, but how many of them are
pro-dure create a mask for a sprite artist's indifference?
Personally, I have not videlni one (this, incidentally, one of
prichinpochemu I do address this problem-I). It is quite
possible, of course, that yaprosto and simply do not know about
this editor (Not an artist because in the end). However, I hope
that after reading this article, our coders who
closely involved in the creation of programs
for working with graphics (just is not
see new photo editor. Is ART STUDIO will remain
only, which is more or less convenient
I use it? ") in new versions of their
program will introduce the function AUTOMASK. Probably their
version of the algorithm described below would look much more
attractive My (I'm not a programmer).
To get started is to answer two questions. First: what is
the mask and why is it necessary? Answer is almost not
necessary. Those who makes the game and so everybody knows, and
those who does not, can read or INFORKOM'ovskih publications,
or see DIZZY on and see why it is not
merges with the background, and separated the thin edge. The
second question is: what (and for whom) you want to
automatically mask? Answer like this: first, the artists no
longer have a headache, when before them is a coder with yells,
"Why your bun on the right seems a continuation of
chair ?!?!", because quite human
inattention (more would create a mask
much more boring and laborious than to draw face brave Santa
Clause or Russianised Dizzy); secondly, when under hand is not
the artist, who can be "Go after" for "the continuation of the
chair, and mask needed badly, the whole problem can be solved
in seconds, third-and last, imagine the following situation:
You have an ambitious plan to enter the game
mode is going down for the items, or you
want to be active subjects (well, those
Dizzy who constantly takes it, then throws) do not "take a
bite" anywhere on the half of familiarity background, however,
places at ext. schedule was nearly empty (because
there is support for every conceivable
"Wash ";-). Here and useful program that will dynamically create
mask only for the sprites, which
for example, involved only in that screen (yes, in that;).
There are three algorithm (unless, of course, someone will
come up again, then let let you know write to the registry :-).
Third, the easiest and fastest, is described in more detail at
the end of this narrative. The first two are briefly described
in view of low feasibility of their application
(After reading some try to count how many times the 2-nd
algorithm will faster the 1 st and 3 rd - faster
2-nd. This is so for the sake of diversity).
1. Method "vykusyvaniya.
As it turned out, it was the most obvious option. The
principle of its operation is very simple. Take the sprite is
created equal he largest buffer masks, which we
fill # FF. Found, created, filled
and began to engage the most interesting thing: Scan the base
sprite. Ie take a byte of the sprite and check the 7-bit (if
the scan goes from left to right). If bit off, then proceed to
the next bat without reference to the buffer mask. Otherwise,
we find the corresponding bits in the pattern mask and
extinguish it, but at the same time reset all the bits around
and found neutralized (just note that it is necessary
check where exactly is this
bits. I will not list all possible
options, only to say that there are only 9).
After that, go back to the sprite and go to the next bit. And
so to the finish. As a result, we obtain
excellent mask and a huge break in
runtime. So swing
this wild idea to implement this algorithm, a better read on
the following, which in principle is a modification (Quality)
of the preceding.
2. Method "vykusyvaniya # 2."
Looks a little bit at first. Once the buffer
we fill in # 00. Again scan. Only
here, if we found included bits immediately check the district
(the same 9 conditions, anywhere they do not share:) for no
other of ones. If at least one there, then throw this thing and
move on to further line scan
sprite. But in that case, when around 1
the crowd was 0 (in an amount of from 3 to
8), we immediately run into the buffer mask, find the
appropriate place and put a bunch of units (from 4 to 9). After
a complete pass sprite we take the buffer mask and invert the
contents. As a result, we have perfect mask and a little less
break (Ie tea you will not have time to drink) in their work.
But as it is interesting to observe the work of BASIC-program
creates this proverbial mask ... Yes, even without the
compiler. Can you imagine? No, do not cheat, that's when we
ourselves experience this, then I believe.
And now we come to the best algorithm.
3. Shift method.
It's very simple. Reserve buffer
under the mask. Take the part of the sprite (without
top line of the image) and throw it
in the buffer - this is equivalent to a shift upwards
point (namely for the sprite into memory, rather than
images on the screen, because In this case there are
additional. problems that nobody wants). Then take the other
part sprite (not the bottom line, that is, minus the width) and
do OR with the contents of the buffer and address of the buffer
increase on the same the amount by which we reduced the length
of sprite in the first two manipulations (eg, width = 18
familiarity with a total length sprite = 1728 bytes, then we
toss and a 1-m, and the 2-m cases 1728-18 = 1710
bytes). As a result, the buffer we got
shifted the image up and down on
one pixel. It remains only to identify
side of the border. There quite simply, we take
byte of the sprite, we shift it to the side
much more like us and OR'im it with
resp. byte buffer mask obtained
the result is buffered. Then we do
All the same, but in the opposite direction and
immediately after the OR CPL'im to mask
adopted its legal form. As a result,
buffer is a quality mask
any complicated and not very sprites, and pause ... Where is
she? .. As an example, I quote let still not perfect, but
quite workable and tested
program, with commentaries. All
very simply, I think there should be no ambiguity.
The program will automatically create
MASKS for sprites AUTOMASK v1.02
(C) 1997 BROKIMSOFT
(C) 1997 Idea by
TICKLISH JIM, STEELER
(C) 1997 Code by
TICKLISH JIM
WARNING!
This version is designed
only to demonstrate the algorithm
AVTOMASKI, so before you start
to clear the buffer MASKS. Who wants to, of course, can alter
the procedure formation of borders, good opportunity
there.
ORG 40000; for illustrative purposes only
INSERT "MONAST"
SPR_PL EQU 40000; start address Sprite
SPR_BUF EQU 30000; ADDRESS BUFFER MASK
ORG 25000
LD HL, SPR_PL; HOME Sprite
LD (SPR2 +1), HL
LD A, (X_SIZE); X_SZ
LD (L1 +1), A
LD (L2 +1), A
LD (L3 +1), A
LD B, A
LD A, (Y_SIZE); Y_SZ
ADD A, A
ADD A, A
ADD A, A
LD HL, 0
LD D, 0
LD E, A
MULTADD HL, DE
DJNZ MULT
; In HL Length of machined Sprite
LD (X1 +1), HL
; LD (X0-2), HL; FOR DEMO
LD (L4 +1), HL
; Skidded LENGTH IN BC
LD HL, SPR_BUF
PUSH HL
PUSH HL
PUSH HL
EXX
POP DE
SPR2LD HL, SPR_PL
PUSH HL
L2LD A, 0
ADD A, E
LD E, A
JR NC, L1_1
INC D
; HL '= SPR_PL, DE' = SPR_BUF + X_SIZE
L1_1EXX
POP HL
POP DE
L1LD A, 0
ADD A, L
LD L, A
JR NC, X1
INC H
; HL = SPR_PL + X_SIZE, DE = SPR_BUF
X1LD BC, 0
LOOPDEC BC
DEC A
JR NZ, LOOP
; BC '= LENGTH Sprite-X_SIZE
SCROLLPUSH BC
LD A, (DE)
EXX
OR (HL)
EXX
OR (HL)
LD (DE), A
EXX
LD A, (DE)
EXX
OR (HL)
INC HL
INC DE
EXX
OR (HL)
LD (DE), A
INC HL
INC DE
POP BC
DEC BC
LD A, B
OR C
JR NZ, SCROLL
; This part to set an upper and
; Lower Bound create masks.
Written by no means perfect and is not optimal, but quite
suitable for demonstration, and a place to use their own ideas
remains.
LD HL, 10072
; RESTORE HL '
EXX
; Change to Main KIT registration; DOM
POP HL
L4LD BC, 0
PUSH BC
EX AF, AF '
XOR A
JR ROLL_RT +1
ROLL_RT EX AF, AF '
LD E, (HL)
RR (HL)
EX AF, AF '
LD A, E
OR (HL)
LD (HL), A
INC HL
DEC BC
LD A, B
OR C
JR NZ, ROLL_RT
, Denote the right BORDER MASKS
DEC HL
POP BC
EX AF, AF '
XOR A
JR ROLL_LT +1
ROLL_LT EX AF, AF '
LD E, (HL)
RL (HL)
EX AF, AF '
LD A, E
OR (HL)
CPL; INVERSION BYTE MASK
LD (HL), A
DEC HL
DEC BC
LD A, B
OR C
JR NZ, ROLL_LT
; THIS SECTION indicating the last, left,
; BORDER OF MASKS AND SIMULTANEOUSLY Inverts
; BYTES to end up Get real
; BYTE mask.
; These two procedures can be combined into
, One that significantly speed up the work
; Program. Besides the inversion of bytes
; Masks can do is direct
, The derivation of the image on the screen.
RET
, Variable, indicate the size
; Sprites (in familiarity)
X_SIZEDB 18
Y_SIZEDB 12
; DEMONSTRATION ON MASKS OR AS A RESULT
; The subprogramme C ADDRESSES
; SPR_BUF will be located Sprite VPECHA; culated in Create a
mask.
; DEMO LD HL, SPR_BUF
; SPR3 LD DE, SPR_PL
; LD BC, 0
; X0 LD A, (DE)
; OR (HL)
; LD (HL), A
; INC HL
; INC DE
; DEC BC
; LD A, B
; OR C
; JR NZ, X0
; RET
As you can see an example of this
program is good. However, its application
can be considered more or less appropriate
Is that some sort of editor, sprite
but certainly not in the game program, where
requires a high speed of the procedure with a relatively small
amount memory used by vserazlichnye buffers. In general, the
title of this REALTIME procedure is not explicitly drawn. The
following program, I dare to hope, will be more
it is useful from a practical point of view.
As usual, comments are attached.
The algorithm works the same as was used in the previous
program.
Naturally, I do not claim to absolute truth (I repeat: I
not a programmer, but only the attacker, who was forced to
wallow in koderstve); sure - if you prefer, you can do
better than he is, therefore, I say
this is just an example. Disassemble,
Experiment and use, because the scope of this program is very
wide, especially in games of the genre ARKADE-ADVENTURE.
When we use two buffers for
8 bytes each (sprite width of 8
familiarity; can, of course, more if
necessary), ie 16 bytes total.
ORG 40000
;. INCBIN tree
; File 'tree' - this is handled by sprite
ORG 25000
JR START
WD DEFB 5; width of sprite in the familiarity
HG DEFB 7; height sprite familiarity
PL DEFW 40000; start address sprite
START
LD IX, (PL)
LD A, (HG)
ADD A, A
ADD A, A
ADD A, A; height multiplied by 8
, Ie transferred to the familiarity
; Pixels (lines)
LD (M1-1), A
LD A, (WD)
LD (M2 +2), A
LD (M2-1), A
LD (BF0-1), A
LD HL, 16384; address on the screen, where
; Be displayed sprite
, With a mask
DEC A
LD E, A
LD D, 0
ADD HL, DE; increased it to (Shea
, Width-1), t.k.pechat ve
; Exists a right to left
LD (PR_LN +1), HL
; LD HL, 18432; MASK_RESTORE_BUFER
; LD (PR_LN +4), HL
; Specify the address of the buffer to be entered
; Background for a sprite. In this case, I had
; Just do not use.
XOR A
LD (TT1), A
, Blocked a clearing buffer (at startup
And must be cleaned)
CALL REAL_MASK
; Accessed directly print program
; Sprite with a mask.
RET
REAL_MASK
LD B, 0, count lines sprite
M1PUSH BC
EX AF, AF '
XOR A; folded flag C in F '
EX AF, AF '
LD HL, BUF0; buffer address for the form
; Formation of the first part
; Tea Mask (shift
; Up-down)
EXX
LD HL, BUF1; address buffer
; Final mask
, (Left-right and Information
; Version)
EXX
LD B, 0, byte count (the width
; On)
M2LD A, (IX +0)
OR (IX +0)
INC IX
LD E, A
OR (HL)
LD (HL), E; record in BUF0 results
; Tat shift up and down
INC HL
EXX
LD E, A
LD D, A
EX AF, AF '
RR E; at the same time shift vpra
; During imposed on the pre
; Preceding result and
, Enters the resulting
; Bytes BUF1
EX AF, AF '
LD A, E
OR D
LD (HL), A
INC HL
EXX
DJNZ M2
LD (SPR +1), IX; IX indicates that at
; Chalo next line
; Sprite
LD (BF0 +1), HL; HL indicates
; Next byte buffer
; BUF0
CALL PR_LN; print the line
; Sprite with a mask
POP BC
LD A, B
DEC A
CP 1
JR NZ, STOP
And if we are left untreated village; glacial line of the
sprite, then turn on ; Clean main buffer (BUF1), for
; Follow-up and block increments, of IX, in order not to climb
beyond nuzh; Nogo us sprite.
XOR A
LD (M2 +2), A
LD A, # 36
LD (TT1), A
STOPDJNZ M1
EXX
LD HL, 10072; restored HL '
EXX
RET
PR_LN
LD HL, 0; here will be addressed in
; Screen to print
; Sprite (right to left)
; LD DE, 0; buffer address for the background
; (Not fix).
PUSH HL
EXX
LD B, 0, width
BF0 LD DE, 0; DE '= BUF0 + width,
; HL '= BUF1 + width
XOR A; folded flag C to F
T1 DEC HL; HL 'set to on
; Recent bytes used
; Acterized part of the buffer
; BUF1
DEC DE; same for BUF0
LD A, (HL)
RL (HL); shifted to the left
PUSH AF
OR (HL); imposed on the initially
; Initial
EX DE, HL
OR (HL); imposed on the shifted
; Right
TT1LD (HL), 0, clears the buffer (if
, Last line)
EX DE, HL
CPL; invert the byte scale
, Ki
EXX
LD C, (HL); bytes saved background
; (Not fix).
AND (HL); used bytes
; Mask
PUSH HL
SPRLD HL, 0; HL points to the beginning
; Lo ff. line AB.
DEC HL; now at the end of the formation
; Oped
OR (HL); imposed byte image
; Motion
LD (SPR +1), HL; changed pointer
, Addresses the JWP.
POP HL
LD (HL), A; brought to the screen B
, With a mask
DEC HL; reduced address Pec
, T
; LD A, C
; LD (DE), A; log into the buffer B
; Background
; INC DE
EXX
POP AF; went to print the following
; Blowing bytes AB.
DJNZ T1
EXX
POP HL
CALL NEXT_L; next line in the equivalent
; Wound
LD (PR_LN +1), HL; remember
; LD (PR_LN +4), DE; remember the lyrics. hell
; Res buffer
RET
; Procedure for calculating the lyrics. line in the screen,
; To explain anything to anybody, I think not.
NEXT_L
INC H
LD A, H
AND 7
RET NZ
LD A, L
ADD A, 32
LD L, A
RET C
LD A, H
SUB 8
LD H, A
RET
BUF0 DEFS 8, the main buffer
BUF1 DEFS 8; auxiliary buffer
, The value of both is the maximum possible; natural width of
printed sprites. ; And remember that when you print background
preserves; Xia backwards - do not get confused (if ; Will be
using, of course, is my ; Procedure) during recovery. If anyone
; Unclear, then explain: for example, the width
; Sprite is 3, then the background will be preserved; nyatsya
my program is not standard , 1,2,3, 4,5, etc., and in another
way - that is, , 3,2,1,6,5, 4,9,8,7, etc. I have not cleaned
And this small inconvenience because it
; Really small.
. . .
And finally, some more common phrases.
This article was begun in 1997, and last revised specifically
for Journal ZX-POWER is dated April of this
year. Quite naturally, the material
could become obsolete. However, I still
has not appeared human sprite-editor'a, which tries to make can
be compared with SPREDIT2.0 (1993!), Not to mention a better
program (I've heard that SPRITE MASTER v5.0 is something
stunning, but alas - not seen. If someone does not sorry, we
share the program that my address is listed at the end of the
article). Therefore, we how to use and continue
enjoy their own procedure.
If anyone is interested, I can advise to delve into the Czech
toy TOWDIE. There also used avtomaska,
moreover, the rate is a clear leader - 11
cycles per byte. However, there is a "but" -
mask is not very high quality.
Say, for sprite width of 2 bytes (not
more) the mask will be satisfactory, of course, if you do not
mind that character will merge with the background
top and bottom. However, just download
TOWDIE and take a closer look, all at once become clear.
Further, to illustrate the above program in Appendix
ZX-POWER'a written to two files: "scr1" and "scr2". The first -
an example of the construction of the game screen without the
use of masks for sprites the second - using.
But it's best to download "CSCDV_D2" -
where all the rooms are built specifically with the use of
procedures avtomaski. Of course, performance has been and
remains sensitive issue, but all are known to pay. Although the
arcade adventyur speed construction of the screen is not
is the determining factor, right?
For those interested, I can say that the maximum time it takes
for my program to print the game screen of
99i sprites with a mask (in practice, of course, so much is not
necessary) is 2 sec.
By the way, on the same drive should be
write file "REAL". It is a ready program that creates the data
block on a "mask byte - byte sprite. REAL written in assembly
language STORMv1.1 (interestingly, he's just my "kill" the
disks with records, or both? In my view the guys from
X-TRADE nevertheless necessary to consider that not
all are TEAC'i) and then exported to a format TASM2.0.
On this, let finish. A for
those who want to contact me here
my coordinates:
Tel: (0472) 43-37-97 (18:00 to 22:00)
Address: 257005, Ukraine, Cherkasy,
Shevchenko, d.367 / 1 kv.37,
Bezuglov Andrey
04/20/1998. TJ / BIS
_________________________________________