; Hi guys...       
; Here it is...    
; The long awaited source code for my 666 byte wireframe-vector engine ...
; i have released it by request of some guys...
;                  
; Sum facts...     
; You have to run a postprocessor to make it excactly 666 byte
; i have included one, see POSTPROC.PAS for further information
; (For the beginners: The postprocessor cuts the uninitialised data
; from the back of the COM (that data after the ZERODATA_START label)
; a little routine called at the beginning of the program sets this area
; to zero, and SHAZAM we have gained in this case 708 bytes :))
;                  
; if you want to know more about keeping your code small read Imphobia #8
; there's a very interesting article by THE FAKER ...
;                  
; Sum words about the rotation: Yes, it's rotated only around one angle but
; in 3 Dimensions, i had to rotate it around a single angle to gain size...
;                  
; The first quarter of the sine table is precalclated, the other quarters
; and the cosines can be derived from them...
;                  
; Well i think you should know know everything about it..
; Go on, make it smaller and send your work to me (you can find my contact
; adresses farther down)...
; The first one who'll get it below 400 byte will get a bottle of 
; luxembourgish beer ;-)
;                  
; Greets fly out to (no speacial order): The rest of SoS, Poll Fabaire,
;  Lone Wolf/iGH, The Cha()T, Fire, Magic/Finix, Slaine, Mikee Mouse, 
;  Krash/AcmE, Speed Freak, Kaos, X-Treme, 4e2CS from LCD, Crusty, Deadline,
;  LastV8/CSi, Kraut, Phos4, Tasmaniac, Screamager, Dwarf, Stingray, Tonic,
;  and all those i forgot...
;                  
; How to contact me ...
; ~~~~~~~~~~~~~~~~~
; BBS: Neurotic +352-313377 (Mail to BLACK AXE)
;      Coders Corner +352-313377 (Mail to BLACK AXE)
;                  
; Snail-Mail:     Laurent Schmalen
;                 6, rue Tony Schmit
;                 L-9081 Ettelbruck
;                 Luxembourg
;                  
; Voice-Phone: +352-810013  (from 18:00 to 21:30)
;                  
; HAVE FUN!        
;            BLACK AXE / SoS, 12th May 1996
                                           
                                           
.386p              
wirecol   equ 14          ; Color of the Object 
maxpnts   equ 8           ; Number of points (from 1 to MAXPNTS)
maxplanes equ 6           ; Number of Planes (from 1 to MAXPLANES)
xpos      equ 160         ; X-Position of the Object
ypos      equ 140         ; Y-Position of the Object
depth     equ 1524        ; X-Position of the Object (ZooM)
                          
code    segment use16 'CODE'
        org     100h      
        assume cs:code,ds:code
                          
start:  jmp     ufankk    
                          
db      'SOS RULEZ !!   '                ; PlaceHolder to make it 666 byte :)
                                     ; So, it's only 651 bytes big 
angleun union                     
        b db ?                  
        w dw ?                  
angleun ends                    
                                
ptsxyz  dw -200,-200, 200        ; The base object (a nice cube :))
        dw  200,-200, 200                                          
        dw  200, 200, 200                                          
        dw -200, 200, 200                                          
        dw -200,-200,-200                                          
        dw  200,-200,-200                                          
        dw -200, 200,-200                                          
        dw  200, 200,-200                                          
                                                                   
planes  db 0,1,2,3              ; Everyone should know it :)
        db 4,5,7,6                                          
        db 0,4,6,3                                                 
        db 1,5,7,2                                                 
        db 0,4,5,1                                          
        db 6,7,2,3                                          
                                                            
kk      struc                                                           
        x dw ?                                              
        y dw ?                                              
        z dw ?                                              
ends                                                        
                                                            
damn    proc    near                ; Does that (for the rotate proc)                        
        imul    bx                  ; To gain sum silly bytes    
        shl     edx,16                                        
        mov     dx,ax                                         
        mov     edi,edx                                       
        ret                                                   
damn    endp                                                  
                                                              
rotate  proc    near                                         
;iNPUT   BX    CX
; DESTROYS:  QUITE A LOT
        mov     si,angle.w                                    
        add     si,si                                         
        mov     ax,[cosinus+si]                               
        call    damn                                          
                                                              
        mov     ax,[sinus+si]                                 
        imul    cx                                            
        shl     edx,16                                        
        mov     dx,ax                                         
        sub     edi,edx                                       
        sar     edi,8                                         
        mov     ebp,edi                                       
                                                              
        mov     ax,[sinus+si]          
        call    damn
                                               
        mov     ax,[cosinus+si]        
        imul    cx                     
        shl     edx,16                 
        mov     dx,ax                        
        add     edi,edx                
        sar     edi,8                  
        mov     bx,bp                  
        mov     cx,di                  
        ret             
rotate  endp                
                        
mover   proc    near    
        mov     di,ax   
        mov     bp,bx   
        imul    bp,6    
        imul    di,6          
        mov     ax,[trans.x+bp]         
        mov     bx,[trans.y+bp]         
        mov     cx,[trans.x+di]         
        mov     dx,[trans.y+di]         
        push    si                      
        call    line    
        pop     si                      
        ret             
mover   endp            
                                                
drawobj proc   near                     ; Draw the object
        mov     cx,maxplanes-1
        xor     ah,ah   
        xor     bh,bh   
pllop:  push    cx      
        shl     cx,2                    
        mov     si,cx   
        mov     bl,[planes+si]
        mov     al,[planes+si+1]
        call    mover         
                                                     
        mov     bl,[planes+si+1]
        mov     al,[planes+si+2]
        call    mover         
                                                
        mov     bl,[planes+si+2]
        mov     al,[planes+si+3]
        call    mover   
                                                
        mov     bl,[planes+si+3]
        mov     al,[planes+si]
        call    mover           
        pop     cx      
        loop    pllop
        ret                                      
drawobj endp
                          
dorot   macro                           ; Does Rotation, 3D to 2D conv etc
        call    drawobj
        mov     bp,maxpnts*6-6                                            
lé:     mov     bx,[ptsxyz.x+bp]                                          
        mov     cx,[ptsxyz.z+bp]                                          
        push    bp                                                        
        call    rotate                                                    
        pop     bp                                                        
        mov     [trans.x+bp],bx                                           
        mov     bx,[ptsxyz.y+bp]                                          
        push    bp                                                        
        call    rotate                                                    
        pop     bp                                                        
        mov     [trans.z+bp],cx                                           
        mov     cx,bx                                                     
        mov     bx,[trans.x+bp]                                           
        push    bp                                                        
        call    rotate                                                    
        pop     bp                                                        
        mov     [trans.x+bp],bx                                           
        mov     [trans.y+bp],cx                                           
;== 3d 2 2D conversation
        mov     cx,[trans.z+bp]                                           
        add     cx,depth                                                  
        mov     ax,bx   ;[trans.x+bp]                                     
        movsx   dx,ah                                                     
        mov     ah,al                   ; 1 byte less than SHL AX,8
        idiv    cx                               
        add     ax,xpos                          
        mov     [trans.x+bp],ax      
        mov     ax,[trans.y+bp]      
        movsx   dx,ah                
        mov     ah,al                   ; 1 byte!
        idiv    cx                               
        add     ax,ypos   
        mov     [trans.y+bp],ax
                          
        sub     bp,6      
        jns     lé        
        mov     color,wirecol
        call    drawobj
        endm              
                               
putpixel macro            
        pusha
        lea     di,[ebx+ebx*4]          ; Very fast and small!
        shl     di,6
        add     di,ax     
        mov     al,color  
        mov     es:[di],al
        popa        
        endm              

;== Draws a line from AX/BX to CX/DX
;== Original routine by InspirE/TC and Atan/VF (taken from PCUNDERGROUND)
;== but i've optimised it :))                          
line    proc    near         
        push    bp  
        push    ax  
        push    bx  
        mov     bx,4340h
        sub     cx,ax
        jns     deltax_ok
        neg     cx  
        mov     bl,48h
deltax_ok: mov  bp,sp
        sub     dx,ss:[bp]
        jns     deltay_ok
        neg     dx  
        mov     bh,4bh
deltay_ok: mov  si,dx
        or      si,cx                                                                               
        jne     ok    
        add     sp,6                                                                                
        ret         
ok:     mov     word ptr cs:dist_pos,bx
        cmp     cx,dx
        jge     deltax_gross
        xchg    cx,dx
        mov     bl,90h
        jmp     konstanten
deltax_gross:       
        mov     bh,90h
konstanten:         
        mov     word ptr cs:dist_neg,bx
;        shl     dx,1
        add     dx,dx        ; is faster than SHL DX,1
        mov     di,dx        
        sub     dx,cx        
        mov     bp,dx        
        mov     si,bp        
        sub     si,cx                                                                               
        xor     ebx,ebx                                                                             
        pop     bx                                                                                  
        pop     ax           
loop_p: putpixel             
        or      bp,bp
        jns     dist_pos
dist_neg: inc   ax   
        inc     bx   
        add     bp,di
        loop    loop_p
        jmp     fertig
dist_pos: inc   ax                                                                                  
        inc     bx                                                                                  
        add     bp,si                                 
        loop    loop_p
fertig: pop     bp                                                                                  
        ret
line    endp                                                                                                 
                          
ufankk: mov     al,13h    
        int     10h       
        mov     di,offset zerodata_start
        mov     cx,offset zerodata_end-zerodata_start
        push    cs        
        pop     es   
        xor     al,al
        rep     stosb         ; Initialeses the Zeroeddata     
        push    cs     
        pop     ds      
                       
;=== init trig-tables
        xor     si,si  
        xor     di,di  
        mov     cx,64  
        mov     bx,63  
init:   xor     ah,ah  
        mov     al,[sin_init+si]
        mov     [sinus+di],ax
        mov     [cosinus+di+384],ax
        neg     ax                 
        mov     [cosinus+di+128],ax
        xor     ah,ah
        mov     al,[sin_init+bx]
        mov     [cosinus+di],ax
        neg     ax
        mov     [cosinus+di+256],ax
        dec     bx  
        inc     si           
        add     di,2   
        loop    init   
        
;========== ============
;   Main Routines 
;========== ============                
        push    0a000h  
        pop     es      
ll:     mov     color,0
        mov     dx,3dah     ;Vertical Retrace
l1:     in      al,dx                
        test    al,8h     
        jz      l1        
                          
        dorot
        inc     angle.b
                          
        mov     ah,1                         
        int     16h            
        jz      ll             
                          
        mov     ax,0003h
        int     10h                
                                   
ede:    ret                        ; is smaller than MOV AH,4Ch; INT 21h
                                   ; and does the SAME
             
Sin_init db   0,6,13,19,25,31,38,44,50,56
        db   62,69,75,81,87,92,98,104,110,116
        db   121,127,132,137,143,148,153,158,163,168
        db   172,177,182,186,190,194,198,202,206,210
        db   213,217,220,223,226,229,232,235,237,239
        db   241,243,245,247,249,250,251,252,253,254
        db   255,255,255,255   
                               
zerodata_start label               
sinus   dw 64 dup(0)               
cosinus dw 256 dup(0)          
trans   dw maxpnts*4 dup(0)        
bs      dw 0                       
color   db 0
angle  angleun <0>
zerodata_end label                    
code    ends                   
        end     start
             
