home *** CD-ROM | disk | FTP | other *** search
- *******************************************************************************
- * Example scope for HippoPlayer
- * By K-P Koljonen
- *******************************************************************************
- * Can be assembled with Asm-One v1.25, at least.
- * Works on all Amiga configurations!
-
- * Version 1.1: Considered sample length to be bytes when it actually was in
- * words.
- * V1.2: Little fix.
-
-
- *** Includes:
-
- incdir include:
- include exec/exec_lib.i
- include exec/ports.i
- include exec/types.i
- include graphics/graphics_lib.i
- include graphics/rastport.i
- include intuition/intuition_lib.i
- include intuition/intuition.i
- incdir
-
- *** Some useful macros
-
- lob macro
- jsr _LVO\1(a6)
- endm
-
- lore macro
- ifc "\1","Exec"
- ifd _ExecBase
- ifeq _ExecBase
- move.l (a5),a6
- else
- move.l _ExecBase(a5),a6
- endc
- else
- move.l 4.w,a6
- endc
- else
- move.l _\1Base(a5),a6
- endc
- jsr _LVO\2(a6)
- endm
-
- pushm macro
- ifc "\1","all"
- movem.l d0-a6,-(sp)
- else
- movem.l \1,-(sp)
- endc
- endm
-
- popm macro
- ifc "\1","all"
- movem.l (sp)+,d0-a6
- else
- movem.l (sp)+,\1
- endc
- endm
-
- push macro
- move.l \1,-(sp)
- endm
-
- pop macro
- move.l (sp)+,\1
- endm
-
-
-
- *** HippoPlayer's port:
-
- STRUCTURE HippoPort,MP_SIZE
- LONG hip_private1 * Private..
- APTR hip_kplbase * kplbase address
- WORD hip_reserved0 * Private..
- BYTE hip_reserved1 * Private..
- BYTE hip_opencount * Open count
- BYTE hip_mainvolume * Main volume, 0-64
- BYTE hip_play * If non-zero, HiP is playing
- BYTE hip_playertype * 33 = Protracker, 49 = PS3M.
- *** Protracker ***
- BYTE hip_reserved2
- APTR hip_PTch1 * Protracker channel data for ch1
- APTR hip_PTch2 * ch2
- APTR hip_PTch3 * ch3
- APTR hip_PTch4 * ch4
- *** PS3M ***
- APTR hip_ps3mleft * Buffer for the left side
- APTR hip_ps3mright * Buffer for the right side
- LONG hip_ps3moffs * Playing position
- LONG hip_ps3mmaxoffs * Max value for hip_ps3moffs
-
- BYTE hip_PTtrigger1
- BYTE hip_PTtrigger2
- BYTE hip_PTtrigger3
- BYTE hip_PTtrigger4
-
- LABEL HippoPort_SIZEOF
-
- *** PT channel data block
- STRUCTURE PTch,0
- LONG PTch_start * Start address of sample
- WORD PTch_length * Length of sample in words
- LONG PTch_loopstart * Start address of loop
- WORD PTch_replen * Loop length in words
- WORD PTch_volume * Channel volume
- WORD PTch_period * Channel period
- WORD PTch_private1 * Private...
-
- *** Dimensions:
-
- WIDTH = 320
- HEIGHT = 64
-
- *** Variables:
-
- rsreset
- _ExecBase rs.l 1
- _GFXBase rs.l 1
- _IntuiBase rs.l 1
- port rs.l 1
- owntask rs.l 1
- screenlock rs.l 1
- oldpri rs.l 1
- windowbase rs.l 1
- rastport rs.l 1
- userport rs.l 1
- windowtop rs 1
- windowright rs 1
- windowleft rs 1
- windowbottom rs 1
- draw1 rs.l 1
- draw2 rs.l 1
- omabitmap rs.b bm_SIZEOF
- size_var rs.b 0
-
- *** Main program
-
- main lea var_b,a5 * Store execbase
- move.l 4.w,a6
- move.l a6,(a5)
-
- sub.l a1,a1 * Find our process
- lob FindTask
- move.l d0,owntask(a5)
-
- lea intuiname(pc),a1 * Open libs
- lore Exec,OldOpenLibrary
- move.l d0,_IntuiBase(a5)
-
- lea gfxname(pc),a1
- lob OldOpenLibrary
- move.l d0,_GFXBase(a5)
-
- *** Try to find HippoPlayer's port. If succesful, add 1 to hip_opencount
- *** indicating we are using the information in the port.
- *** Protect this procedure with Forbid()-Permit()!
-
- lob Forbid
- lea portname(pc),a1
- lob FindPort
- move.l d0,port(a5)
- beq.w exit
- move.l d0,a0
- addq.b #1,hip_opencount(a0) * We are using the port now!
- lob Permit
-
- *** Get some info about the screen we're running on
-
- bsr.w getscreendata
-
- *** Open our window
-
- lea winstruc,a0
- lore Intui,OpenWindow
- move.l d0,windowbase(a5)
- beq.w exit
- move.l d0,a0
- move.l wd_RPort(a0),rastport(a5) * Store rastport and userport
- move.l wd_UserPort(a0),userport(a5)
-
- *** Draw a bevel box
-
- plx1 equr d4
- plx2 equr d5
- ply1 equr d6
- ply2 equr d7
-
- moveq #8,plx1
- move #331,plx2
- moveq #13,ply1
- moveq #80,ply2
- add windowleft(a5),plx1
- add windowleft(a5),plx2
- add windowtop(a5),ply1
- add windowtop(a5),ply2
- move.l rastport(a5),a2
- bsr.w piirra_loota2
- subq #1,plx1
- addq #1,plx2
- bsr.w piirra_loota2a
-
- *** Initialize the bitmap structure
-
- lea omabitmap(a5),a0
- moveq #1,d0 * depth (1 bitplane)
- move #WIDTH,d1 * width
- move #HEIGHT,d2 * height
- lore GFX,InitBitMap
- move.l #buffer1,omabitmap+bm_Planes(a5) * Plane pointer
-
- move.l #buffer1,draw1(a5) * Buffer pointers for drawing
- move.l #buffer2,draw2(a5)
-
- *** Set task priority to -30 to prevent messing up with other programs
-
- move.l owntask(a5),a1
- moveq #-30,d0
- lore Exec,SetTaskPri
- move.l d0,oldpri(a5) * Store the old priority
-
- *** Main loop begins here
-
- loop move.l _GFXBase(a5),a6 * Wait a while..
- lob WaitTOF
-
- move.l port(a5),a0 * Check if HiP is playing
- tst.b hip_play(a0)
- beq.b .oh
- bsr.w dung * Do the scope
- .oh
- move.l userport(a5),a0 * Get messages from IDCMP
- lore Exec,GetMsg
- tst.l d0
- beq.b loop
- move.l d0,a1
-
- move.l im_Class(a1),d2
- lob ReplyMsg
- cmp.l #IDCMP_CLOSEWINDOW,d2 * Should we exit?
- bne.b loop * No. Keep loopin'
-
- move.l owntask(a5),a1 * Restore the old priority
- move.l oldpri(a5),d0
- lore Exec,SetTaskPri
-
- exit
-
- *** Exit program
-
- move.l port(a5),d0 * IMPORTANT! Subtract 1 from
- beq.b .uh0 * hip_opencount when the port is not
- move.l d0,a0 * needed anymore!
- subq.b #1,hip_opencount(a0)
- .uh0
-
- move.l windowbase(a5),d0 * Close the window
- beq.b .uh1
- move.l d0,a0
- lore Intui,CloseWindow
- .uh1
- move.l _IntuiBase(a5),a1 * And the libs
- lore Exec,CloseLibrary
- move.l _GFXBase(a5),a1
- lob CloseLibrary
-
- moveq #0,d0 * No error
- rts
-
- ***** Get some info about the screen we're running on
-
- getscreendata
- move.l (a5),a0 * Running kick2.0 or newer?
- cmp #37,LIB_VERSION(a0)
- bhs.b .new
- rts
- .new * Yes.
-
- sub.l a0,a0 * Default public screen
- lore Intui,LockPubScreen * Kick2.0+ function
- move.l d0,d7
- beq.b exit
-
- move.l d0,a0 * Store the values
- move.b sc_BarHeight(a0),windowtop+1(a5)
- move.b sc_WBorLeft(a0),windowleft+1(a5)
- move.b sc_WBorRight(a0),windowright+1(a5)
- move.b sc_WBorBottom(a0),windowbottom+1(a5)
- subq #4,windowleft(a5)
- subq #4,windowright(a5)
- subq #2,windowbottom(a5)
- sub #10,windowtop(a5)
- bpl.b .olde
- clr windowtop(a5)
- .olde
- move windowtop(a5),d0 * Adjust the window size
- add d0,winstruc+nw_Height
- move windowleft(a5),d1
- add d1,winstruc+nw_Width
- move windowbottom(a5),d3
- add d3,winstruc+nw_Height
-
- move.l d7,a1 * Unlock it. Let's hope it doesn't
- sub.l a0,a0 * go anywhere before we open our
- lob UnlockPubScreen * window ;-)
- rts
-
-
- *** Draw a bevel box
-
- piirra_loota2a
- pushm all
- moveq #1,d3
- bra.b prl
-
- piirra_loota2
- pushm all
- moveq #0,d3
- prl
- move.l rastport(a5),a2
- move #1,a3
- move #2,a4
-
- move.l _GFXBase(a5),a6
- move.l a3,d0
- move.l a2,a1
- lob SetAPen
-
- move.l plx1,d0
- move.l ply2,d1
- lob Move
- move.l a2,a1
- move.l plx1,d0
- move.l ply1,d1
- lob Draw
-
- move.l a2,a1
- move.l plx2,d0
- move.l ply1,d1
- lob Draw
-
- move.l a2,a1
- move.l a4,d0
- lob SetAPen
-
- move.l a2,a1
- move.l plx2,d0
- move.l ply1,d1
- addq.l #1,d1
- sub.l d3,d1
- lob Move
- move.l a2,a1
- move.l plx2,d0
- move.l ply2,d1
- lob Draw
-
- move.l a2,a1
- move.l plx1,d0
- addq.l #1,d0
- move.l ply2,d1
- lob Draw
-
- move.l a2,a1
- moveq #1,d0
- lob SetAPen
-
- popm all
- rts
-
-
-
- *** Display the scope
-
- * I have two buffers, one for drawing and one for clearing.
- * Clearing is done with blitter during which cpu draws into the other
- * buffer. The drawn buffer is then dumped into the window using
- * BltBitMapRastPort(). If someone knows a faster way for doing this please
- * tell me.
-
- dung
- move.l _GFXBase(a5),a6 * Grab the blitter
- lob OwnBlitter
- lob WaitBlit
-
- * Clear the drawing area using 'demo programmer code'.. :)
- move.l draw2(a5),$dff054 * Blitter destination D
- move #0,$dff066 * Modulo D
- move.l #$01000000,$dff040 * Enable D
- move #HEIGHT*64+WIDTH/16,$dff058 * Write size, start blitter
-
- lob DisownBlitter * Free the blitter
-
- pushm all
- move.l port(a5),a0
- cmp.b #33,hip_playertype(a0) * Protracker?
- beq.b .1
- cmp.b #49,hip_playertype(a0) * PS3M?
- beq.b .2
- bra.b .3
- .1 bsr.b quadrascope * Quadrascope for PT
- bra.b .3
- .2 bsr.w multiscope * Stereoscope for PS3M
- .3 popm all
-
- movem.l draw1(a5),d0/d1 * Switch the buffers
- exg d0,d1
- movem.l d0/d1,draw1(a5)
-
- lea omabitmap(a5),a0 * Set the bitplane pointer
- move.l d1,bm_Planes(a0)
-
- ; lea omabitmap(a5),a0 * Copy from bitmap to rastport
- move.l rastport(a5),a1
- moveq #0,d0 * source x,y
- moveq #0,d1
- moveq #10,d2 * dest x,y
- moveq #15,d3
- add windowleft(a5),d2
- add windowtop(a5),d3
- move #$c0,d6 * minterm a->d
- move #WIDTH,d4 * x-size
- move #HEIGHT,d5 * y-size
- lore GFX,BltBitMapRastPort * Zwoosh!
- rts
-
- *** Quarascope routine for Protracker
-
- * This (and the stereoscope) are very unoptimized. The reason for this is
- * that unoptimized code is usually easier to understand than optimized code.
- * Also this leaves a certain challenge for coders to try to get the loop
- * as fast as possible.
-
- quadrascope
- move.l port(a5),a3
- move.l hip_PTch1(a3),a3 * Channel 1 data
- move.l draw1(a5),a0
- bsr.b .scope
-
- * WIDTH/8/4 = 10
-
- move.l port(a5),a3
- move.l hip_PTch2(a3),a3
- move.l draw1(a5),a0
- lea 10(a0),a0 * Position
- bsr.b .scope
-
- move.l port(a5),a3
- move.l hip_PTch3(a3),a3
- move.l draw1(a5),a0
- lea 10+10(a0),a0
- bsr.b .scope
-
- move.l port(a5),a3
- move.l hip_PTch4(a3),a3
- move.l draw1(a5),a0
- lea 10+10+10(a0),a0
- bsr.b .scope
- rts
-
- .scope
- tst.l PTch_loopstart(a3) * Always check these to avoid
- beq.b .halt * enforcer hits!
- move.l PTch_start(a3),d0
- bne.b .jolt
- .halt rts
-
- .jolt
- move.l d0,a1 * Sample start
- moveq #0,d5
- move PTch_length(a3),d5 * Sample length in words
- add.l d5,d5 * Convert to bytes
-
- move.l port(a5),a2 * Get mainvolume
- moveq #0,d1
- move.b hip_mainvolume(a2),d1 * (Main volume * sample volume)/64
- mulu PTch_volume(a3),d1
- lsr #6,d1 * Value for scaling the data
-
- moveq #0,d0 * X coordinate
- moveq #80-1,d7 * Loop counter, do 80 pixels
- drlo
- move.b (a1)+,d2 * Read one byte sample data
- ext d2 * Sign extend to word
- muls d1,d2 * Scale according to volume
- asr #6,d2 * ...
- add #$80,d2 * Change the sign
- asr #2,d2 * Scale down to 0-63
- mulu #WIDTH/8,d2 * Get Y coordinate in the bitplane
-
- move d0,d4 * X
- move d0,d3
- lsr #3,d4 * X offset in bytes = x-coord/8
- add d4,d2 * Add to Y
- not d3 * Plot pixel
- bset d3,(a0,d2) * ...
-
- subq.l #1,d5 * Subtract sample length
- bpl.b .l * sample end?
- moveq #0,d5 * Get values for loop
- move PTch_replen(a3),d5
- add.l d5,d5
- move.l PTch_loopstart(a3),a1
- .l
- addq #1,d0 * Increase X
-
- dbf d7,drlo * Loop..
- rts
-
-
-
- *** Stereoscope for PS3M
-
- multiscope
- move.l port(a5),a1
- move.l hip_ps3mleft(a1),a1
- move.l draw1(a5),a0
- bsr.b .h
-
- move.l port(a5),a1
- move.l hip_ps3mright(a1),a1
- move.l draw1(a5),a0
- lea WIDTH/8/2(a0),a0
- bsr.b .h
- rts
-
- .h move.l port(a5),a2
- move.l hip_ps3moffs(a2),d5 * Get offset in buffers
- move.l hip_ps3mmaxoffs(a2),d4 * Get max offset
-
- move #160-1,d7 * Draw 160 pixels
- moveq #0,d0 * X coord
- .drlo
- moveq #0,d2
- move.b (a1,d5.l),d2 * Get data from mixing buffer
- add.b #$80,d2
- lsr #2,d2
- mulu #WIDTH/8,d2 * Y
-
- move d0,d6
- move d0,d3
- lsr #3,d6 * X offset in bytes = x-coord/8
- add d6,d2
- not d3 * Plot pixel
- bset d3,(a0,d2) * ...
-
- addq #1,d0 * Increase x coord
- addq.l #1,d5 * Increase buffer position
- and.l d4,d5 * make sure it stays in the buffer
-
- dbf d7,.drlo * Loop
- rts
-
-
-
- *******************************************************************************
- * Window
-
- wflags = WFLG_SMART_REFRESH!WFLG_DRAGBAR!WFLG_CLOSEGADGET!WFLG_DEPTHGADGET
- idcmpflags = IDCMP_CLOSEWINDOW
-
- winstruc
- dc 110,85 * x,y position
- winsiz dc 340,85 * x,y size
- dc.b 2,1
- dc.l idcmpflags
- dc.l wflags
- dc.l 0
- dc.l 0
- dc.l .t * title
- dc.l 0
- dc.l 0
- dc 0,640 * min/max x
- dc 0,256 * min/max y
- dc WBENCHSCREEN
- dc.l 0
-
- .t dc.b "HiP - Example scope",0
-
- intuiname dc.b "intuition.library",0
- gfxname dc.b "graphics.library",0
- portname dc.b "HiP-Port",0
- even
-
-
- section udnm,bss_p
-
- * Variables
-
- var_b ds.b size_var
-
- section hihi,bss_c
-
- * GFX buffers
-
- buffer1 ds.b WIDTH/8*HEIGHT
- buffer2 ds.b WIDTH/8*HEIGHT
-
- end
-