home *** CD-ROM | disk | FTP | other *** search
/ Archive Magazine 1996 / ARCHIVE_96.iso / discs / mag_discs / volume_9 / issue_01 / extasm / !extASM / Examples / EasyVector / Vector
Text File  |  1995-05-16  |  14KB  |  497 lines

  1. ; ----------------------------------------
  2. ; Simple Vector Pyramid
  3. ; ⌐ Eivind Hagen
  4. ; ⌐ Zynx/ArcEmpire
  5. ; Based on RGBW Pyramid, The Gathering '93
  6. ; Programmed : 10 August 1993 - Evening
  7. ;
  8. ; Modified by Terje Sletteb° to take
  9. ; advantage of new extASM features, such
  10. ; as the 'relative' statement, april 1995.
  11. ; ----------------------------------------
  12.  
  13. #set vdu = 256
  14.  
  15. #set Stack_Size=2048
  16. #set Screen_Mode=13
  17.  
  18. #set Screen_Width=320
  19. #set Screen_Height=256
  20. #set Screen_BPP=8
  21.  
  22. #set Screen_Size=(Screen_Width*Screen_BPP/8)*Screen_Height
  23. #set Screen_Buffers=2
  24.  
  25. .Code_Start
  26.  
  27. ;  >============================================================<
  28. ;  >                             START                          <
  29. ;  >============================================================<
  30.  
  31. .Start
  32.    ADRL     R12,General_Data
  33.    STR      R13,Old_Stack
  34.    ADR      R13,New_Stack+Stack_Size
  35.    STMFD    R13!,{R0-R12,R14}
  36.  
  37. ; >-----------------------------------------------------------<
  38.  
  39.    BL       Initialize
  40.  
  41. ; >-------------------------------------------------------------<
  42.  
  43. .Main_Loop
  44.    MOV      R0,#19
  45.    SWI      OS_Byte
  46.  
  47.    BL       Swap_Screens
  48.    BL       Clear_Screen
  49.    BL       GorTri
  50.  
  51. ._Loop
  52.    SWI      OS_Mouse
  53.    TST      R2,#%001
  54.    BNE      _Loop                      ; Right buttom = Pause
  55.    TST      R2,#%100
  56.    BEQ      Main_Loop
  57.  
  58. ; >-------------------------------------------------------------<
  59.  
  60. .The_End
  61.    B        Quit
  62.  
  63. ; >=============================================================<
  64.  
  65. ;  --------------------------------------------------------------
  66. ;  |      ####  #####  #   #  #####  ####    ###   #            |
  67. ;  |     #      #      ##  #  #      #   #  #   #  #            |
  68. ;  |     #  ##  ###    # # #  ###    ####   #####  #            |
  69. ;  |     #   #  #      #  ##  #      #  #   #   #  #            |
  70. ;  |      ###   #####  #   #  #####  #   #  #   #  #####        |
  71. ;  --------------------------------------------------------------
  72.  
  73. ;  >============================================================<
  74. ;  >                      GENERAL ROUTINES                      <
  75. ;  >============================================================<
  76.  
  77. .Initialize
  78.    STMFD    R13!,{R14}
  79.  
  80.    MOV      R0,#135
  81.    SWI      OS_Byte 
  82.    STR      R2,Original_Mode
  83.  
  84.    SWI      vdu+22                     ; VDU 22 - SET SCREEN MODE
  85.    SWI      vdu+0                      ; MODE 0 - USED TO FREE LOT'S OF MEMORY
  86.  
  87.    MOV      R0,#2
  88.    SWI      OS_ReadDynamicArea
  89.  
  90.    MOV      R0,#2
  91.    MOV      R2,#Screen_Buffers*Screen_Size
  92.    RSB      R1,R1,R2
  93.    SWI      OS_ChangeDynamicArea
  94.  
  95.    MOV      R0,#2
  96.    SWI      OS_ReadDynamicArea
  97.    MOV      R2,#Screen_Buffers*Screen_Size
  98.    CMP      R1,R2
  99.    MOVLT    PC,#0
  100.  
  101.    ADR      R0,Buffer 
  102.    MOV      R1,R0
  103.    MOV      R2,#149
  104.    STR      R2,[R0,#0]
  105.    MVN      R2,#0
  106.    STR      R2,[R0,#4]
  107.    SWI      OS_ReadVduVariables 
  108.    LDR      R2,[R1,#0]
  109.    STR      R2,Screen_Top 
  110.    SWI      vdu+22                     ; VDU 22 - SET SCREEN MODE
  111.    SWI      vdu+Screen_Mode            ; Set proper screen mode
  112.    SWI      OS_RemoveCursors 
  113.  
  114.    MOV      R0,#Screen_Buffers         ; Clear screen memory
  115.    LDR      R1,Screen_Top 
  116. .Clear_Screen_Memory
  117.    STR      R1,Screen_Adr 
  118.    STMFD    R13!,{R0,R1}
  119.    BL       Clear_Screen
  120.    LDMFD    R13!,{R0,R1}
  121.    MOV      R2,#Screen_Size
  122.    ADD      R1,R1,R2
  123.    SUBS     R0,R0,#1
  124.    BGT      Clear_Screen_Memory
  125.    LDMFD    R13!,{PC}^
  126.  
  127. ; >-------------------------------------------------------------<
  128.  
  129. .Quit
  130.    SWI      OS_RestoreCursors 
  131.    MVN      R0,#0                      ; -1, close commandwindow
  132.    SWI      Wimp_CommandWindow 
  133.    LDR      R0,Original_Mode
  134.    SWI      Wimp_SetMode 
  135.    LDMFD    R13!,{R0-R12,R14}
  136.    LDR      R13,Old_Stack
  137.    MOVS     PC,R14
  138.  
  139. ; >-------------------------------------------------------------<
  140.  
  141. .Swap_Screens
  142.    STMFD    R13!,{R14}
  143.  
  144.    MOV      R0,#113                    ; OS_Byte 113 - SET HARDWARE SCREEN BANK
  145.    LDR      R1,Screen_Bank             ;
  146.    ADD      R1,R1,#1                   ;
  147.    SWI      OS_Byte                    ;
  148.  
  149.    LDR      R0,Screen_Top 
  150.    LDR      R3,Screen_Bank 
  151.    ADD      R1,R3,#1
  152.    CMP      R1,#Screen_Buffers
  153.    MOVGE    R1,#0
  154.    STR      R1,Screen_Bank 
  155.    MOV      R2,#Screen_Size                  ; R2 = Screen size
  156.    MLA      R1,R2,R1,R0
  157.    STR      R1,Screen_Adr 
  158.    ADD      R1,R1,R2,ASR #1
  159.    MOV      R2,#Screen_Width*Screen_BPP/8    ; R2 = Line size
  160.    ADD      R1,R1,R2,ASR #1
  161.    STR      R1,Screen_Origo 
  162.    MLA      R3,R2,R3,R0
  163.    STR      R3,Screen_Old 
  164.  
  165.    LDMFD    R13!,{PC}^
  166.  
  167. ; >-------------------------------------------------------------<
  168.  
  169. .Clear_Screen
  170.    LDR      R0,Screen_Adr 
  171.    MOV      R1,#Screen_Size/4/10/4
  172.    MOV      R2,#0
  173.    MOV      R3,#0
  174.    MOV      R4,#0
  175.    MOV      R5,#0
  176.    MOV      R6,#0
  177.    MOV      R7,#0
  178.    MOV      R8,#0
  179.    MOV      R9,#0
  180.    MOV      R10,#0
  181.    MOV      R11,#0
  182. .Clear_Screen_Loop
  183.    STMIA    R0!,{R2-R11}
  184.    STMIA    R0!,{R2-R11}
  185.    STMIA    R0!,{R2-R11}
  186.    STMIA    R0!,{R2-R11}
  187.    SUBS     R1,R1,#1
  188.    BGT      Clear_Screen_Loop
  189.    MOV      PC,R14
  190.  
  191. ; >-------------------------------------------------------------<
  192.  
  193.  
  194. .Tri_Model                             ; 3d coordinates for Tetraeder
  195.    DCD     0 : DCD    60-60 : DCD   -40+40
  196.    DCD   -60 : DCD   -40-60 : DCD   -40+40
  197.    DCD    60 : DCD   -40-60 : DCD   -40+40
  198.    DCD     0 : DCD     0-60 : DCD    60+40
  199.  
  200. .Tri_Temp
  201.    DCD     0 : DCD     0 : DCD     0
  202.    DCD     0 : DCD     0 : DCD     0
  203.    DCD     0 : DCD     0 : DCD     0
  204.    DCD     0 : DCD     0 : DCD     0
  205.  
  206. .Tri_Coord                             ; Coordinates
  207.    DCD   200, 150
  208.    DCD   250, 250
  209.    DCD   400, 170
  210.    DCD   100, 130
  211.  
  212. .Triangles_Num
  213.    DCD     4
  214.  
  215. .Triangles                             ; Coord-ptrs & colour [4 colour bytes]
  216.    DCD     0,1,2 , &40404040
  217.    DCD     0,2,3 , &80808080
  218.    DCD     0,3,1 , &a0a0a0a0
  219.    DCD     3,2,1 , &f0f0f0f0
  220.  
  221. .Rot_X     DCD   0
  222. .Rot_Y     DCD   0
  223. .Rot_Z     DCD   0
  224.  
  225. .GorTri
  226.    STMFD    R13!,{R0-R12,R14}
  227.  
  228.    ;------> Rotate model
  229.    ;        X Rotate
  230.  
  231.    ADR      R0,Tri_Model               ; R0-> Model coords  [X,Y,Z]
  232.    ADR      R1,Tri_Temp                ; R1-> Temp coords   [X,Y,Z]
  233.    ADR      R2,Sin_Tab 
  234.    ADR      R3,Cos_Tab 
  235.  
  236.    LDR      R4,Rot_X
  237.    ADD      R4,R4,#3
  238.    BIC      R4,R4,#512
  239.    STR      R4,Rot_X
  240.  
  241.    LDR      R2,[R2,R4,ASL #2]          ; R2 = SinX
  242.    LDR      R3,[R3,R4,ASL #2]          ; R3 = CosX
  243.    MOV      R4,#4                      ; R4 = Points
  244. ._Loop
  245.    LDMIA    R0!,{R5,R6,R7}             ; R5 = X * R6=Y, R7=Z            [0 Bit]
  246.    MUL      R8,R3,R6                   ; R8 = Y * CosX                  [12 Bit]
  247.    MUL      R9,R3,R7                   ; R9 = Z * CosX                  [12 Bit]
  248.    MUL      R10,R2,R6                  ; R10= Y * SinX                  [12 Bit]
  249.    MUL      R11,R2,R7                  ; R11= Z * SinX                  [12 Bit]
  250.    SUB      R6,R8,R11                  ;                                [12 Bit]
  251.    ADD      R7,R9,R10                  ;                                [12 Bit]
  252.    MOV      R6,R6,ASR #12              ;                                [0 Bit]
  253.    MOV      R7,R7,ASR #12              ;                                [0 Bit]
  254.    STMIA    R1!,{R5,R6,R7}             ; Store Rotated coords
  255.  
  256.    SUBS     R4,R4,#1
  257.    BGT      _Loop
  258.  
  259.    ;        Z Rotate
  260.  
  261.    ADR      R0,Tri_Temp                ; R0-> Model coords  [X,Y,Z]
  262.    ADR      R1,Tri_Temp                ; R1-> Temp coords   [X,Y,Z]
  263.    ADR      R2,Sin_Tab 
  264.    ADR      R3,Cos_Tab 
  265.  
  266.    LDR      R4,Rot_Z
  267.    ADD      R4,R4,#2
  268.    BIC      R4,R4,#512
  269.    STR      R4,Rot_Z
  270.  
  271.    LDR      R2,[R2,R4,ASL #2]          ; R2 = SinX
  272.    LDR      R3,[R3,R4,ASL #2]          ; R3 = CosX
  273.    MOV      R4,#4                      ; R4 = Points
  274. ._Loop2
  275.    LDMIA    R0!,{R5,R6,R7}             ; R5 = X * R6=Y, R7=Z            [0 Bit]
  276.    MUL      R8,R3,R5                   ; R8 = Y * CosX                  [12 Bit]
  277.    MUL      R9,R3,R6                   ; R9 = Z * CosX                  [12 Bit]
  278.    MUL      R10,R2,R5                  ; R10= Y * SinX                  [12 Bit]
  279.    MUL      R11,R2,R6                  ; R11= Z * SinX                  [12 Bit]
  280.    SUB      R5,R8,R11                  ;                                [12 Bit]
  281.    ADD      R6,R9,R10                  ;                                [12 Bit]
  282.    MOV      R5,R5,ASR #12              ;                                [0 Bit]
  283.    MOV      R6,R6,ASR #12              ;                                [0 Bit]
  284.    STMIA    R1!,{R5,R6,R7}             ; Store Rotated coords
  285.  
  286.    SUBS     R4,R4,#1
  287.    BGT      _Loop2
  288.  
  289.    ;------> Project 3D -> 2D
  290.  
  291.    ADR      R0,Tri_Temp                ; R0-> Temp coords   [X,Y,Z]
  292.    ADR      R1,Tri_Coord               ; R1-> Screen coords [X,Y]
  293.    ADR      R14,Per_Tab
  294.    MOV      R2,#4                      ; R2 = Number of Points
  295. ._Loop3
  296.    LDMIA    R0!,{R3,R4,R5}             ; R3=X, R4=Y, R5=Z
  297.    ADD      R5,R5,#480
  298.    LDR      R5,[R14,R5,ASL #2]
  299.    MUL      R3,R5,R3
  300.    MUL      R4,R5,R4
  301.    MOV      R3,R3,ASR #12+2
  302.    MOV      R4,R4,ASR #12+2
  303.    ADD      R3,R3,#Screen_Width/2
  304.    RSB      R4,R4,#Screen_Height/2
  305.    STMIA    R1!,{R3,R4}                ; Next coord
  306.  
  307.    SUBS     R2,R2,#1
  308.    BGT      _Loop3
  309.  
  310.    ;------> Plot triangles
  311.  
  312.    MOV      R4,#0
  313. .Polygons_Loop
  314.    ADR      R3,Triangles               ; R3-> Triangle vertices
  315.    ADD      R3,R3,R4,ASL #4
  316.  
  317.    ;------> Check face
  318.  
  319.    ADR      R2,Tri_Coord 
  320.    LDMIA    R3,{R6,R8,R10}
  321.    ADD      R6,R2,R6,ASL #3
  322.    ADD      R8,R2,R8,ASL #3
  323.    ADD      R10,R2,R10,ASL #3
  324.    LDMIA    R6,{R6,R7}
  325.    LDMIA    R8,{R8,R9}
  326.    LDMIA    R10,{R10,R11}
  327.    SUB      R8,R8,R6
  328.    SUB      R9,R9,R7
  329.    SUB      R6,R10,R6
  330.    SUB      R7,R11,R7
  331.  
  332.    MUL      R10,R6,R9
  333.    MUL      R11,R7,R8
  334.    CMP      R10,R11
  335.    BLT      Next_Polygon
  336.  
  337.    ;------> Clear Scan buffers
  338.  
  339.    STMFD    R13!,{R0-R4}
  340.  
  341.    ADR      R0,Tri_Buff_Left 
  342.    ADR      R1,Tri_Buff_Right 
  343.    MOV      R2,#Screen_Height
  344.    MOV      R3,#-1
  345. ._Loop
  346.    STMIA    R0!,{R3}
  347.    STMIA    R1!,{R3}
  348.    SUBS     R2,R2,#1
  349.    BGT      _Loop
  350.  
  351.    LDMFD    R13!,{R0-R4}
  352.  
  353.    ;------> Scan all vertices
  354.  
  355.    STMFD    R13!,{R3,R4}
  356.  
  357.    ADR      R0,Tri_Buff_Left 
  358.    ADR      R1,Tri_Buff_Right 
  359.    ADR      R2,Tri_Coord 
  360.  
  361.    LDR      R5,[R3,#0]
  362.    LDR      R7,[R3,#4]
  363.    BL       Scan_Vertice               ; p0 - p1
  364.    LDR      R5,[R3,#4]
  365.    LDR      R7,[R3,#8]
  366.    BL       Scan_Vertice               ; p1 - p2
  367.    LDR      R5,[R3,#8]
  368.    LDR      R7,[R3,#0]
  369.    BL       Scan_Vertice               ; p2 - p0
  370.  
  371.    ;------> Plot Scan buffers
  372.  
  373.    LDR      R10,[R3,#12]
  374.    ADR      R0,Tri_Buff_Left
  375.    ADR      R1,Tri_Buff_Right
  376.    LDR      R14,Screen_Adr
  377.    MOV      R3,#Screen_Height
  378. .Line_Loop
  379.    LDMIA    R0!,{R6}                   ; R6=x0
  380.    LDMIA    R1!,{R8}                   ; R8=x1
  381.  
  382.    CMP      R6,R8
  383.    EXGGT    R6,R8                      ; R6 < R8, fill line from R6 to R8 with colour in R10
  384.    CMP      R8,#-1                     ; if R8 = -1, then this line is not important
  385.    BEQ      Line_Filled
  386.    CMP      R6,#-1                     ; check if line start is missing ? (sort of a bug)
  387.    MOVEQ    R6,R8
  388.  
  389.    ADD      R6,R14,R6
  390.    ADD      R8,R14,R8
  391.  
  392. .Line_Fill_Start
  393.    ;------> Fill until word boundary
  394. ._Loop
  395.    STRB     R10,[R6],#1
  396.    CMP      R6,R8
  397.    BGT      Line_Filled
  398.    TST      R6,#%11                    ; test byte-bits
  399.    BNE      _Loop                      ; fill until word boundary
  400.  
  401. .Line_Fill_Fast
  402.    ;------> Fill as many words as possible
  403.    SUB      R8,R8,#4                   ; reduce R8 to detect end quicker
  404. ._Loop
  405.    CMP      R6,R8
  406.    BGT      Line_Fill_End
  407.    STR      R10,[R6],#4
  408.    BLE      _Loop                      ; fill more words
  409.  
  410. .Line_Fill_End
  411.    ADD      R8,R8,#4                   ; fix R8 after manipulation
  412.    ;------> Fill until end
  413. ._Loop
  414.    STRB     R10,[R6],#1
  415.    CMP      R6,R8
  416.    BLE      _Loop                      ; fill until word boundary
  417.  
  418. .Line_Filled
  419.    ADD      R14,R14,#Screen_Width      ; Add 1 line
  420.    SUBS     R3,R3,#1
  421.    BGT      Line_Loop
  422.  
  423.    LDMFD    R13!,{R3,R4}
  424.  
  425. ; >- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<
  426.  
  427. .Next_Polygon
  428.    ADD      R4,R4,#1
  429.    LDR      R5,Triangles_Num 
  430.    CMP      R4,R5
  431.    BLT      Polygons_Loop
  432.  
  433.    LDMFD    R13!,{R0-R12,PC}^
  434.  
  435. ; >-------------------------------------------------------------<
  436.  
  437. .Scan_Vertice
  438.    STMFD    R13!,{R0-R12,R14}
  439.  
  440.    ADD      R5,R2,R5,ASL #3            ; *8
  441.    ADD      R7,R2,R7,ASL #3            ; *8
  442.    LDMIA    R5,{R5,R6,R10}             ; R5=x0, R6=y0, R10=RRGGBB
  443.    LDMIA    R7,{R7,R8,R11}             ; R7=x1, R8=y1, R11=RRGGBB
  444.    CMP      R6,R8
  445.    MOVLE    R9,R0
  446.    MOVGT    R9,R1                      ; R9-> Scan buffer, X update
  447.    EXGGT    R5,R7
  448.    EXGGT    R6,R8                      ; y0 < y1
  449.    EXGGT    R10,R11
  450.  
  451.    MOV      R5,R5,ASL #16              ; R5=x0             [16 Bit]
  452.    MOV      R7,R7,ASL #16              ; R7=x1             [16 Bit]
  453.    SUB      R10,R7,R5                  ; R10=dx            [16 Bit]
  454.    SUB      R11,R8,R6                  ; R11=dy
  455.    ADD      R11,R11,#1                 ; NO DIVISION BY ZERO !!!!!!!!!!!!!!
  456.    TEMP     R0
  457.    DIV      R14,R10,R11                ; R14=dx/dy         [16 Bit]
  458.    LOCK     R0
  459. ._Loop
  460.    MOV      R10,R5,ASR #16
  461.    STR      R10,[R9,R6,ASL #2]
  462.    ADD      R5,R5,R14
  463.    ADD      R6,R6,#1
  464.    CMP      R6,R8
  465.    BLE      _Loop
  466.  
  467.    LDMFD    R13!,{R0-R12,PC}^
  468.  
  469. ;  >============================================================<
  470. ;  >                         GENERAL DATA                       <
  471. ;  >============================================================<
  472.  
  473. .General_Data
  474.    relative R12
  475.    {
  476. .Original_Mode          DCD   0
  477. .Screen_Top             DCD   0
  478. .Screen_Adr             DCD   0
  479. .Screen_Old             DCD   0
  480. .Screen_Origo           DCD   0
  481. .Screen_Bank            DCD   0
  482. .Old_Stack              DCD   0
  483.    ALIGN 256
  484. .New_Stack              DBB   Stack_Size,0
  485. .Buffer                 DBB   1024,0
  486. .Tri_Buff_Left          DBD   Screen_Height,0
  487. .Tri_Buff_Right         DBD   Screen_Height,0
  488.  
  489. .Sin_Tab    incbin   "<Tmp$Dir>.Tables.S_512_12"
  490. .Cos_Tab    incbin   "<Tmp$Dir>.Tables.C_512_12"
  491. .Per_Tab    incbin   "<Tmp$Dir>.Tables.P_1024_12"
  492.    }
  493.  
  494. ; >-------------------------------------------------------------<
  495.  
  496. .Code_End
  497.