|
Demo or Die #02
31 июля 1999 |
|
Demo-Building - an ancient effect a tricky name Moving Shit.

__________________________________________
(C) Devil of eTc / Scene '99
..... Moving Shit .....
This article describes the effect of ancient
a tricky name Moving Shit. I am sure
that many of our readers have long been aware of it,
but for a novice programmer it
will, I hope, interesting.
Along the way we look at many problems
arising opimizatsii algorithms
such as:
- Transfer of the sprite to the screen
ispolizovaniem stack
- Rational use of tables for
calculate the address screen, the address line
sprite, etc. etc.
To begin the essence of the algorithm.
For example we have a table of sines and
just two variables characterizing
offset in this table.
For definiteness, let the table with us
will be longer than 256 bytes and will take
values from 0 to 64. Just to speed up
code, place it on a multiple address.
Variable displacement will take 8-bit
and let them find a match in
variables A and B.
Now we need to create a sprite in which
or editor. In this case, sprat may have
arbitrary width (within reason)
but the length must be equal to twice
muksimalnomu value neshey sinusoid
ie 64 * 2 = 128. In the sprite can be located
anything: teugolniki circles, etc.
in general it all depends on your imagination (for
example, I created two different sprite and you
can immediately see the difference in the effect).
Next, we need to organize a series of
which we seem to be on display sprite
screen, but not directly, but raschityvaya address
each line based on the fact that
NumLin: = (SIN [A + n] + SIN [B + n]);
AddrLine: = AddrSpr + NumLin * len;
where NumLin - number of output lines;
n - is taken from schetka cycle;
AddrSpr - well, everything is clear this is hell
res sprite in memory;
len - the width of sprite in familiarity;
Once we got the address line
safely conclude it to the screen and go to
calculation of the next.
Once we have built a sprite
izment variables A and B-type formula:
A: = A + Step1;
B: = B + Step2;
{Step1 not equal to Step2}
That's it. If you're ponel then further
can not read, and for the doubters
cite an example of source code with detailed
explanations.
ORG # 7000
Y_S EQU 129; length sprite
CALL INIT_P; Initialize all
, Tables, and kideteli
For more detail in the most
; Procedure
START LD A, # 7F; check for depression
IN A, (# FE); space and leave
RRA
RET NC
EI
XOR A
OUT (# FE), A
HALT; waiting INT'a
LD A, 1
OUT (# FE), A
DI
LD D, SINTAB [; record in the D and H
LD H, D; senior Address Table.
; Sinuses
POS1 LD A, 0; INC'aem variable
.1 INC A; A (see above)
LD (POS1 +1), A
LD E, A
POS2 LD A, 0; DEC'aem variable
.4 DEC A; B (see above)
LD (POS2 +1), A
LD L, A
, In principle, INC or DEC Pick up on their
; Taste, more importantly, to priroshenie
; Variables A and B was as much as possible
; Different
EXX
LD H, TBLADD [; record in H ', Senior
EXX; byte tables to
; Torah, we believe
; AddrLine, substituting
, In L ', NumLin
LD (SPBUF), SP
LD SP, BUFADR; in SP, address table
; Lines in the open
; Kidatele sprite
GETAD INC E, L
LD A, (DE)
ADD A, (HL)
EXX
ADD A, A; nabodim NumLin
LD H, TBLADD [
LD L, A; L = NumLin
POP DE; DE, address in kidatele
; Sprite
LDI; puts AddrLin
LDI; in the open kidatel
EXX; sprite
ENDGET
DS (ENDGET-GETAD) * Y_S
; In this buffer, we povtruen 129 times
; Piece of code from GETAD to ENDGET, for
; Acceleration
LD SP, (SPBUF)
CALL PUTSP; actually throw on
; Screen sprite
JP START; on top
DOWN_HL 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
; Procedure generates INIT_P kidatel
; Sprite with the application stack
INIT_P
LD HL, PUTLIN
LD DE, ENDPUTL
LD BC, (ENDPUTL-PUTLIN) * (Y_S-1)
LDIR
EX DE, HL
LD (HL), # ED
INC HL
LD (HL), # 7B
INC HL
LD (HL), SPBUF]
INC HL
LD (HL), SPBUF [
INC HL
LD (HL), # C9
, Further there is a procedure which generates
; Procedure for calculating the address table lines
LD HL, GETAD
LD DE, ENDGET
LD BC, (ENDGET-GETAD) * (Y_S-1)
LDIR
LD B, Y_S
LD HL, # 4010
LD IX, ADRSCR +1
LD DE, ENDPUTL-PUTLIN
INIT1 LD (IX), L
LD (IX +1), H
ADD IX, DE
CALL DOWN_HL
DJNZ INIT1
LD B, Y_S
LD DE, ENDPUTL-PUTLIN
LD IX, BUFADR
LD HL, PUTLIN +1
INIT2 LD (IX), L
LD (IX +1), H
INC IX
INC IX
ADD HL, DE
DJNZ INIT2
LD B, Y_S
LD HL, 0
LD DE, SPRAIT
LD IX, TBLADD
INIT3 LD C, L
.4 ADD HL, HL
ADD HL, DE
LD (IX), L
INC IX
LD (IX), H
INC IX
LD H, 0
LD L, C
INC L
DJNZ INIT3
RET
; SPRAIT INCB "SHIT_SP1"
SPRAIT INCB "SHIT_SP2"
SPBUF DW 0
BUFADR DS Y_S * 2
ORG (($ -1) [+1) * 256
SINTAB INCB "STAB"
ORG (($ -1) [+1) * 256
TBLADD DS Y_S * 2
PUTSP LD (SPBUF), SP; 20
PUTLIN LD SP, 0, 10
EXX; 4
POP HL; 10
POP DE; 10
POP BC; 10
POP AF; 10
EXX; 4
POP DE; 10
POP BC; 10
POP HL; 10
POP IY; 10
ADRSCR LD SP, 0, 6
PUSH IY; 11
PUSH HL; 11
PUSH BC; 11
PUSH DE; 11
EXX; 4
PUSH AF; 11
PUSH BC; 11
PUSH DE; 11
PUSH HL; 11
EXX; 4
ENDPUTL; Total: 222 cycles
, Ie 13.87 cycles per byte
, That is not so bad ...
At Sim simpler and conclusion
add that the way to optimize
incalculable, and as one of the great:
"There is no program that can not be
make one byte shorter or one
beat faster. "
Questions please send email to:
to: Sergey Movchan 2:4635 / 100.128 @ FidoNet
__________________________________________
Other articles:
Similar articles:
В этот день... 15 November