home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / MATRIX.ZIP / SOURCE.ZIP / MTXCODE.ASM < prev   
Encoding:
Assembly Source File  |  1995-06-13  |  6.5 KB  |  267 lines

  1. ;
  2. ;   MTXCODE.ASM
  3. ;
  4. ;   (Simon Hern, August 1993 - June 1995)
  5. ;
  6. ;   Graphics routines for Matrix demo
  7. ;   Three simple functions and the main animation routine
  8. ;
  9. ;   (Some 32-bit code wouldn't go amiss here, but the assembler doesn't like
  10. ;    that sort of thing, so too bad)
  11. ;   (I'm sure there was some self-altering code in here somewhere last time
  12. ;    I looked, but it seems to have been replaced. Pity. I miss it.)
  13. ;
  14.  
  15.  
  16.     public _ScreenOn, _ScreenOff, _SetPalette
  17.     public _DisplayMatrix
  18.  
  19.  
  20.  
  21. ANGLES       EQU 1024
  22. SCR_HEIGHT   EQU 200
  23. SCR_WIDTH    EQU 320
  24. VIEW_DIST    EQU 512
  25. TILE_SIZE    EQU 256*256
  26.  
  27.  
  28.  
  29.  
  30. _Text   SEGMENT BYTE PUBLIC 'Code'
  31.  
  32.  
  33. VSYNC MACRO                 ; Macro waiting for vertical sync
  34.     push dx
  35.     push ax
  36.     mov dx,03dah
  37. M1:
  38.     in al,dx
  39.     test al,8
  40.     jnz M1
  41. M2:
  42.     in al,dx
  43.     test al,8
  44.     jz M2
  45.     pop ax
  46.     pop dx
  47. #EM
  48.  
  49.  
  50.  
  51. _ScreenOn:                  ; SCREENON(): vga, mode 13h, 320*200*256
  52.     mov ax,00013h
  53.     int 10h
  54.     ret
  55.  
  56.  
  57.  
  58. _ScreenOff:                 ; SCREENOFF(): text mode, 80*25 colour
  59.     mov ax,00003h
  60.     int 10h
  61.     ret
  62.  
  63.  
  64.  
  65. _SetPalette:                ; SETPALETTE(char near *, int first, int number)
  66.     push bp                 ; Table takes form of r-byte, g-byte, b-byte
  67.     mov bp,sp               ;  repeated 'number' times
  68.     push si
  69.  
  70.     mov si,w[bp+4]          ; ds:si = start of colour table
  71.     mov ax,w[bp+6]          ; al = first colour to change
  72.     mov cx,w[bp+8]          ; cx = number of colours to change
  73.     mov bx,cx
  74.     shl cx,1
  75.     add cx,bx
  76.  
  77.     VSYNC
  78.     mov dx,03c8h
  79.     out dx,al               ; first colour
  80.     inc dx
  81. spa01:
  82.     lodsb
  83.     out dx,al
  84.     loop spa01
  85.  
  86.     pop si
  87.     pop bp
  88.     ret
  89.  
  90.  
  91.  
  92. ; DisplayMatrix routine starts HERE
  93.  
  94.  
  95. UNROLL1 MACRO           ; Unrolled central loop - start at middle, work right
  96. #RX1(SCR_WIDTH/4)         ; i.e. Repeat SCR_WIDTH/4 times
  97.     mov bl,ch
  98.     mov bh,dh
  99.     or al,b[bx]           ; (bh,bl) = position within Tile array
  100.     add cx,si
  101.     add dx,bp             ; Displace position (dx,cx) by (bp,si)
  102.  
  103.     mov bl,ch
  104.     mov bh,dh
  105.     or ah,b[bx]           ; Same thing again
  106.     add cx,si
  107.     add dx,bp
  108.  
  109.     stosw                 ; Write two pixels at a time
  110.     and ax,0E0E0h         ; Clear ax except for 'blur' bits
  111. #ER
  112. #EM
  113.  
  114.  
  115. UNROLL2 MACRO           ; Unrolled central loop 2 - start at middle, work left
  116. #RX1(SCR_WIDTH/4)         ; i.e. Repeat SCR_WIDTH/4 times
  117.     sub cx,si
  118.     sub dx,bp             ; Displace position (dx,cx) by (-bp,-si)
  119.     mov bl,ch
  120.     mov bh,dh
  121.     or ah,b[bx]           ; (bh,bl) = position within Tile array
  122.  
  123.     sub cx,si
  124.     sub dx,bp
  125.     mov bl,ch             ; Same thing again
  126.     mov bh,dh
  127.     or al,b[bx]
  128.  
  129.     stosw                 ; Write two pixels at a time
  130.     and ax,0E0E0h         ; Clear ax except for 'blur' bits
  131. #ER
  132. #EM
  133.  
  134.  
  135.  
  136. EVEN
  137.  
  138. dmCosAngle:     dw ?    ; cos(angle) (16-bit fraction)
  139. dmSinAngle:     dw ?    ; sin(angle) (16-bit fraction)
  140.  
  141. dmXPos:         db ?    ; Origin's x coordinate within a tile
  142. dmYPos:         db ?    ; Origin's y coordinate within a tile
  143.  
  144. dmDistPtr:      dw ?    ; Pointer to place in Distances array
  145. dmBlursPtr:     dw ?    ; Pointer to place in Blurs array
  146. dmTilesSeg:     dw ?    ; Segment containing Tiles array (fills whole segment)
  147.  
  148. dmLineCounter:  db ?    ; Keep track of number of lines to draw
  149.  
  150.  
  151. EVEN
  152.  
  153. _DisplayMatrix:             ; DisplayMatrix(int angle, int xpos, int ypos)
  154.  
  155.     push bp
  156.     mov bp,sp
  157.  
  158.     push di
  159.     push si
  160.     push ds
  161.     push es
  162.  
  163.     mov bx,w[bp+4]                    ; int angle
  164.     shl bx,1
  165.     mov ax,w[bx+OFFSET _AngleSines]
  166.     mov cs:w[dmSinAngle],ax
  167.     add bx,2*ANGLES/4
  168.     and bx,2*ANGLES - 1
  169.     mov ax,w[bx+OFFSET _AngleSines]
  170.     mov cs:w[dmCosAngle],ax
  171.  
  172.     mov ax,w[bp+6]                    ; int xpos
  173.     mov cs:b[dmXPos],al
  174.  
  175.     mov ax,w[bp+8]                    ; int ypos
  176.     mov cs:b[dmYPos],al
  177.  
  178.     les di,d[_ScrBuffer]            ; Draw image in buffer then copy to screen
  179.     add di,SCR_WIDTH/2              ; es:di = buffer pointer
  180.  
  181.     mov ax,w[_Distances]            ; Set up local copies of pointers
  182.     mov cs:w[dmDistPtr],ax
  183.     mov ax,w[_Blurs]
  184.     mov cs:w[dmBlursPtr],ax
  185.     mov ax,w[_Tile+2]
  186.     mov cs:w[dmTilesSeg],ax
  187.  
  188.     mov cs:w[dmLineCounter],SCR_HEIGHT/2
  189.  
  190. dm01:                               ; Draw each line
  191.  
  192.     mov bx,cs:w[dmDistPtr]
  193.     add cs:w[dmDistPtr],2           ; Look up distance to line in array
  194.     mov bx,w[bx]                    ; Then rotate distance through Angle
  195.     mov ax,bx                       ;  to get starting position on tile plane
  196.     imul cs:w[dmCosAngle]
  197.     mov cx,dx
  198.     mov ax,bx
  199.     imul cs:w[dmSinAngle]           ; (cx,dx) = positn of middle point on line
  200.  
  201.     mov si,dx
  202.     mov bp,cx
  203.     neg bp                          ; (si,bp) = displacement to next point
  204.  
  205.     mov ch,cl                       ; Scale (cx,dx) up by factor of 256
  206.     mov dh,dl                       ;  so bottom 8 bits are 'fractional' part
  207.     mov cl,0                        ; Position is relative to one tile - all
  208.     mov dl,0                        ;  tiles are identical
  209.     add ch,cs:w[dmXPos]
  210.     add dh,cs:w[dmYPos]             ; Displace starting point by (XPos,YPos)
  211.  
  212.     mov bx,cs:w[dmBlursPtr]         ; al = ah = blur bits for this line
  213.     inc cs:w[dmBlursPtr]            ; (It would be good if the blur bits could
  214.     mov ah,b[bx]                    ;  be 'stuck' onto the screen so that they
  215.     mov al,ah                       ;  don't have to be rewritten each frame,
  216.                                     ;  and also so that they could be arranged
  217.                                     ;  in a more random fading pattern than
  218.                                     ;  'bands' of lines. This is probably
  219.                                     ;  possible by tweaking VGA registers but
  220.                                     ;  I don't know how to do it.)
  221.  
  222.     push ds
  223.     mov ds,cs:w[dmTilesSeg]
  224.  
  225.     push cx
  226.     push dx
  227.     cld
  228.  
  229.     UNROLL1                         ; Draw pixels to the left
  230.  
  231.     sub di,162
  232.     pop dx
  233.     pop cx
  234.     std
  235.  
  236.     UNROLL2                         ; Draw pixels to the right
  237.  
  238.     add di,162+320
  239.  
  240.     pop ds
  241.  
  242.     dec cs:b[dmLineCounter]
  243.     jz dm02
  244.     jmp dm01                        ; Move on to next line
  245. dm02:
  246.  
  247.     cld
  248.     lds si,d[_ScrBuffer]
  249.     mov ax,0a000h
  250.     mov es,ax
  251.     mov di,SCR_WIDTH * SCR_HEIGHT / 2
  252.     mov cx,SCR_WIDTH * (SCR_HEIGHT/2) / 2
  253.     VSYNC
  254.     rep movsw                       ; Spew buffer to screen on vsync
  255.  
  256.     pop es
  257.     pop ds
  258.     pop si
  259.     pop di
  260.  
  261.     pop bp
  262.     ret
  263.  
  264.  
  265. _TEXT    ENDS
  266.  
  267.