home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 1 / amigaformatcd01.iso / pd / music / utilities / hippoplayer / scopes / examplescope.s next >
Text File  |  1996-04-30  |  12KB  |  603 lines

  1. *******************************************************************************
  2. *                         Example scope for HippoPlayer
  3. *                            By K-P Koljonen
  4. *******************************************************************************
  5. * Can be assembled with Asm-One v1.25, at least. 
  6. * Works on all Amiga configurations!
  7.  
  8. * Version 1.1: Considered sample length to be bytes when it actually was in
  9. *              words.
  10. * V1.2:           Little fix.
  11.  
  12.  
  13. *** Includes:
  14.  
  15.      incdir    include:
  16.     include    exec/exec_lib.i
  17.     include    exec/ports.i
  18.     include    exec/types.i
  19.     include    graphics/graphics_lib.i
  20.     include    graphics/rastport.i
  21.     include    intuition/intuition_lib.i
  22.     include    intuition/intuition.i
  23.     incdir
  24.  
  25. *** Some useful macros
  26.  
  27. lob    macro
  28.     jsr    _LVO\1(a6)
  29.     endm
  30.  
  31. lore    macro
  32.     ifc    "\1","Exec"
  33.     ifd    _ExecBase
  34.     ifeq    _ExecBase
  35.     move.l    (a5),a6
  36.     else
  37.     move.l    _ExecBase(a5),a6
  38.     endc
  39.     else
  40.     move.l    4.w,a6
  41.     endc
  42.     else
  43.     move.l    _\1Base(a5),a6
  44.     endc
  45.     jsr    _LVO\2(a6)
  46.     endm
  47.  
  48. pushm    macro
  49.     ifc    "\1","all"
  50.     movem.l    d0-a6,-(sp)
  51.     else
  52.     movem.l    \1,-(sp)
  53.     endc
  54.     endm
  55.  
  56. popm    macro
  57.     ifc    "\1","all"
  58.     movem.l    (sp)+,d0-a6
  59.     else
  60.     movem.l    (sp)+,\1
  61.     endc
  62.     endm
  63.  
  64. push    macro
  65.     move.l    \1,-(sp)
  66.     endm
  67.  
  68. pop    macro
  69.     move.l    (sp)+,\1
  70.     endm
  71.  
  72.  
  73.  
  74. *** HippoPlayer's port:
  75.  
  76.     STRUCTURE    HippoPort,MP_SIZE
  77.     LONG        hip_private1    * Private..
  78.     APTR        hip_kplbase    * kplbase address
  79.     WORD        hip_reserved0    * Private..
  80.     BYTE        hip_reserved1    * Private..
  81.     BYTE        hip_opencount    * Open count
  82.     BYTE        hip_mainvolume    * Main volume, 0-64
  83.     BYTE        hip_play    * If non-zero, HiP is playing
  84.     BYTE        hip_playertype     * 33 = Protracker, 49 = PS3M. 
  85.     *** Protracker ***
  86.     BYTE        hip_reserved2
  87.     APTR        hip_PTch1    * Protracker channel data for ch1
  88.     APTR        hip_PTch2    * ch2
  89.     APTR        hip_PTch3    * ch3
  90.     APTR        hip_PTch4    * ch4
  91.     *** PS3M ***
  92.     APTR        hip_ps3mleft    * Buffer for the left side
  93.     APTR        hip_ps3mright    * Buffer for the right side
  94.     LONG        hip_ps3moffs    * Playing position
  95.     LONG        hip_ps3mmaxoffs    * Max value for hip_ps3moffs
  96.  
  97.     BYTE        hip_PTtrigger1
  98.     BYTE        hip_PTtrigger2
  99.     BYTE        hip_PTtrigger3
  100.     BYTE        hip_PTtrigger4
  101.  
  102.     LABEL        HippoPort_SIZEOF 
  103.  
  104.     *** PT channel data block
  105.     STRUCTURE    PTch,0
  106.     LONG        PTch_start    * Start address of sample
  107.     WORD        PTch_length    * Length of sample in words
  108.     LONG        PTch_loopstart    * Start address of loop
  109.     WORD        PTch_replen    * Loop length in words
  110.     WORD        PTch_volume    * Channel volume
  111.     WORD        PTch_period    * Channel period
  112.     WORD        PTch_private1    * Private...
  113.  
  114. *** Dimensions:
  115.  
  116. WIDTH    =    320    
  117. HEIGHT    =    64
  118.  
  119. *** Variables:
  120.  
  121.     rsreset
  122. _ExecBase    rs.l    1
  123. _GFXBase    rs.l    1
  124. _IntuiBase    rs.l    1
  125. port        rs.l    1
  126. owntask        rs.l    1
  127. screenlock    rs.l    1
  128. oldpri        rs.l    1
  129. windowbase    rs.l    1
  130. rastport    rs.l    1
  131. userport    rs.l    1
  132. windowtop    rs    1
  133. windowright    rs    1
  134. windowleft    rs    1
  135. windowbottom    rs    1
  136. draw1        rs.l    1
  137. draw2        rs.l    1
  138. omabitmap    rs.b    bm_SIZEOF
  139. size_var    rs.b    0
  140.  
  141. *** Main program
  142.  
  143. main    lea    var_b,a5        * Store execbase
  144.     move.l    4.w,a6
  145.     move.l    a6,(a5)
  146.     
  147.     sub.l    a1,a1            * Find our process
  148.     lob    FindTask
  149.     move.l    d0,owntask(a5)
  150.  
  151.     lea    intuiname(pc),a1    * Open libs
  152.     lore    Exec,OldOpenLibrary
  153.     move.l    d0,_IntuiBase(a5)
  154.  
  155.     lea     gfxname(pc),a1        
  156.     lob    OldOpenLibrary
  157.     move.l    d0,_GFXBase(a5)
  158.  
  159. *** Try to find HippoPlayer's port. If succesful, add 1 to hip_opencount
  160. *** indicating we are using the information in the port.
  161. *** Protect this procedure with Forbid()-Permit()!
  162.  
  163.     lob    Forbid
  164.     lea    portname(pc),a1
  165.     lob    FindPort
  166.     move.l    d0,port(a5)
  167.     beq.w    exit
  168.     move.l    d0,a0
  169.     addq.b    #1,hip_opencount(a0)    * We are using the port now!
  170.     lob    Permit
  171.  
  172. *** Get some info about the screen we're running on
  173.  
  174.     bsr.w    getscreendata
  175.  
  176. *** Open our window
  177.  
  178.     lea    winstruc,a0
  179.     lore    Intui,OpenWindow
  180.     move.l    d0,windowbase(a5)
  181.     beq.w    exit
  182.     move.l    d0,a0
  183.     move.l    wd_RPort(a0),rastport(a5)    * Store rastport and userport
  184.     move.l    wd_UserPort(a0),userport(a5)
  185.  
  186. *** Draw a bevel box
  187.  
  188. plx1    equr    d4
  189. plx2    equr    d5
  190. ply1    equr    d6
  191. ply2    equr    d7
  192.  
  193.     moveq   #8,plx1
  194.     move    #331,plx2
  195.     moveq   #13,ply1
  196.     moveq   #80,ply2
  197.     add    windowleft(a5),plx1
  198.     add    windowleft(a5),plx2
  199.     add    windowtop(a5),ply1
  200.     add    windowtop(a5),ply2
  201.     move.l    rastport(a5),a2
  202.     bsr.w    piirra_loota2
  203.     subq    #1,plx1
  204.     addq    #1,plx2
  205.     bsr.w    piirra_loota2a
  206.  
  207. *** Initialize the bitmap structure
  208.  
  209.     lea    omabitmap(a5),a0
  210.     moveq    #1,d0            * depth (1 bitplane)
  211.     move    #WIDTH,d1        * width
  212.     move    #HEIGHT,d2        * height 
  213.     lore    GFX,InitBitMap
  214.     move.l    #buffer1,omabitmap+bm_Planes(a5) * Plane pointer
  215.  
  216.     move.l    #buffer1,draw1(a5)    * Buffer pointers for drawing
  217.     move.l    #buffer2,draw2(a5)
  218.  
  219. *** Set task priority to -30 to prevent messing up with other programs
  220.  
  221.     move.l    owntask(a5),a1        
  222.     moveq    #-30,d0
  223.     lore    Exec,SetTaskPri
  224.     move.l    d0,oldpri(a5)        * Store the old priority
  225.  
  226. *** Main loop begins here
  227.  
  228. loop    move.l    _GFXBase(a5),a6        * Wait a while..
  229.     lob    WaitTOF
  230.  
  231.     move.l    port(a5),a0        * Check if HiP is playing
  232.     tst.b    hip_play(a0)
  233.     beq.b    .oh
  234.     bsr.w    dung            * Do the scope
  235. .oh
  236.     move.l    userport(a5),a0        * Get messages from IDCMP
  237.     lore    Exec,GetMsg
  238.     tst.l    d0
  239.     beq.b    loop
  240.     move.l    d0,a1
  241.  
  242.     move.l    im_Class(a1),d2        
  243.     lob    ReplyMsg
  244.     cmp.l    #IDCMP_CLOSEWINDOW,d2    * Should we exit?
  245.     bne.b    loop            * No. Keep loopin'
  246.     
  247.     move.l    owntask(a5),a1        * Restore the old priority
  248.     move.l    oldpri(a5),d0
  249.     lore    Exec,SetTaskPri
  250.  
  251. exit
  252.  
  253. *** Exit program
  254.     
  255.     move.l    port(a5),d0        * IMPORTANT! Subtract 1 from
  256.     beq.b    .uh0            * hip_opencount when the port is not
  257.     move.l    d0,a0            * needed anymore!
  258.     subq.b    #1,hip_opencount(a0)
  259. .uh0
  260.  
  261.     move.l    windowbase(a5),d0    * Close the window
  262.     beq.b    .uh1
  263.     move.l    d0,a0
  264.     lore    Intui,CloseWindow
  265. .uh1
  266.     move.l    _IntuiBase(a5),a1    * And the libs
  267.     lore    Exec,CloseLibrary
  268.     move.l    _GFXBase(a5),a1
  269.     lob    CloseLibrary
  270.  
  271.     moveq    #0,d0            * No error
  272.     rts
  273.     
  274. ***** Get some info about the screen we're running on
  275.  
  276. getscreendata
  277.     move.l    (a5),a0            * Running kick2.0 or newer?
  278.     cmp    #37,LIB_VERSION(a0)
  279.     bhs.b    .new        
  280.     rts                
  281. .new                    * Yes.
  282.     
  283.     sub.l    a0,a0            * Default public screen
  284.     lore    Intui,LockPubScreen      * Kick2.0+ function
  285.     move.l    d0,d7
  286.     beq.b    exit
  287.  
  288.     move.l    d0,a0            * Store the values
  289.     move.b    sc_BarHeight(a0),windowtop+1(a5) 
  290.     move.b    sc_WBorLeft(a0),windowleft+1(a5)
  291.     move.b    sc_WBorRight(a0),windowright+1(a5)
  292.     move.b    sc_WBorBottom(a0),windowbottom+1(a5)
  293.     subq    #4,windowleft(a5)
  294.     subq    #4,windowright(a5)
  295.     subq    #2,windowbottom(a5)
  296.     sub    #10,windowtop(a5)
  297.     bpl.b    .olde
  298.     clr    windowtop(a5)
  299. .olde
  300.     move    windowtop(a5),d0    * Adjust the window size
  301.     add    d0,winstruc+nw_Height
  302.     move    windowleft(a5),d1
  303.     add    d1,winstruc+nw_Width
  304.     move    windowbottom(a5),d3
  305.     add    d3,winstruc+nw_Height
  306.  
  307.     move.l    d7,a1            * Unlock it. Let's hope it doesn't
  308.     sub.l    a0,a0            * go anywhere before we open our
  309.     lob    UnlockPubScreen        * window ;-)
  310.     rts
  311.  
  312.  
  313. *** Draw a bevel box
  314.  
  315. piirra_loota2a
  316.     pushm    all
  317.     moveq    #1,d3
  318.     bra.b    prl
  319.  
  320. piirra_loota2
  321.     pushm    all
  322.     moveq    #0,d3
  323. prl
  324.     move.l    rastport(a5),a2
  325.     move    #1,a3
  326.     move    #2,a4
  327.  
  328.     move.l    _GFXBase(a5),a6
  329.     move.l    a3,d0
  330.     move.l    a2,a1
  331.     lob    SetAPen
  332.  
  333.     move.l    plx1,d0
  334.     move.l    ply2,d1
  335.     lob    Move
  336.     move.l    a2,a1
  337.     move.l    plx1,d0
  338.     move.l    ply1,d1
  339.     lob    Draw
  340.  
  341.     move.l    a2,a1
  342.     move.l    plx2,d0
  343.     move.l    ply1,d1
  344.     lob    Draw
  345.  
  346.     move.l    a2,a1
  347.     move.l    a4,d0
  348.     lob    SetAPen
  349.  
  350.     move.l    a2,a1
  351.     move.l    plx2,d0
  352.     move.l    ply1,d1
  353.     addq.l    #1,d1
  354.     sub.l    d3,d1
  355.     lob    Move
  356.     move.l    a2,a1
  357.     move.l    plx2,d0
  358.     move.l    ply2,d1
  359.     lob    Draw
  360.  
  361.     move.l    a2,a1
  362.     move.l    plx1,d0
  363.     addq.l    #1,d0
  364.     move.l    ply2,d1
  365.     lob    Draw
  366.  
  367.     move.l    a2,a1
  368.     moveq    #1,d0
  369.     lob    SetAPen
  370.  
  371.     popm    all
  372.     rts
  373.  
  374.  
  375.  
  376. *** Display the scope
  377.  
  378. * I have two buffers, one for drawing and one for clearing.
  379. * Clearing is done with blitter during which cpu draws into the other
  380. * buffer. The drawn buffer is then dumped into the window using
  381. * BltBitMapRastPort().  If someone knows a faster way for doing this please
  382. * tell me.
  383.  
  384. dung
  385.     move.l    _GFXBase(a5),a6        * Grab the blitter
  386.     lob    OwnBlitter
  387.     lob    WaitBlit
  388.  
  389. * Clear the drawing area using 'demo programmer code'.. :)
  390.     move.l    draw2(a5),$dff054    * Blitter destination D
  391.     move    #0,$dff066        * Modulo D
  392.     move.l    #$01000000,$dff040    * Enable D
  393.     move    #HEIGHT*64+WIDTH/16,$dff058 * Write size, start blitter
  394.  
  395.     lob    DisownBlitter        * Free the blitter
  396.  
  397.     pushm    all
  398.     move.l    port(a5),a0
  399.     cmp.b    #33,hip_playertype(a0)    * Protracker?
  400.     beq.b    .1
  401.     cmp.b    #49,hip_playertype(a0)    * PS3M?
  402.     beq.b    .2
  403.     bra.b    .3
  404. .1    bsr.b    quadrascope        * Quadrascope for PT
  405.     bra.b    .3
  406. .2    bsr.w    multiscope        * Stereoscope for PS3M
  407. .3    popm    all
  408.  
  409.     movem.l    draw1(a5),d0/d1        * Switch the buffers
  410.     exg    d0,d1
  411.     movem.l    d0/d1,draw1(a5)
  412.  
  413.     lea    omabitmap(a5),a0    * Set the bitplane pointer
  414.     move.l    d1,bm_Planes(a0)
  415.  
  416. ;    lea    omabitmap(a5),a0    * Copy from bitmap to rastport
  417.     move.l    rastport(a5),a1
  418.     moveq    #0,d0        * source x,y
  419.     moveq    #0,d1
  420.     moveq    #10,d2        * dest x,y
  421.     moveq    #15,d3
  422.     add    windowleft(a5),d2
  423.     add    windowtop(a5),d3
  424.     move    #$c0,d6        * minterm a->d
  425.     move    #WIDTH,d4    * x-size
  426.     move    #HEIGHT,d5    * y-size
  427.     lore    GFX,BltBitMapRastPort    * Zwoosh!
  428.     rts
  429.  
  430. *** Quarascope routine for Protracker
  431.  
  432. * This (and the stereoscope) are very unoptimized. The reason for this is
  433. * that unoptimized code is usually easier to understand than optimized code.
  434. * Also this leaves a certain challenge for coders to try to get the loop
  435. * as fast as possible.
  436.  
  437. quadrascope
  438.     move.l    port(a5),a3
  439.     move.l    hip_PTch1(a3),a3    * Channel 1 data
  440.     move.l    draw1(a5),a0        
  441.     bsr.b    .scope
  442.  
  443. * WIDTH/8/4 = 10
  444.  
  445.     move.l    port(a5),a3
  446.     move.l    hip_PTch2(a3),a3
  447.     move.l    draw1(a5),a0
  448.     lea    10(a0),a0        * Position
  449.     bsr.b    .scope
  450.  
  451.     move.l    port(a5),a3
  452.     move.l    hip_PTch3(a3),a3
  453.     move.l    draw1(a5),a0
  454.     lea    10+10(a0),a0
  455.     bsr.b    .scope
  456.  
  457.     move.l    port(a5),a3
  458.     move.l    hip_PTch4(a3),a3
  459.     move.l    draw1(a5),a0
  460.     lea    10+10+10(a0),a0
  461.     bsr.b    .scope
  462.     rts
  463.  
  464. .scope
  465.     tst.l    PTch_loopstart(a3)    * Always check these to avoid
  466.     beq.b    .halt            * enforcer hits!
  467.     move.l    PTch_start(a3),d0
  468.     bne.b    .jolt
  469. .halt    rts
  470.  
  471. .jolt    
  472.     move.l    d0,a1                * Sample start
  473.     moveq    #0,d5
  474.     move    PTch_length(a3),d5        * Sample length in words
  475.     add.l    d5,d5                * Convert to bytes
  476.  
  477.     move.l    port(a5),a2        * Get mainvolume
  478.     moveq    #0,d1
  479.     move.b    hip_mainvolume(a2),d1    * (Main volume * sample volume)/64
  480.     mulu    PTch_volume(a3),d1    
  481.     lsr    #6,d1            * Value for scaling the data
  482.  
  483.     moveq    #0,d0            * X coordinate
  484.     moveq    #80-1,d7        * Loop counter, do 80 pixels
  485. drlo    
  486.     move.b    (a1)+,d2        * Read one byte sample data
  487.     ext    d2            * Sign extend to word
  488.     muls    d1,d2            * Scale according to volume
  489.     asr    #6,d2            * ...
  490.     add    #$80,d2            * Change the sign
  491.     asr    #2,d2            * Scale down to 0-63
  492.     mulu    #WIDTH/8,d2        * Get Y coordinate in the bitplane
  493.  
  494.     move    d0,d4            * X
  495.     move    d0,d3
  496.     lsr    #3,d4            * X offset in bytes = x-coord/8
  497.     add    d4,d2            * Add to Y
  498.     not    d3            * Plot pixel
  499.     bset    d3,(a0,d2)        * ...
  500.  
  501.     subq.l    #1,d5            * Subtract sample length
  502.     bpl.b    .l            * sample end?
  503.     moveq    #0,d5            * Get values for loop 
  504.     move    PTch_replen(a3),d5    
  505.     add.l    d5,d5
  506.     move.l    PTch_loopstart(a3),a1
  507. .l
  508.     addq    #1,d0        * Increase X
  509.  
  510.     dbf    d7,drlo        * Loop..
  511.     rts
  512.  
  513.  
  514.  
  515. *** Stereoscope for PS3M
  516.  
  517. multiscope
  518.     move.l    port(a5),a1
  519.     move.l    hip_ps3mleft(a1),a1
  520.     move.l    draw1(a5),a0
  521.     bsr.b    .h
  522.  
  523.     move.l    port(a5),a1
  524.     move.l    hip_ps3mright(a1),a1
  525.     move.l    draw1(a5),a0
  526.     lea    WIDTH/8/2(a0),a0
  527.     bsr.b    .h
  528.     rts
  529.  
  530. .h    move.l    port(a5),a2
  531.     move.l    hip_ps3moffs(a2),d5        * Get offset in buffers
  532.     move.l    hip_ps3mmaxoffs(a2),d4        * Get max offset
  533.         
  534.     move    #160-1,d7        * Draw 160 pixels
  535.     moveq    #0,d0            * X coord
  536. .drlo    
  537.     moveq    #0,d2
  538.     move.b    (a1,d5.l),d2        * Get data from mixing buffer
  539.     add.b    #$80,d2
  540.     lsr    #2,d2
  541.     mulu    #WIDTH/8,d2        * Y
  542.  
  543.     move    d0,d6
  544.     move    d0,d3
  545.     lsr    #3,d6            * X offset in bytes = x-coord/8
  546.     add    d6,d2            
  547.     not    d3            * Plot pixel
  548.     bset    d3,(a0,d2)        * ...
  549.  
  550.     addq    #1,d0            * Increase x coord
  551.     addq.l    #1,d5            * Increase buffer position
  552.     and.l    d4,d5            * make sure it stays in the buffer
  553.  
  554.     dbf    d7,.drlo        * Loop
  555.     rts
  556.  
  557.  
  558.  
  559. *******************************************************************************
  560. * Window
  561.  
  562. wflags     = WFLG_SMART_REFRESH!WFLG_DRAGBAR!WFLG_CLOSEGADGET!WFLG_DEPTHGADGET
  563. idcmpflags = IDCMP_CLOSEWINDOW
  564.  
  565. winstruc
  566.     dc    110,85    * x,y position
  567. winsiz    dc    340,85    * x,y size
  568.     dc.b    2,1    
  569.     dc.l    idcmpflags
  570.     dc.l    wflags
  571.     dc.l    0
  572.     dc.l    0    
  573.     dc.l    .t    * title
  574.     dc.l    0
  575.     dc.l    0    
  576.     dc    0,640    * min/max x
  577.     dc    0,256    * min/max y
  578.     dc    WBENCHSCREEN
  579.     dc.l    0
  580.  
  581. .t    dc.b    "HiP - Example scope",0
  582.  
  583. intuiname    dc.b    "intuition.library",0
  584. gfxname        dc.b    "graphics.library",0
  585. portname    dc.b    "HiP-Port",0
  586.  even
  587.  
  588.  
  589.      section    udnm,bss_p
  590.  
  591. * Variables
  592.  
  593. var_b        ds.b    size_var
  594.  
  595.     section    hihi,bss_c
  596.  
  597. * GFX buffers
  598.  
  599. buffer1    ds.b    WIDTH/8*HEIGHT
  600. buffer2    ds.b    WIDTH/8*HEIGHT
  601.  
  602.  end
  603.