Secrets DAINGY
Here, then asked me to write about my
intro DAINGY, which is known to
ranked third at the demoparty CC'999.
Honestly, I really do not remember
how things work there, but I'll try to move
this article remember all the details and
to reveal to you the essence of certain procedures.
Just want to make a reservation that I do not
contend that the language used in the intro
methods are the most steep and not
subject to further optimization. More
Besides, now some things seem to me
very poorly executed, but that
done is done, the more that
the end result, I think, quite
not bad. And now proceed
directly to the consideration of the source
DAINGY.
First of all we need to describe
memory allocation in ascending order
addresses, so:
[Line] (This address is calculated
from the address chunks)-a procedure for constructing
in the shadow buffer line image
rotated at an angle.
[Chunks]-there are textures.
[Sin]-sinusoid.
[# 8000], the image itself, length = # 100,
height = # 1000, 1 byte = 1 pixel.
[Tenbuf]-frame buffer.
tenbuf EQU # fa00
chunks EQU # 7600
sin EQU # 7900
line EQU chunks-(linep2-linep1) * 32-1
Addresses sin and chunks are chosen
that the difference between them was
is # 300 because it uses
a procedure for filling a byte by
LDIR to reset the memory location for
setting attributes, if a little
sit and porazbiratsya, then we can
understand ...
Traditionally the program begins with
decrunching'a. Let us consider in more detail
all its stages.
First is the construction procedure
rotation of one image line.
ORG # 6200
decrun LD de, line
LD a, 32
d1 LD hl, linep1
LD bc, linep2-linep1
LDIR
DEC a
JR nz, d1
LDI; put the command RET
Next comes the construction of the chunks on the table.
I note that they have a size of 8 * 4 pixels, and
composed of pairs of standard chankov 4 * 4.
LD b, 32
CALL raspch
CALL raspch
INC hl
DJNZ $ -7
Sub-raspch located at the end
text, but for clarity, and bring her
now:
raspch XOR a
RLD
LD c, A
RLCA
RLCA
RLCA
RLCA
OR c
JR linep2-2 transition on a piece of
; Code
; LD (de), A
; INC de
; RET
, Thus
; Saves one
; Bytes.
I think in the notes, this piece is not
needy, noting only that the table
contains all 16 * 4 = 64 byte chunks, but
in each byte are significant
only 4 bits, then it is reduced to the size of
64 / 2 = 32 bytes. You could make a plate
and smaller, but this method is offset by
minimization procedures for unpacking.
The following piece of code provides
zero padding of chunks, codes
which more than # 0f.
EX de, HL
XOR a
CALL fill2
This could not do under the condition
that the memory at startup was not crowded
various debris.
Now it's time to form
some semblance of the sine:
LD l, C; input we have
, The following values:
INC a; C = 0
And A = 0
; DE = sin + # 7f
; H = sin'h-byte
; Address sin
LD c, 6
msin2b EX af, AF '
LD a, C
ADD a, 7
LD b, A
EX af, AF '
msin2a LD (hl), A
LD (de), A
INC l
DEC e
ADD a, C
BIT 6, l
JR nz, makstr
DJNZ msin2a
DEC c
JR msin2b
This method was invented by me personally and
is the shortest of all the me
known. I'll try to explain the gist of it.
It is easy to notice the difference between
current and subsequent values in the function
sinus changes from high to low
when the argument between 0 and PI / 2.
In fact, this difference is equal to the value
the first derivative of the function sin (x) at
tends to zero difference between the arguments. So
Now, if we are some variables in
cycle to increase by a constant, which
from time to time to reduce (and
more constant, the more times we
it increments the variable), we obtain
some semblance of a quarter period of sine.
This is the purpose above fragment
code. In this case, we obtain
half-sine wave with an amplitude
changing from # 01 to # ef excluding
sign.
Next comes the formation of primary
inscriptions, the rotation of which you may
behold after running DAINGY. Here, all
rather trivial, except for
reduce the amount of code letters of a string
located in a format (letter-# 20) * 4.
Uses a standard font,
located at # 3d00, letters
which is thicker in the horizontal
direction.
makstr LD ix, string
LD de, # 8000
ff1 LD l, (ix)
INC ix
LD bc, # 3d00
LD h, C
ADD hl, HL
ADD hl, BC
EX de, HL
LD b, 8
ff3 PUSH bc
PUSH hl
EX de, HL
LD a, (HL)
RRCA
OR (hl)
EX de, HL
INC de
LD b, 8
ff2 RLCA
LD c, 0
JR nc, $ +4
LD c, 15
LD (hl), C
INC h
LD (hl), C
INC l
LD (hl), C
DEC h
LD (hl), C
INC l
DJNZ ff2
POP hl
INC h
INC h
POP bc
DJNZ ff3
LD de, # f010
ADD hl, DE
EX de, HL
INC e; check
DEC e; end
JR nz, ff1; line
It's time to set the color and BORDER'a
ATTRIBUTES in both screens
OUT (# fe), a; A = 0
CALL fill
Sub-fill looks like
as follows:
fill LD a, # 55
CALL fill1
LD a, # 57 8
fill1 OUT (# fd), a
LD a, 65
LD hl, # d800
fill2 LD d, H
LD e, L
INC de
LD (hl), A
LD bc, sin + # 7e-chunks-64;
LDIR; BC> = # 300 trail-but
RET; attributes we have set
, Albeit with a slight
; Excess ...
At this preparatory process ends
and starts the main loop, repeating
256 times since When this plot
Register B contains 0.
start PUSH bc
CALL wave; the construction of another
; Phase of the so-called
, "Traveling wave"
In fact, here it was necessary to immediately insert a
text of this subprogramme, thereby
saving 4 bytes, but in a hurry I forgot it
do ...
ugol LD a, (kx +1); X coordinate
ADD a, # 97 - # f0; depending
; From her
, Calculated
, The increment of
, One of the axes
LD e, A
CALL takesin; dy = a * sin (alpha)
LD c, A
LD a, E
RLCA
RLCA
AND # 7f
LD l, A
LD d, (HL)
LD a, # f0; try XOR and
RLD
CPL
LD (hl), D
LD (plus +1), a; set
; Basic level
; Background intensity
LD a, E
RLCA
ADD a, C; A = beta
EXX
CALL takesin; based on this
, Calculated
; Increment on the other axis
LD c, A; dx = a * cos (beta)
This piece of code generates a trajectory
"Flight" approach, resulting in
due to the fact that in calculating
increments the value of arguments alpha and
beta were not always at # 40, and
on top of that, sets the current
background color.
After obtaining the increments in the BC and BC '
performs a rotation labels, to be entered
the result in buffer at
tenbuf.
kx LD a, # 10, the X coordinate
INC a
LD (kx +1), a; A = X +1
LD h, A
JR nz, $ +7; if X = # 100,
, Beginning the process of darkening
LD a, # c6; ADD A, n
LD (zatemn), a
EXX
LD de, tenbuf
w2 PUSH bc
PUSH bc
EXX
PUSH hl
PUSH bc
EXX
PUSH hl
CALL line
POP hl
POP bc
ADD hl, BC
EXX
POP hl
POP de
SBC hl, DE
EXX
POP bc
DEC bc; change one of the
; Increments for
; Introducing distortion.
DEC bc
LD a, D
OR a
JR nz, w2; if not achieved
; End of the buffer, then
; Repeat rotation
; For next line
So, we made a turn, now
it is time to create some kind of illusion
three dimensions by creating a lateral
faces of the letters. This is done very simply:
alternatively we look at each column
tenbuf, as occurs bytes
different from zero, we start to fill in all the
the next byte value column, each
time decreases by one. This is done
until then, until we get a negative
number, or do not reach the lower limit
buffer.
Here is the text of this procedure:
LD c, 15
LD de, 32
LD l, D
m3d6 LD h, tenbuf'h
m3d4 LD a, (HL)
LD b, C
OR a
JR z, m3d1
m3d2 ADD hl, DE
JR nc, m3d4
JR m3d5
m3d3 LD a, (HL)
OR a
JR nz, m3d2
m3d1 DEC b
JP m, $ +4
LD (hl), B
ADD hl, DE
JR nc, m3d3
m3d5 INC l
BIT 5, l
JR z, m3d6
This method of construction has a very
drawback: if the letter
not entirely fit in the buffer, we
We observe a sharp break side
faces, going beyond the buffer. To
mitigate this effect, I darken the top
part of the image, changing the brightness from 0 to
peak from the upper boundary.
LD hl, tenbuf
PUSH hl
LD c, 15
LD b, 61
de3a LD a, (HL)
SUB c
JR nc, $ +3
XOR a
LD (hl), A
INC hl
DJNZ de3a
DEC c
JR nz, de3a-2
And in order to gradually appear in
eventually darken the picture, I just
move it about a chunk.
LD hl, chunks
LD d, H
INC d
swet LD a, 64
LD e, A
LD c, 64
LDIR
zatemn SUB 4
JR c, $ +5
LD (swet +1), a
The same effect could be obtained
directly in the output, but then we would
already low rate of
decreased somewhat.
But somehow all the transformations of the frame
performed and left only his take on the
screen. I note that I did not "unraveled"
to accelerate the program output, and perform
its just a cycle.
HALT
LD b, D; in the B set
, High byte address
; Information about chunk
LD a, # 55 8
XOR 10
LD ($ -3), a
OUT (# fd), a
LD de, # c000
POP hl; to obtain HL
; Address tenbuf
ch4 PUSH de
LD a, 32
ch1 EX af, AF '
LD a, (HL)
plus ADD a, 0; adding here
, A value
, We set
CP 16, the background color and
JR c, $ +5; obtain the brightness
CPL; divorce on the letters
AND 15
RLCA
RLCA
LD c, A
PUSH de
! ASSM 3
LD a, (BC); this fragment
INC bc; code
LD (de), A; repeated
INC d; 3 times
! CONT
LD a, (BC)
LD (de), A
POP de
INC e
INC hl
EX af, AF '
DEC a
JR nz, ch1; check at the end
; Line
POP de
LD a, D
ADD a, 4
LD d, A
AND 7
JR nz, ch4
LD a, E
ADD a, 32
LD e, A
JR c, ch2
LD a, D
SUB 8
LD d, A
ch2 LD a, H; check at the end
; Image
OR a
JR nz, ch4
st1 POP bc
DEC b
JP nz, start; check
; End
; Ground
; Cycle
LD hl, 10072; output
EXX; of
RET; intro
Next come the various podprogramki and
plaques, a quick look at them as well.
Spreadsheet sinus
takesin LD l, A
LD h, sin'h
RES 7, l
RLCA
LD a, (HL)
LD b, 0
RET nc
NEG
DEC b
RET
Input: the A-argument to the sine
Output: the A-significant byte sinus
B-byte sine
Data for the inscription.
string DB # 28, # 8c, # c8, # e4
DB # cc, # cc, # 3c, # c8
DB # e8, # b0, # 28, # 8c
DB # 8c, # 64, # 64, # 64
The string "* CRYSS / RZL * CC999"
Iteration of the rotation for a single pixel
linep1 ADD hl, BC; smeschaemsya on Y
LD a, H
EXX
AND% 00,010
, Used for
And some
; Enlarge
RRCA; high
ADD a, # 80
LD d, A
ADD hl, BC; shifts X
LD e, H
LD a, (DE)
EXX
LD (de), A; NeuStar pixel
INC de; in tenbuf
linep2 RET
Description chunks.
DB 0,0, # 80,0, # 80, # 20, # a0, # 20
DB # a0, # a0, # a4, # a0, # a4, # a1
DB # a5, # a1, # a5, # a5, # e5, # a5
DB # e5, # b5, # f5, # b5, # f5, # f5
DB # fd, # f5, # fd, # f7, # ff, # ff
raspch see above
fill above
"Traveling wave"
wave LD hl, # 8000; coordinates
PUSH hl; "wavefront"
LD b, 16
wave1 LD a, B
CP 9; check
wave2 JR c, wave3; "peak-wave"
LD c, A
LD a, 17
SUB c
INC l
JR $ +3
wave3 DEC l
XOR (hl); transformation
LD (hl), A; images under
, "Wavefront"
INC h; the transition to
; The next line
DJNZ wave1
POP hl
INC l; change
LD (wave +1), hl; coordinates
RET; "front"
Well, like it is all about code
DAINGY. Maybe I forgot to describe
Coy any details, but the general idea is to
Have you been understandable, but it seems to me,
is the main objective of this article. After
for the further development of our beloved
SPECCY we should share our knowledge
and expertise to facilitate and accelerate time
new high-quality software to
promoted in light of new methods of coding, so
and in general just to raise the level of
intelligence.
And finally, I want to lift the veil of secrecy
with the word "DAINGY". If you try
just find it in the dictionary, you
Nothing will come as an abbreviation
two English words: dainty and gyration,
which translates as "elegant
rotation. "And now try to draw
abbreviation of these words, but in Russian
Language ... Guess? If yes, then you are
appreciate our efforts in
choosing the original name for the intro.
For sim farewell to you before I met in our
new programs.
BYE!
(C) Cryss / Razzlers