English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. Tutorials (https://eab.abime.net/forumdisplay.php?f=73)
-   -   Sine scroller (https://eab.abime.net/showthread.php?t=28937)

pmc 01 April 2007 19:06

Sine scroller
 
Can anyone explain the method used to apply sine effects to scrollers?

I don't want a source code cos I want to code a routine myself but I don't understand the way they're created.

How do I go about creating a sine table for my code and then use this sine data to effect the displayed bitplane?

bobbybearing 01 April 2007 20:07

you can create a sin tab 0 to 360 degree with a simple BASIC program or use a sintab creator on Amiga (or on Windows: sincreator by the gang http://www.thegang.nu/ )

there are 2 types of sine scrollers Y (and 2 with X -vertical scroller)

DYCP (Different Y Character Position) : a line of text where each character is displayed in a Y position following a sintab. More simple to do. use a character matrix to save y pos of each char.

DYPP (Different Y Pixel Position) : the scrollbuffer (the line of text) is broken apart at every pixel ("One Pixel"), and each strip is displayed in a different Y position following a sintab. more difficult to code and more Blitter used. many sin scrollers are in 2 pixels (skidrow lemmings intro). (in dycp, the width of strip is = width of char)

there are also DXCP, DXPP, and DXYCP

now, which other infos you need ?

musashi5150 01 April 2007 20:41

The DYPP method above is what I think of as a sinus scroller :)

All you need to do is plot a vertical strip of your scrollbuffer on the screen every 1 pixel (or 2,3,4..x pixels). You can use the Blitter for this. You may have trouble using 3+ planes due to the amount of Blitter work needed if you want to keep it running in 1 frame ;)

bobbybearing 01 April 2007 20:48

?! a DYCP is a sinus scroller Width-of-char pixels !

musashi5150 01 April 2007 21:44

Quote:

Originally Posted by bobbybearing
?! a DYCP is a sinus scroller Width-of-char pixels !

Yes it is. Sorry if what I said was misunderstood.

pmc 01 April 2007 21:56

Nice one chaps. Appreciated.

I'll give it a try and see how I get on...

pmc 13 April 2007 16:17

Quick update...
 
Thought I'd let you know how I'm getting on with my sinescroll routine.

Things are moving VERY slowly because I'm in no way, shape or form a very experienced coder! I've only ever done a few routines so this is by far the biggest thing I've attempted and is therefore taxing my ageing brain quite heavily!

I've got all my data defined now (font, logo, sine table etc.) and all the various parts of the routine are there - some working, some in embryo.

I try to break the code into smaller tasks and then have an educated stab at writing a routine to perform each task, test it, tweak it, get it working and write the next one.

So far my code forbids multitasking, saves the system copper list, installs my own copper list, opens a 1 bitmap screen with a couple of border copper bars, blits my logo into that screen, and then sits there waiting for the left mouse button before restoring all the system stuff and quitting back to the OS.

I've also successfully tested the routine that grabs the characters from my scrolltext and translates their ASCII character codes into positions in my font bitmap to grab the correct character image from before blitting into the scrollplane.

Next I need to do the scrolling, probably using the blitter and shifting (not 100% sure how to do this yet so the routine is embryo currently), and the routine that copies the scroll plane data to the displayed bitmap using the sine values as y-offsets - again I've only currently got this routine in embryo form.

Once it's all (should I say if I can ever get it all...!) working I'm gonna try to stick the main routine in a copper interrupt too.

If anyone's interested in checking the current source code I'm more than happy to share / discuss / get told how wrong I'm doing it! It's commented and all the data is self contained, font and logo etc. are all defined as dc.w lists...

bobbybearing 13 April 2007 16:27

why not ? you send the source by pm or in the zone
very interresting and hard work to start from scratch!

pmc 13 April 2007 20:51

Source in the zone...
 
Thanks bobbybearing.

I've posted the sinescroll source to the zone.

bobbybearing 13 April 2007 22:35

wooo
you seems to want make all in one step!

have you tested each routine, step by step, before put the whole routs in interrupt ?

first test if text appear on main screen, to see if modulos or addresses are good.
then make a scroll routine and test it in the main loop with a wait vbl
wait_lmb:
move.l $dff004,d0
and.l #$1ff00,d0
cmpi.l #256<<8,d0
bne.s wait_lmb

bsr get_char_pos

btst #6,mouse
bne.s wait_lmb

and if these 2 routs run fine, you can start the sinus copy. it's more simple to detect bug.

/!\ : in case of animation, you have to use the double buffering for a good result !

start your code with :
movem.l d0-d7/a0-a6,-(sp)
and end the code with:
movem.l (sp)+,d0-d7/a0-a6
moveq #0,d0 ; no error
rts

try to use decimal value for some registers like modulos, bltsize... you can write expressions. more simple to read

about the interrupt, you miss to save and restore intreq/intena registers.
Terminate your interrupt with rte, and not the old address and rts

about scroll : more smooth 8!

sin rout : stay in loop => freeze

pmc 13 April 2007 22:58

Thanks for taking the time to go through my undoubtedly amateur source code - all your help & advice is appreciated!

I have had a version of the code running where I tested the get_char routine and proved it grabs the characters from the font bitmap properly cos I blitted into the displayed screen so I could see the result.

I also did the same thing with the scoll part (I scrolled a chunk of the displayed bitplane) but my code as it is did weird things so I need give that part some more thought.

I'll try to pick apart all the bits of advice you've noted down and see if I can get the code edited accordingly...

Even though there are big errors in the code that need to be corrected, am I on the right track as far as the actual method for getting a sinescoller working goes?

In particular I wasn't sure about the sine copy part, the way my thinking went on this was to grab a word width chunk of the scrollplane, mask off 15 bits of this word, so I could blit just one line of the data into the displayed screen, and repeat this blit of the same word 16 times, each time masking off different bits and adding the next y value from the sine table before moving onto the next word of the scrollplane and repeating. Is that in the right ball park?

pmc 13 April 2007 23:07

Ooops, nearly forgot, just a couple more questions:

Do you need double buffering to make everything smooth even if the routine runs in 1 frame - ie. all the screen updates are done during the vertical blank?

Also, I didn't quite follow what you meant when you said about the scroll : more smooth 8...

bobbybearing 13 April 2007 23:15

yes, to make everything smooth, you need double buf, and more in the case of sinscroller (because of flickering)!

Edit: Oooops... sorry about the scroll, It's OK, very smooth (I made a little error in my test :laughing )

for sin, it's the idea... keep on Good work

bobbybearing 14 April 2007 00:01

little error at the beginning of get_char_pos when text=255
move.l #scroll_text,scroll_ptr
move.l scroll_ptr,a0

pmc 14 April 2007 00:03

I'll keep on keeping on with it... Hopefully during the next week I can improve it and come back with an updated source...

pmc 14 April 2007 00:09

Quote:

Originally Posted by bobbybearing
little error at the beginning of get_char_pos when text=255
move.l #scroll_text,scroll_ptr
move.l scroll_ptr,a0

Ahhh, I see it - well spotted!

:great

pmc 14 April 2007 23:21

Another step forward...
 
I've been tweaking with my source code again this evening - I've posted the updated version in the zone...

Following your advice about testing, I made some changes:

I made the displayed screen 4 bytes wider so that I could blit the scrolltext characters off screen to the right and then scroll them on screen. After playing with my blitter shift scrolling routine for a bit it now works properly and scrolls the scrolltext across the middle of the displayed bitplane in a continuous loop.

First, I did this within the wait for vertical blank code you gave me and got it working that way. Next I put it all into the copper interrupt and got it working that way too.

One quick thing about the copper interrupt. You recommended using rte instead of putting the old address on the stack and doing an rts. So I changed the interrupt_done code from:

movem.l (sp)+,d0-d7/a0-a6
move.l cop_int_address,-(sp)
rts

to:

movem.l (sp)+,d0-d7/a0-a6
rte

but then the program didn't work properly, the scrolly still scrolled but it didn't quit when I pressed the left mouse button - am I missing something?

bobbybearing 15 April 2007 00:15

yes, with rte you have to initialize the interruption in another way

there are 3 ways to manage interruptions :
- simple interruption:
Code:

start:
... save Intena registers
move.l $6c.w,saveint
move.l #newint,$6c.w
move.w #$c010,$dff09a ; (intreq)
...
move.l saveint,$6c.w ; restore old int
rts
newint:
movem.l d0/a6,-(sp)
move.w $dff01c,d0 ; intenar
btst #$e,d0
beq.s noint
and.w $dff01e,d0 ; intreqr
btst #4,d0
beq.s noint
...
move.w #$10,$dff09c ; intreq
noint:
movem.l (sp)+,d0/a6
rte

- you use this one:
Code:

start:
... save intena
move.l $6c.w,saveint
move.l #newint,$6c.w
move.w #$c010,$dff09a
...
move.l saveint,$6c.w
rts
newint:
movem.l d0/a6,-(sp)
noint:
movem.l (sp)+,d0/a6
move.l saveint,-(sp)
rts

- third:
Code:

start:
...
move.w $dff01c,d0 ; intenar
or.w #$8000,d0
move.w d0,saveintena
move.w #$7fff,$dff09a
wait_it:
btst #4,$dff01e
beq.s wait_it
move.w #$10,$dff09c
... prog
bra wait_it


bobbybearing 15 April 2007 00:27

personaly, I initialize like that :
Code:

start:
...
move.w $10(a6),d0 ;save adkcon
ori.w #$8000,d0
move.w d0,adkcon(a5)
move.w 2(a6),d0 ;save dma
ori.w #$8000,d0
move.w d0,sDma(a5)
move.w $1c(a6),d0 ;save intena
ori.w #$8000,d0
move.w d0,intena(a5)

bsr waitvbl
move.w #$7fff,d0
move.w d0,$9a(a6) ; disable interrupts
move.w d0,$96(a6) ; stop dma channels
move.w d0,$9c(a6) ; stop int requests
       
move.l        $6c.w,saveintvbl ; or $6c(a1) with a1=VBR if you get vbr
lea interrupt(pc),a0
move.l a0,$6c.w

move.w        #$8000|$4000|$20,$9a(a6) ; start vbl interrupt
move.w        #$8200|$100|$80|$40,$96(a6) ; init dma

bsr Main
; restore
bsr waitvbl
move.w #$7fff,d0
move.w d0,$96(a6)
move.w d0,$9a(a6)
move.w d0,$9c(a6)
       
move.l        saveintvbl,$6c.w
move.w        intena(a5),$9a(a6)
move.w        sDma(a5),$96(a6)
move.w        adkcon(a5),$9e(a6)
...
rts
------------------
interrupt:
movem.l d0/a6,-(sp)
lea $dff000,a6
andi.w #$20,$1e(a6) ; it's possible to skip test
beq noint
...
move.w #$20,$dff09c ; twice (a4000 bug)
move.w #$20,$dff09c
noint
movem.l (sp)+,d0/a6
rte


pmc 15 April 2007 00:29

OK, thanks. Interrupts are something I've never played with before and are definitely something I'm still trying to get my head fully around.

Now I think it's time to try and get the sine copy routine working!


All times are GMT +2. The time now is 06:49.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.10650 seconds with 11 queries