Started by Overflow, 00:43, 19 March 14

0 Members and 1 Guest are viewing this topic.

#### Overflow

Hi everybody!

A few days ago, I felt like writing down some thougts about YAP!
Might be as a therapy to cure myself from retirement.
EDIT: You may have never heard about YAP! check this:
http://www.pouet.net/prod.php?which=60660
and start by this as a technical introduction:
Example asm program: rasterline-plasma, step by step

Disclaimer: I do not intend anything else than sharing,
I do not pretend having high skills or big knowledge,
some past and recent releases make me feel so little;
to name a few: Batman Forever, Still Rising, R-Type... ouch!
-

Before crunching, data+player = #06B9 bytes
It is not a plain AYC song, not real-time-decrunched/played.
I've learnt from what McKlain has done to add some specific code:
1st, the input song does not have duplicated pattern
(it implies: a pattern used twice is not decrunched twice, just re-played);
2ndly, the input song has patterns ordered for best compression by exomizer
(it implies: all patterns are decrunched, then played in right order)
3rdly, last 2 patterns have not been included in the song
(but are generated by code, mixing 2 channels from main theme
with 1 channel from the starting pattern).
All of this has been done as last action on the demo,
when McKlain has sent much more pattern than I have asked.
I have done my best to make the song fit... without changing the code.
Once done, I've checked: this was not the best decision,
since crunching the whole AY/YM-list by exomizer would have require less space!
-

I have re-used some pre-crunching principle from a previous unreleased work.
There might be some theory about it, but let me hope it's my own idea.
I am assuming that the curve is continuous, and its slope does not change much.
Briefly? ddV is from [-1,0,1] , 5 ddV are stored in 1 byte (3^5=243 <256)
One loop to get a new V value for the curve is:
dV = dV + ddV
V = V + dV
Got it? has it got a name or is this an unusual trick?
-

Many years ago in my very first works,
I used to put some special byte in text data
(yes, you know that text, the one which scrolls )
to raise an event = something changing on screen.
Then I met Longshot and I've learnt about the events' list:
some separate data to list which events occurs when.
Data could be 2-bytes witdh:
how many VBLs to wait,
which event to call.
For YAP, this would have required too much space:
an event is, finally, only a call with specific code.
So I've switch to something requiring less space:
let's call it a pokes' list.
Data is now:
how many VBLs to wait,
byte to poke
Or to give full details:
how many VBLs to wait (on 6 bits)
from 1 to 3 bytes to poke (depend on previous unused 2 bits)
This allows
data pointer to be changed (example: palette),
small code to switch (example: switch from INC to DEC),
some called adress to be changed (2 bytes required),
demo to end (put a JP XXXX at the right place).
-

When requiring precise timing, Longshot years ago has showed the way:
waiting for VBL and have a NOP-cycle precision thanks to HALT.
Thanks to constant-time song player such as AYC player (thanks Madram!),
it's easy to keep that NOP-cycle precision til' the 1st displayed scanline.
Then came Ramlaid and DTC: the demo cycles without any wait for VBL,
exactly 19968 NOP-cycles at each VBL.
Was it necessary? no, could have been done without this;
I mean: same display at screen at less cost.
Who cares? only a very few, I am one of them, I like this.
I reset the interruption counter (OUT #7Fxx,#9C) somewhere in the last scanlines,
so that HALT can occur at the beginning of the VBL.
Pf! funny I had a wrong souvenir for something one year old.

-

About YAP!'s length & CRTC compatibility
Beware that these 2 lasts points may lead to some new scene drama.
I've written about my motivation here in French:
http://cpcrulez.fr/forum/viewtopic.php?f=3&t=4956&start=18
Briefly: first of all, it's a hobby = having fun while (retro-) coding!
then: personal challenge = releasing something 10 years after.
but it is not a motivation as itself for me.
However, no doubt I have found some key-points within "the scene".

Length? I wanted something very short after watching this:
http://www.pouet.net/prod.php?which=59813
The 1st part from AST was way too long
(note: I've told it to him before release, he has not been offended);
a bit sad since there are a lot of work for nice fx in it.
This has convinced me to make YAP! so short.
>> OMG! too short! RUN"-YAP again <<
-->exactly what I was aiming for.
How many times in a row have you really RUN"YAP! tell the truth.

CRTC compatibility?
It is linked to past and today demos which don't run on CRTC2
(and I will include myself first, see S&KOH) or even CRTC3/Asic:
there's no need of high-end HW CRTC-specific trick,
you can use old&easy ones (here on YAP!: line-splitting + rasters)
to display some not-seen-yet fx.
Also, it is said that CRTC1 allows more tricks;
YAP! shows the way it could be:
runs on all CRTCs, is better on CRTC 1 (1 line accuracy vs 2).

EDIT: About color-cycling synched with drums
This one is dedicated to the plasma from Batman Forever:
which uses exactly same trick (id est line-splitting) than YAP!
and also uses color-cycling in a simple way that was not my taste.
When McKlain wrote that the drums pattern should not last,
I clearly remember that I then knew exactly what to do with color-cycling:
cycling only half of the colors, and synchronizing them with drums.
I really like this point: a very simple idea (color-cycling, what is easier?),
but used in a creative way for a better experience.
I'd like to think the whole intro follows the same way:
easy HW tricks used in a smart way to get a nice show.

EDIT:  About palette and mode 1 vs mode 0.
See attached DSK, RUN"-YAP
At the early stage of the work, mode 1 was an alternative.

I was also using a modern (?) palette.

I has been my own choice to keep only what I think was better.
-

See attached dsk, it was the 1st day I've tried this strange use of raster.
What is done is simple:
from line n=0 to 15, set INK n at same background color
from line n=16 to 31, set INKs back to the palette
The result has surprised me, an optical illusion:
it seems we get some waves following the curve/gfx, but it doesn't.
As a conclusion: well, I found this by pure chance.
Have a look at attached dsk which displays the rasterized fx for long:
now you will see that the wave is not complete but broken.

About splitting plasma into two parts (right + left lightly slided)
Again: pure chance!
I was coding symetry on curves (to avoid storing more data),
and it was first a bug which gave the right part different from the expected symetry.
I found it cool and decided to have it for release.
-

EDIT: About morphing the plasma gfx.
First, only one row was modified by frame: it was not enough, too slow.
I had to code a second main loop:
the code which modifies rows is included into the 268 line-splitting code.
Finally, 2 versions of the main loop are called:
the first one which has rasters and modifies palette at each line,
the second one which does not have rasters but modifies 8 rows by frame.
See previously: half of the 128Kb ram is full of uncrunched pattern for the song.
The other half is full of 2-bytes data:
which row number has to be modified,
what must be put in this row.
-

Wow! what a long message.

Overflow / Logon System
Unregistered from CPCwiki forum.

#### Gryzor

Thanks for doing that; didn't understand half of it, but very interesting read!

#### rexbeng

Oh, I ran -YAP several times in a row, thank you

rb

#### McKlain

We did it man, we did it

#### arnoldemu

Interesting information.

The events list is a nice way to synchronise the actions in the demo, and I like the way that instead of a

if event=0 do this
if event=1 do this

you turned it into a poke the ram to redirect the demo to perform the action.

The synchro by resetting the interrupt counter is a good method where you can have used all the screen time.

Interesting that you wanted to make a demo 19968 cycles long, is this more for programmer satisfaction or because you need to use all cycles?

Length: it did the trick. I ran it a few times. It's a small clean demo with 1 effect well done and not overdone.

crtc2 is a hard beast to work with, making the demo work better on crtc 1 is also nice.

I think what made the demo for me:

- overscan
- nice effect with various differences shown through the demo and the effect is done well
- short
- fast
- great music

Short demos are equally as nice as long demos.

Have you come out of retirement to make another demo/intro?
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

#### Gryzor

Just watched it again for several minutes now, really lovely!

#### Overflow

#6
Api apo!
Quote from: arnoldemu
Have you come out of retirement to make another demo/intro?
A least for trolling having a few interesting discussions here and there.
My own last line of z80 code is from December '12, don't expect anything soon
(and actually what I have/had as WIP is... unexpected, I won't say more).
Quote from: arnoldemu
The events list is a nice way to synchronise the actions in the demo, and I like the way that instead of a
if event=0 do this
if event=1 do this
you turned it into a poke the ram to redirect the demo to perform the action.
Yes, you got it.
I am also wondering if this is something "new";

Quote from: arnoldemu
The synchro by resetting the interrupt counter is a good method where you can have used all the screen time.
Interesting that you wanted to make a demo 19968 cycles long, is this more for programmer satisfaction or because you need to use all cycles?
Oops! I've coded this more than one year ago, and yesterday/this morning I was wrong:
the intro IS NOT a 19968 nop-cycles thingie.
It uses a classical "HALT" to wait for the 1st interruption at VBL (and EI:RET at interruption jump)
I wanted a 1 nop-cycle precision (even if, finally, it was not required).
To achieve this, it is not enough to EI or reset the interruption counter after the seen scanlines:
there aren't enough remaining (unseen) scanlines at the bottom of the screen to generate an interruption,
since you need to reach at least 32 on interruption counter to generate an interruption;
I took it easy: I reset the interruption by OUT #7Fxx,#9C 32 lines before the end of the screen.
Which implies: in my unrolled loop (268 lines displayed), I have kept 4 nop-cycle on each line (!)
just because on THAT line I required a OUT.
Back to the 19968 nop-cycles thingie: maybe next time?
this would be a way not to waste 4 nop-cycles out of 64 on each loop;
no need to rely on interruption if your code is exactly one frame long.
This is...exciting, from my coder point of view: achieving something quite hard,
having a new constraint, for fun more than a mean to achieve a fx which would require all nop-cycles.

Quote from: arnoldemu
I think what made the demo for me:
- overscan
- nice effect with various differences shown through the demo and the effect is done well
- short
- fast
- great music
No doubt I've learnt from this work:
I do think the music from McKlain IS the main support of the show
(I mean: it wouldn't have been so nice with a so-so song; thanks guy!).
As he wrote: >>WE<< did it, which is fully right, definitely not my only work.

About the category (id est: short overscan intro with one short fx),
I do think this is the (my?) best choice for our days:
IRL with wife, children, job, other hobbies,...
we/I do not want to spend so much time on massive demo (BF! aaaaaaaaaaaargh!!!),
a nice intro is a different way. May I promote the idea?

OVF/Logon System
Unregistered from CPCwiki forum.

#### BSC

Quote from: Overflow on 00:43, 19 March 14
A few days ago, I felt like writing down some thougts about YAP!
Might be as a therapy to cure myself from retirement.

Disclaimer: I do not intend anything else than sharing,

Holy Roland on the ropes! I like that you like to share and have to have a peek at all of this later.
Did a quick skim and must say that I was totally flabbergasted on how this was achieved..

Welcome back Overflow btw
My SID player/tracker AYAY Kaeppttn! on github
Some CPC music and experiments
Other music
More music on scenestream (former nectarine)

My hardware:
- 1985 Schneider CPC 464 with GT65 (later replaced by CTM), dk'tronics 64k extension, 3" and 5,25 disk drives, A/B drive switch, Multiface 2, custom Amsdos-ROM with integrated SMon, switchable 6128 ROM, reset and pause switches
- Amstrad CPC 6128 with CTM (same as above) and M4 board

10 print"This is no signature.": goto 10

#### MacDeath

#8
I had the chance to see it before release on day Overflow came to my home with Hermol.
We made a few palette tests and it was very interesting to see real coders at work... on one of my Amstrads.
still I failed to understand really how it is done.

I guess there are some limitations with this sort of stuff in mode0 because the limited CPC palette doesn't always enable problem long gradiants.
In mode1 the limitation comes from having only 4 colours of course.

and I suppose to use a PLUS would be to cheat.

the "classic overused" blue-to-cyan and red-to-yellow are not overused for nothing. those are the only 2 smooth long palettes possible.

May be cool, if possible to get this with not 2 long palettes gradiants but perhaps 3 shorter ones...

hey, repasse à la maison avec hermol un jour...

#### ralferoo

Quote from: Overflow on 20:42, 19 March 14
Quote from: arnoldemu on 19:42, 19 March 14
you turned it into a poke the ram to redirect the demo to perform the action.
I am also wondering if this is something "new";
It's not a new technique to me as I used to do similar things on the Amiga way back when. A very simple example on the CPC, if I'm doing split rasters I'll often use this idiom:

`#38 contains JP intsyncintsync:        ld b,#f5        in a,(c)        rrca        jr c, intvec0 ; when we detect the first vsync since start, rejoin at intvec0...        retintvec0:    ld hl,intvec1    ld (#39),hl...intvec1:    ld hl,intvec2    ld (#39),hl...intvec5:    ld hl,intvec0    ld (#39),hl...`

#### Overflow

Hi early birds! (It's 7:15 on a Saturday morning and I'm up! )

Quote from: MacDeath
We made a few palette tests (...)
Actually Hermol and you are the ones who have created last palette (purple+green).
But also, about this last fx (blanking only half of the (green) palette to simulate a wavy background):
it was not part of the shown preview; it was part of the wasted previous tests I've shown asides.
When I've asked: "what do you think: should I put this one?" I remember you guys have shouted "YES!".

Quote from: MacDeath
the "classic overused" blue-to-cyan and red-to-yellow are not overused for nothing. those are the only 2 smooth long palettes possible.
May be cool, if possible to get this with not 2 long palettes gradiants but perhaps 3 shorter ones...
I'm not fond of "modern" palettes.
What I like in these "classic overused" palettes, it is that it relies on RGB components values: "coder colors"?
Also: might be classic for CPCers; but could be the best "ambassador" for non-CPCers to show "our" native colors.

Trying 3 gradiants? nice idea. You still have the dsk with basic launcher to test palettes, don't you?
Feel free to perform your own tests and post them. That said, might be a bit late!
You should keep your time to go on working on our secret big project to be released in 2016.

Tcho!
OVF/Logon System
Unregistered from CPCwiki forum.

#### Overflow

#11
Back to "pokes list" versus "events list".
When reading Ralferoo's post, I believe I may have not been clear enough.

Let's say we want as events:
- after 0.5 second, switch palette
then
- after 1 second, go down instead of going up.

As an events list, it would be
` events_list    db 25 :  dw event1     ; 0.5 second is 25 frames to wait for    db 50 :  dw event2     ;   1 second is 50 frames to wait for; called eventsevent1  ld hl,new_palette:ld (adr_palette+1),hl:retevent2  ld a,#2B: ld (adr_incdec),a:ret;somewhere in codeadr_palette    ld hl,old_palette;somewhere elseadr_incdev    inc hl ; ==#23 while #2B== dec hl`

As a pokes list, it could be
` pokes_list    db 25+#80 :  dw adr_palette+1 : dw new_palette  ; +#80 stands for: pokes 2 bytes    db 50+#40 :  dw adr_incdec    : db #2B          ; +#40 stands for: pokes 1 byte;somewhere in codeadr_palette    ld hl,old_palette;somewhere elseadr_incdev    inc hl ; ==#23 while #2B== dec hl`

The main idea is:
somehow, an event is only a list of pokes;
instead of listing events , let's list the pokes
to avoid wasting bytes on always same kind of opcodes (those to poke).

OVF/Logon System
Unregistered from CPCwiki forum.

#### ralferoo

Oh, right, it's still a list rather than code! Yeah, that's not at all like what I thought you meant! When it's formatted like that, though,  it looks a lot like a copperlist for the Amiga...

Coincidentally the demo I'm currently working on (the tape loader) does make use of a similar method - it's data driven but it's more like a signal rather than a VBL count as events depend on tape data which can't be guaranteed to take the same length of time each time. I'll explain more when the demo is released and you can see what I'm talking about...

#### Overflow

Quote from: Gryzor
Thanks for doing that; didn't understand half of it, but very interesting read!
Quote from: OverflowAbout the curves (...)
I am assuming that the curve is continuous, and its slope does not change much.
Briefly? ddV is from [-1,0,1] , 5 ddV are stored in 1 byte (3^5=243 <256)
One loop to get a new V value for the curve is:
dV = dV + ddV
V = V + dV
I believe this was not clear neither.
Let's say I'd like to pre-crunch some V values.
V
0
1
2
2
1
-1
-3
-6
...

Instead of storing value V, its slope dV can be stored: dV = V minus its previous value.
Nice! assuming that V is an 8 bit value, dV surely can be stored on 4 (3?) bits.
V          dV
0
1          1
2          1
2          0
1          -1
-1          -2
-3          -2
-6          -3
...

Now instead of storing dV, ddV can be stored. ddV= dV minus its previous value.
V          dV          ddV
0
1          1
2          1          0
2          0          -1
1          -1          -1
-1          -2          -1
-3          -2          0
-6          -3          -1
...

[-1,0,1] these are 3 values; I can stock 5 of them into 1 byte
(since 3 ^ 5 = 243 which is < 256 = 1 byte)

Finally, this is a pre-crunch with a 1:5 ratio.

I've tried o explain the best I could, with my words.
Starting point: assuming that ddV has only 3 values -1,0 or +1.

"Et voilà!"

Unregistered from CPCwiki forum.

#### Overflow

Quote from: ralferoo on 11:37, 22 March 14
(...) looks a lot like a copperlist for the Amiga...
Try the DMA-list from the 6128+.
Unregistered from CPCwiki forum.

#### MacDeath

QuoteYou still have the dsk with basic launcher to test palettes, don't you?
lol no, you erased it or took it back home, too afraid I may/would release it before your release...