This commit is contained in:
Frater 2017-09-24 01:45:36 +02:00
commit 43352ff262
1291 changed files with 220976 additions and 0 deletions

188
VISU/A.INC Normal file
View file

@ -0,0 +1,188 @@
;/****************************************************************************
;** MODULE: a.inc
;** AUTHOR: Sami Tammilehto / Fennosoftec OY
;** DOCUMENT: ?
;** VERSION: 1.0
;** REFERENCE: -
;** REVISED BY: -
;*****************************************************************************
;**
;** Assembler / Include
;** - variable definitions
;** - constant definitions
;**
;****************************************************************************/
.386
LOCALS
;######## macros ########
;note: C macros expect a LARGE memory model
LOADDS MACRO ;loads the ds segment to point to asm_data
mov ax,SEG _datanull
mov ds,ax
ENDM
LOADES MACRO ;loads the es segment to point to asm_data
mov ax,SEG _datanull
mov es,ax
ENDM
LOADGS MACRO ;loads the gs segment to point to asm_data
mov ax,SEG _datanull
mov gs,ax
ENDM
CBEG MACRO ;C/Assembler procedure begin
push bp
mov bp,sp
push si
push di
push ds
LOADDS ;since all routines expect to have DS pointed to the
;data segment, it's loaded at every public entrypoint
;(which should all be C procedures).
ENDM
CEND MACRO ;C/Assembler procedure end
pop ds
pop di
pop si
pop bp
ret
ENDM
CBEGR MACRO bytes ;C/Assembler procedure begin - with local variable reserve
push bp
mov bp,sp
sub sp,bytes
push si
push di
push ds
push bp ;just in case the asm routine changes bp
LOADDS ;since all routines expect to have DS pointed to the
;data segment, it's loaded at every public entrypoint
;(which should all be C procedures).
ENDM
CENDR MACRO ;C/Assembler procedure end
pop bp
pop ds
pop di
pop si
mov sp,bp
pop bp
ret
ENDM
movpar MACRO reg,par ;loads parameter [par(0..)] to register [reg]
mov reg,[bp+(par)*2+6]
ENDM
ldspar MACRO reg,par ;loads pointer parameter [par(0..)] to register ds:[reg]
lds reg,[bp+(par)*2+6]
ENDM
lespar MACRO reg,par ;loads pointer parameter [par(0..)] to register es:[reg]
les reg,[bp+(par)*2+6]
ENDM
lfspar MACRO reg,par ;loads pointer parameter [par(0..)] to register fs:[reg]
lfs reg,[bp+(par)*2+6]
ENDM
lgspar MACRO reg,par ;loads pointer parameter [par(0..)] to register gs:[reg]
lgs reg,[bp+(par)*2+6]
ENDM
;######## public routines ########
global _vid_init:far
global _vid_window:far
global _vid_cameraangle:far
global _vid_deinit:far
global _vid_setpal:far
global _vid_dotdisplay_pvlist:far
global _vid_dotdisplay_zcolor:far
global _vid_clear:far
global _vid_clear255:far
global _vid_clearbg:far
global _vid_switch:far
global _vid_setswitch:far
global _vid_waitb:far
global _vid_poly:far
global _vid_pset:far
global _vid_skyclear:far
global _vid_drawpolylist:far
global _vid_inittimer:far
global _vid_deinittimer:far
global _vid_drawsight:far
global _vid_pic320200:far
;polygon fillers
global _vid_drawfill:far
global _vid_drawfill_nrm:far
global _vid_drawfill_grd:far
global _vid_drawdots:far
global _calc_project:far
global _calc_project16:far
global _calc_setrmatrix_rotyxz:far
global _calc_setrmatrix_rotxyz:far
global _calc_setrmatrix_rotzyx:far
global _calc_setrmatrix_ident:far
global _calc_applyrmatrix:far
global _calc_rotate:far
global _calc_rotate16:far
global _calc_sftranslate:far
global _calc_singlez:far
global _calc_nrotate:far
global _calc_mulrmatrix:far
global _calc_invrmatrix:far
global _draw_polylist:far
global _draw_setfillroutine:far
;######## constants ######## (these should be same as in CDATA.H)
MAXROWS = 480 ;maximum number of rows used in any mode
MAXCOLS = 640 ;maximum number of rows used in any mode (should be divisible with 4)
MAXPOLYSIDES = 16 ;maximum sides in a polygon
;######## variables ########
;for documentation on global variables, see adata.asm
global _datanull:dword
global _rows:word
global _rowlen:word
global _vramseg:word
global _cdataseg:word
CLIPMIN equ 0
CLIPMAX equ 4
global _projclipx:dword
global _projclipy:dword
global _projclipz:dword
global _projmulx:dword
global _projmuly:dword
global _projaddx:dword
global _projaddy:dword
global _projaspect:word
global _projoversampleshr:word
;equs are offsets of routine pointers inside vr for current video driver
PSET equ 0
CLEAR equ 2
SWITCH equ 4
WAITB equ 6
VRSIZE equ 8
global vr:word
global _sintable:word
global _avistan:word
global _afilldiv:word
global _polydrw:word
;####### data types ########
include ad.inc

887
VISU/ACALC.ASM Normal file
View file

@ -0,0 +1,887 @@
;/****************************************************************************
;** MODULE: acalc.asm
;** AUTHOR: Sami Tammilehto / Fennosoftec OY
;** DOCUMENT: ?
;** VERSION: 1.0
;** REFERENCE: -
;** REVISED BY: -
;*****************************************************************************
;**
;** Assembler / Calculations
;**
;****************************************************************************/
include a.inc
asm_code SEGMENT para public use16 'CODE'
ASSUME cs:asm_code
;entry: bx=angle (0..65535)
; exit: ax=sin(angle) [range -unit..unit]
sin PROC NEAR
shr bx,4-1
and bx,not 1
mov ax,ds:_sintable[bx]
ret
sin ENDP
;entry: bx=angle (0..65535)
; exit: ax=cos(angle) [range -unit..unit]
cos PROC NEAR
shr bx,4-1
add bx,1024*2
and bx,not (8192 or 1)
mov ax,ds:_sintable[bx]
ret
cos ENDP
;entry: bx=angle (0..65535)
; exit: ax=sin(angle) [range -unit..unit]
; bx=cos(angle) [range -unit..unit]
sincos PROC NEAR
shr bx,4-1
and bx,not 1
mov ax,ds:_sintable[bx]
add bx,1024*2
and bx,not (8192 or 1)
mov bx,ds:_sintable[bx]
ret
sincos ENDP
;used for matrix multiply EXPECTS the matrices to be of integer size
mulmacro MACRO row,col
mov eax,ds:[si+0+row*12]
imul dword ptr es:[di+0+col*4]
mov ebx,eax
mov eax,ds:[si+4+row*12]
imul dword ptr es:[di+12+col*4]
add ebx,eax
mov eax,ds:[si+8+row*12]
imul dword ptr es:[di+24+col*4]
add ebx,eax
sar ebx,unitshr
ENDM
;entry: fs:si=matrix1, es:di=matrix2
; exit: fs:si=matrix1*matrix2 (matrix 1 overwritten)
mulmatrices PROC NEAR
push ds
mov ax,fs
mov ds,ax
mulmacro 0,0
push ebx
mulmacro 0,1
push ebx
mulmacro 0,2
push ebx
mulmacro 1,0
push ebx
mulmacro 1,1
push ebx
mulmacro 1,2
push ebx
mulmacro 2,0
push ebx
mulmacro 2,1
push ebx
mulmacro 2,2
mov ds:[si+8+24],ebx
pop dword ptr ds:[si+4+24]
pop dword ptr ds:[si+0+24]
pop dword ptr ds:[si+8+12]
pop dword ptr ds:[si+4+12]
pop dword ptr ds:[si+0+12]
pop dword ptr ds:[si+8]
pop dword ptr ds:[si+4]
pop dword ptr ds:[si+0]
pop ds
ret
mulmatrices ENDP
;entry: fs:si=matrix1, es:di=matrix2
; exit: es:di=matrix1*matrix2 (matrix 2 overwritten)
mulmatrices2 PROC NEAR
push ds
mov ax,fs
mov ds,ax
mulmacro 0,0
push ebx
mulmacro 0,1
push ebx
mulmacro 0,2
push ebx
mulmacro 1,0
push ebx
mulmacro 1,1
push ebx
mulmacro 1,2
push ebx
mulmacro 2,0
push ebx
mulmacro 2,1
push ebx
mulmacro 2,2
mov es:[di+8+24],ebx
pop dword ptr es:[di+4+24]
pop dword ptr es:[di+0+24]
pop dword ptr es:[di+8+12]
pop dword ptr es:[di+4+12]
pop dword ptr es:[di+0+12]
pop dword ptr es:[di+8]
pop dword ptr es:[di+4]
pop dword ptr es:[di+0]
pop ds
ret
mulmatrices2 ENDP
;entry: ax=rotx, bx=roty, cx=rotz, es:di=rmatrix.m
; exit: (writes rmatrix.m)
calcmatrixsep PROC NEAR ;calc 3 separate matrices
push bp
mov bp,sp
sub sp,12 ;for local variables
push ds
push di
push bx
push cx
mov bx,ax
neg bx
call sincos
mov ss:[bp-12+0],ax ;rxsin
mov ss:[bp-12+2],bx ;rxcos
pop bx
neg bx
call sincos
mov ss:[bp-12+4],ax ;rysin
mov ss:[bp-12+6],bx ;rycos
pop bx
neg bx
call sincos
mov ss:[bp-12+8],ax ;rzsin
mov ss:[bp-12+10],bx ;rzcos
mov ebx,0
mov ecx,unit
mov ax,es
mov ds,ax
;rX
mov ds:[di+2*0],ecx
mov ds:[di+2*2],ebx
mov ds:[di+2*4],ebx
mov ds:[di+2*6],ebx
movsx eax,word ptr ss:[bp-12+2]
mov ds:[di+2*8],eax
movsx eax,word ptr ss:[bp-12+0]
mov ds:[di+2*10],eax
mov ds:[di+2*12],ebx
movsx eax,word ptr ss:[bp-12+0]
neg eax
mov ds:[di+2*14],eax
movsx eax,word ptr ss:[bp-12+2]
mov ds:[di+2*16],eax
add di,36
;rY
movsx eax,word ptr ss:[bp-12+6]
mov ds:[di+2*0],eax
mov ds:[di+2*2],ebx
movsx eax,word ptr ss:[bp-12+4]
neg eax
mov ds:[di+2*4],eax
mov ds:[di+2*6],ebx
mov ds:[di+2*8],ecx
mov ds:[di+2*10],ebx
movsx eax,word ptr ss:[bp-12+4]
mov ds:[di+2*12],eax
mov ds:[di+2*14],ebx
movsx eax,word ptr ss:[bp-12+6]
mov ds:[di+2*16],eax
add di,36
;rZ
movsx eax,word ptr ss:[bp-12+10]
mov ds:[di+2*0],eax
movsx eax,word ptr ss:[bp-12+8]
mov ds:[di+2*2],eax
mov ds:[di+2*4],ebx
movsx eax,word ptr ss:[bp-12+8]
neg eax
mov ds:[di+2*6],eax
movsx eax,word ptr ss:[bp-12+10]
mov ds:[di+2*8],eax
mov ds:[di+2*10],ebx
mov ds:[di+2*12],ebx
mov ds:[di+2*14],ebx
mov ds:[di+2*16],ecx
pop di
pop ds
mov sp,bp
pop bp
ret
calcmatrixsep ENDP
;±±±±±±±± _calc_setrmatrix_ident(rmatrix *matrix) ±±±±±±±±
;entry: matrix=destination matrix (only rotation fields modified)
; exit: (data written to matrix)
;descr: Writes an identity rotation matrix to rmatrix
_calc_setrmatrix_ident PROC FAR
CBEG
lespar di,0
mov edx,unit
xor eax,eax
mov es:[di+rmatrix_m+0*4],edx
mov es:[di+rmatrix_m+1*4],eax
mov es:[di+rmatrix_m+2*4],eax
mov es:[di+rmatrix_m+3*4],eax
mov es:[di+rmatrix_m+4*4],edx
mov es:[di+rmatrix_m+5*4],eax
mov es:[di+rmatrix_m+6*4],eax
mov es:[di+rmatrix_m+7*4],eax
mov es:[di+rmatrix_m+8*4],edx
CEND
_calc_setrmatrix_ident ENDP
;±±±±±±±± _calc_setrmatrix_rotyxz(rmatrix *matrix,angle rotx,angle roty,angle rotz) ±±±±±±±±
;entry: matrix=destination matrix (only rotation fields modified)
; rotx/y/z=rotation angles
; exit: (data written to matrix)
;descr: Calculates a rotation matrix
_calc_setrmatrix_rotyxz PROC FAR
CBEGR 36*3
mov ax,ss
mov es,ax
mov fs,ax
movpar ax,2
movpar bx,3
movpar cx,4
lea di,[bp-36*3]
call calcmatrixsep
lea si,[bp-36*3+36*1]
lea di,[bp-36*3+36*0]
call mulmatrices ;Y*=X
lea si,[bp-36*3+36*1]
lea di,[bp-36*3+36*2]
call mulmatrices ;Y*=Z
lespar di,0
zzz=0
REPT 9
mov eax,fs:[si+zzz]
mov es:[di+rmatrix_m+zzz],eax
zzz=zzz+4
ENDM
CENDR
_calc_setrmatrix_rotyxz ENDP
;±±±±±±±± _calc_setrmatrix_rotxyz(rmatrix *matrix,angle rotx,angle roty,angle rotz) ±±±±±±±±
;entry: matrix=destination matrix (only rotation fields modified)
; rotx/y/z=rotation angles
; exit: (data written to matrix)
;descr: Calculates a rotation matrix
_calc_setrmatrix_rotxyz PROC FAR
CBEGR 36*3
mov ax,ss
mov es,ax
mov fs,ax
movpar ax,2
movpar bx,3
movpar cx,4
lea di,[bp-36*3]
call calcmatrixsep
lea si,[bp-36*3+36*0]
lea di,[bp-36*3+36*1]
call mulmatrices ;X*=Y
lea si,[bp-36*3+36*0]
lea di,[bp-36*3+36*2]
call mulmatrices ;X*=Z
lespar di,0
zzz=0
REPT 9
mov eax,fs:[si+zzz]
mov es:[di+rmatrix_m+zzz],eax
zzz=zzz+4
ENDM
CENDR
_calc_setrmatrix_rotxyz ENDP
;±±±±±±±± _calc_setrmatrix_rotzyx(rmatrix *matrix,
; angle rotx,angle roty,angle rotz) ±±±±±±±±
;entry: matrix=destination matrix (only rotation fields modified)
; rotx/y/z=rotation angles
; exit: (data written to matrix)
;descr: Calculates a rotation matrix
_calc_setrmatrix_rotzyx PROC FAR
CBEGR 36*3
mov ax,ss
mov es,ax
mov fs,ax
movpar ax,2
movpar bx,3
movpar cx,4
lea di,[bp-36*3]
call calcmatrixsep
lea si,[bp-36*3+36*2]
lea di,[bp-36*3+36*1]
call mulmatrices ;Z*=Y
lea si,[bp-36*3+36*2]
lea di,[bp-36*3+36*0]
call mulmatrices ;Z*=X
lespar di,0
zzz=0
REPT 9
mov eax,fs:[si+zzz]
mov es:[di+rmatrix_m+zzz],eax
zzz=zzz+4
ENDM
CENDR
_calc_setrmatrix_rotzyx ENDP
;±±±±±±±± _calc_mulrmatrix(rmatrix *dest, rmatrix *source) ±±±±±±±±
;entry: dest=destination matrix (matrix modified)
; source=source matrix (modifying matrix)
; exit: (data written to dest matrix)
;descr: dest=source*dest. Transposition first, rotation second.
_calc_mulrmatrix PROC FAR
CBEG
;fs:si=dest, es:di=source
lfspar si,0
lespar di,2
call mulmatrices
;fs:si now has the new rotation matrix, next rotate position
push bp
lespar di,0
add di,rmatrix_x
ldspar si,2 ;DS destroyed
lfspar bp,0
add bp,rmatrix_x
call rotatesingle
pop bp
;translate (inverse)
lespar di,2
lfspar si,0
mov eax,es:[di+rmatrix_x]
add fs:[si+rmatrix_x],eax
mov eax,es:[di+rmatrix_y]
add fs:[si+rmatrix_y],eax
mov eax,es:[di+rmatrix_z]
add fs:[si+rmatrix_z],eax
@@x: CEND
_calc_mulrmatrix ENDP
;±±±±±±±± _calc_applyrmatrix(rmatrix *dest, rmatrix *apply) ±±±±±±±±
;entry: dest=destination matrix (matrix modified)
; apply=apply matrix (modifying matrix)
; exit: (data written to dest matrix)
;descr: The apply matrix is the camera matrix, the dest contains
; the objects own rotation/position, which is modified
; according to the camera.
_calc_applyrmatrix PROC FAR
CBEG
;fs:si=source, es:di=dest
lfspar si,2
lespar di,0
call mulmatrices2
;es:di now has the new rotation matrix, next rotate position
push bp
lespar di,0
add di,rmatrix_x
ldspar si,2 ;rotate according to apply matrix
lfspar bp,0
add bp,rmatrix_x
call rotatesingle
pop bp
;translate
lespar di,2
lfspar si,0
mov eax,es:[di+rmatrix_x]
add fs:[si+rmatrix_x],eax
mov eax,es:[di+rmatrix_y]
add fs:[si+rmatrix_y],eax
mov eax,es:[di+rmatrix_z]
add fs:[si+rmatrix_z],eax
@@x: CEND
_calc_applyrmatrix ENDP
rotatesingle PROC NEAR
;ds:si=rmatrix
;fs:bp=source[]: x,y,z (long)
;es:di=destination[]: x,y,z (long)
;destination and source can be same
mov eax,fs:[bp+0]
imul dword ptr ds:[si+rmatrix_m+2*0]
mov ebx,eax
mov ecx,edx
mov eax,fs:[bp+4]
imul dword ptr ds:[si+rmatrix_m+2*2]
add ebx,eax
adc ecx,edx
mov eax,fs:[bp+8]
imul dword ptr ds:[si+rmatrix_m+2*4]
add ebx,eax
adc ecx,edx
shrd ebx,ecx,unitshr
push ebx
mov eax,fs:[bp+0]
imul dword ptr ds:[si+rmatrix_m+2*6]
mov ebx,eax
mov ecx,edx
mov eax,fs:[bp+4]
imul dword ptr ds:[si+rmatrix_m+2*8]
add ebx,eax
adc ecx,edx
mov eax,fs:[bp+8]
imul dword ptr ds:[si+rmatrix_m+2*10]
add ebx,eax
adc ecx,edx
shrd ebx,ecx,unitshr
push ebx
mov eax,fs:[bp+0]
imul dword ptr ds:[si+rmatrix_m+2*12]
mov ebx,eax
mov ecx,edx
mov eax,fs:[bp+4]
imul dword ptr ds:[si+rmatrix_m+2*14]
add ebx,eax
adc ecx,edx
mov eax,fs:[bp+8]
imul dword ptr ds:[si+rmatrix_m+2*16]
add ebx,eax
adc ecx,edx
shrd ebx,ecx,unitshr
mov es:[di+8],ebx
pop dword ptr es:[di+4]
pop dword ptr es:[di+0]
ret
rotatesingle ENDP
;±±±±±±±± _calc_sftranslate(int count,vlist *dest,long tx,long ty,long tz) ±±±±±±±±
;entry: count=number of vertices to sftranslate
; dest=destination 3D list
; matrix=rmatrix containing rotation / moving
; exit: -
;descr: Translates dest with matrix and and (starfield)
_calc_sftranslate PROC FAR
CBEG
movpar ax,0
or ax,ax
jz @@0
ldspar si,1 ;destination
movpar bx,3
movpar cx,5
movpar dx,7
mov bp,ax
@@1:
mov ax,ds:[si+vlist_x]
add ax,bx
mov ds:[si+vlist_x],ax
mov ax,ds:[si+vlist_y]
add ax,cx
mov ds:[si+vlist_y],ax
mov ax,ds:[si+vlist_z]
add ax,dx
mov ds:[si+vlist_z],ax
add si,vlist_size
dec bp
jnz @@1
@@0: CEND
_calc_sftranslate ENDP
;±±±±±±±± _calc_rotate(int count,vlist *dest,vlist *source,rmatrix *matrix) ±±±±±±±±
;entry: count=number of vertices to rotate/move
; dest=destination 3D list
; source=source 3D list
; matrix=rmatrix containing rotation / moving
; exit: -
;descr: Rotates (and moves) the given list
_calc_rotate PROC FAR
CBEG
movpar cx,0
jcxz @@0
lespar di,1 ;destination
ldspar si,5 ;matrix - dataseg not used in procedure, so DS can be used
lfspar bp,3 ;source - NOTE: bp/parameter pointer destroyed!
@@1: push cx
movsx eax,word ptr ds:[si+rmatrix_m+2*0]
imul dword ptr fs:[bp+vlist_x]
mov ebx,eax
mov ecx,edx
movsx eax,word ptr ds:[si+rmatrix_m+2*2]
imul dword ptr fs:[bp+vlist_y]
add ebx,eax
adc ecx,edx
movsx eax,word ptr ds:[si+rmatrix_m+2*4]
imul dword ptr fs:[bp+vlist_z]
add ebx,eax
adc ecx,edx
shrd ebx,ecx,unitshr
add ebx,ds:[si+rmatrix_x]
mov dword ptr es:[di+vlist_x],ebx
movsx eax,word ptr ds:[si+rmatrix_m+2*6]
imul dword ptr fs:[bp+vlist_x]
mov ebx,eax
mov ecx,edx
movsx eax,word ptr ds:[si+rmatrix_m+2*8]
imul dword ptr fs:[bp+vlist_y]
add ebx,eax
adc ecx,edx
movsx eax,word ptr ds:[si+rmatrix_m+2*10]
imul dword ptr fs:[bp+vlist_z]
add ebx,eax
adc ecx,edx
shrd ebx,ecx,unitshr
add ebx,ds:[si+rmatrix_y]
mov dword ptr es:[di+vlist_y],ebx
movsx eax,word ptr ds:[si+rmatrix_m+2*12]
imul dword ptr fs:[bp+vlist_x]
mov ebx,eax
mov ecx,edx
movsx eax,word ptr ds:[si+rmatrix_m+2*14]
imul dword ptr fs:[bp+vlist_y]
add ebx,eax
adc ecx,edx
movsx eax,word ptr ds:[si+rmatrix_m+2*16]
imul dword ptr fs:[bp+vlist_z]
add ebx,eax
adc ecx,edx
shrd ebx,ecx,unitshr
add ebx,ds:[si+rmatrix_z]
mov dword ptr es:[di+vlist_z],ebx
mov ax,word ptr fs:[bp+vlist_normal]
mov word ptr es:[di+vlist_normal],ax
;next point
add bp,vlist_size
add di,vlist_size
pop cx
loop @@1
@@0: CEND
_calc_rotate ENDP
;±±±±±±±± _calc_singlez(int vertex,vlist *vertexlist,rmatrix *matrix) ±±±±±±±±
;entry: vertex=number of vertex to process
; vertexlist=list from which to pick the vertex
; exit: -
;descr: Rotates the single vertex and returns the resulting Z coordinate.
_calc_singlez PROC FAR
CBEG
ldspar si,3 ;matrix - dataseg not used in procedure, so DS can be used
movpar ax,0
lfspar bp,1 ;source - NOTE: bp/parameter pointer destroyed!
shl ax,vlist_sizeshl
add bp,ax
mov eax,ds:[si+rmatrix_m+24]
imul dword ptr fs:[bp+vlist_x]
mov ebx,eax
mov ecx,edx
mov eax,ds:[si+rmatrix_m+28]
imul dword ptr fs:[bp+vlist_y]
add ebx,eax
adc ecx,edx
mov eax,ds:[si+rmatrix_m+32]
imul dword ptr fs:[bp+vlist_z]
add ebx,eax
adc ecx,edx
shrd ebx,ecx,unitshr
add ebx,ds:[si+rmatrix_z]
mov ax,bx
shr ebx,16
mov dx,bx
CEND
_calc_singlez ENDP
;±±±±±±±± _calc_nrotate(int count,nlist *dest,nlist *source,rmatrix *matrix) ±±±±±±±±
;entry: count=number of normals to rotate
; dest=destination 3Dnormal list
; source=source 3Dnormal list
; matrix=rmatrix containing rotation (moving part of rmatrix not used)
; exit: -
;descr: Rotates the given normal list
_calc_nrotate PROC FAR
CBEG
movpar cx,0
jcxz @@0
lespar di,1 ;destination
ldspar si,5 ;matrix - dataseg not used in procedure, so DS can be used
lfspar bp,3 ;source - NOTE: bp/parameter pointer destroyed!
@@1: push cx
mov ax,word ptr fs:[bp+nlist_x]
imul word ptr ds:[si+rmatrix_m+2*0]
mov bx,ax
mov cx,dx
mov ax,word ptr fs:[bp+nlist_y]
imul word ptr ds:[si+rmatrix_m+2*2]
add bx,ax
adc cx,dx
mov ax,word ptr fs:[bp+nlist_z]
imul word ptr ds:[si+rmatrix_m+2*4]
add bx,ax
adc cx,dx
shrd bx,cx,unitshr
mov word ptr es:[di+nlist_x],bx
mov ax,word ptr fs:[bp+nlist_x]
imul word ptr ds:[si+rmatrix_m+2*6]
mov bx,ax
mov cx,dx
mov ax,word ptr fs:[bp+nlist_y]
imul word ptr ds:[si+rmatrix_m+2*8]
add bx,ax
adc cx,dx
mov ax,word ptr fs:[bp+nlist_z]
imul word ptr ds:[si+rmatrix_m+2*10]
add bx,ax
adc cx,dx
shrd bx,cx,unitshr
mov word ptr es:[di+nlist_y],bx
mov ax,word ptr fs:[bp+nlist_x]
imul word ptr ds:[si+rmatrix_m+2*12]
mov bx,ax
mov cx,dx
mov ax,word ptr fs:[bp+nlist_y]
imul word ptr ds:[si+rmatrix_m+2*14]
add bx,ax
adc cx,dx
mov ax,word ptr fs:[bp+nlist_z]
imul word ptr ds:[si+rmatrix_m+2*16]
add bx,ax
adc cx,dx
shrd bx,cx,unitshr
mov word ptr es:[di+nlist_z],bx
;next point
add bp,nlist_size
add di,nlist_size
pop cx
loop @@1
@@0: CEND
_calc_nrotate ENDP
;±±±±±±±± _calc_rotate16(int count,nlist *dest,nlist *source,rmatrix *matrix) ±±±±±±±±
;entry: count=number of normals to rotate
; dest=destination 3Dnormal list
; source=source 3Dnormal list
; matrix=rmatrix containing rotation (moving part of rmatrix not used)
; exit: -
;descr: Rotates the given normal list
_calc_rotate16 PROC FAR
CBEG
movpar cx,0
jcxz @@0
lespar di,1 ;destination
ldspar si,5 ;matrix - dataseg not used in procedure, so DS can be used
lfspar bp,3 ;source - NOTE: bp/parameter pointer destroyed!
@@1: push cx
mov ax,word ptr fs:[bp+vlist_x]
imul word ptr ds:[si+rmatrix_m+2*0]
mov bx,ax
mov cx,dx
mov ax,word ptr fs:[bp+vlist_y]
imul word ptr ds:[si+rmatrix_m+2*2]
add bx,ax
adc cx,dx
mov ax,word ptr fs:[bp+vlist_z]
imul word ptr ds:[si+rmatrix_m+2*4]
add bx,ax
adc cx,dx
shrd bx,cx,unitshr
mov word ptr es:[di+vlist_x],bx
mov ax,word ptr fs:[bp+vlist_x]
imul word ptr ds:[si+rmatrix_m+2*6]
mov bx,ax
mov cx,dx
mov ax,word ptr fs:[bp+vlist_y]
imul word ptr ds:[si+rmatrix_m+2*8]
add bx,ax
adc cx,dx
mov ax,word ptr fs:[bp+vlist_z]
imul word ptr ds:[si+rmatrix_m+2*10]
add bx,ax
adc cx,dx
shrd bx,cx,unitshr
mov word ptr es:[di+vlist_y],bx
mov ax,word ptr fs:[bp+vlist_x]
imul word ptr ds:[si+rmatrix_m+2*12]
mov bx,ax
mov cx,dx
mov ax,word ptr fs:[bp+vlist_y]
imul word ptr ds:[si+rmatrix_m+2*14]
add bx,ax
adc cx,dx
mov ax,word ptr fs:[bp+vlist_z]
imul word ptr ds:[si+rmatrix_m+2*16]
add bx,ax
adc cx,dx
shrd bx,cx,unitshr
mov word ptr es:[di+vlist_z],bx
;next point
add bp,vlist_size
add di,vlist_size
pop cx
loop @@1
@@0: CEND
_calc_rotate16 ENDP
;±±±±±±±± _calc_project(int count,pvlist *dest,vlist *source) ±±±±±±±±
;entry: count=number of vertices to project
; dest=destination projected list
; source=source 3D list
; (_proj* variables in data segment define the projection)
; exit: logical and of visibility flags for all vertices (!=0 == object invis.)
;descr: Projects the given list = does perspective transformation
_calc_project PROC FAR
CBEG
lfspar si,3
lespar di,1
mov ax,0ffffh
movpar cx,0
jcxz @@0
@@1: push cx
push ax
mov ecx,fs:[si+vlist_x]
mov eax,fs:[si+vlist_y]
mov ebx,fs:[si+vlist_z]
xor bp,bp
cmp ebx,ds:_projclipz[CLIPMIN]
jge @@21
or bp,VF_NEAR
mov ebx,ds:_projclipz[CLIPMIN]
jmp @@22
@@21: cmp ebx,ds:_projclipz[CLIPMAX]
jle @@22
or bp,VF_FAR
@@22: ;
imul ds:_projmuly
idiv ebx
add eax,ds:_projaddy
cmp eax,ds:_projclipy[CLIPMAX]
jng @@41
or bp,VF_DOWN
@@41: cmp eax,ds:_projclipy[CLIPMIN]
jnl @@42
or bp,VF_UP
@@42: mov es:[di+pvlist_y],ax ;store Y
;
mov eax,ds:_projmulx
imul ecx
idiv ebx
add eax,ds:_projaddx
cmp eax,ds:_projclipx[CLIPMAX]
jng @@43
or bp,VF_RIGHT
@@43: cmp eax,ds:_projclipx[CLIPMIN]
jnl @@44
or bp,VF_LEFT
@@44: mov es:[di+pvlist_x],ax ;store X
@@5: mov es:[di+pvlist_vf],bp ;store visiblity flags
;next point
add si,vlist_size
add di,pvlist_size
pop ax
pop cx
and ax,bp
loop @@1
@@0: CEND
_calc_project ENDP
;±±±±±±±± _calc_project16(int count,pvlist *dest,vlist *source) ±±±±±±±±
;entry: count=number of vertices to project
; dest=destination projected list
; source=source 3D list
; (_proj* variables in data segment define the projection)
; exit: logical and of visibility flags for all vertices (!=0 == object invis.)
;descr: Projects the given list = does perspective transformation
_calc_project16 PROC FAR
CBEG
lfspar si,3
lespar di,1
mov ax,0ffffh
movpar cx,0
jcxz @@0
@@1: push cx
push ax
movsx ecx,word ptr fs:[si+vlist_x]
movsx eax,word ptr fs:[si+vlist_y]
movsx ebx,word ptr fs:[si+vlist_z]
xor bp,bp
cmp ebx,ds:_projclipz[CLIPMIN]
jge @@21
or bp,VF_NEAR
mov ebx,ds:_projclipz[CLIPMIN]
jmp @@22
@@21: cmp ebx,ds:_projclipz[CLIPMAX]
jle @@22
or bp,VF_FAR
@@22: ;
imul ds:_projmuly
idiv ebx
add eax,ds:_projaddy
cmp eax,ds:_projclipy[CLIPMAX]
jng @@41
or bp,VF_DOWN
@@41: cmp eax,ds:_projclipy[CLIPMIN]
jnl @@42
or bp,VF_UP
@@42: mov es:[di+pvlist_y],ax ;store Y
;
mov eax,ds:_projmulx
imul ecx
idiv ebx
add eax,ds:_projaddx
cmp eax,ds:_projclipx[CLIPMAX]
jng @@43
or bp,VF_RIGHT
@@43: cmp eax,ds:_projclipx[CLIPMIN]
jnl @@44
or bp,VF_LEFT
@@44: mov es:[di+pvlist_x],ax ;store X
@@5: mov es:[di+pvlist_vf],bp ;store visiblity flags
;next point
add si,vlist_size
add di,pvlist_size
pop ax
pop cx
and ax,bp
loop @@1
@@0: CEND
_calc_project16 ENDP
asm_code ENDS
END

BIN
VISU/ACALC.OBJ Normal file

Binary file not shown.

74
VISU/AD.INC Normal file
View file

@ -0,0 +1,74 @@
;/****************************************************************************
;** MODULE: ad.inc
;** AUTHOR: Sami Tammilehto / Fennosoftec OY
;** DOCUMENT: ?
;** VERSION: 1.0
;** REFERENCE: -
;** REVISED BY: -
;*****************************************************************************
;**
;** Assembler / Include - THIS FILE AND CD.H SHOULD BE IN SYNC
;** - data types and related constants
;**
;****************************************************************************/
pvlist_x equ 0
pvlist_y equ 2
pvlist_vf equ 4
pvlist_normal equ 8
pvlist_size equ 16
pvlist_sizeshl equ 4 ;[!!] vlist_sizeshl==pvlist_sizeshl required in many
;places! seek for [!!] for places expecting this
vlist_x equ 0
vlist_y equ 4
vlist_z equ 8
vlist_normal equ 12
vlist_size equ 16
vlist_sizeshl equ 4 ;[!!] vlist_sizeshl==pvlist_sizeshl required in many
;places! seek for [!!] for places expecting this
nlist_x equ 0
nlist_y equ 2
nlist_z equ 4
nlist_size equ 8
nlist_sizeshl equ 3
rmatrix_m equ 0
rmatrix_x equ 36
rmatrix_y equ 40
rmatrix_z equ 44
rmatrix_size equ 48
unit equ 16384
unitshr equ 14
VF_UP equ 1
VF_DOWN equ 2
VF_LEFT equ 4
VF_RIGHT equ 8
VF_NEAR equ 16
VF_FAR equ 32
MAXSIDES equ 16
;offsets to fields inside polylist. First vertex at offset 0, next at 4
;and so on. For example third vertices X coordinate is at [base+3*4+POLYX]
POLYSIDES equ 0
POLYCOLOR equ 2
POLYFLAGS equ 4
POLYVXSEG equ 6 ;segment
POLYX equ (16)
POLYY equ (16+2)
POLYVX equ (16+MAXSIDES*4) ;offset
POLYGR equ (16+2*MAXSIDES*4) ;color
POLYTX equ (16+2*MAXSIDES*4+2)
POLYSIZE equ (16+3*MAXSIDES*4)
F_DEFAULT equ 0f001h
F_VISIBLE equ 00001h
F_FLIP equ 00100h
F_2SIDE equ 00200h
F_SHADE8 equ 00400h
F_SHADE16 equ 00800h
F_SHADE32 equ 00C00h
F_GOURAUD equ 01000h
F_TEXTURE equ 02000h

60
VISU/ADATA.ASM Normal file
View file

@ -0,0 +1,60 @@
;/****************************************************************************
;** MODULE: adata.asm
;** AUTHOR: Sami Tammilehto / Fennosoftec OY
;** DOCUMENT: ?
;** VERSION: 1.0
;** REFERENCE: -
;** REVISED BY: -
;*****************************************************************************
;**
;** Assembler / Data
;**
;****************************************************************************/
include a.inc
asm_data SEGMENT para public use16 'DATA'
_datanull dd 12345678h
;offsets to rows in vram
_rows LABEL WORD
dw MAXROWS dup(0)
_rowlen dw 0
_cdataseg dw 0
;segment to video memory
_vramseg dw 0
ALIGN 4
;projection clip window
_projclipx dd 0,319 ;(xmin,xmax)
_projclipy dd 0,199 ;(ymin,ymax)
_projclipz dd 256,1000000000 ;(zmin,zmax)
;projection variables
_projmulx dd 250
_projmuly dd 220
_projaddx dd 160
_projaddy dd 100
_projaspect dw 256 ;aspect ratio (ratio=256*ypitch/xpitch)
_projoversampleshr dw 0
;video driver routine pointers
vr LABEL WORD
dw VRSIZE dup(0)
_polydrw LABEL WORD
dw 1024 dup(0)
_sintable LABEL WORD
include adatasin.inc
_avistan LABEL WORD
include avistan.inc
_afilldiv LABEL WORD
include afilldiv.inc
asm_data ENDS
END

BIN
VISU/ADATA.OBJ Normal file

Binary file not shown.

515
VISU/ADATASIN.INC Normal file
View file

@ -0,0 +1,515 @@
;Sinus table for a circle with 4096 subdivision
;4096 values in range -16384..16384
dw 0, 25, 50, 75, 101, 126, 151, 176
dw 201, 226, 251, 276, 302, 327, 352, 377
dw 402, 427, 452, 477, 503, 528, 553, 578
dw 603, 628, 653, 678, 704, 729, 754, 779
dw 804, 829, 854, 879, 904, 929, 955, 980
dw 1005, 1030, 1055, 1080, 1105, 1130, 1155, 1180
dw 1205, 1230, 1255, 1280, 1306, 1331, 1356, 1381
dw 1406, 1431, 1456, 1481, 1506, 1531, 1556, 1581
dw 1606, 1631, 1656, 1681, 1706, 1731, 1756, 1781
dw 1806, 1831, 1856, 1881, 1906, 1931, 1956, 1981
dw 2006, 2031, 2055, 2080, 2105, 2130, 2155, 2180
dw 2205, 2230, 2255, 2280, 2305, 2329, 2354, 2379
dw 2404, 2429, 2454, 2479, 2503, 2528, 2553, 2578
dw 2603, 2628, 2652, 2677, 2702, 2727, 2752, 2776
dw 2801, 2826, 2851, 2875, 2900, 2925, 2949, 2974
dw 2999, 3024, 3048, 3073, 3098, 3122, 3147, 3172
dw 3196, 3221, 3246, 3270, 3295, 3320, 3344, 3369
dw 3393, 3418, 3442, 3467, 3492, 3516, 3541, 3565
dw 3590, 3614, 3639, 3663, 3688, 3712, 3737, 3761
dw 3786, 3810, 3835, 3859, 3883, 3908, 3932, 3957
dw 3981, 4005, 4030, 4054, 4078, 4103, 4127, 4151
dw 4176, 4200, 4224, 4249, 4273, 4297, 4321, 4346
dw 4370, 4394, 4418, 4442, 4467, 4491, 4515, 4539
dw 4563, 4587, 4612, 4636, 4660, 4684, 4708, 4732
dw 4756, 4780, 4804, 4828, 4852, 4876, 4900, 4924
dw 4948, 4972, 4996, 5020, 5044, 5068, 5092, 5115
dw 5139, 5163, 5187, 5211, 5235, 5259, 5282, 5306
dw 5330, 5354, 5377, 5401, 5425, 5449, 5472, 5496
dw 5520, 5543, 5567, 5591, 5614, 5638, 5661, 5685
dw 5708, 5732, 5756, 5779, 5803, 5826, 5850, 5873
dw 5897, 5920, 5943, 5967, 5990, 6014, 6037, 6060
dw 6084, 6107, 6130, 6154, 6177, 6200, 6223, 6247
dw 6270, 6293, 6316, 6339, 6363, 6386, 6409, 6432
dw 6455, 6478, 6501, 6524, 6547, 6570, 6593, 6616
dw 6639, 6662, 6685, 6708, 6731, 6754, 6777, 6800
dw 6823, 6846, 6868, 6891, 6914, 6937, 6960, 6982
dw 7005, 7028, 7050, 7073, 7096, 7118, 7141, 7164
dw 7186, 7209, 7231, 7254, 7276, 7299, 7321, 7344
dw 7366, 7389, 7411, 7434, 7456, 7478, 7501, 7523
dw 7545, 7568, 7590, 7612, 7635, 7657, 7679, 7701
dw 7723, 7746, 7768, 7790, 7812, 7834, 7856, 7878
dw 7900, 7922, 7944, 7966, 7988, 8010, 8032, 8054
dw 8076, 8098, 8119, 8141, 8163, 8185, 8207, 8228
dw 8250, 8272, 8293, 8315, 8337, 8358, 8380, 8401
dw 8423, 8445, 8466, 8488, 8509, 8531, 8552, 8573
dw 8595, 8616, 8638, 8659, 8680, 8702, 8723, 8744
dw 8765, 8787, 8808, 8829, 8850, 8871, 8892, 8914
dw 8935, 8956, 8977, 8998, 9019, 9040, 9061, 9082
dw 9102, 9123, 9144, 9165, 9186, 9207, 9227, 9248
dw 9269, 9290, 9310, 9331, 9352, 9372, 9393, 9413
dw 9434, 9455, 9475, 9496, 9516, 9537, 9557, 9577
dw 9598, 9618, 9638, 9659, 9679, 9699, 9720, 9740
dw 9760, 9780, 9800, 9820, 9841, 9861, 9881, 9901
dw 9921, 9941, 9961, 9981, 10001, 10020, 10040, 10060
dw 10080, 10100, 10120, 10139, 10159, 10179, 10198, 10218
dw 10238, 10257, 10277, 10296, 10316, 10336, 10355, 10374
dw 10394, 10413, 10433, 10452, 10471, 10491, 10510, 10529
dw 10549, 10568, 10587, 10606, 10625, 10644, 10663, 10683
dw 10702, 10721, 10740, 10759, 10778, 10796, 10815, 10834
dw 10853, 10872, 10891, 10909, 10928, 10947, 10966, 10984
dw 11003, 11021, 11040, 11059, 11077, 11096, 11114, 11133
dw 11151, 11169, 11188, 11206, 11224, 11243, 11261, 11279
dw 11297, 11316, 11334, 11352, 11370, 11388, 11406, 11424
dw 11442, 11460, 11478, 11496, 11514, 11532, 11550, 11567
dw 11585, 11603, 11621, 11638, 11656, 11674, 11691, 11709
dw 11727, 11744, 11762, 11779, 11797, 11814, 11831, 11849
dw 11866, 11883, 11901, 11918, 11935, 11952, 11970, 11987
dw 12004, 12021, 12038, 12055, 12072, 12089, 12106, 12123
dw 12140, 12157, 12173, 12190, 12207, 12224, 12240, 12257
dw 12274, 12290, 12307, 12324, 12340, 12357, 12373, 12390
dw 12406, 12423, 12439, 12455, 12472, 12488, 12504, 12520
dw 12537, 12553, 12569, 12585, 12601, 12617, 12633, 12649
dw 12665, 12681, 12697, 12713, 12729, 12744, 12760, 12776
dw 12792, 12807, 12823, 12839, 12854, 12870, 12885, 12901
dw 12916, 12932, 12947, 12963, 12978, 12993, 13008, 13024
dw 13039, 13054, 13069, 13085, 13100, 13115, 13130, 13145
dw 13160, 13175, 13190, 13205, 13219, 13234, 13249, 13264
dw 13279, 13293, 13308, 13323, 13337, 13352, 13366, 13381
dw 13395, 13410, 13424, 13439, 13453, 13467, 13482, 13496
dw 13510, 13524, 13538, 13553, 13567, 13581, 13595, 13609
dw 13623, 13637, 13651, 13665, 13678, 13692, 13706, 13720
dw 13733, 13747, 13761, 13774, 13788, 13802, 13815, 13829
dw 13842, 13856, 13869, 13882, 13896, 13909, 13922, 13935
dw 13949, 13962, 13975, 13988, 14001, 14014, 14027, 14040
dw 14053, 14066, 14079, 14092, 14104, 14117, 14130, 14143
dw 14155, 14168, 14181, 14193, 14206, 14218, 14231, 14243
dw 14256, 14268, 14280, 14293, 14305, 14317, 14329, 14341
dw 14354, 14366, 14378, 14390, 14402, 14414, 14426, 14438
dw 14449, 14461, 14473, 14485, 14497, 14508, 14520, 14531
dw 14543, 14555, 14566, 14578, 14589, 14601, 14612, 14623
dw 14635, 14646, 14657, 14668, 14680, 14691, 14702, 14713
dw 14724, 14735, 14746, 14757, 14768, 14779, 14789, 14800
dw 14811, 14822, 14832, 14843, 14854, 14864, 14875, 14885
dw 14896, 14906, 14917, 14927, 14937, 14948, 14958, 14968
dw 14978, 14989, 14999, 15009, 15019, 15029, 15039, 15049
dw 15059, 15069, 15078, 15088, 15098, 15108, 15118, 15127
dw 15137, 15146, 15156, 15166, 15175, 15184, 15194, 15203
dw 15213, 15222, 15231, 15240, 15250, 15259, 15268, 15277
dw 15286, 15295, 15304, 15313, 15322, 15331, 15340, 15349
dw 15357, 15366, 15375, 15383, 15392, 15401, 15409, 15418
dw 15426, 15435, 15443, 15451, 15460, 15468, 15476, 15485
dw 15493, 15501, 15509, 15517, 15525, 15533, 15541, 15549
dw 15557, 15565, 15573, 15581, 15588, 15596, 15604, 15611
dw 15619, 15627, 15634, 15642, 15649, 15656, 15664, 15671
dw 15679, 15686, 15693, 15700, 15707, 15715, 15722, 15729
dw 15736, 15743, 15750, 15757, 15763, 15770, 15777, 15784
dw 15791, 15797, 15804, 15810, 15817, 15824, 15830, 15837
dw 15843, 15849, 15856, 15862, 15868, 15875, 15881, 15887
dw 15893, 15899, 15905, 15911, 15917, 15923, 15929, 15935
dw 15941, 15946, 15952, 15958, 15964, 15969, 15975, 15980
dw 15986, 15991, 15997, 16002, 16008, 16013, 16018, 16024
dw 16029, 16034, 16039, 16044, 16049, 16054, 16059, 16064
dw 16069, 16074, 16079, 16084, 16088, 16093, 16098, 16103
dw 16107, 16112, 16116, 16121, 16125, 16130, 16134, 16138
dw 16143, 16147, 16151, 16156, 16160, 16164, 16168, 16172
dw 16176, 16180, 16184, 16188, 16192, 16195, 16199, 16203
dw 16207, 16210, 16214, 16218, 16221, 16225, 16228, 16232
dw 16235, 16238, 16242, 16245, 16248, 16251, 16255, 16258
dw 16261, 16264, 16267, 16270, 16273, 16276, 16279, 16281
dw 16284, 16287, 16290, 16292, 16295, 16298, 16300, 16303
dw 16305, 16308, 16310, 16312, 16315, 16317, 16319, 16321
dw 16324, 16326, 16328, 16330, 16332, 16334, 16336, 16338
dw 16340, 16341, 16343, 16345, 16347, 16348, 16350, 16352
dw 16353, 16355, 16356, 16358, 16359, 16360, 16362, 16363
dw 16364, 16365, 16367, 16368, 16369, 16370, 16371, 16372
dw 16373, 16374, 16375, 16375, 16376, 16377, 16378, 16378
dw 16379, 16380, 16380, 16381, 16381, 16382, 16382, 16382
dw 16383, 16383, 16383, 16384, 16384, 16384, 16384, 16384
dw 16384, 16384, 16384, 16384, 16384, 16384, 16383, 16383
dw 16383, 16382, 16382, 16382, 16381, 16381, 16380, 16380
dw 16379, 16378, 16378, 16377, 16376, 16375, 16375, 16374
dw 16373, 16372, 16371, 16370, 16369, 16368, 16367, 16365
dw 16364, 16363, 16362, 16360, 16359, 16358, 16356, 16355
dw 16353, 16352, 16350, 16348, 16347, 16345, 16343, 16341
dw 16340, 16338, 16336, 16334, 16332, 16330, 16328, 16326
dw 16324, 16321, 16319, 16317, 16315, 16312, 16310, 16308
dw 16305, 16303, 16300, 16298, 16295, 16292, 16290, 16287
dw 16284, 16281, 16279, 16276, 16273, 16270, 16267, 16264
dw 16261, 16258, 16255, 16251, 16248, 16245, 16242, 16238
dw 16235, 16232, 16228, 16225, 16221, 16218, 16214, 16210
dw 16207, 16203, 16199, 16195, 16192, 16188, 16184, 16180
dw 16176, 16172, 16168, 16164, 16160, 16156, 16151, 16147
dw 16143, 16138, 16134, 16130, 16125, 16121, 16116, 16112
dw 16107, 16103, 16098, 16093, 16088, 16084, 16079, 16074
dw 16069, 16064, 16059, 16054, 16049, 16044, 16039, 16034
dw 16029, 16024, 16018, 16013, 16008, 16002, 15997, 15991
dw 15986, 15980, 15975, 15969, 15964, 15958, 15952, 15946
dw 15941, 15935, 15929, 15923, 15917, 15911, 15905, 15899
dw 15893, 15887, 15881, 15875, 15868, 15862, 15856, 15849
dw 15843, 15837, 15830, 15824, 15817, 15810, 15804, 15797
dw 15791, 15784, 15777, 15770, 15763, 15757, 15750, 15743
dw 15736, 15729, 15722, 15715, 15707, 15700, 15693, 15686
dw 15679, 15671, 15664, 15656, 15649, 15642, 15634, 15627
dw 15619, 15611, 15604, 15596, 15588, 15581, 15573, 15565
dw 15557, 15549, 15541, 15533, 15525, 15517, 15509, 15501
dw 15493, 15485, 15476, 15468, 15460, 15451, 15443, 15435
dw 15426, 15418, 15409, 15401, 15392, 15383, 15375, 15366
dw 15357, 15349, 15340, 15331, 15322, 15313, 15304, 15295
dw 15286, 15277, 15268, 15259, 15250, 15240, 15231, 15222
dw 15213, 15203, 15194, 15184, 15175, 15166, 15156, 15146
dw 15137, 15127, 15118, 15108, 15098, 15088, 15078, 15069
dw 15059, 15049, 15039, 15029, 15019, 15009, 14999, 14989
dw 14978, 14968, 14958, 14948, 14937, 14927, 14917, 14906
dw 14896, 14885, 14875, 14864, 14854, 14843, 14832, 14822
dw 14811, 14800, 14789, 14779, 14768, 14757, 14746, 14735
dw 14724, 14713, 14702, 14691, 14680, 14668, 14657, 14646
dw 14635, 14623, 14612, 14601, 14589, 14578, 14566, 14555
dw 14543, 14531, 14520, 14508, 14497, 14485, 14473, 14461
dw 14449, 14438, 14426, 14414, 14402, 14390, 14378, 14366
dw 14354, 14341, 14329, 14317, 14305, 14293, 14280, 14268
dw 14256, 14243, 14231, 14218, 14206, 14193, 14181, 14168
dw 14155, 14143, 14130, 14117, 14104, 14092, 14079, 14066
dw 14053, 14040, 14027, 14014, 14001, 13988, 13975, 13962
dw 13949, 13935, 13922, 13909, 13896, 13882, 13869, 13856
dw 13842, 13829, 13815, 13802, 13788, 13774, 13761, 13747
dw 13733, 13720, 13706, 13692, 13678, 13665, 13651, 13637
dw 13623, 13609, 13595, 13581, 13567, 13553, 13538, 13524
dw 13510, 13496, 13482, 13467, 13453, 13439, 13424, 13410
dw 13395, 13381, 13366, 13352, 13337, 13323, 13308, 13293
dw 13279, 13264, 13249, 13234, 13219, 13205, 13190, 13175
dw 13160, 13145, 13130, 13115, 13100, 13085, 13069, 13054
dw 13039, 13024, 13008, 12993, 12978, 12963, 12947, 12932
dw 12916, 12901, 12885, 12870, 12854, 12839, 12823, 12807
dw 12792, 12776, 12760, 12744, 12729, 12713, 12697, 12681
dw 12665, 12649, 12633, 12617, 12601, 12585, 12569, 12553
dw 12537, 12520, 12504, 12488, 12472, 12455, 12439, 12423
dw 12406, 12390, 12373, 12357, 12340, 12324, 12307, 12290
dw 12274, 12257, 12240, 12224, 12207, 12190, 12173, 12157
dw 12140, 12123, 12106, 12089, 12072, 12055, 12038, 12021
dw 12004, 11987, 11970, 11952, 11935, 11918, 11901, 11883
dw 11866, 11849, 11831, 11814, 11797, 11779, 11762, 11744
dw 11727, 11709, 11691, 11674, 11656, 11638, 11621, 11603
dw 11585, 11567, 11550, 11532, 11514, 11496, 11478, 11460
dw 11442, 11424, 11406, 11388, 11370, 11352, 11334, 11316
dw 11297, 11279, 11261, 11243, 11224, 11206, 11188, 11169
dw 11151, 11133, 11114, 11096, 11077, 11059, 11040, 11021
dw 11003, 10984, 10966, 10947, 10928, 10909, 10891, 10872
dw 10853, 10834, 10815, 10796, 10778, 10759, 10740, 10721
dw 10702, 10683, 10663, 10644, 10625, 10606, 10587, 10568
dw 10549, 10529, 10510, 10491, 10471, 10452, 10433, 10413
dw 10394, 10374, 10355, 10336, 10316, 10296, 10277, 10257
dw 10238, 10218, 10198, 10179, 10159, 10139, 10120, 10100
dw 10080, 10060, 10040, 10020, 10001, 9981, 9961, 9941
dw 9921, 9901, 9881, 9861, 9841, 9820, 9800, 9780
dw 9760, 9740, 9720, 9699, 9679, 9659, 9638, 9618
dw 9598, 9577, 9557, 9537, 9516, 9496, 9475, 9455
dw 9434, 9413, 9393, 9372, 9352, 9331, 9310, 9290
dw 9269, 9248, 9227, 9207, 9186, 9165, 9144, 9123
dw 9102, 9082, 9061, 9040, 9019, 8998, 8977, 8956
dw 8935, 8914, 8892, 8871, 8850, 8829, 8808, 8787
dw 8765, 8744, 8723, 8702, 8680, 8659, 8638, 8616
dw 8595, 8573, 8552, 8531, 8509, 8488, 8466, 8445
dw 8423, 8401, 8380, 8358, 8337, 8315, 8293, 8272
dw 8250, 8228, 8207, 8185, 8163, 8141, 8119, 8098
dw 8076, 8054, 8032, 8010, 7988, 7966, 7944, 7922
dw 7900, 7878, 7856, 7834, 7812, 7790, 7768, 7746
dw 7723, 7701, 7679, 7657, 7635, 7612, 7590, 7568
dw 7545, 7523, 7501, 7478, 7456, 7434, 7411, 7389
dw 7366, 7344, 7321, 7299, 7276, 7254, 7231, 7209
dw 7186, 7164, 7141, 7118, 7096, 7073, 7050, 7028
dw 7005, 6982, 6960, 6937, 6914, 6891, 6868, 6846
dw 6823, 6800, 6777, 6754, 6731, 6708, 6685, 6662
dw 6639, 6616, 6593, 6570, 6547, 6524, 6501, 6478
dw 6455, 6432, 6409, 6386, 6363, 6339, 6316, 6293
dw 6270, 6247, 6223, 6200, 6177, 6154, 6130, 6107
dw 6084, 6060, 6037, 6014, 5990, 5967, 5943, 5920
dw 5897, 5873, 5850, 5826, 5803, 5779, 5756, 5732
dw 5708, 5685, 5661, 5638, 5614, 5591, 5567, 5543
dw 5520, 5496, 5472, 5449, 5425, 5401, 5377, 5354
dw 5330, 5306, 5282, 5259, 5235, 5211, 5187, 5163
dw 5139, 5115, 5092, 5068, 5044, 5020, 4996, 4972
dw 4948, 4924, 4900, 4876, 4852, 4828, 4804, 4780
dw 4756, 4732, 4708, 4684, 4660, 4636, 4612, 4587
dw 4563, 4539, 4515, 4491, 4467, 4442, 4418, 4394
dw 4370, 4346, 4321, 4297, 4273, 4249, 4224, 4200
dw 4176, 4151, 4127, 4103, 4078, 4054, 4030, 4005
dw 3981, 3957, 3932, 3908, 3883, 3859, 3835, 3810
dw 3786, 3761, 3737, 3712, 3688, 3663, 3639, 3614
dw 3590, 3565, 3541, 3516, 3492, 3467, 3442, 3418
dw 3393, 3369, 3344, 3320, 3295, 3270, 3246, 3221
dw 3196, 3172, 3147, 3122, 3098, 3073, 3048, 3024
dw 2999, 2974, 2949, 2925, 2900, 2875, 2851, 2826
dw 2801, 2776, 2752, 2727, 2702, 2677, 2652, 2628
dw 2603, 2578, 2553, 2528, 2503, 2479, 2454, 2429
dw 2404, 2379, 2354, 2329, 2305, 2280, 2255, 2230
dw 2205, 2180, 2155, 2130, 2105, 2080, 2055, 2031
dw 2006, 1981, 1956, 1931, 1906, 1881, 1856, 1831
dw 1806, 1781, 1756, 1731, 1706, 1681, 1656, 1631
dw 1606, 1581, 1556, 1531, 1506, 1481, 1456, 1431
dw 1406, 1381, 1356, 1331, 1306, 1280, 1255, 1230
dw 1205, 1180, 1155, 1130, 1105, 1080, 1055, 1030
dw 1005, 980, 955, 929, 904, 879, 854, 829
dw 804, 779, 754, 729, 704, 678, 653, 628
dw 603, 578, 553, 528, 503, 477, 452, 427
dw 402, 377, 352, 327, 302, 276, 251, 226
dw 201, 176, 151, 126, 101, 75, 50, 25
dw 0, -24, -49, -74, -100, -125, -150, -175
dw -200, -225, -250, -275, -301, -326, -351, -376
dw -401, -426, -451, -476, -502, -527, -552, -577
dw -602, -627, -652, -677, -703, -728, -753, -778
dw -803, -828, -853, -878, -903, -928, -954, -979
dw -1004, -1029, -1054, -1079, -1104, -1129, -1154, -1179
dw -1204, -1229, -1254, -1279, -1305, -1330, -1355, -1380
dw -1405, -1430, -1455, -1480, -1505, -1530, -1555, -1580
dw -1605, -1630, -1655, -1680, -1705, -1730, -1755, -1780
dw -1805, -1830, -1855, -1880, -1905, -1930, -1955, -1980
dw -2005, -2030, -2054, -2079, -2104, -2129, -2154, -2179
dw -2204, -2229, -2254, -2279, -2304, -2328, -2353, -2378
dw -2403, -2428, -2453, -2478, -2502, -2527, -2552, -2577
dw -2602, -2627, -2651, -2676, -2701, -2726, -2751, -2775
dw -2800, -2825, -2850, -2874, -2899, -2924, -2948, -2973
dw -2998, -3023, -3047, -3072, -3097, -3121, -3146, -3171
dw -3195, -3220, -3245, -3269, -3294, -3319, -3343, -3368
dw -3392, -3417, -3441, -3466, -3491, -3515, -3540, -3564
dw -3589, -3613, -3638, -3662, -3687, -3711, -3736, -3760
dw -3785, -3809, -3834, -3858, -3882, -3907, -3931, -3956
dw -3980, -4004, -4029, -4053, -4077, -4102, -4126, -4150
dw -4175, -4199, -4223, -4248, -4272, -4296, -4320, -4345
dw -4369, -4393, -4417, -4441, -4466, -4490, -4514, -4538
dw -4562, -4586, -4611, -4635, -4659, -4683, -4707, -4731
dw -4755, -4779, -4803, -4827, -4851, -4875, -4899, -4923
dw -4947, -4971, -4995, -5019, -5043, -5067, -5091, -5114
dw -5138, -5162, -5186, -5210, -5234, -5258, -5281, -5305
dw -5329, -5353, -5376, -5400, -5424, -5448, -5471, -5495
dw -5519, -5542, -5566, -5590, -5613, -5637, -5660, -5684
dw -5707, -5731, -5755, -5778, -5802, -5825, -5849, -5872
dw -5896, -5919, -5942, -5966, -5989, -6013, -6036, -6059
dw -6083, -6106, -6129, -6153, -6176, -6199, -6222, -6246
dw -6269, -6292, -6315, -6338, -6362, -6385, -6408, -6431
dw -6454, -6477, -6500, -6523, -6546, -6569, -6592, -6615
dw -6638, -6661, -6684, -6707, -6730, -6753, -6776, -6799
dw -6822, -6845, -6867, -6890, -6913, -6936, -6959, -6981
dw -7004, -7027, -7049, -7072, -7095, -7117, -7140, -7163
dw -7185, -7208, -7230, -7253, -7275, -7298, -7320, -7343
dw -7365, -7388, -7410, -7433, -7455, -7477, -7500, -7522
dw -7544, -7567, -7589, -7611, -7634, -7656, -7678, -7700
dw -7722, -7745, -7767, -7789, -7811, -7833, -7855, -7877
dw -7899, -7921, -7943, -7965, -7987, -8009, -8031, -8053
dw -8075, -8097, -8118, -8140, -8162, -8184, -8206, -8227
dw -8249, -8271, -8292, -8314, -8336, -8357, -8379, -8400
dw -8422, -8444, -8465, -8487, -8508, -8530, -8551, -8572
dw -8594, -8615, -8637, -8658, -8679, -8701, -8722, -8743
dw -8764, -8786, -8807, -8828, -8849, -8870, -8891, -8913
dw -8934, -8955, -8976, -8997, -9018, -9039, -9060, -9081
dw -9101, -9122, -9143, -9164, -9185, -9206, -9226, -9247
dw -9268, -9289, -9309, -9330, -9351, -9371, -9392, -9412
dw -9433, -9454, -9474, -9495, -9515, -9536, -9556, -9576
dw -9597, -9617, -9637, -9658, -9678, -9698, -9719, -9739
dw -9759, -9779, -9799, -9819, -9840, -9860, -9880, -9900
dw -9920, -9940, -9960, -9980,-10000,-10019,-10039,-10059
dw -10079,-10099,-10119,-10138,-10158,-10178,-10197,-10217
dw -10237,-10256,-10276,-10295,-10315,-10335,-10354,-10373
dw -10393,-10412,-10432,-10451,-10470,-10490,-10509,-10528
dw -10548,-10567,-10586,-10605,-10624,-10643,-10662,-10682
dw -10701,-10720,-10739,-10758,-10777,-10795,-10814,-10833
dw -10852,-10871,-10890,-10908,-10927,-10946,-10965,-10983
dw -11002,-11020,-11039,-11058,-11076,-11095,-11113,-11132
dw -11150,-11168,-11187,-11205,-11223,-11242,-11260,-11278
dw -11296,-11315,-11333,-11351,-11369,-11387,-11405,-11423
dw -11441,-11459,-11477,-11495,-11513,-11531,-11549,-11566
dw -11584,-11602,-11620,-11637,-11655,-11673,-11690,-11708
dw -11726,-11743,-11761,-11778,-11796,-11813,-11830,-11848
dw -11865,-11882,-11900,-11917,-11934,-11951,-11969,-11986
dw -12003,-12020,-12037,-12054,-12071,-12088,-12105,-12122
dw -12139,-12156,-12172,-12189,-12206,-12223,-12239,-12256
dw -12273,-12289,-12306,-12323,-12339,-12356,-12372,-12389
dw -12405,-12422,-12438,-12454,-12471,-12487,-12503,-12519
dw -12536,-12552,-12568,-12584,-12600,-12616,-12632,-12648
dw -12664,-12680,-12696,-12712,-12728,-12743,-12759,-12775
dw -12791,-12806,-12822,-12838,-12853,-12869,-12884,-12900
dw -12915,-12931,-12946,-12962,-12977,-12992,-13007,-13023
dw -13038,-13053,-13068,-13084,-13099,-13114,-13129,-13144
dw -13159,-13174,-13189,-13204,-13218,-13233,-13248,-13263
dw -13278,-13292,-13307,-13322,-13336,-13351,-13365,-13380
dw -13394,-13409,-13423,-13438,-13452,-13466,-13481,-13495
dw -13509,-13523,-13537,-13552,-13566,-13580,-13594,-13608
dw -13622,-13636,-13650,-13664,-13677,-13691,-13705,-13719
dw -13732,-13746,-13760,-13773,-13787,-13801,-13814,-13828
dw -13841,-13855,-13868,-13881,-13895,-13908,-13921,-13934
dw -13948,-13961,-13974,-13987,-14000,-14013,-14026,-14039
dw -14052,-14065,-14078,-14091,-14103,-14116,-14129,-14142
dw -14154,-14167,-14180,-14192,-14205,-14217,-14230,-14242
dw -14255,-14267,-14279,-14292,-14304,-14316,-14328,-14340
dw -14353,-14365,-14377,-14389,-14401,-14413,-14425,-14437
dw -14448,-14460,-14472,-14484,-14496,-14507,-14519,-14530
dw -14542,-14554,-14565,-14577,-14588,-14600,-14611,-14622
dw -14634,-14645,-14656,-14667,-14679,-14690,-14701,-14712
dw -14723,-14734,-14745,-14756,-14767,-14778,-14788,-14799
dw -14810,-14821,-14831,-14842,-14853,-14863,-14874,-14884
dw -14895,-14905,-14916,-14926,-14936,-14947,-14957,-14967
dw -14977,-14988,-14998,-15008,-15018,-15028,-15038,-15048
dw -15058,-15068,-15077,-15087,-15097,-15107,-15117,-15126
dw -15136,-15145,-15155,-15165,-15174,-15183,-15193,-15202
dw -15212,-15221,-15230,-15239,-15249,-15258,-15267,-15276
dw -15285,-15294,-15303,-15312,-15321,-15330,-15339,-15348
dw -15356,-15365,-15374,-15382,-15391,-15400,-15408,-15417
dw -15425,-15434,-15442,-15450,-15459,-15467,-15475,-15484
dw -15492,-15500,-15508,-15516,-15524,-15532,-15540,-15548
dw -15556,-15564,-15572,-15580,-15587,-15595,-15603,-15610
dw -15618,-15626,-15633,-15641,-15648,-15655,-15663,-15670
dw -15678,-15685,-15692,-15699,-15706,-15714,-15721,-15728
dw -15735,-15742,-15749,-15756,-15762,-15769,-15776,-15783
dw -15790,-15796,-15803,-15809,-15816,-15823,-15829,-15836
dw -15842,-15848,-15855,-15861,-15867,-15874,-15880,-15886
dw -15892,-15898,-15904,-15910,-15916,-15922,-15928,-15934
dw -15940,-15945,-15951,-15957,-15963,-15968,-15974,-15979
dw -15985,-15990,-15996,-16001,-16007,-16012,-16017,-16023
dw -16028,-16033,-16038,-16043,-16048,-16053,-16058,-16063
dw -16068,-16073,-16078,-16083,-16087,-16092,-16097,-16102
dw -16106,-16111,-16115,-16120,-16124,-16129,-16133,-16137
dw -16142,-16146,-16150,-16155,-16159,-16163,-16167,-16171
dw -16175,-16179,-16183,-16187,-16191,-16194,-16198,-16202
dw -16206,-16209,-16213,-16217,-16220,-16224,-16227,-16231
dw -16234,-16237,-16241,-16244,-16247,-16250,-16254,-16257
dw -16260,-16263,-16266,-16269,-16272,-16275,-16278,-16280
dw -16283,-16286,-16289,-16291,-16294,-16297,-16299,-16302
dw -16304,-16307,-16309,-16311,-16314,-16316,-16318,-16320
dw -16323,-16325,-16327,-16329,-16331,-16333,-16335,-16337
dw -16339,-16340,-16342,-16344,-16346,-16347,-16349,-16351
dw -16352,-16354,-16355,-16357,-16358,-16359,-16361,-16362
dw -16363,-16364,-16366,-16367,-16368,-16369,-16370,-16371
dw -16372,-16373,-16374,-16374,-16375,-16376,-16377,-16377
dw -16378,-16379,-16379,-16380,-16380,-16381,-16381,-16381
dw -16382,-16382,-16382,-16383,-16383,-16383,-16383,-16383
dw -16383,-16383,-16383,-16383,-16383,-16383,-16382,-16382
dw -16382,-16381,-16381,-16381,-16380,-16380,-16379,-16379
dw -16378,-16377,-16377,-16376,-16375,-16374,-16374,-16373
dw -16372,-16371,-16370,-16369,-16368,-16367,-16366,-16364
dw -16363,-16362,-16361,-16359,-16358,-16357,-16355,-16354
dw -16352,-16351,-16349,-16347,-16346,-16344,-16342,-16340
dw -16339,-16337,-16335,-16333,-16331,-16329,-16327,-16325
dw -16323,-16320,-16318,-16316,-16314,-16311,-16309,-16307
dw -16304,-16302,-16299,-16297,-16294,-16291,-16289,-16286
dw -16283,-16280,-16278,-16275,-16272,-16269,-16266,-16263
dw -16260,-16257,-16254,-16250,-16247,-16244,-16241,-16237
dw -16234,-16231,-16227,-16224,-16220,-16217,-16213,-16209
dw -16206,-16202,-16198,-16194,-16191,-16187,-16183,-16179
dw -16175,-16171,-16167,-16163,-16159,-16155,-16150,-16146
dw -16142,-16137,-16133,-16129,-16124,-16120,-16115,-16111
dw -16106,-16102,-16097,-16092,-16087,-16083,-16078,-16073
dw -16068,-16063,-16058,-16053,-16048,-16043,-16038,-16033
dw -16028,-16023,-16017,-16012,-16007,-16001,-15996,-15990
dw -15985,-15979,-15974,-15968,-15963,-15957,-15951,-15945
dw -15940,-15934,-15928,-15922,-15916,-15910,-15904,-15898
dw -15892,-15886,-15880,-15874,-15867,-15861,-15855,-15848
dw -15842,-15836,-15829,-15823,-15816,-15809,-15803,-15796
dw -15790,-15783,-15776,-15769,-15762,-15756,-15749,-15742
dw -15735,-15728,-15721,-15714,-15706,-15699,-15692,-15685
dw -15678,-15670,-15663,-15655,-15648,-15641,-15633,-15626
dw -15618,-15610,-15603,-15595,-15587,-15580,-15572,-15564
dw -15556,-15548,-15540,-15532,-15524,-15516,-15508,-15500
dw -15492,-15484,-15475,-15467,-15459,-15450,-15442,-15434
dw -15425,-15417,-15408,-15400,-15391,-15382,-15374,-15365
dw -15356,-15348,-15339,-15330,-15321,-15312,-15303,-15294
dw -15285,-15276,-15267,-15258,-15249,-15239,-15230,-15221
dw -15212,-15202,-15193,-15183,-15174,-15165,-15155,-15145
dw -15136,-15126,-15117,-15107,-15097,-15087,-15077,-15068
dw -15058,-15048,-15038,-15028,-15018,-15008,-14998,-14988
dw -14977,-14967,-14957,-14947,-14936,-14926,-14916,-14905
dw -14895,-14884,-14874,-14863,-14853,-14842,-14831,-14821
dw -14810,-14799,-14788,-14778,-14767,-14756,-14745,-14734
dw -14723,-14712,-14701,-14690,-14679,-14667,-14656,-14645
dw -14634,-14622,-14611,-14600,-14588,-14577,-14565,-14554
dw -14542,-14530,-14519,-14507,-14496,-14484,-14472,-14460
dw -14448,-14437,-14425,-14413,-14401,-14389,-14377,-14365
dw -14353,-14340,-14328,-14316,-14304,-14292,-14279,-14267
dw -14255,-14242,-14230,-14217,-14205,-14192,-14180,-14167
dw -14154,-14142,-14129,-14116,-14103,-14091,-14078,-14065
dw -14052,-14039,-14026,-14013,-14000,-13987,-13974,-13961
dw -13948,-13934,-13921,-13908,-13895,-13881,-13868,-13855
dw -13841,-13828,-13814,-13801,-13787,-13773,-13760,-13746
dw -13732,-13719,-13705,-13691,-13677,-13664,-13650,-13636
dw -13622,-13608,-13594,-13580,-13566,-13552,-13537,-13523
dw -13509,-13495,-13481,-13466,-13452,-13438,-13423,-13409
dw -13394,-13380,-13365,-13351,-13336,-13322,-13307,-13292
dw -13278,-13263,-13248,-13233,-13218,-13204,-13189,-13174
dw -13159,-13144,-13129,-13114,-13099,-13084,-13068,-13053
dw -13038,-13023,-13007,-12992,-12977,-12962,-12946,-12931
dw -12915,-12900,-12884,-12869,-12853,-12838,-12822,-12806
dw -12791,-12775,-12759,-12743,-12728,-12712,-12696,-12680
dw -12664,-12648,-12632,-12616,-12600,-12584,-12568,-12552
dw -12536,-12519,-12503,-12487,-12471,-12454,-12438,-12422
dw -12405,-12389,-12372,-12356,-12339,-12323,-12306,-12289
dw -12273,-12256,-12239,-12223,-12206,-12189,-12172,-12156
dw -12139,-12122,-12105,-12088,-12071,-12054,-12037,-12020
dw -12003,-11986,-11969,-11951,-11934,-11917,-11900,-11882
dw -11865,-11848,-11830,-11813,-11796,-11778,-11761,-11743
dw -11726,-11708,-11690,-11673,-11655,-11637,-11620,-11602
dw -11584,-11566,-11549,-11531,-11513,-11495,-11477,-11459
dw -11441,-11423,-11405,-11387,-11369,-11351,-11333,-11315
dw -11296,-11278,-11260,-11242,-11223,-11205,-11187,-11168
dw -11150,-11132,-11113,-11095,-11076,-11058,-11039,-11020
dw -11002,-10983,-10965,-10946,-10927,-10908,-10890,-10871
dw -10852,-10833,-10814,-10795,-10777,-10758,-10739,-10720
dw -10701,-10682,-10662,-10643,-10624,-10605,-10586,-10567
dw -10548,-10528,-10509,-10490,-10470,-10451,-10432,-10412
dw -10393,-10373,-10354,-10335,-10315,-10295,-10276,-10256
dw -10237,-10217,-10197,-10178,-10158,-10138,-10119,-10099
dw -10079,-10059,-10039,-10019,-10000, -9980, -9960, -9940
dw -9920, -9900, -9880, -9860, -9840, -9819, -9799, -9779
dw -9759, -9739, -9719, -9698, -9678, -9658, -9637, -9617
dw -9597, -9576, -9556, -9536, -9515, -9495, -9474, -9454
dw -9433, -9412, -9392, -9371, -9351, -9330, -9309, -9289
dw -9268, -9247, -9226, -9206, -9185, -9164, -9143, -9122
dw -9101, -9081, -9060, -9039, -9018, -8997, -8976, -8955
dw -8934, -8913, -8891, -8870, -8849, -8828, -8807, -8786
dw -8764, -8743, -8722, -8701, -8679, -8658, -8637, -8615
dw -8594, -8572, -8551, -8530, -8508, -8487, -8465, -8444
dw -8422, -8400, -8379, -8357, -8336, -8314, -8292, -8271
dw -8249, -8227, -8206, -8184, -8162, -8140, -8118, -8097
dw -8075, -8053, -8031, -8009, -7987, -7965, -7943, -7921
dw -7899, -7877, -7855, -7833, -7811, -7789, -7767, -7745
dw -7722, -7700, -7678, -7656, -7634, -7611, -7589, -7567
dw -7544, -7522, -7500, -7477, -7455, -7433, -7410, -7388
dw -7365, -7343, -7320, -7298, -7275, -7253, -7230, -7208
dw -7185, -7163, -7140, -7117, -7095, -7072, -7049, -7027
dw -7004, -6981, -6959, -6936, -6913, -6890, -6867, -6845
dw -6822, -6799, -6776, -6753, -6730, -6707, -6684, -6661
dw -6638, -6615, -6592, -6569, -6546, -6523, -6500, -6477
dw -6454, -6431, -6408, -6385, -6362, -6338, -6315, -6292
dw -6269, -6246, -6222, -6199, -6176, -6153, -6129, -6106
dw -6083, -6059, -6036, -6013, -5989, -5966, -5942, -5919
dw -5896, -5872, -5849, -5825, -5802, -5778, -5755, -5731
dw -5707, -5684, -5660, -5637, -5613, -5590, -5566, -5542
dw -5519, -5495, -5471, -5448, -5424, -5400, -5376, -5353
dw -5329, -5305, -5281, -5258, -5234, -5210, -5186, -5162
dw -5138, -5114, -5091, -5067, -5043, -5019, -4995, -4971
dw -4947, -4923, -4899, -4875, -4851, -4827, -4803, -4779
dw -4755, -4731, -4707, -4683, -4659, -4635, -4611, -4586
dw -4562, -4538, -4514, -4490, -4466, -4441, -4417, -4393
dw -4369, -4345, -4320, -4296, -4272, -4248, -4223, -4199
dw -4175, -4150, -4126, -4102, -4077, -4053, -4029, -4004
dw -3980, -3956, -3931, -3907, -3882, -3858, -3834, -3809
dw -3785, -3760, -3736, -3711, -3687, -3662, -3638, -3613
dw -3589, -3564, -3540, -3515, -3491, -3466, -3441, -3417
dw -3392, -3368, -3343, -3319, -3294, -3269, -3245, -3220
dw -3195, -3171, -3146, -3121, -3097, -3072, -3047, -3023
dw -2998, -2973, -2948, -2924, -2899, -2874, -2850, -2825
dw -2800, -2775, -2751, -2726, -2701, -2676, -2651, -2627
dw -2602, -2577, -2552, -2527, -2502, -2478, -2453, -2428
dw -2403, -2378, -2353, -2328, -2304, -2279, -2254, -2229
dw -2204, -2179, -2154, -2129, -2104, -2079, -2054, -2030
dw -2005, -1980, -1955, -1930, -1905, -1880, -1855, -1830
dw -1805, -1780, -1755, -1730, -1705, -1680, -1655, -1630
dw -1605, -1580, -1555, -1530, -1505, -1480, -1455, -1430
dw -1405, -1380, -1355, -1330, -1305, -1279, -1254, -1229
dw -1204, -1179, -1154, -1129, -1104, -1079, -1054, -1029
dw -1004, -979, -954, -928, -903, -878, -853, -828
dw -803, -778, -753, -728, -703, -677, -652, -627
dw -602, -577, -552, -527, -502, -476, -451, -426
dw -401, -376, -351, -326, -301, -275, -250, -225
dw -200, -175, -150, -125, -100, -74, -49, -24

608
VISU/ADRAW.ASM Normal file
View file

@ -0,0 +1,608 @@
;/****************************************************************************
;** MODULE: adraw.asm
;** AUTHOR: Sami Tammilehto / Fennosoftec OY
;** DOCUMENT: ?
;** VERSION: 1.0
;** REFERENCE: -
;** REVISED BY: -
;*****************************************************************************
;**
;** Object drawing (and polygon calculations & clipping (included))
;**
;****************************************************************************/
include a.inc
asm_code SEGMENT para public use16 'CODE'
ASSUME cs:asm_code
ALIGN 2
newlight dw 12118,10603,3030
;entry: AX=polyflags,ES:DI=normal for which to calculate light
; exit: AX=colorshade (based 0)
calclight PROC NEAR
and ax,F_SHADE32 ;=F_SHADE* orred together)
jz @@nc
;lightsource
push ax
call normallight
pop dx
shr dx,10
mov cx,6
sub cx,dx
shr ax,cl ;0400=5, 0800=4, 0C00=3
@@mm: cmp ax,1
jg @@m1
mov ax,1
@@m1: cmp ax,30
jl @@m2
mov ax,30
@@m2: ret
@@nc: xor ax,ax
jmp @@mm
calclight ENDP
normallight PROC NEAR
;return: ax=relative brightness 0..255
push bp
mov ax,es:[di+nlist_x]
imul cs:newlight[0]
mov bp,ax
mov cx,dx
mov ax,es:[di+nlist_y]
imul cs:newlight[2]
add bp,ax
adc cx,dx
mov ax,es:[di+nlist_z]
imul cs:newlight[4]
add ax,bp
adc dx,cx
mov ax,dx
sar ax,2*unitshr-7-16
add ax,128
cmp ax,255
jle @@1
mov ax,255
@@1: cmp ax,0
jge @@2
mov ax,0
@@2: pop bp
ret ;ax=0..255
normallight ENDP
checkculling PROC NEAR
;es:di=normal
;fs:si=vertex
;ret: carry=1=hidden
push bp
movsx eax,word ptr es:[di+nlist_x]
imul dword ptr fs:[si+vlist_x]
mov ebp,eax
mov ecx,edx
movsx eax,word ptr es:[di+nlist_y]
imul dword ptr fs:[si+vlist_y]
add ebp,eax
adc ecx,edx
movsx eax,word ptr es:[di+nlist_z]
imul dword ptr fs:[si+vlist_z]
add ebp,eax
adc ecx,edx
rcl ecx,1 ;if cx<0, carry=1=visible
cmc ;now carry=1 when invisible
pop bp
ret
checkculling ENDP
ALIGN 16
poly1 LABEL WORD
db POLYSIZE dup(0)
ALIGN 16
poly2 LABEL WORD
db POLYSIZE dup(0)
include adrawclp.asm
ALIGN 16
drawfill_routine dd _vid_drawfill
drawfill_routine0 dd _vid_drawfill ;nrm ;original (=NULL)
polyomin dw 0
polyomax dw 0
polycury dw 0
polylhig dw 0
polyrhig dw 0
polyoversample16 db 0
polyoversamplea db 0
polyoversamples db 0
polyoversample db 0
POLYSIDECALC MACRO fr,to
local l1,l2
;when entering, AX should be heigth
push ax
mov word ptr es:[bp-2],07777h
movsx edx,word ptr ds:[fr+POLYX]
movzx ecx,byte ptr cs:polyoversample16 ;sets ECX hi to zero
shl edx,cl
mov dx,32768 ;NOOVERSAMPLECENTER
mov es:[bp+0],edx ;Xstart
movsx eax,word ptr ds:[to+POLYX]
shl eax,cl
mov ax,32768 ;NOOVERSAMPLECENTER
sub eax,edx
cdq
pop cx
idiv ecx
mov cl,byte ptr cs:polycury
and cl,cs:polyoversamplea
jz l1
l2: sub es:[bp+0],eax
dec cl
jnz l2
l1: mov cl,cs:polyoversample
shl eax,cl
mov es:[bp+4],eax ;Xadd
add bp,8
ENDM
poly_nrm PROC NEAR
;handles a normal polygon (preclipped one)
;polydata at DS:SI. SIDES must be >=3
;drawing orders written to ES:DI
;-------Calculate bounds for SI
mov bx,ds:[si+POLYSIDES]
shl bx,2
lea ax,[bx-4+si]
mov cs:polyomax,ax
mov cs:polyomin,si
;the SI should always be in range POLYOMIN..POLYOMAX
;-------Find uppermost vertex in polygon
push si
mov bx,si
mov dx,ds:[si+POLYY]
mov bp,dx
mov cx,ds:[si+POLYSIDES]
@@11: add si,4
dec cx
jz @@2
@@1: mov ax,ds:[si+POLYY]
cmp ax,bp
jle @@13
mov bp,ax
@@13: cmp ax,dx
jge @@11
mov dx,ax
mov bx,si
jmp @@11
@@2: mov cx,bp
;DS:BX=uppermost vertex, DX=uppermost Y, CX=lowermost Y
mov cs:polycury,dx
pop si
;-------Write the startup info to drawinfo
push cx
mov bp,di ;es:di was to drawinfo, now ES:BP is
mov ax,ds:[si+POLYCOLOR]
mov es:[bp],ax
mov cl,cs:polyoversample
mov ax,dx
sar ax,cl
mov es:[bp+2],ax
add bp,4+2
pop cx
cmp dx,cx
je @@d0 ;heigth zero, nothing to do
sub bp,2
;-------Set up SI for left edge (--), DI for right edge (++)
mov si,bx
mov di,bx
;-------Loop
@@l1: mov word ptr es:[bp],0
add bp,2
mov ax,ds:[si+POLYY]
cmp ax,cs:polycury
jne @@a2
@@a4: ;Left side reload
lea bx,[si-4] ;BX=SI--
cmp bx,cs:polyomin
jge @@a1
mov bx,cs:polyomax
@@a1: mov ax,ds:[bx+POLYY]
sub ax,ds:[si+POLYY]
jc @@d0 ;turned upwards, end of polygon
jnz @@a3
mov si,bx
jmp @@a4
@@a3: mov cs:polylhig,ax
POLYSIDECALC si,bx
mov si,bx
@@a2: ;
mov word ptr es:[bp],0
add bp,2
mov ax,ds:[di+POLYY]
cmp ax,cs:polycury
jne @@b2
@@b4: ;Right side reload
lea bx,[di+4] ;BP=DI++
cmp bx,cs:polyomax
jle @@b1
mov bx,cs:polyomin
@@b1: mov ax,ds:[bx+POLYY]
sub ax,ds:[di+POLYY]
jc @@d0 ;turned upwards, end of polygon
jnz @@b3
mov di,bx
jmp @@b4
@@b3: mov cs:polyrhig,ax
POLYSIDECALC di,bx
mov di,bx
@@b2: ;
mov ax,cs:polylhig
cmp ax,cs:polyrhig
jl @@c1
;right shorter
mov ax,cs:polyrhig
@@c1: ;AX=shorter
mov cl,cs:polyoversample
mov dx,ax
sar dx,cl
mov es:[bp],dx ;Ycount
sub cs:polylhig,ax
sub cs:polyrhig,ax
add bp,2
add cs:polycury,ax
jmp @@l1
@@d0: mov word ptr es:[bp-2],0ffffh
ret
poly_nrm ENDP
POLYSIDECALC_GRD MACRO fr,to
local l1,l2
;when entering, AX should be heigth
push ax
mov word ptr es:[bp-2],07777h
;
mov cx,ax
mov ax,word ptr ds:[to+POLYGR]
mov dx,word ptr ds:[fr+POLYGR]
mov es:[bp+0],dx ;COLORstart
sub ax,dx
cwd
idiv cx
mov es:[bp+2],ax ;COLORadd
;
movsx edx,word ptr ds:[fr+POLYX]
xor ecx,ecx
mov cl,byte ptr cs:polyoversample16
shl edx,cl
mov dx,32768 ;NOOVERSAMPLECENTER
mov es:[bp+4],edx ;Xstart
movsx eax,word ptr ds:[to+POLYX]
shl eax,cl
mov ax,32768 ;NOOVERSAMPLECENTER
sub eax,edx
cdq
pop cx
idiv ecx
mov cl,byte ptr cs:polycury
and cl,cs:polyoversamplea
jz l1
l2: sub es:[bp+0],eax
dec cl
jnz l2
l1: mov cl,cs:polyoversample
shl eax,cl
mov es:[bp+8],eax ;Xadd
add bp,12
ENDM
poly_grd PROC NEAR
;handles a gouraud polygon (preclipped one)
;polydata at DS:SI. SIDES must be >=3
;drawing orders written to ES:DI
;-------Calculate bounds for SI
mov bx,ds:[si+POLYSIDES]
shl bx,2
lea ax,[bx-4+si]
mov cs:polyomax,ax
mov cs:polyomin,si
;the SI should always be in range POLYOMIN..POLYOMAX
;-------Find uppermost vertex in polygon
push si
mov bx,si
mov dx,ds:[si+POLYY]
mov bp,dx
mov cx,ds:[si+POLYSIDES]
@@11: add si,4
dec cx
jz @@2
@@1: mov ax,ds:[si+POLYY]
cmp ax,bp
jle @@13
mov bp,ax
@@13: cmp ax,dx
jge @@11
mov dx,ax
mov bx,si
jmp @@11
@@2: mov cx,bp
;DS:BX=uppermost vertex, DX=uppermost Y, CX=lowermost Y
mov cs:polycury,dx
pop si
;-------Write the startup info to drawinfo
push cx
mov bp,di ;es:di was to drawinfo, now ES:BP is
mov ax,ds:[si+POLYCOLOR]
mov es:[bp],ax
mov cl,cs:polyoversample
mov ax,dx
sar ax,cl
mov es:[bp+2],ax
add bp,4+2
pop cx
cmp dx,cx
je @@d0 ;heigth zero, nothing to do
sub bp,2
;-------Set up SI for left edge (--), DI for right edge (++)
mov si,bx
mov di,bx
;-------Loop
@@l1: mov word ptr es:[bp],0
add bp,2
mov ax,ds:[si+POLYY]
cmp ax,cs:polycury
jne @@a2
@@a4: ;Left side reload
lea bx,[si-4] ;BX=SI--
cmp bx,cs:polyomin
jge @@a1
mov bx,cs:polyomax
@@a1: mov ax,ds:[bx+POLYY]
sub ax,ds:[si+POLYY]
jc @@d0 ;turned upwards, end of polygon
jnz @@a3
mov si,bx
jmp @@a4
@@a3: mov cs:polylhig,ax
POLYSIDECALC_GRD si,bx
mov si,bx
@@a2: ;
mov word ptr es:[bp],0
add bp,2
mov ax,ds:[di+POLYY]
cmp ax,cs:polycury
jne @@b2
@@b4: ;Right side reload
lea bx,[di+4] ;BP=DI++
cmp bx,cs:polyomax
jle @@b1
mov bx,cs:polyomin
@@b1: mov ax,ds:[bx+POLYY]
sub ax,ds:[di+POLYY]
jc @@d0 ;turned upwards, end of polygon
jnz @@b3
mov di,bx
jmp @@b4
@@b3: mov cs:polyrhig,ax
POLYSIDECALC_GRD di,bx
mov di,bx
@@b2: ;
mov ax,cs:polylhig
cmp ax,cs:polyrhig
jl @@c1
;right shorter
mov ax,cs:polyrhig
@@c1: ;AX=shorter
mov cl,cs:polyoversample
mov dx,ax
sar dx,cl
mov es:[bp],dx ;Ycount
sub cs:polylhig,ax
sub cs:polyrhig,ax
add bp,2
add cs:polycury,ax
jmp @@l1
@@d0: mov word ptr es:[bp-2],0ffffh
ret
poly_grd ENDP
;±±±±±±±± _draw_setfillroutine(void (*fillroutine)(int *)) ±±±±±±±±
;entry: Pointer to a routine to handle polygon filling
; exit: -
;descr: The specified function will be called for each polygon drawed
; with a pointer to {NORMAL-FILL-DATA} of the polygon.
_draw_setfillroutine PROC FAR
CBEG
movpar eax,0
or ax,ax
jnz @@1
mov eax,cs:drawfill_routine0
@@1: mov dword ptr cs:drawfill_routine,eax
CEND
_draw_setfillroutine ENDP
;±±±±±±±± _draw_polylist(polylist *l,polydata *d,vlist *v,pvlist *pv,
; nlist *n,int f) ±±±±±±±±
;entry: 0 l=pointer to a polygon list (in polylist format)
; 2 d=pointer to polygon data (to which polylist points using indices)
; 4 v=pointer to rotated 3D vertices (for 3D clipping)
; 6 pv=pointer to projected vertices (for drawing)
; 8 n=pointer to normals (for culling)
; 10 f=object flags
; exit: -
;descr: draw the contents of the polylist.
_draw_polylist PROC FAR
CBEG
movpar ax,10
test ax,1
jz @@invi ;F_VISIBLE not set
;set poly oversampling
mov ax,16
mov cx,ds:_projoversampleshr
mov cs:polyoversample,cl
sub ax,cx
mov cs:polyoversample16,al
mov al,1
shl al,cl
mov cs:polyoversamples,al
dec al
mov cs:polyoversamplea,al
;start with the actual work
movpar si,0+0
add si,4 ;skip count - sort vertex
@@1: movpar ds,0+1
push si
mov si,ds:[si]
cmp si,0
je @@0 ;end of list
movpar ax,2+0
add si,ax
movpar ds,2+1
;ds:si points to polydata/polygon we are now drawing
mov cx,ds:[si+0]
movpar ax,10
or ax,0f00h
and ax,cx
mov cs:poly1[POLYFLAGS],ax
and cx,0ffh
mov cs:poly1[POLYSIDES],cx
push si
mov ax,ds:[si+4] ;normal
mov bx,ds:[si+6] ;first point
cmp word ptr ds:[si+2],-1 ;color
je @@cull2
shl bx,vlist_sizeshl
lfspar si,4 ;rotated vertices
add si,bx
mov bx,ax ;normal
shl bx,nlist_sizeshl
lespar di,8 ;rotated normals
add di,bx
test cs:poly1[POLYFLAGS],F_2SIDE
jnz @@2side
call checkculling
pop si
jc @@cull
jmp @@nocl
@@cull2: pop si
jmp @@cull
;es:di=still normal
@@2side: pop si
@@nocl: ;lightsource
mov ax,cs:poly1[POLYFLAGS]
test ax,F_GOURAUD
jnz @@nosh
call calclight
add al,ds:[si+2]
mov byte ptr cs:poly1[POLYCOLOR],al
jmp @@yosh
@@nosh: mov al,ds:[si+2]
mov byte ptr cs:poly1[POLYCOLOR],al
@@yosh: ;
mov cx,cs:poly1[POLYSIDES]
lespar di,6 ;projected vertices
mov dx,0ff00h ;for vf calc
push bp
movpar ax,4+1
movpar bp,4+0
xchg bp,di
mov cs:poly1[POLYVXSEG],ax
;ds:bp=projected vertices
;??:di=rotated vertices
zzs=0
zzd=0
REPT MAXPOLYSIDES ;max sides in polygon
mov bx,ds:[si+6+zzs]
shl bx,pvlist_sizeshl ;==vlist_sizeshl (required) [!!]
lea ax,[bx+di]
mov word ptr cs:poly1[POLYVX+zzd],ax
add bx,bp
mov al,es:[bx+pvlist_vf]
and dh,al ;if anded!=0, out of screen
or dl,al ;if orred!=0, must clip
mov eax,es:[bx+pvlist_x]
mov dword ptr cs:poly1[POLYX+zzd],eax
dec cx
jz @@2
zzs=zzs+2
zzd=zzd+4
ENDM
@@2: pop bp
push bp
push dx
;gouraud color calcs
mov ax,cs:poly1[POLYFLAGS]
test ax,F_GOURAUD
jz @@nogr
;
mov cx,cs:poly1[POLYSIDES]
lespar di,8 ;rotated normals
mov fs,cs:poly1[POLYVXSEG]
mov bp,OFFSET poly1
@@gr1: push cx
push di
mov bx,cs:[POLYVX+bp]
mov bx,fs:[bx+vlist_normal]
shl bx,nlist_sizeshl
add di,bx
;es:di=now normal for which to calculate
mov ax,cs:poly1[POLYFLAGS]
call calclight
add al,byte ptr cs:poly1[POLYCOLOR]
shl ax,8
mov cs:[POLYGR+bp],ax
pop di
pop cx
add bp,4
loop @@gr1
@@nogr: ;
pop dx
pop bp
LOADDS
push bp
push ds
mov ax,cs
mov ds,ax
mov si,OFFSET poly1
or dh,dh ;dh=visfl anded
jnz @@cl0 ;entire polygon invisible
or dl,dl ;dl=visfl orred
jz @@cl4 ;no clipping
mov di,OFFSET poly2
mov ax,ds:[si+POLYFLAGS]
call newclip
cmp word ptr ds:[si+POLYSIDES],0
je @@cl0 ;entire polygon clipped away, nothing to draw
;
@@cl4: LOADES
mov di,OFFSET _polydrw
test word ptr ds:[si+POLYFLAGS],F_GOURAUD
jz @@ngrd
mov word ptr es:[di],1 ;gouraud fill
add di,2
call poly_grd
jmp @@pgdn
@@ngrd: mov word ptr es:[di],0 ;normal fill
add di,2
call poly_nrm
@@pgdn:
push es
push OFFSET _polydrw
call cs:drawfill_routine
add sp,4
@@cl0: pop ds
pop bp
@@cull: pop si
add si,2
jmp @@1
@@0: pop si
@@invi: CEND
_draw_polylist ENDP
asm_code ENDS
END

BIN
VISU/ADRAW.OBJ Normal file

Binary file not shown.

552
VISU/ADRAWCLP.ASM Normal file
View file

@ -0,0 +1,552 @@
;/****************************************************************************
;** MODULE: adrawclp.asm
;** AUTHOR: Sami Tammilehto / Fennosoftec OY
;** DOCUMENT: ?
;** VERSION: 1.0
;** REFERENCE: -
;** REVISED BY: -
;*****************************************************************************
;**
;** Polygon clipping (included to adraw.asm)
;** All routines take DS:SI as an entry list and write a clipped list to
;** ES:DI. The clipnear also returns in AX the orred visvf for the clipped
;** polygon since it might change during Z clipping.
;**
;****************************************************************************/
ALIGN 16
newclipflip db 0,0
newclipprog dw 0
clipcount dw 0
clipzero dw 0
clipvisfl dw 0
newclip_grd PROC NEAR
;DS:BX->DS:SI is clipped at CX (BX end=0..16384=SI end)
;resulted clip stored to ES:DI
mov ax,ds:[bx+POLYGR]
sub ax,ds:[si+POLYGR]
imul cx
shld dx,ax,2
add dx,ds:[si+POLYGR]
mov ds:[di+POLYGR],dx
ret
ENDP
NEWCLIPCALC MACRO clipped,other
local l1,l2,l3,l4,l5,l6
;DS:BX->DS:SI is clipped at (-,BP) with result stored to DS:DI
push si
push bx
push bp
mov dx,ds:[si+other]
mov cx,ds:[si+clipped]
mov ax,ds:[bx+other]
mov bx,ds:[bx+clipped]
mov cs:newclipflip,0
cmp cx,bx
jl l3
mov cs:newclipflip,1
xchg cx,bx
xchg ax,dx
l3: push dx
sub bp,cx
sub ax,dx
push ax
mov dx,bp
xor ax,ax
shrd ax,dx,2
sar dx,2
;dx:ax=short length*16384
sub bx,cx
idiv bx
mov bx,ax
;bx=0..16384 multiplier
pop ax
imul bx
shld dx,ax,2
pop ax
add dx,ax ;dx=clipped other
pop bp
mov cx,bp
cmp ds:[di+other-4],dx
jne l1
cmp ds:[di+clipped-4],cx
jne l1
jmp l2
l1: mov ds:[di+other],dx
mov ds:[di+clipped],cx
mov cx,bx
pop bx
mov ax,cs:newclipprog
or ax,ax
jz l4
mov dl,cs:newclipflip
or dl,dl
jz l6
xchg si,bx
l6: call ax ;also stores gouraud&texture clipped
l4: add di,4
jmp l5
l2: pop bx
l5: pop si
ENDM
NEWCLIPNEXT MACRO ;sets bx(last)=si(current) and loads si with next vertex
local l1,l2
mov bx,si
mov dx,cs:clipcount
dec dx
cmp dx,1
jl @@0 ;list ended, jmp to end of clip procedure
mov cs:clipcount,dx
jg l1
;1 vertex left, means we rotated the list
mov si,cs:clipzero
jmp l2
l1: add si,4
l2: ENDM
NEWCLIPCOPY MACRO ;should copy also texture
local l1
mov eax,ds:[si+POLYX] ;&POLYY
cmp ds:[di+POLYX-4],eax
je l1
mov ds:[di+POLYX],eax
mov ax,ds:[si+POLYGR]
mov ds:[di+POLYGR],ax
add di,4
l1: ENDM
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ZCLIPCLIP MACRO
local l1,l41,l42,l43,l44
;(fs:bp)-(fs:bx) is clipped at (-,-,ECX) with result stored to (DX,CX) & AX=visfl
push bx
push bp
push esi
push edi
push ecx
;
mov eax,fs:[bx+vlist_z]
mov edx,fs:[bp+vlist_z]
cmp eax,edx
jg l1
xchg eax,edx
xchg bx,bp
l1: ;EAX=farther vertex (>EDX), BX=offset of farther vertex
mov esi,eax
mov edi,eax
sub esi,edx ;>=0 divver
sub edi,ecx ;>=0 muller, esi>edi
;
mov eax,fs:[bp+vlist_x]
sub eax,fs:[bx+vlist_x]
imul edi
idiv esi
add eax,fs:[bx+vlist_x]
push eax
;
mov eax,fs:[bp+vlist_y]
sub eax,fs:[bx+vlist_y]
imul edi
idiv esi
add eax,fs:[bx+vlist_y]
;
pop esi ;X
pop ecx ;cliplimit
xor di,di
;
imul gs:_projmuly
idiv ecx
add eax,gs:_projaddy
cmp eax,gs:_projclipy[CLIPMAX]
jng l41
or di,VF_DOWN
l41: cmp eax,gs:_projclipy[CLIPMIN]
jnl l42
or di,VF_UP
l42: push ax
;
mov eax,esi
imul gs:_projmulx
idiv ecx
add eax,gs:_projaddx
cmp eax,gs:_projclipx[CLIPMAX]
jng l43
or di,VF_RIGHT
l43: cmp eax,gs:_projclipx[CLIPMIN]
jnl l44
or di,VF_LEFT
l44: ;
mov dx,ax
mov ax,di
pop cx
;dx=x,cx=y,ax=visfl
pop edi
pop esi
pop bp
pop bx
;NOTE: ECX was destroyed while clipping. It is used to return data.
;It must be pushed by the 'calling' procedure after the macro and
;the usage of the data the macro returned!
ENDM
ZCLIPGETVX MACRO ;reads to bx the offset of next vertex from DS:SI (copies last vx to bp)
local l1,l2
mov bp,bx
mov dx,cs:clipcount
dec dx
cmp dx,1
jl @@0 ;list ended, jmp to end of clip procedure
mov cs:clipcount,dx
jg l1
;1 vertex left, means we rotated the list
mov si,cs:clipzero
jmp l2
l1: add si,4
l2: mov bx,ds:[si+POLYVX]
ENDM
ZCLIPADDVISVX MACRO ;adds ds:si[bx+POLYX/Y] to list (the vx must be visible for this to work) at DS:DI
local l1,l2
mov dx,ds:[si+POLYX]
mov ax,ds:[si+POLYY]
cmp ds:[di+POLYX-4],dx
jne l1
cmp ds:[di+POLYY-4],ax
jne l1
jmp l2
l1: mov ds:[di+POLYX],dx
mov ds:[di+POLYY],ax
mov ax,ds:[si+POLYGR]
mov ds:[di+POLYGR],ax
add di,4
l2: ;;;
ENDM
ZCLIPADDVX MACRO ;adds (DX,CX) to list at DS:DI
local l1,l2
cmp ds:[di+POLYX-4],dx
jne l1
cmp ds:[di+POLYY-4],cx
jne l1
jmp l2
l1: mov ds:[di+POLYX],dx
mov ds:[di+POLYY],cx
mov ax,ds:[di-4+POLYGR]
mov ds:[di+POLYGR],ax
add di,4
l2: ;;;
ENDM
clipnear PROC NEAR
;clips list DS:SI -> DS:DI (source list must NOT be empty)
push bp
push si
push di
mov cs:clipzero,si
mov ecx,gs:_projclipz[CLIPMIN] ;ECX=cliplimit
mov eax,ds:[si+POLYSIDES] ;&POLYCOLOR
mov ds:[di+POLYSIDES],eax
inc ax
mov cs:clipcount,ax
mov eax,ds:[si+POLYFLAGS] ;&POLYVXSEG
mov ds:[di+POLYFLAGS],eax
mov fs,ds:[si+POLYVXSEG]
mov word ptr ds:[di+POLYX-4],07fffh ;for CLIPADDVX to surely do it's work
mov bx,ds:[si+POLYVX]
cmp ecx,fs:[bx+vlist_z]
jle @@2
@@1: ;LAST POINT HIDDEN
ZCLIPGETVX
cmp ecx,fs:[bx+vlist_z]
jge @@1
;this point visible, clip
ZCLIPCLIP ;returns data in cx
or cs:clipvisfl,ax
ZCLIPADDVX
mov ecx,gs:_projclipz[CLIPMIN] ;ECX was destroyed by ZCLIPCLIP
@@2: ;LAST POINT VISIBLE
ZCLIPADDVISVX
ZCLIPGETVX
cmp ecx,fs:[bx+vlist_z]
jle @@2
;this point hidden, clip
ZCLIPCLIP ;returns data in cx
or cs:clipvisfl,ax
ZCLIPADDVX
mov ecx,gs:_projclipz[CLIPMIN] ;ECX was destroyed by ZCLIPCLIP
jmp @@1 ;to hidden
@@0: pop bx
sub di,bx
shr di,2
mov ds:[bx+POLYSIDES],di ;Sides in clipped polygon
mov di,bx
pop si
pop bp
mov ax,cs:clipvisfl
ret
clipnear ENDP
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
newclipup PROC NEAR
;clips list DS:SI -> DS:DI (source list must NOT be empty)
push bp
push si
push di
mov cs:clipzero,si
mov bp,word ptr gs:_projclipy[CLIPMIN]
mov eax,ds:[si+POLYSIDES] ;&POLYCOLOR
mov ds:[di+POLYSIDES],eax
inc ax
mov cs:clipcount,ax
mov eax,ds:[si+POLYFLAGS] ;&POLYVXSEG
mov ds:[di+POLYFLAGS],eax
mov word ptr ds:[di+POLYX-4],07fffh ;for CLIPADDVX to surely do it's work
;bx=last, si=current
cmp ds:[si+POLYY],bp
jge @@2
@@1: ;LAST POINT HIDDEN
NEWCLIPNEXT
cmp ds:[si+POLYY],bp
jle @@1
;this point visible, clip
NEWCLIPCALC POLYY,POLYX
@@2: ;LAST POINT VISIBLE
NEWCLIPCOPY ;copies always also texture & gouraud
NEWCLIPNEXT
cmp ds:[si+POLYY],bp
jge @@2
;this point hidden, clip
NEWCLIPCALC POLYY,POLYX
jmp @@1 ;to hidden
@@0: pop bx
sub di,bx
shr di,2
mov ds:[bx+POLYSIDES],di ;Sides in clipped polygon
mov di,bx
pop si
pop bp
ret
newclipup ENDP
newclipdown PROC NEAR
;clips list DS:SI -> DS:DI (source list must NOT be empty)
push bp
push si
push di
mov cs:clipzero,si
mov bp,word ptr gs:_projclipy[CLIPMAX]
mov eax,ds:[si+POLYSIDES] ;&POLYCOLOR
mov ds:[di+POLYSIDES],eax
inc ax
mov cs:clipcount,ax
mov eax,ds:[si+POLYFLAGS] ;&POLYVXSEG
mov ds:[di+POLYFLAGS],eax
mov word ptr ds:[di+POLYX-4],07fffh ;for CLIPADDVX to surely do it's work
;bx=last, si=current
cmp ds:[si+POLYY],bp
jle @@2
@@1: ;LAST POINT HIDDEN
NEWCLIPNEXT
cmp ds:[si+POLYY],bp
jge @@1
;this point visible, clip
NEWCLIPCALC POLYY,POLYX
@@2: ;LAST POINT VISIBLE
NEWCLIPCOPY ;copies always also texture & gouraud
NEWCLIPNEXT
cmp ds:[si+POLYY],bp
jle @@2
;this point hidden, clip
NEWCLIPCALC POLYY,POLYX
jmp @@1 ;to hidden
@@0: pop bx
sub di,bx
shr di,2
mov ds:[bx+POLYSIDES],di ;Sides in clipped polygon
mov di,bx
pop si
pop bp
ret
newclipdown ENDP
newclipleft PROC NEAR
;clips list DS:SI -> DS:DI (source list must NOT be empty)
push bp
push si
push di
mov cs:clipzero,si
mov bp,word ptr gs:_projclipx[CLIPMIN]
mov eax,ds:[si+POLYSIDES] ;&POLYCOLOR
mov ds:[di+POLYSIDES],eax
inc ax
mov cs:clipcount,ax
mov eax,ds:[si+POLYFLAGS] ;&POLYVXSEG
mov ds:[di+POLYFLAGS],eax
mov word ptr ds:[di+POLYX-4],07fffh ;for CLIPADDVX to surely do it's work
;bx=last, si=current
cmp ds:[si+POLYX],bp
jge @@2
@@1: ;LAST POINT HIDDEN
NEWCLIPNEXT
cmp ds:[si+POLYX],bp
jle @@1
;this point visible, clip
NEWCLIPCALC POLYX,POLYY
@@2: ;LAST POINT VISIBLE
NEWCLIPCOPY ;copies always also texture & gouraud
NEWCLIPNEXT
cmp ds:[si+POLYX],bp
jge @@2
;this point hidden, clip
NEWCLIPCALC POLYX,POLYY
jmp @@1 ;to hidden
@@0: pop bx
sub di,bx
shr di,2
mov ds:[bx+POLYSIDES],di ;Sides in clipped polygon
mov di,bx
pop si
pop bp
ret
newclipleft ENDP
newclipright PROC NEAR
;clips list DS:SI -> DS:DI (source list must NOT be empty)
push bp
push si
push di
mov cs:clipzero,si
mov bp,word ptr gs:_projclipx[CLIPMAX]
mov eax,ds:[si+POLYSIDES] ;&POLYCOLOR
mov ds:[di+POLYSIDES],eax
inc ax
mov cs:clipcount,ax
mov eax,ds:[si+POLYFLAGS] ;&POLYVXSEG
mov ds:[di+POLYFLAGS],eax
mov word ptr ds:[di+POLYX-4],07fffh ;for CLIPADDVX to surely do it's work
;bx=last, si=current
cmp ds:[si+POLYX],bp
jle @@2
@@1: ;LAST POINT HIDDEN
NEWCLIPNEXT
cmp ds:[si+POLYX],bp
jge @@1
;this point visible, clip
NEWCLIPCALC POLYX,POLYY
@@2: ;LAST POINT VISIBLE
NEWCLIPCOPY ;copies always also texture & gouraud
NEWCLIPNEXT
cmp ds:[si+POLYX],bp
jle @@2
;this point hidden, clip
NEWCLIPCALC POLYX,POLYY
jmp @@1 ;to hidden
@@0: pop bx
sub di,bx
shr di,2
mov ds:[bx+POLYSIDES],di ;Sides in clipped polygon
mov di,bx
pop si
pop bp
ret
newclipright ENDP
newclip PROC NEAR
;ENTRY:
;ds:si=pointer to list to be clipped
;ds:di=pointer to temporary list
;dx=visibility flag for polygon
;ax=flags for polygon (determines if texture and/or gouraud is clipped)
;EXIT:
;ds:si=clipped list (could be either of the entry lists)
xor bx,bx
test ax,F_GOURAUD
jz @@f1
mov bx,OFFSET newclip_grd
@@f1: mov cs:newclipprog,bx
;
LOADGS
test dh,VF_FAR ;If *ANY* vertex is 'far', entire polygon is
jnz @@cl7 ;skipped (no clipping visible far away)
test dl,VF_NEAR ;ClipNear must be done first, for in NEAR case
jz @@cl6 ;not all vertices are even calculated!
cmp word ptr ds:[si+POLYSIDES],0
je @@cl6
push dx
call clipnear
xchg si,di
pop dx ; clipnear return in ax the visfl for new vertices.
or dl,al ;<-this is done so that if the new vertices are outside the screen they'll be clipped
@@cl6: ;
test dl,VF_UP
jz @@cl1
cmp word ptr ds:[si+POLYSIDES],0
je @@cl1
push dx
call newclipup
xchg si,di
pop dx
@@cl1: ;
test dl,VF_DOWN
jz @@cl2
cmp word ptr ds:[si+POLYSIDES],0
je @@cl2
push dx
call newclipdown
xchg si,di
pop dx
@@cl2: ;
test dl,VF_LEFT
jz @@cl3
cmp word ptr ds:[si+POLYSIDES],0
je @@cl3
push dx
call newclipleft
xchg si,di
pop dx
@@cl3: ;
test dl,VF_RIGHT
jz @@cl4
cmp word ptr ds:[si+POLYSIDES],0
je @@cl4
push dx
call newclipright
xchg si,di
pop dx
;
@@cl4: ret
@@cl7: ;polygon marked invisible:
mov word ptr ds:[si+POLYSIDES],0
ret
newclip ENDP

769
VISU/ADRAWCLP.OLD Normal file
View file

@ -0,0 +1,769 @@
;/****************************************************************************
;** MODULE: adrawclp.asm
;** AUTHOR: Sami Tammilehto / Fennosoftec OY
;** DOCUMENT: ?
;** VERSION: 1.0
;** REFERENCE: -
;** REVISED BY: -
;*****************************************************************************
;**
;** Polygon clipping (included to adraw.asm)
;** All routines take DS:SI as an entry list and write a clipped list to
;** ES:DI. The clipnear also returns in AX the orred visvf for the clipped
;** polygon since it might change during Z clipping.
;**
;****************************************************************************/
CLIPCLIP MACRO
local l1,l0
;(AX,BX)-(DX,CX) is clipped at (-,BP) with result stored to (DX,CX)
;AX,BX destroyed
push bp
cmp cx,bx
jl l1
xchg cx,bx
xchg ax,dx
l1: push dx
sub bp,cx
sub ax,dx
imul bp
sub bx,cx
idiv bx
pop dx
add dx,ax
pop bp
mov cx,bp
ENDM
ZCLIPCLIP MACRO
local l1,l41,l42,l43,l44
;(fs:bp)-(fs:bx) is clipped at (-,-,ECX) with result stored to (DX,CX) & AX=visfl
push bx
push bp
push esi
push edi
push ecx
;
mov eax,fs:[bx+vlist_z]
mov edx,fs:[bp+vlist_z]
cmp eax,edx
jg l1
xchg eax,edx
xchg bx,bp
l1: ;EAX=farther vertex (>EDX), BX=offset of farther vertex
mov esi,eax
mov edi,eax
sub esi,edx ;>=0 divver
sub edi,ecx ;>=0 muller, esi>edi
;
mov eax,fs:[bp+vlist_x]
sub eax,fs:[bx+vlist_x]
imul edi
idiv esi
add eax,fs:[bx+vlist_x]
push eax
;
mov eax,fs:[bp+vlist_y]
sub eax,fs:[bx+vlist_y]
imul edi
idiv esi
add eax,fs:[bx+vlist_y]
;
pop esi ;X
pop ecx ;cliplimit
xor di,di
;
imul gs:_projmuly
idiv ecx
add eax,gs:_projaddy
cmp eax,gs:_projclipy[CLIPMAX]
jng l41
or di,VF_DOWN
l41: cmp eax,gs:_projclipy[CLIPMIN]
jnl l42
or di,VF_UP
l42: push ax
;
mov eax,esi
imul gs:_projmulx
idiv ecx
add eax,gs:_projaddx
cmp eax,gs:_projclipx[CLIPMAX]
jng l43
or di,VF_RIGHT
l43: cmp eax,gs:_projclipx[CLIPMIN]
jnl l44
or di,VF_LEFT
l44: ;
mov dx,ax
mov ax,di
pop cx
;dx=x,cx=y,ax=visfl
pop edi
pop esi
pop bp
pop bx
;NOTE: ECX was destroyed while clipping. It is used to return data.
;It must be pushed by the 'calling' procedure after the macro and
;the usage of the data the macro returned!
ENDM
CLIPADDVX MACRO ;adds (AX,BX) to list at DS:DI
local l1,l2
cmp ds:[di+POLYX-4],dx
jne l1
cmp ds:[di+POLYY-4],cx
jne l1
jmp l2
l1: mov ds:[di+POLYX],dx
mov ds:[di+POLYY],cx
add di,4
l2: ;;;
ENDM
CLIPGETVX MACRO ;reads to (dx,cx) the next vertext from DS:SI (copies last vx to ax,bx)
local l1,l2
mov ax,dx
mov bx,cx
mov dx,cs:clipcount
dec dx
cmp dx,1
jl @@0 ;list ended, jmp to end of clip procedure
mov cs:clipcount,dx
jg l1
;1 vertex left, means we rotated the list
mov si,cs:clipzero
jmp l2
l1: add si,4
l2: mov dx,ds:[si+POLYX]
mov cx,ds:[si+POLYY]
ENDM
CLIPADDVXR MACRO ;adds (DX,CX) to list at DS:DI [R=X/Y reversed]
local l1,l2
cmp ds:[di+POLYX-4],dx
jne l1
cmp ds:[di+POLYY-4],cx
jne l1
jmp l2
l1: mov ds:[di+POLYY],dx
mov ds:[di+POLYX],cx
add di,4
l2: ;;;
ENDM
CLIPGETVXR MACRO ;reads to (dx,cx) the next vertext from DS:SI (copies last vx to ax,bx) [R=X/Y reversed]
local l1,l2
mov ax,dx
mov bx,cx
mov dx,cs:clipcount
dec dx
cmp dx,1
jl @@0 ;list ended, jmp to end of clip procedure
mov cs:clipcount,dx
jg l1
;1 vertex left, means we rotated the list
mov si,cs:clipzero
jmp l2
l1: add si,4
l2: mov dx,ds:[si+POLYY]
mov cx,ds:[si+POLYX]
ENDM
ZCLIPADDVISVX MACRO ;adds ds:si[bx+POLYX/Y] to list (the vx must be visible for this to work) at DS:DI
local l1,l2
mov dx,ds:[si+POLYX]
mov ax,ds:[si+POLYY]
cmp ds:[di+POLYX-4],dx
jne l1
cmp ds:[di+POLYY-4],ax
jne l1
jmp l2
l1: mov ds:[di+POLYX],dx
mov ds:[di+POLYY],ax
add di,4
l2: ;;;
ENDM
ZCLIPADDVX MACRO ;adds (DX,CX) to list at DS:DI
local l1,l2
cmp ds:[di+POLYX-4],dx
jne l1
cmp ds:[di+POLYY-4],cx
jne l1
jmp l2
l1: mov ds:[di+POLYX],dx
mov ds:[di+POLYY],cx
add di,4
l2: ;;;
ENDM
ZCLIPGETVX MACRO ;reads to bx the offset of next vertex from DS:SI (copies last vx to bp)
local l1,l2
mov bp,bx
mov dx,cs:clipcount
dec dx
cmp dx,1
jl @@0 ;list ended, jmp to end of clip procedure
mov cs:clipcount,dx
jg l1
;1 vertex left, means we rotated the list
mov si,cs:clipzero
jmp l2
l1: add si,4
l2: mov bx,ds:[si+POLYVX]
ENDM
ALIGN 16
clipcount dw 0
clipzero dw 0
clipvisfl dw 0
clipnear PROC NEAR
;clips list DS:SI -> DS:DI (source list must NOT be empty)
push bp
push si
push di
mov cs:clipzero,si
mov ecx,gs:_projclipz[CLIPMIN] ;ECX=cliplimit
mov eax,ds:[si+POLYSIDES] ;&POLYCOLOR
mov ds:[di+POLYSIDES],eax
inc ax
mov cs:clipcount,ax
mov eax,ds:[si+POLYFLAGS] ;&POLYVXSEG
mov ds:[di+POLYFLAGS],eax
mov fs,ds:[si+POLYVXSEG]
mov word ptr ds:[di+POLYX-4],07fffh ;for CLIPADDVX to surely do it's work
mov bx,ds:[si+POLYVX]
cmp ecx,fs:[bx+vlist_z]
jle @@2
@@1: ;LAST POINT HIDDEN
ZCLIPGETVX
cmp ecx,fs:[bx+vlist_z]
jge @@1
;this point visible, clip
ZCLIPCLIP ;returns data in cx
or cs:clipvisfl,ax
ZCLIPADDVX
mov ecx,gs:_projclipz[CLIPMIN] ;ECX was destroyed by ZCLIPCLIP
@@2: ;LAST POINT VISIBLE
ZCLIPADDVISVX
ZCLIPGETVX
cmp ecx,fs:[bx+vlist_z]
jle @@2
;this point hidden, clip
ZCLIPCLIP ;returns data in cx
or cs:clipvisfl,ax
ZCLIPADDVX
mov ecx,gs:_projclipz[CLIPMIN] ;ECX was destroyed by ZCLIPCLIP
jmp @@1 ;to hidden
@@0: pop bx
sub di,bx
shr di,2
mov ds:[bx+POLYSIDES],di ;Sides in clipped polygon
mov di,bx
pop si
pop bp
mov ax,cs:clipvisfl
ret
clipnear ENDP
clipdown PROC NEAR
;clips list DS:SI -> DS:DI (source list must NOT be empty)
push bp
push si
push di
mov cs:clipzero,si
mov bp,word ptr gs:_projclipy[CLIPMAX]
mov eax,ds:[si+POLYSIDES] ;&POLYCOLOR
mov ds:[di+POLYSIDES],eax
inc ax
mov cs:clipcount,ax
mov eax,ds:[si+POLYFLAGS] ;&POLYVXSEG
mov ds:[di+POLYFLAGS],eax
mov word ptr ds:[di+POLYX-4],07fffh ;for CLIPADDVX to surely do it's work
mov dx,ds:[si+POLYX]
mov cx,ds:[si+POLYY]
cmp cx,bp
jle @@2
@@1: ;LAST POINT HIDDEN
CLIPGETVX
cmp cx,bp
jge @@1
;this point visible, clip
push dx
push cx
CLIPCLIP
CLIPADDVX
pop cx
pop dx
@@2: ;LAST POINT VISIBLE
CLIPADDVX
CLIPGETVX
cmp cx,bp
jle @@2
;this point hidden, clip
push dx
push cx
CLIPCLIP
CLIPADDVX
pop cx
pop dx ;now dx/cx are the true last point
jmp @@1 ;to hidden
@@0: pop bx
sub di,bx
shr di,2
mov ds:[bx+POLYSIDES],di ;Sides in clipped polygon
mov di,bx
pop si
pop bp
ret
clipdown ENDP
clipup PROC NEAR
;clips list DS:SI -> DS:DI (source list must NOT be empty)
push bp
push si
push di
mov cs:clipzero,si
mov bp,word ptr gs:_projclipy[CLIPMIN]
mov eax,ds:[si+POLYSIDES] ;&POLYCOLOR
mov ds:[di+POLYSIDES],eax
inc ax
mov cs:clipcount,ax
mov eax,ds:[si+POLYFLAGS] ;&POLYVXSEG
mov ds:[di+POLYFLAGS],eax
mov word ptr ds:[di+POLYX-4],07fffh ;for CLIPADDVX to surely do it's work
mov dx,ds:[si+POLYX]
mov cx,ds:[si+POLYY]
cmp cx,bp
jge @@2
@@1: ;LAST POINT HIDDEN
CLIPGETVX
cmp cx,bp
jle @@1
;this point visible, clip
push dx
push cx
CLIPCLIP
CLIPADDVX
pop cx
pop dx
@@2: ;LAST POINT VISIBLE
CLIPADDVX
CLIPGETVX
cmp cx,bp
jge @@2
;this point hidden, clip
push dx
push cx
CLIPCLIP
CLIPADDVX
pop cx
pop dx ;now dx/cx are the true last point
jmp @@1 ;to hidden
@@0: pop bx
sub di,bx
shr di,2
mov ds:[bx+POLYSIDES],di ;Sides in clipped polygon
mov di,bx
pop si
pop bp
ret
clipup ENDP
clipright PROC NEAR
;clips list DS:SI -> DS:DI (source list must NOT be empty)
push bp
push si
push di
mov cs:clipzero,si
mov bp,word ptr gs:_projclipx[CLIPMAX]
mov eax,ds:[si+POLYSIDES] ;&POLYCOLOR
mov ds:[di+POLYSIDES],eax
inc ax
mov cs:clipcount,ax
mov eax,ds:[si+POLYFLAGS] ;&POLYVXSEG
mov ds:[di+POLYFLAGS],eax
mov word ptr ds:[di+POLYX-4],07fffh ;for CLIPADDVX to surely do it's work
mov dx,ds:[si+POLYY]
mov cx,ds:[si+POLYX]
cmp cx,bp
jle @@2
@@1: ;LAST POINT HIDDEN
CLIPGETVXR
cmp cx,bp
jge @@1
;this point visible, clip
push dx
push cx
CLIPCLIP
CLIPADDVXR
pop cx
pop dx
@@2: ;LAST POINT VISIBLE
CLIPADDVXR
CLIPGETVXR
cmp cx,bp
jle @@2
;this point hidden, clip
push dx
push cx
CLIPCLIP
CLIPADDVXR
pop cx
pop dx ;now dx/cx are the true last point
jmp @@1 ;to hidden
@@0: pop bx
sub di,bx
shr di,2
mov ds:[bx+POLYSIDES],di ;Sides in clipped polygon
mov di,bx
pop si
pop bp
ret
clipright ENDP
clipleft PROC NEAR
;clips list DS:SI -> DS:DI (source list must NOT be empty)
push bp
push si
push di
mov cs:clipzero,si
mov bp,word ptr gs:_projclipx[CLIPMIN]
mov eax,ds:[si+POLYSIDES] ;&POLYCOLOR
mov ds:[di+POLYSIDES],eax
inc ax
mov cs:clipcount,ax
mov eax,ds:[si+POLYFLAGS] ;&POLYVXSEG
mov ds:[di+POLYFLAGS],eax
mov word ptr ds:[di+POLYX-4],07fffh ;for CLIPADDVX to surely do it's work
mov dx,ds:[si+POLYY]
mov cx,ds:[si+POLYX]
cmp cx,bp
jge @@2
@@1: ;LAST POINT HIDDEN
CLIPGETVXR
cmp cx,bp
jle @@1
;this point visible, clip
push dx
push cx
CLIPCLIP
CLIPADDVXR
pop cx
pop dx
@@2: ;LAST POINT VISIBLE
CLIPADDVXR
CLIPGETVXR
cmp cx,bp
jge @@2
;this point hidden, clip
push dx
push cx
CLIPCLIP
CLIPADDVXR
pop cx
pop dx ;now dx/cx are the true last point
jmp @@1 ;to hidden
@@0: pop bx
sub di,bx
shr di,2
mov ds:[bx+POLYSIDES],di ;Sides in clipped polygon
mov di,bx
pop si
pop bp
ret
clipleft ENDP
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ALIGN 16
newclipflip db 0,0
newclipprog dw 0
newclip_grd PROC NEAR
;DS:BX->DS:SI is clipped at CX (BX end=0..16384=SI end)
;resulted clip stored to ES:DI
mov ax,ds:[si+POLYGR]
sub ax,ds:[bx+POLYGR]
imul cx
shld dx,ax,2
add dx,ds:[bx+POLYGR]
mov ds:[di+POLYGR],dx
ret
ENDP
NEWCLIPCALC MACRO clipped,other
local l1,l2,l3,l4,l5,l6
;DS:BX->DS:SI is clipped at (-,BP) with result stored to DS:DI
push si
push bx
push bp
mov dx,ds:[si+other]
mov cx,ds:[si+clipped]
mov ax,ds:[bx+other]
mov bx,ds:[bx+clipped]
mov cs:newclipflip,0
cmp cx,bx
jl l3
mov cs:newclipflip,1
xchg cx,bx
xchg ax,dx
l3: push dx
sub bp,cx
sub ax,dx
push ax
mov dx,bp
xor ax,ax
shrd ax,dx,2
sar dx,2
;dx:ax=short length*16384
sub bx,cx
idiv bx
mov bx,ax
;bx=0..16384 multiplier
pop ax
imul bx
shld dx,ax,2
pop ax
add dx,ax ;dx=clipped other
pop bp
mov cx,bp
cmp ds:[di+other-4],dx
jne l1
cmp ds:[di+clipped-4],cx
jne l1
jmp l2
l1: mov ds:[di+other],dx
mov ds:[di+clipped],cx
mov cx,bx
pop bx
mov ax,cs:newclipprog
or ax,ax
jz l4
mov dl,cs:newclipflip
or dl,dl
jz l6
xchg si,bx
l6: call ax ;also stores gouraud&texture clipped
l4: add di,4
jmp l5
l2: pop bx
l5: pop si
ENDM
NEWCLIPNEXT MACRO ;sets bx(last)=si(current) and loads si with next vertex
local l1,l2
mov bx,si
mov dx,cs:clipcount
dec dx
cmp dx,1
jl @@0 ;list ended, jmp to end of clip procedure
mov cs:clipcount,dx
jg l1
;1 vertex left, means we rotated the list
mov si,cs:clipzero
jmp l2
l1: add si,4
l2: ENDM
NEWCLIPCOPY MACRO ;should copy also texture
local l1
mov eax,ds:[si+POLYX] ;&POLYY
cmp ds:[di+POLYX-4],eax
je l1
mov ds:[di+POLYX],eax
mov ax,ds:[si+POLYGR]
mov ds:[di+POLYGR],ax
add di,4
l1: ENDM
newclipup PROC NEAR
;clips list DS:SI -> DS:DI (source list must NOT be empty)
push bp
push si
push di
mov cs:clipzero,si
mov bp,word ptr gs:_projclipy[CLIPMIN]
mov eax,ds:[si+POLYSIDES] ;&POLYCOLOR
mov ds:[di+POLYSIDES],eax
inc ax
mov cs:clipcount,ax
mov eax,ds:[si+POLYFLAGS] ;&POLYVXSEG
mov ds:[di+POLYFLAGS],eax
mov word ptr ds:[di+POLYX-4],07fffh ;for CLIPADDVX to surely do it's work
;bx=last, si=current
cmp ds:[si+POLYY],bp
jge @@2
@@1: ;LAST POINT HIDDEN
NEWCLIPNEXT
cmp ds:[si+POLYY],bp
jle @@1
;this point visible, clip
NEWCLIPCALC POLYY,POLYX
@@2: ;LAST POINT VISIBLE
NEWCLIPCOPY ;copies always also texture & gouraud
NEWCLIPNEXT
cmp ds:[si+POLYY],bp
jge @@2
;this point hidden, clip
NEWCLIPCALC POLYY,POLYX
jmp @@1 ;to hidden
@@0: pop bx
sub di,bx
shr di,2
mov ds:[bx+POLYSIDES],di ;Sides in clipped polygon
mov di,bx
pop si
pop bp
ret
newclipup ENDP
newclipdown PROC NEAR
;clips list DS:SI -> DS:DI (source list must NOT be empty)
push bp
push si
push di
mov cs:clipzero,si
mov bp,word ptr gs:_projclipy[CLIPMAX]
mov eax,ds:[si+POLYSIDES] ;&POLYCOLOR
mov ds:[di+POLYSIDES],eax
inc ax
mov cs:clipcount,ax
mov eax,ds:[si+POLYFLAGS] ;&POLYVXSEG
mov ds:[di+POLYFLAGS],eax
mov word ptr ds:[di+POLYX-4],07fffh ;for CLIPADDVX to surely do it's work
;bx=last, si=current
cmp ds:[si+POLYY],bp
jle @@2
@@1: ;LAST POINT HIDDEN
NEWCLIPNEXT
cmp ds:[si+POLYY],bp
jge @@1
;this point visible, clip
NEWCLIPCALC POLYY,POLYX
@@2: ;LAST POINT VISIBLE
NEWCLIPCOPY ;copies always also texture & gouraud
NEWCLIPNEXT
cmp ds:[si+POLYY],bp
jle @@2
;this point hidden, clip
NEWCLIPCALC POLYY,POLYX
jmp @@1 ;to hidden
@@0: pop bx
sub di,bx
shr di,2
mov ds:[bx+POLYSIDES],di ;Sides in clipped polygon
mov di,bx
pop si
pop bp
ret
newclipdown ENDP
newclip PROC NEAR
;ENTRY:
;ds:si=pointer to list to be clipped
;ds:di=pointer to temporary list
;dx=visibility flag for polygon
;ax=flags for polygon (determines if texture and/or gouraud is clipped)
;EXIT:
;ds:si=clipped list (could be either of the entry lists)
LOADGS
;
xor bx,bx
test ax,F_GOURAUD
jz @@f1
mov bx,OFFSET newclip_grd
@@f1: mov cs:newclipprog,bx
;
test dh,VF_FAR ;If *ANY* vertex is 'far', entire polygon is
jnz @@cl7 ;skipped (no clipping visible far away)
test dl,VF_NEAR ;ClipNear must be done first, for in NEAR case
jz @@cl6 ;not all vertices are even calculated!
cmp word ptr ds:[si+POLYSIDES],0
je @@cl6
push dx
call clipnear
xchg si,di
pop dx ; clipnear return in ax the visfl for new vertices.
or dl,al ;<-this is done so that if the new vertices are outside the screen they'll be clipped
@@cl6: ;
test dl,VF_UP
jz @@cl1
cmp word ptr ds:[si+POLYSIDES],0
je @@cl1
push dx
int 3
call newclipup
xchg si,di
pop dx
@@cl1: ;
test dl,VF_DOWN
jz @@cl2
cmp word ptr ds:[si+POLYSIDES],0
je @@cl2
push dx
call newclipdown
xchg si,di
pop dx
@@cl2: ;
test dl,VF_LEFT
jz @@cl3
cmp word ptr ds:[si+POLYSIDES],0
je @@cl3
push dx
call clipleft
xchg si,di
pop dx
@@cl3: ;
test dl,VF_RIGHT
jz @@cl4
cmp word ptr ds:[si+POLYSIDES],0
je @@cl4
push dx
call clipright
xchg si,di
pop dx
;
@@cl4: ret
@@cl7: ;polygon marked invisible:
mov word ptr ds:[si+POLYSIDES],0
ret
newclip ENDP

33
VISU/AFILLDIV.INC Normal file
View file

@ -0,0 +1,33 @@
dw -1,-1,-32768,21845,16384,13107,10922,9362,8192,7281,6553,5957,5461,5041,4681,4369
dw 4096,3855,3640,3449,3276,3120,2978,2849,2730,2621,2520,2427,2340,2259,2184,2114
dw 2048,1985,1927,1872,1820,1771,1724,1680,1638,1598,1560,1524,1489,1456,1424,1394
dw 1365,1337,1310,1285,1260,1236,1213,1191,1170,1149,1129,1110,1092,1074,1057,1040
dw 1024,1008,992,978,963,949,936,923,910,897,885,873,862,851,840,829
dw 819,809,799,789,780,771,762,753,744,736,728,720,712,704,697,689
dw 682,675,668,661,655,648,642,636,630,624,618,612,606,601,595,590
dw 585,579,574,569,564,560,555,550,546,541,537,532,528,524,520,516
dw 512,508,504,500,496,492,489,485,481,478,474,471,468,464,461,458
dw 455,451,448,445,442,439,436,434,431,428,425,422,420,417,414,412
dw 409,407,404,402,399,397,394,392,390,387,385,383,381,378,376,374
dw 372,370,368,366,364,362,360,358,356,354,352,350,348,346,344,343
dw 341,339,337,336,334,332,330,329,327,326,324,322,321,319,318,316
dw 315,313,312,310,309,307,306,304,303,302,300,299,297,296,295,293
dw 292,291,289,288,287,286,284,283,282,281,280,278,277,276,275,274
dw 273,271,270,269,268,267,266,265,264,263,262,261,260,259,258,257
dw 256,255,254,253,252,251,250,249,248,247,246,245,244,243,242,241
dw 240,240,239,238,237,236,235,234,234,233,232,231,230,229,229,228
dw 227,226,225,225,224,223,222,222,221,220,219,219,218,217,217,216
dw 215,214,214,213,212,212,211,210,210,209,208,208,207,206,206,205
dw 204,204,203,202,202,201,201,200,199,199,198,197,197,196,196,195
dw 195,194,193,193,192,192,191,191,190,189,189,188,188,187,187,186
dw 186,185,185,184,184,183,183,182,182,181,181,180,180,179,179,178
dw 178,177,177,176,176,175,175,174,174,173,173,172,172,172,171,171
dw 170,170,169,169,168,168,168,167,167,166,166,165,165,165,164,164
dw 163,163,163,162,162,161,161,161,160,160,159,159,159,158,158,157
dw 157,157,156,156,156,155,155,154,154,154,153,153,153,152,152,152
dw 151,151,151,150,150,149,149,149,148,148,148,147,147,147,146,146
dw 146,145,145,145,144,144,144,144,143,143,143,142,142,142,141,141
dw 141,140,140,140,140,139,139,139,138,138,138,137,137,137,137,136
dw 136,136,135,135,135,135,134,134,134,134,133,133,133,132,132,132
dw 132,131,131,131,131,130,130,130,130,129,129,129,129,128,128,128

33
VISU/AMAIN.ASM Normal file
View file

@ -0,0 +1,33 @@
;/****************************************************************************
;** MODULE: amain.asm
;** AUTHOR: Sami Tammilehto / Fennosoftec OY
;** DOCUMENT: ?
;** VERSION: 1.0
;** REFERENCE: -
;** REVISED BY: -
;*****************************************************************************
;**
;** Assembler / Main
;** - segment definitions
;** - public routines
;**
;****************************************************************************/
include a.inc
;######## Segment definitions ########
asm_data SEGMENT para public use16 'DATA'
asm_data ENDS ;(ad.asm)
asm_code SEGMENT para public use16 'CODE'
asm_code ENDS ;(am.asm,ac.asm,ad.asm)
;######## Public Routines ########
asm_code SEGMENT para public 'CODE'
ASSUME cs:asm_code
asm_code ENDS
END

BIN
VISU/AMAIN.OBJ Normal file

Binary file not shown.

95
VISU/ATEXT.ASM Normal file
View file

@ -0,0 +1,95 @@
ALIGN 2
public _prtt,_txtx,_txty,_prttcol
_txtx dw 0
_txty dw 0
_prttcol dw 0
public _font3x5
_font3x5 dw 0,0
truerowsadd dw 0
prtmacro MACRO
local prt41,prt42,prt43,prt44,prt45
push di
out dx,al
mov al,byte ptr cs:_prttcol
rcr bl,1
jnc prt41
mov es:[di],al
prt41: add di,cs:truerowsadd
rcr bh,1
jnc prt42
mov es:[di],al
prt42: add di,cs:truerowsadd
rcr cl,1
jnc prt43
mov es:[di],al
prt43: add di,cs:truerowsadd
rcr ch,1
jnc prt44
mov es:[di],al
prt44: add di,cs:truerowsadd
rcr ah,1
jnc prt45
mov es:[di],al
prt45: pop di
ENDM
_prtt PROC FAR
CBEG
call vidstart
mov ax,ds:_rowlen
mov cs:truerowsadd,ax
mov fs,cs:_font3x5[2]
movpar ds,1
movpar si,0
mov di,cs:_txty
mov ax,cs:truerowsadd
mul di
mov di,ax
mov dx,cs:_txtx
shr dx,2
add di,dx
mov dx,3c4h
mov al,02h
out dx,al
inc dx
xor bp,bp ;cnt
mov cx,256
prt3: lodsb
cmp al,9 ;tab
je prt21
cmp al,0
je prt1x
cmp al,31
ja prt2
prt22: jmp prt10
prt1x: jmp prt1
prt21: inc bp
inc di
test bp,7
jz prt22
jmp prt21
prt2: inc bp
push cx
mov bl,al
xor bh,bh
shl bx,3
mov ah,fs:[bx+4]
mov cx,fs:[bx+2]
mov bx,fs:[bx+0]
mov al,01h
prtmacro
mov al,02h
prtmacro
mov al,04h
prtmacro
inc di
inc cs:_txtx
pop cx
prt10: dec cx
jz prt1
jmp prt3
prt1: CEND
_prtt ENDP

632
VISU/AVID.ASM Normal file
View file

@ -0,0 +1,632 @@
;/****************************************************************************
;** MODULE: avid.asm
;** AUTHOR: Sami Tammilehto / Fennosoftec OY
;** DOCUMENT: ?
;** VERSION: 1.0
;** REFERENCE: -
;** REVISED BY: -
;*****************************************************************************
;**
;** Assembler / Video (drawing, init...)
;**
;****************************************************************************/
include a.inc
asm_code SEGMENT para public use16 'CODE'
ASSUME cs:asm_code
framecounter dw 0
include avidm1.asm ;320x200x256 (tweak)
include avidm2.asm ;640x400x256 (tweak)
;entry: -
; exit: -
;descr: does nothing
emptyroutine PROC NEAR
ret
emptyroutine ENDP
;entry: -
; exit: -
;descr: executed before using graphics routines at entries.
; loads es => vram, and sets some VGA registers the
; way the gfx routines expect them to be.
vidstart PROC NEAR
mov es,ds:_vramseg
mov dx,3c4h
mov ax,0f02h
out dx,ax ;set the plane register ready (&enable all planes)
ret
vidstart ENDP
;entry: cx=rows to calc, dx=row length
setrows PROC NEAR
mov ds:_rowlen,dx
mov bx,OFFSET _rows
xor ax,ax
@@1: mov ds:[bx],ax
add ax,dx
add bx,2
loop @@1
ret
setrows ENDP
;±±±±±±±± _vid_cameraangle(angle a) ±±±±±±±±
;entry: (see above)
; exit: -
;descr: sets the vision angle (a=0..65535)
_vid_cameraangle PROC FAR
CBEG
mov eax,ds:_projclipx[CLIPMAX] ;right edge
sub eax,ds:_projaddx ;center X
;ax=width of half of screen
movpar bx,0
shr bx,1 ;divide by 2 for half of angle
cmp bx,8*64
jae @@2 ;about 3 degrees minimum
mov bx,8*64
@@2: cmp bx,16384
jb @@1
mov bx,16383 ;90 degrees maximum
@@1: shr bx,6-1
and bx,not 1
;bx=word index (0..255)*2
movzx ecx,word ptr ds:_avistan[bx]
mul ecx
shrd eax,edx,8
mov ds:_projmulx,eax
movzx ecx,word ptr ds:_projaspect
mul ecx
shrd eax,edx,8
mov ds:_projmuly,eax
CEND
_vid_cameraangle ENDP
;±±±±±±±± _vid_window(long x1,y1,x2,y2,z1,z2) ±±±±±±±±
;entry: (see above)
; exit: -
;descr: sets the video window (for clipping) and sets xadd/yadd to the
; center of the window
_vid_window PROC FAR
CBEG
movpar eax,0
mov edx,eax
mov ds:_projclipx[CLIPMIN],eax
movpar eax,2
add edx,eax
mov ds:_projclipx[CLIPMAX],eax
sar edx,1
mov ds:_projaddx,edx
movpar eax,4
mov edx,eax
mov ds:_projclipy[CLIPMIN],eax
movpar eax,6
add edx,eax
mov ds:_projclipy[CLIPMAX],eax
sar edx,1
mov ds:_projaddy,edx
movpar eax,8
mov ds:_projclipz[CLIPMIN],eax
movpar eax,10
mov ds:_projclipz[CLIPMAX],eax
CEND
_vid_window ENDP
;±±±±±±±± _vid_init(int mode) ±±±±±±±±
;entry: mode (see below)
; exit: -
;descr: initializes screen to graphics and sets up required variables
; NOTE: the screen / palette is left black.
;modes: 1=320x200x256 (tweak)
_vid_init PROC FAR
;CBEG (follows)
push bp
mov bp,sp
push si
push di
push ds
mov ax,ds
LOADDS
mov ds:_cdataseg,ax
movpar ax,0
cmp ax,1
jne @@1
call m1_init
@@1: cmp ax,11
jne @@11
call m11_init
@@11: cmp ax,2
jne @@2
call m2_init
@@2: cmp ax,3
jne @@3
call m1o_init
@@3: CEND
_vid_init ENDP
;±±±±±±±± _vid_deinit() ±±±±±±±±
;entry: -
; exit: -
;descr: resets screen to text mode
_vid_deinit PROC FAR
CBEG
mov ax,3
int 10h
CEND
_vid_deinit ENDP
;±±±±±±±± _vid_setpal(char far *pal) ±±±±±±±±
;entry: pal=palette (768 bytes VGA RGB)
; exit: -
;descr: sets screen palette
_vid_setpal PROC FAR
CBEG
ldspar si,0
mov dx,3dah
@@1: in al,dx
test al,8
jnz @@1
@@2: in al,dx
test al,8
jz @@2
mov dx,3c8h
xor al,al
out dx,al
inc dx
mov cx,256
@@3: mov al,ds:[si+0]
out dx,al
mov al,ds:[si+1]
out dx,al
mov al,ds:[si+2]
out dx,al
add si,3
loop @@3
CEND
_vid_setpal ENDP
;±±±±±±±± _vid_drawdots(int count,pvlist *pv) ±±±±±±±±
;entry: count=number of points to draw
; pv=pointer to projected vertex list
; exit: -
;descr: plots vertices in list
_vid_drawdots PROC FAR
CBEG
call vidstart
movpar cx,0
lfspar si,1
@@1: mov ax,fs:pvlist_vf[si]
or ax,ax
jnz @@2
mov dx,fs:pvlist_x[si]
mov bx,fs:pvlist_y[si]
mov ah,31
push cx
call ds:vr[PSET]
pop cx
@@2: add si,pvlist_size
loop @@1
CEND
_vid_drawdots ENDP
;±±±±±±±± _vid_dotdisplay_pvlist(int count,pvlist *list) ±±±±±±±±
;entry: count=number of elements in pvlist
; list=pointer to pvlist
; exit: -
;descr: TEST ROUTINE
; displays the projected vertices in the list as dots
_vid_dotdisplay_pvlist PROC FAR
CBEG
call vidstart
lfspar si,1
movpar cx,0
@@1: push cx
mov ax,fs:[si+pvlist_vf]
or ax,ax
jnz @@2
mov dx,fs:[si+pvlist_x]
mov bx,fs:[si+pvlist_y]
mov ah,15 ;color
call ds:vr[PSET]
@@2: add si,pvlist_size
pop cx
loop @@1
CEND
_vid_dotdisplay_pvlist ENDP
;±±±±±±±± _vid_pset(int x,int y,int color) ±±±±±±±±
_vid_pset PROC FAR
CBEG
call vidstart
movpar dx,0
movpar bx,1
movpar ah,2
call ds:vr[PSET]
CEND
_vid_pset ENDP
;±±±±±±±± _vid_dotdisplay_zcolor(int count,pvlist *list1,vlist *list2) ±±±±±±±±
;entry: count=number of elements in pvlist
; list1=pointer to pvlist
; list2=pointer to vlist (both lists should have same vertices!)
; exit: -
;descr: TEST ROUTINE
; displays the projected vertices in the list as dots colored
; according to depth
_vid_dotdisplay_zcolor PROC FAR
CBEG
call vidstart
lfspar si,1
lgspar di,3
movpar cx,0
@@1: push cx
mov ax,fs:[si+pvlist_vf]
or ax,ax
jnz @@2
mov dx,fs:[si+pvlist_x]
mov bx,fs:[si+pvlist_y]
mov eax,gs:[di+vlist_z]
sar eax,11
cmp ax,1
jge @@3
mov ax,1
@@3: cmp ax,31
jle @@4
mov ax,31
@@4: mov ah,al
call ds:vr[PSET]
@@2: add si,pvlist_size
add di,vlist_size
pop cx
loop @@1
CEND
_vid_dotdisplay_zcolor ENDP
;±±±±±±±± _vid_clear(void) ±±±±±±±±
;entry: -
; exit: -
;descr: Clears the current screen to black (color 0)
_vid_clear PROC FAR
CBEG
call vidstart
mov ax,0 ;blackclear
call ds:vr[CLEAR]
CEND
_vid_clear ENDP
;±±±±±±±± _vid_clear255(void) ±±±±±±±±
;entry: -
; exit: -
;descr: Clears the current screen to black (color 0)
_vid_clear255 PROC FAR
CBEG
call vidstart
mov ax,9 ;255clear
call ds:vr[CLEAR]
CEND
_vid_clear255 ENDP
;±±±±±±±± _vid_clearbg(char *bg) ±±±±±±±±
;entry: -
; exit: -
;descr: Copies the bg to screen
_vid_clearbg PROC FAR
CBEG
call vidstart
mov ax,2 ;bgcopy
mov si,[bp+6]
mov fs,[bp+8]
call ds:vr[CLEAR]
CEND
_vid_clearbg ENDP
;±±±±±±±± _vid_switch(void) ±±±±±±±±
;entry: -
; exit: -
;descr: Switch to the next screen page (_vid_waitb should be called after
; this)
_vid_switch PROC FAR
CBEG
call vidstart
call ds:vr[SWITCH]
CEND
_vid_switch ENDP
;±±±±±±±± _vid_setswitch(int,int) ±±±±±±±±
;entry: -
; exit: -
;descr: Forces a separate write/display switch
_vid_setswitch PROC FAR
CBEG
;call vidstart
movpar ax,0
cmp ax,-1
je @@1
shl ax,14-4
add ax,0a000h
mov ds:_vramseg,ax
@@1: movpar ax,1
cmp ax,-1
je @@2
shl ax,14
mov dx,3d4h
mov al,0ch
out dx,ax
@@2: CEND
_vid_setswitch ENDP
;±±±±±±±± _vid_waitb(void) ±±±±±±±±
;entry: -
; exit: -
;descr: Waits for border (=retrace)
_vid_waitb PROC FAR
CBEG
call vidstart
call ds:vr[WAITB]
CEND
_vid_waitb ENDP
;±±±±±±±± _vid_clear(char *sky) ±±±±±±±±
;entry: [sky]=pointer to sky data structure
; exit: -
;descr: Clears the current screen with a sky pattern according to [sky]
_vid_skyclear PROC FAR
CBEG
call vidstart
lfspar si,0
mov ax,1 ;skyclear
call ds:vr[CLEAR]
CEND
_vid_skyclear ENDP
;##########################################################################
; 'Temporary' text routines
;##########################################################################
include atext.asm
;##########################################################################
; Common routines that work in all current screen modes
;##########################################################################
;entry: dx=x, bx=y, ax=width, cx=heigth
; exit:
;descr: calculates the 'good' copying sequence for the bitmap
ALIGN 2
bb_hidden dw 0
bb_yskip dw 0
bb_ycount dw 0
bb_xskip dw 0
bb_xcopy dw 0
;
bb_doskip dw 0,0,0,0 ;bytes
bb_doskip2 dw 0,0,0,0 ;pages 0..3
bb_doplane dw 0,0,0,0
bb_dodest dw 0,0,0,0
bb_docount dw 0,0,0,0
bitbltanalyze PROC NEAR
push si
push di
;clip up/down
mov cs:bb_xskip,0
mov cs:bb_yskip,0
mov si,word ptr ds:_projclipy[CLIPMAX]
cmp bx,si
jg @@out
mov si,word ptr ds:_projclipy[CLIPMIN]
cmp bx,si
jge @@1
sub si,bx
mov cs:bb_yskip,si
add bx,si
sub cx,si
@@1: mov si,word ptr ds:_projclipy[CLIPMAX]
sub si,bx
cmp cx,si
jle @@2
mov cx,si
inc cx
@@2: mov cs:bb_ycount,cx
mov si,bx
add si,cx
cmp si,word ptr ds:_projclipy[CLIPMIN]
jl @@out
;clip left/right
mov si,word ptr ds:_projclipx[CLIPMAX]
cmp dx,si
jg @@out
mov si,word ptr ds:_projclipx[CLIPMIN]
cmp dx,si
jge @@3
sub si,dx
mov cs:bb_xskip,si
add dx,si
sub ax,si
@@3: mov si,word ptr ds:_projclipx[CLIPMAX]
sub si,dx
cmp ax,si
jle @@4
mov ax,si
inc ax
@@4: mov cs:bb_xcopy,ax
mov si,dx
add si,ax
cmp si,word ptr ds:_projclipx[CLIPMIN]
jl @@out
;calc start address
shl bx,1
mov bx,ds:_rows[bx]
mov cx,dx
shr dx,2
add bx,dx
and cl,3
mov ax,1102h
rol ah,cl
mov dx,bx
mov si,cs:bb_xskip
mov di,cs:bb_xcopy
add di,3
xor bx,bx
REPT 4
local l1
push ax
mov cs:bb_doplane[bx],ax
mov cs:bb_dodest[bx],dx
mov ax,si
shr ax,2
mov cs:bb_doskip[bx],ax
mov ax,si
and ax,3
mov cs:bb_doskip2[bx],ax
mov ax,di
shr ax,2
mov cs:bb_docount[bx],ax
pop ax
rol ah,1
jnc l1
inc dx
l1: inc si
dec di
add bx,2
ENDM
mov cs:bb_hidden,0
pop di
pop si
ret
@@out: mov cs:bb_hidden,1
pop di
pop si
ret
bitbltanalyze ENDP
;±±±±±±±± _vid_pic320200(char *p,int x,int y) ±±±±±±±±
;entry: p=pointer to pic, x/y=screen position to write to
; exit: -
;descr: copies pic to screen. The pic format is {PIC64TW}
ALIGN 2
yrow dw 0
yrowlen dw 0
xm0 dw 0
xmstart dw 0
_vid_pic320200 PROC FAR
CBEG
call vidstart
movpar dx,2
movpar bx,3
mov cx,200
mov ax,320
call bitbltanalyze
cmp cs:bb_hidden,0
jne @@0
mov ax,ds:_rowlen
mov cs:yrowlen,ax
ldspar si,0
xor bx,bx
mov cx,4
@@1: push cx
push bx
push si
push di
mov ax,320 ;line length in source buf
mul cs:bb_yskip
add si,ax
mov ax,80 ;lenght of single 'bit'plane
mul cs:bb_doskip2[bx]
add si,ax
add si,cs:bb_doskip[bx]
mov ax,cs:bb_doplane[bx]
mov dx,3c4h
out dx,ax
mov di,cs:bb_dodest[bx]
mov dx,cs:bb_docount[bx]
or dx,dx
jz @@20
mov cx,cs:bb_ycount
jcxz @@20
cmp cx,7
ja @@2
@@5: ;simplex nonaligned copy
push cx
push si
push di
mov cx,dx
shr cx,2
rep movsd ;copy dwords
mov cx,dx
and cx,3
rep movsb ;copy rest
pop di
pop si
pop cx
add di,cs:yrowlen
add si,320 ;line length in source buf
loop @@5
jmp @@20
@@2: ;aligned copy
push cx
push dx
push si
push di
mov cx,di
neg cx
and cx,3
sub dx,cx
rep movsb ;align
mov cx,dx
shr cx,2
rep movsd ;copy dwords
mov cx,dx
and cx,3
rep movsb ;copy rest
pop di
pop si
pop dx
pop cx
add di,cs:yrowlen
add si,320 ;line length in source buf
loop @@2
@@20: pop di
pop si
pop bx
pop cx
add bx,2
loop @@1
@@0: CEND
_vid_pic320200 ENDP
;±±±±±±±± _vid_drawsight(char *sight) ±±±±±±±±
;entry: [sight]=pointer to sight data
; exit: -
;descr: overlays a sight picture to the screen. The picture must be in
; sight format {SIGHT-DATA}
_vid_drawsight PROC FAR
CBEG
call vidstart
ldspar si,0
zzz=1
REPT 4
local l1
mov dx,3c5h
mov al,zzz
out dx,al
mov cx,ds:[si]
add si,2
mov al,127
l1: mov di,ds:[si]
add si,2
mov es:[di],al
loop l1
zzz=zzz*2
ENDM
CEND
_vid_drawsight ENDP
include avidfill.asm
asm_code ENDS
END

BIN
VISU/AVID.OBJ Normal file

Binary file not shown.

704
VISU/AVIDFILL.ASM Normal file
View file

@ -0,0 +1,704 @@
;/****************************************************************************
;** MODULE: avidfill.asm
;** AUTHOR: Sami Tammilehto / Fennosoftec OY
;** DOCUMENT: ?
;** VERSION: 1.0
;** REFERENCE: -
;** REVISED BY: -
;*****************************************************************************
;**
;** Assembler / Video (polygon filling)
;**
;****************************************************************************/
;±±±±±±±± _vid_drawpolylist(...) ±±±±±±±±
;This call is obsolote. The correct call is to _draw_polylist.
_vid_drawpolylist PROC FAR
pop cx ;retoffset
pop dx ;retsegment
mov ax,0f001h
push ax ;oflags
push dx ;retsegment
push cx ;retoffset
jmp _draw_polylist ;draw.asm
_vid_drawpolylist ENDP
;±±±±±±±± _vid_drawfill(char *drawdata) ±±±±±±±±
;entry: [drawdata]=pointer to fill data stream
; exit: -
;descr: This routine fills a polygon on screen according to instructions in
; the data stream. The 'nrm' stands for normal = flat shaded polygon.
; Stream format: {FILL-DATA}
drawfill_progs LABEL WORD
dw OFFSET drawfill_nrm
dw OFFSET drawfill_grd
_vid_drawfill PROC FAR
CBEG
call vidstart
lfspar si,0
mov bx,ds:[si]
cmp bx,1
ja @@1
add bx,bx
add si,2
call drawfill_progs[bx]
@@1: CEND
_vid_drawfill ENDP
ALIGN 4
leftside db 1111b,1110b,1100b,1000b
rightside db 0001b,0011b,0111b,1111b
middledot db 0001b,0010b,0100b,1000b
ALIGN 16
vdf_leftx dd 0
vdf_lefta dd 0
vdf_rightx dd 0
vdf_righta dd 0
vdf_count dw 0
vdf_di dw 0
vdf_color db 0
ALIGN 16
vdfg_color1 dw 0
vdfg_color2 dw 0
vdfg_left dw 0
vdfg_right dw 0
vdfg_leftc dw 0 ;c & ca must be in this order for 32 bit
vdfg_leftca dw 0 ;data transfer (seek for [32])
vdfg_rightc dw 0
vdfg_rightca dw 0
vdfg_lefts dw 0
vdfg_left4 dw 0
vdfg_buf db MAXCOLS dup(0)
;±±±±±±±± drawfill_nrm ±±±±±±±±
;entry: DS:SI=pointer to {NORMAL-FILL-DATA} stream
; exit: -
drawfill_nrm PROC NEAR
mov ax,fs:[si]
mov cs:vdf_color,al
mov bx,fs:[si+2] ;StartY
add si,4
shl bx,1
mov ax,ds:_rows[bx]
mov cs:vdf_di,ax
;es:vdf_di=dest
jmp @@1
@@0: ret
@@1: mov ax,fs:[si]
add si,2
or ax,ax
js @@0
jz @@11
mov eax,fs:[si]
mov cs:vdf_leftx,eax
mov eax,fs:[si+4]
mov cs:vdf_lefta,eax
add si,8
@@11: mov ax,fs:[si]
add si,2
or ax,ax
js @@0
jz @@12
mov eax,fs:[si]
mov cs:vdf_rightx,eax
mov eax,fs:[si+4]
mov cs:vdf_righta,eax
add si,8
@@12: mov ax,fs:[si]
or ax,ax
jz @@0 ;ERROR
add si,2
mov cs:vdf_count,ax
mov di,cs:vdf_di
@@21: ;Fill loop
;;
mov eax,cs:vdf_lefta
add cs:vdf_leftx,eax
mov eax,cs:vdf_righta
add cs:vdf_rightx,eax
;
mov dx,word ptr cs:vdf_leftx[2]
mov ax,word ptr cs:vdf_rightx[2]
;dx=leftx, ax=rightx
;
cmp ax,dx
je @@20
jl @@22
xchg ax,dx
@@22: dec dx ;don't fill the rightmost pixel
mov bx,ax
sar bx,2
mov cx,dx
sar cx,2
sub cx,bx
add di,bx
mov bp,3
and bp,ax
mov bh,cs:leftside[bp]
mov bp,3
and bp,dx
mov bl,cs:rightside[bp]
mov dx,3c5h
;(di..si,bx)
cmp cx,0
je @@29 ;end and beg in same byte
;left side
mov al,bh
out dx,al
mov al,cs:vdf_color
mov es:[di],al
inc di
dec cx
mov ah,al
;middle
jcxz @@24
mov al,0fh
out dx,al
mov al,ah
mov bp,bx
call faststosb
mov bx,bp
@@24: ;right side
mov al,bl
out dx,al
mov al,ah
mov es:[di],al
jmp @@20
@@29: ;end and beg in same byte
mov al,bl
and al,bh
out dx,al
mov al,cs:vdf_color
mov es:[di],al
;;
@@20: mov di,cs:vdf_di
add di,ds:_rowlen
mov cs:vdf_di,di
dec cs:vdf_count
jnz @@21
jmp @@1
drawfill_nrm ENDP
;±±±±±±±± drawfill_grd ±±±±±±±±
;entry: DS:SI=pointer to {GOURAUD-FILL-DATA} stream
; exit: -
drawfill_grd PROC NEAR
mov bx,fs:[si+2] ;StartY
add si,4
shl bx,1
mov ax,ds:_rows[bx]
mov cs:vdf_di,ax
;es:vdf_di=dest
jmp @@1
@@0: ret
@@1: mov ax,fs:[si]
add si,2
or ax,ax
js @@0
jz @@11
mov eax,fs:[si] ;c&ca
mov dword ptr cs:vdfg_leftc,eax ;[32]
mov eax,fs:[si+4]
mov cs:vdf_leftx,eax
mov eax,fs:[si+8]
mov cs:vdf_lefta,eax
add si,12
@@11: mov ax,fs:[si]
add si,2
or ax,ax
js @@0
jz @@12
mov eax,fs:[si] ;c&ca
mov dword ptr cs:vdfg_rightc,eax ;[32]
mov eax,fs:[si+4]
mov cs:vdf_rightx,eax
mov eax,fs:[si+8]
mov cs:vdf_righta,eax
add si,12
@@12: mov ax,fs:[si]
or ax,ax
jz @@0 ;ERROR
add si,2
mov cs:vdf_count,ax
mov di,cs:vdf_di
@@21: ;Fill loop
;;
mov ax,cs:vdfg_leftca
add cs:vdfg_leftc,ax
mov ax,cs:vdfg_rightca
add cs:vdfg_rightc,ax
mov eax,cs:vdf_lefta
add cs:vdf_leftx,eax
mov eax,cs:vdf_righta
add cs:vdf_rightx,eax
;
mov dx,word ptr cs:vdf_leftx[2]
mov ax,word ptr cs:vdf_rightx[2]
mov bx,word ptr cs:vdfg_leftc
mov cx,word ptr cs:vdfg_rightc
;dx=leftx, ax=rightx
;
cmp ax,dx
je @@20
jl @@22
xchg bx,cx
xchg ax,dx
@@22: dec dx ;don't fill the rightmost pixel
mov cs:vdfg_color1,cx
mov cs:vdfg_color2,bx
mov cs:vdfg_left,ax
mov cs:vdfg_right,dx
;set endpoint colors
mov dx,3c5h
;end
mov bl,byte ptr cs:vdfg_right
test bl,1
jnz @@ef2
and bx,3
mov al,cs:middledot[bx]
out dx,al
mov bx,cs:vdfg_right
shr bx,2
add bx,di
mov al,byte ptr cs:vdfg_color2[1]
mov es:[bx],al
@@ef2: ;start
mov bl,byte ptr cs:vdfg_left
test bl,1
jz @@ef1
and bx,3
mov al,cs:middledot[bx]
out dx,al
mov bx,cs:vdfg_left
shr bx,2
add bx,di
mov al,byte ptr cs:vdfg_color1[1]
mov es:[bx],al
@@ef1: ;calc length & beg
mov ax,cs:vdfg_left
mov dx,cs:vdfg_right
inc ax
shr ax,1
mov cs:vdfg_lefts,ax
dec dx
shr dx,1
;
mov cx,ax
shr cx,1
add di,cx
;
mov cx,dx
sub cx,ax
inc cx ;cx=number of 2 byte blocks to fill
cmp cx,0
jg @@2f2
;ends only
jmp @@20
@@2f2:
push si
mov ax,cs:vdfg_color1
sub ax,cs:vdfg_color2
jge @@2f3
neg ax
mov bx,cx
add bx,bx
mul word ptr ds:_afilldiv[bx]
neg dx
jmp @@2f4
@@2f3: mov bx,cx
add bx,bx
mul word ptr ds:_afilldiv[bx]
@@2f4: mov si,cx
@@d0: ;dx=coloradder, cx=len (in 2 byte blocks)
cmp dx,128
jge gouraud12
cmp dx,-128
jle gouraud12
jmp gouraud4
gouraud12:
cmp dx,400
jge gouraud1
cmp dx,-400
jle gouraud1
jmp gouraud2
;----------------------------------------------------------------
gouraud1 PROC NEAR ;1 pixel accuray
sar dx,1
add cx,cx
;
mov ax,cx
shl cx,3
sub ax,cx
;ax=-cx*7
add ax,OFFSET @@vdfg_fcode
mov bx,cs:vdfg_color2
jmp ax
zzz=MAXCOLS
REPT MAXCOLS+1
add bx,dx ;2 bytes
mov cs:vdfg_buf[ (zzz and 3)*(MAXCOLS/4) + (zzz shr 2) ],bh ;5 bytes
zzz=zzz-1
ENDM
mov ax,bx ;2 bytes, 1 clock (filler)
@@vdfg_fcode:
push ds
mov ax,cs
mov ds,ax
mov cx,si
add cx,cx
;
@@f1: mov al,00010001b
test cs:vdfg_lefts,1
jz @@f2
mov al,01000100b
@@f2: ;
zzz=0
add cx,3
REPT 4
local l1
push cx
shr cx,2
jz l1
push ax
push di
mov dx,3c5h
out dx,al
mov si,OFFSET vdfg_buf+zzz*(MAXCOLS/4)
call fastmovsb
pop di
pop ax
l1: pop cx
dec cx
rol al,1
adc di,0
zzz=zzz+1
ENDM
;
@@f0: pop ds
pop si
jmp zzz20
gouraud1 ENDP
;----------------------------------------------------------------
gouraud2 PROC NEAR ;2 pixel accuray
mov ax,cx
shl cx,3
sub ax,cx
;ax=-cx*7
add ax,OFFSET @@vdfg_fcode
mov bx,cs:vdfg_color2
jmp ax
zzz=MAXCOLS
REPT MAXCOLS+1
add bx,dx ;2 bytes
mov cs:vdfg_buf[ (zzz and 1)*(MAXCOLS/2) + (zzz shr 1) ],bh ;5 bytes
zzz=zzz-1
ENDM
mov ax,bx ;2 bytes, 1 clock (filler)
@@vdfg_fcode:
push ds
mov ax,cs
mov ds,ax
mov cx,si
jcxz @@f0
;
@@f1: mov al,00110011b
test cs:vdfg_lefts,1
jz @@f2
mov al,11001100b
@@f2: ;
mov si,OFFSET vdfg_buf
push cx
push di
push ax
inc cx
shr cx,1
mov dx,3c5h
out dx,al
call fastmovsb
pop ax
pop di
pop cx
rol al,2
jnc @@f3
inc di
@@f3: mov si,OFFSET vdfg_buf+MAXCOLS/2
shr cx,1
jz @@f0
mov dx,3c5h
out dx,al
call fastmovsb
;
@@f0: pop ds
pop si
jmp zzz20
gouraud2 ENDP
;----------------------------------------------------------------
gouraud4 PROC NEAR ;4 pixel accuray
cmp cx,4
jl gouraud2
sal dx,1
;
mov cs:vdfg_left4,cx
shr cx,1 ;rescale
inc cx ;one extra
mov ax,cx
shl cx,3
sub ax,cx
;ax=-cx*7
add ax,OFFSET @@vdfg_fcode
mov bx,cs:vdfg_color2
sub bx,dx ;one extra
jmp ax
zzz=MAXCOLS
REPT MAXCOLS+1
add bx,dx ;2 bytes
mov cs:vdfg_buf[zzz],bh ;5 bytes
zzz=zzz-1
ENDM
mov ax,bx ;2 bytes, 1 clock (filler)
@@vdfg_fcode:
push ds
mov dx,cs
mov ds,dx
mov cx,si
;
@@f1: mov si,OFFSET vdfg_buf
test cs:vdfg_lefts,1
jnz @@f3
inc cx
@@f4: shr cx,1
jnc @@f5
mov dx,3c5h
mov al,0fh
out dx,al
call fastmovsb
@@f0: pop ds
pop si
jmp zzz20
@@f5: dec cx
mov dx,3c5h
mov al,0fh
out dx,al
call fastmovsb
mov dx,3c5h
mov al,03h
out dx,al
movsb
pop ds
pop si
jmp zzz20
@@f3: mov dx,3c5h
mov al,0ch
out dx,al
movsb
jmp @@f4
gouraud4 ENDP
;----------------------------------------------------------------
zzz20: ;;
@@20: mov di,cs:vdf_di
add di,ds:_rowlen
mov cs:vdf_di,di
dec cs:vdf_count
jnz @@21
jmp @@1
drawfill_grd ENDP
;±±±±±±±± fastmovsb ±±±±±±±±
;entry: DS:SI=pointer to source data
; ES:DI=pointer to destination (screen)
; CX=number of bytes to copy (MUST BE <512*4)
;exit: copies data like REP MOVSB but uses 32 bit moves and aligns
; destination to dword boundary.
ALIGN 16
fastmovsb_bt LABEL WORD
dw OFFSET fastmovsb_b0
dw OFFSET fastmovsb_b1
dw OFFSET fastmovsb_b2
dw OFFSET fastmovsb_b3
fastmovsb_b1:
mov al,ds:[si]
sub cx,3
mov es:[di],al
mov ax,ds:[si+1]
add si,3
mov es:[di+1],ax
add di,3
jmp fastmovsb_b0
fastmovsb_b2:
mov ax,ds:[si]
sub cx,2
add si,2
mov es:[di],ax
add di,2
jmp fastmovsb_b0
fastmovsb_b3:
mov al,ds:[si]
dec cx
inc si
mov es:[di],al
inc di
jmp fastmovsb_b0
ALIGN 16
fastmovsb_et LABEL WORD
dw OFFSET fastmovsb_e0
dw OFFSET fastmovsb_e1
dw OFFSET fastmovsb_e2
dw OFFSET fastmovsb_e3
fastmovsb_e1:
mov al,ds:[si]
inc si
mov es:[di],al
inc di
ret
fastmovsb_e3:
mov ax,ds:[si]
mov es:[di],ax
mov al,ds:[si+2]
add si,3
mov es:[di+2],al
add di,3
ret
fastmovsb_e2:
mov ax,ds:[si]
add si,2
mov es:[di],ax
add di,2
fastmovsb_e0:
ret
ALIGN 16
fastmovsb PROC NEAR
;copies CX bytes of data from DS:SI to ES:DI aligning destination
;si/di will point to the correct position after this (cx won't)
cmp cx,4
jb @@4
mov bx,di
and bx,3
add bx,bx
jmp fastmovsb_bt[bx]
fastmovsb_b0:
mov bx,cx
add bx,bx
add bx,bx
and bx,not 15
neg bx
;bx=-cx*8
add bx,OFFSET @@jmp
jmp bx
REPT 512
db 66h,8bh,84h,00h,00h ;mov eax,ds:[si+0000h]
db 83h,0c6h,04h ;add si,4
db 66h,26h,89h,05h ;mov es:[di],eax
db 81h,0c7h,04h,00h ;add di,0004h
ENDM ;total 16 bytes
@@jmp: mov bx,cx
and bx,3
add bx,bx
jmp fastmovsb_et[bx]
@@4: mov bx,cx
add bx,bx
jmp fastmovsb_et[bx]
fastmovsb ENDP
;±±±±±±±± faststosb ±±±±±±±±
;entry: ES:DI=pointer to destination (screen)
; AX=word fill (lo/hi byte MUST be same)
; CX=number of bytes to fill (MUST BE <512*4)
;exit: fills data like REP STOSB but uses 32 bit moves and aligns
; destination to dword boundary.
; NOTE: BX modified
ALIGN 16
faststosb_bt LABEL WORD
dw OFFSET faststosb_b0
dw OFFSET faststosb_b1
dw OFFSET faststosb_b2
dw OFFSET faststosb_b3
faststosb_b1:
mov es:[di],al
sub cx,3
mov es:[di+1],ax
add di,3
jmp faststosb_b0
faststosb_b2:
sub cx,2
mov es:[di],ax
add di,2
jmp faststosb_b0
faststosb_b3:
dec cx
mov es:[di],al
inc di
jmp faststosb_b0
ALIGN 16
faststosb_et LABEL WORD
dw OFFSET faststosb_e0
dw OFFSET faststosb_e1
dw OFFSET faststosb_e2
dw OFFSET faststosb_e3
faststosb_e1:
mov es:[di],al
inc di
ret
faststosb_e3:
mov es:[di],ax
mov es:[di+2],al
add di,3
ret
faststosb_e2:
mov es:[di],ax
add di,2
faststosb_e0:
ret
ALIGN 16
faststosb PROC NEAR
;fills CX bytes of data with AX to ES:DI aligning destination
;di will point to the correct position after this (cx won't)
cmp cx,4
jb @@4
mov bx,di
and bx,3
add bx,bx
jmp faststosb_bt[bx]
faststosb_b0:
mov bx,ax
shl eax,16
mov ax,bx
;eax=filler
mov bx,cx
add bx,bx
and bx,not 7
neg bx
;bx=-cx*8
add bx,OFFSET @@jmp
jmp bx
REPT 512
db 66h,26h,89h,05h ;mov es:[di],eax
db 81h,0c7h,04h,00h ;add di,0004h
ENDM ;total 8 bytes
@@jmp: mov bx,cx
and bx,3
add bx,bx
jmp faststosb_et[bx]
@@4: mov bx,cx
add bx,bx
jmp faststosb_et[bx]
faststosb ENDP

708
VISU/AVIDFILL.OK Normal file
View file

@ -0,0 +1,708 @@
;/****************************************************************************
;** MODULE: avidfill.asm
;** AUTHOR: Sami Tammilehto / Fennosoftec OY
;** DOCUMENT: ?
;** VERSION: 1.0
;** REFERENCE: -
;** REVISED BY: -
;*****************************************************************************
;**
;** Assembler / Video (polygon filling)
;**
;****************************************************************************/
;±±±±±±±± _vid_drawpolylist(...) ±±±±±±±±
;This call is obsolote. The correct call is to _draw_polylist.
_vid_drawpolylist PROC FAR
pop cx ;retoffset
pop dx ;retsegment
mov ax,0f001h
push ax ;oflags
push dx ;retsegment
push cx ;retoffset
jmp _draw_polylist ;draw.asm
_vid_drawpolylist ENDP
;±±±±±±±± _vid_drawfill(char *drawdata) ±±±±±±±±
;entry: [drawdata]=pointer to fill data stream
; exit: -
;descr: This routine fills a polygon on screen according to instructions in
; the data stream. The 'nrm' stands for normal = flat shaded polygon.
; Stream format: {FILL-DATA}
drawfill_progs LABEL WORD
dw OFFSET drawfill_nrm
dw OFFSET drawfill_grd
_vid_drawfill PROC FAR
CBEG
call vidstart
lfspar si,0
mov bx,ds:[si]
cmp bx,1
ja @@1
add bx,bx
add si,2
call drawfill_progs[bx]
@@1: CEND
_vid_drawfill ENDP
ALIGN 4
leftside db 1111b,1110b,1100b,1000b
rightside db 0001b,0011b,0111b,1111b
middledot db 0001b,0010b,0100b,1000b
ALIGN 16
vdf_leftx dd 0
vdf_lefta dd 0
vdf_rightx dd 0
vdf_righta dd 0
vdf_count dw 0
vdf_di dw 0
vdf_color db 0
ALIGN 16
vdfg_color1 dw 0
vdfg_color2 dw 0
vdfg_left dw 0
vdfg_right dw 0
vdfg_leftc dw 0 ;c & ca must be in this order for 32 bit
vdfg_leftca dw 0 ;data transfer (seek for [32])
vdfg_rightc dw 0
vdfg_rightca dw 0
vdfg_lefts dw 0
vdfg_left4 dw 0
vdfg_buf db MAXCOLS dup(0)
;±±±±±±±± drawfill_nrm ±±±±±±±±
;entry: DS:SI=pointer to {NORMAL-FILL-DATA} stream
; exit: -
drawfill_nrm PROC NEAR
mov ax,fs:[si]
mov cs:vdf_color,al
mov bx,fs:[si+2] ;StartY
add si,4
shl bx,1
mov ax,ds:_rows[bx]
mov cs:vdf_di,ax
;es:vdf_di=dest
jmp @@1
@@0: ret
@@1: mov ax,fs:[si]
add si,2
or ax,ax
js @@0
jz @@11
mov eax,fs:[si]
mov cs:vdf_leftx,eax
mov eax,fs:[si+4]
mov cs:vdf_lefta,eax
add si,8
@@11: mov ax,fs:[si]
add si,2
or ax,ax
js @@0
jz @@12
mov eax,fs:[si]
mov cs:vdf_rightx,eax
mov eax,fs:[si+4]
mov cs:vdf_righta,eax
add si,8
@@12: mov ax,fs:[si]
or ax,ax
jz @@0 ;ERROR
add si,2
mov cs:vdf_count,ax
mov di,cs:vdf_di
@@21: ;Fill loop
;;
mov eax,cs:vdf_lefta
add cs:vdf_leftx,eax
mov eax,cs:vdf_righta
add cs:vdf_rightx,eax
;
mov dx,word ptr cs:vdf_leftx[2]
mov ax,word ptr cs:vdf_rightx[2]
;dx=leftx, ax=rightx
;
cmp ax,dx
je @@20
jl @@22
xchg ax,dx
@@22: dec dx ;don't fill the rightmost pixel
mov bx,ax
sar bx,2
mov cx,dx
sar cx,2
sub cx,bx
add di,bx
mov bp,3
and bp,ax
mov bh,cs:leftside[bp]
mov bp,3
and bp,dx
mov bl,cs:rightside[bp]
mov dx,3c5h
;(di..si,bx)
cmp cx,0
je @@29 ;end and beg in same byte
;left side
mov al,bh
out dx,al
mov al,cs:vdf_color
stosb
dec cx
mov ah,al
;middle
jcxz @@24
mov al,0fh
out dx,al
cmp cx,8
jae @@23 ;fill >=8 pixels, do dword align
mov al,ah
shr cx,1
rep stosw
adc cx,cx
rep stosb
jmp @@24
@@23: mov al,ah
mov bp,ax
shl eax,16
mov ax,bp
;align
test di,3
jz @@25
stosb
dec cx
test di,3
jz @@25
stosb
dec cx
test di,3
jz @@25
stosb
dec cx
@@25: mov bp,cx
shr cx,2
rep stosd ;fill
mov cx,3
and cx,bp
rep stosb ;fill rest
@@24: ;right side
mov al,bl
out dx,al
mov al,ah
mov es:[di],al
jmp @@20
@@29: ;end and beg in same byte
mov al,bl
and al,bh
out dx,al
mov al,cs:vdf_color
mov es:[di],al
;;
@@20: mov di,cs:vdf_di
add di,ds:_rowlen
mov cs:vdf_di,di
dec cs:vdf_count
jnz @@21
jmp @@1
drawfill_nrm ENDP
;±±±±±±±± drawfill_grd ±±±±±±±±
;entry: DS:SI=pointer to {GOURAUD-FILL-DATA} stream
; exit: -
drawfill_grd PROC NEAR
mov bx,fs:[si+2] ;StartY
add si,4
shl bx,1
mov ax,ds:_rows[bx]
mov cs:vdf_di,ax
;es:vdf_di=dest
jmp @@1
@@0: ret
@@1: mov ax,fs:[si]
add si,2
or ax,ax
js @@0
jz @@11
mov eax,fs:[si] ;c&ca
mov dword ptr cs:vdfg_leftc,eax ;[32]
mov eax,fs:[si+4]
mov cs:vdf_leftx,eax
mov eax,fs:[si+8]
mov cs:vdf_lefta,eax
add si,12
@@11: mov ax,fs:[si]
add si,2
or ax,ax
js @@0
jz @@12
mov eax,fs:[si] ;c&ca
mov dword ptr cs:vdfg_rightc,eax ;[32]
mov eax,fs:[si+4]
mov cs:vdf_rightx,eax
mov eax,fs:[si+8]
mov cs:vdf_righta,eax
add si,12
@@12: mov ax,fs:[si]
or ax,ax
jz @@0 ;ERROR
add si,2
mov cs:vdf_count,ax
mov di,cs:vdf_di
@@21: ;Fill loop
;;
mov ax,cs:vdfg_leftca
add cs:vdfg_leftc,ax
mov ax,cs:vdfg_rightca
add cs:vdfg_rightc,ax
mov eax,cs:vdf_lefta
add cs:vdf_leftx,eax
mov eax,cs:vdf_righta
add cs:vdf_rightx,eax
;
mov dx,word ptr cs:vdf_leftx[2]
mov ax,word ptr cs:vdf_rightx[2]
mov bx,word ptr cs:vdfg_leftc
mov cx,word ptr cs:vdfg_rightc
;dx=leftx, ax=rightx
;
cmp ax,dx
je @@20
jl @@22
xchg bx,cx
xchg ax,dx
@@22: dec dx ;don't fill the rightmost pixel
mov cs:vdfg_color1,cx
mov cs:vdfg_color2,bx
mov cs:vdfg_left,ax
mov cs:vdfg_right,dx
;set endpoint colors
mov dx,3c5h
;end
mov bl,byte ptr cs:vdfg_right
test bl,1
jnz @@ef2
and bx,3
mov al,cs:middledot[bx]
out dx,al
mov bx,cs:vdfg_right
shr bx,2
add bx,di
mov al,byte ptr cs:vdfg_color2[1]
mov es:[bx],al
@@ef2: ;start
mov bl,byte ptr cs:vdfg_left
test bl,1
jz @@ef1
and bx,3
mov al,cs:middledot[bx]
out dx,al
mov bx,cs:vdfg_left
shr bx,2
add bx,di
mov al,byte ptr cs:vdfg_color1[1]
mov es:[bx],al
@@ef1: ;calc length & beg
mov ax,cs:vdfg_left
mov dx,cs:vdfg_right
inc ax
shr ax,1
mov cs:vdfg_lefts,ax
dec dx
shr dx,1
;
mov cx,ax
shr cx,1
add di,cx
;
mov cx,dx
sub cx,ax
inc cx ;cx=number of 2 byte blocks to fill
cmp cx,0
jg @@2f2
;ends only
jmp @@20
@@2f2:
push si
mov ax,cs:vdfg_color1
sub ax,cs:vdfg_color2
jge @@2f3
neg ax
mov bx,cx
add bx,bx
mul word ptr ds:_afilldiv[bx]
neg dx
jmp @@2f4
@@2f3: mov bx,cx
add bx,bx
mul word ptr ds:_afilldiv[bx]
@@2f4: mov si,cx
@@d0: ;dx=coloradder, cx=len (in 2 byte blocks)
cmp dx,128
jge gouraud12
cmp dx,-128
jle gouraud12
jmp gouraud4
gouraud12:
cmp dx,400
jge gouraud1
cmp dx,-400
jle gouraud1
jmp gouraud2
;----------------------------------------------------------------
gouraud1 PROC NEAR ;1 pixel accuray
sar dx,1
add cx,cx
;
mov ax,cx
shl cx,3
sub ax,cx
;ax=-cx*7
add ax,OFFSET @@vdfg_fcode
mov bx,cs:vdfg_color2
jmp ax
zzz=MAXCOLS
REPT MAXCOLS+1
add bx,dx ;2 bytes
mov cs:vdfg_buf[ (zzz and 3)*(MAXCOLS/4) + (zzz shr 2) ],bh ;5 bytes
zzz=zzz-1
ENDM
mov ax,bx ;2 bytes, 1 clock (filler)
@@vdfg_fcode:
push ds
mov ax,cs
mov ds,ax
mov cx,si
add cx,cx
;
@@f1: mov al,00010001b
test cs:vdfg_lefts,1
jz @@f2
mov al,01000100b
@@f2: ;
zzz=0
add cx,3
REPT 4
local l1
push cx
shr cx,2
jz l1
push ax
push di
mov dx,3c5h
out dx,al
mov si,OFFSET vdfg_buf+zzz*(MAXCOLS/4)
call fastmovsb
pop di
pop ax
l1: pop cx
dec cx
rol al,1
adc di,0
zzz=zzz+1
ENDM
;
@@f0: pop ds
pop si
jmp zzz20
gouraud1 ENDP
;----------------------------------------------------------------
gouraud2 PROC NEAR ;2 pixel accuray
mov ax,cx
shl cx,3
sub ax,cx
;ax=-cx*7
add ax,OFFSET @@vdfg_fcode
mov bx,cs:vdfg_color2
jmp ax
zzz=MAXCOLS
REPT MAXCOLS+1
add bx,dx ;2 bytes
mov cs:vdfg_buf[ (zzz and 1)*(MAXCOLS/2) + (zzz shr 1) ],bh ;5 bytes
zzz=zzz-1
ENDM
mov ax,bx ;2 bytes, 1 clock (filler)
@@vdfg_fcode:
push ds
mov ax,cs
mov ds,ax
mov cx,si
jcxz @@f0
;
@@f1: mov al,00110011b
test cs:vdfg_lefts,1
jz @@f2
mov al,11001100b
@@f2: ;
mov si,OFFSET vdfg_buf
push cx
push di
push ax
inc cx
shr cx,1
mov dx,3c5h
out dx,al
call fastmovsb
pop ax
pop di
pop cx
rol al,2
jnc @@f3
inc di
@@f3: mov si,OFFSET vdfg_buf+MAXCOLS/2
shr cx,1
jz @@f0
mov dx,3c5h
out dx,al
call fastmovsb
;
@@f0: pop ds
pop si
jmp zzz20
gouraud2 ENDP
;----------------------------------------------------------------
gouraud4 PROC NEAR ;4 pixel accuray
cmp cx,4
jl gouraud2
sal dx,1
;
mov cs:vdfg_left4,cx
shr cx,1 ;rescale
inc cx ;one extra
mov ax,cx
shl cx,3
sub ax,cx
;ax=-cx*7
add ax,OFFSET @@vdfg_fcode
mov bx,cs:vdfg_color2
sub bx,dx ;one extra
jmp ax
zzz=MAXCOLS
REPT MAXCOLS+1
add bx,dx ;2 bytes
mov cs:vdfg_buf[zzz],bh ;5 bytes
zzz=zzz-1
ENDM
mov ax,bx ;2 bytes, 1 clock (filler)
@@vdfg_fcode:
push ds
mov dx,cs
mov ds,dx
mov cx,si
;
@@f1: mov si,OFFSET vdfg_buf
test cs:vdfg_lefts,1
jnz @@f3
inc cx
@@f4: shr cx,1
jnc @@f5
mov dx,3c5h
mov al,0fh
out dx,al
call fastmovsb
@@f0: pop ds
pop si
jmp zzz20
@@f5: dec cx
mov dx,3c5h
mov al,0fh
out dx,al
call fastmovsb
mov dx,3c5h
mov al,03h
out dx,al
movsb
pop ds
pop si
jmp zzz20
@@f3: mov dx,3c5h
mov al,0ch
out dx,al
movsb
jmp @@f4
gouraud4 ENDP
;----------------------------------------------------------------
zzz20: ;;
@@20: mov di,cs:vdf_di
add di,ds:_rowlen
mov cs:vdf_di,di
dec cs:vdf_count
jnz @@21
jmp @@1
drawfill_grd ENDP
;±±±±±±±± fastmovsb ±±±±±±±±
;entry: DS:SI=pointer to source data
; ES:DI=pointer to destination (screen)
; CX=number of bytes to copy
;exit: copies data like REP MOVSB but uses 32 bit moves and aligns
; destination to dword boundary.
ALIGN 16
fastmovsb_bt LABEL WORD
dw OFFSET fastmovsb_b0
dw OFFSET fastmovsb_b1
dw OFFSET fastmovsb_b2
dw OFFSET fastmovsb_b3
fastmovsb_b1:
mov al,ds:[si]
sub cx,3
mov es:[di],al
mov ax,ds:[si+1]
add si,3
mov es:[di+1],ax
add di,3
jmp fastmovsb_b0
fastmovsb_b2:
mov ax,ds:[si]
sub cx,2
add si,2
mov es:[di],ax
add di,2
jmp fastmovsb_b0
fastmovsb_b3:
mov al,ds:[si]
dec cx
inc si
mov es:[di],al
inc di
jmp fastmovsb_b0
;;
ALIGN 16
fastmovsb_et LABEL WORD
dw OFFSET fastmovsb_e0
dw OFFSET fastmovsb_e1
dw OFFSET fastmovsb_e2
dw OFFSET fastmovsb_e3
fastmovsb_e1:
mov al,ds:[si]
inc si
mov es:[di],al
inc di
ret
fastmovsb_e3:
mov ax,ds:[si]
mov es:[di],ax
mov al,ds:[si+2]
add si,3
mov es:[di+2],al
add di,3
ret
fastmovsb_e2:
mov ax,ds:[si]
add si,2
mov es:[di],ax
add di,2
fastmovsb_e0:
ret
;;
ALIGN 16
fastmovsb PROC NEAR
;copies CX bytes of data from DS:SI to ES:DI aligning destination
;si/di will point to the correct position after this (cx won't)
cmp cx,4
jb @@4
mov bx,di
and bx,3
add bx,bx
jmp fastmovsb_bt[bx]
fastmovsb_b0:
mov bx,cx
and bx,3
add bx,bx
shr cx,2
rep movsd
jmp fastmovsb_et[bx]
@@4: mov bx,cx
add bx,bx
jmp fastmovsb_et[bx]
fastmovsb ENDP
;±±±±±±±± faststosb ±±±±±±±±
;entry: ES:DI=pointer to destination (screen)
; EAX=dword fill (all bytes MUST be same)
; CX=number of bytes to fill††
;exit: fills data like REP STOSB but uses 32 bit moves and aligns
; destination to dword boundary.
ALIGN 16
faststosb_bt LABEL WORD
dw OFFSET faststosb_b0
dw OFFSET faststosb_b1
dw OFFSET faststosb_b2
dw OFFSET faststosb_b3
faststosb_b1:
sub cx,3
mov es:[di],al
mov es:[di+1],ax
add di,3
jmp faststosb_b0
faststosb_b2:
sub cx,2
mov es:[di],ax
add di,2
jmp faststosb_b0
faststosb_b3:
dec cx
mov es:[di],al
inc di
jmp faststosb_b0
;;
ALIGN 16
faststosb_et LABEL WORD
dw OFFSET faststosb_e0
dw OFFSET faststosb_e1
dw OFFSET faststosb_e2
dw OFFSET faststosb_e3
faststosb_e1:
mov es:[di],al
inc di
ret
faststosb_e3:
mov es:[di],ax
mov es:[di+2],al
add di,3
ret
faststosb_e2:
mov es:[di],ax
add di,2
faststosb_e0:
ret
;;
ALIGN 16
faststosb PROC NEAR
;fills CX bytes of data with AX to ES:DI aligning destination
;di will point to the correct position after this (cx won't)
cmp cx,4
jb @@4
mov bx,di
and bx,3
add bx,bx
jmp faststosb_bt[bx]
faststosb_b0:
mov bx,cx
and bx,3
add bx,bx
shr cx,2
rep movsd
jmp faststosb_et[bx]
@@4: mov bx,cx
add bx,bx
jmp faststosb_et[bx]
faststosb ENDP

282
VISU/AVIDM1.ASM Normal file
View file

@ -0,0 +1,282 @@
;/****************************************************************************
;** MODULE: avidm1.asm
;** AUTHOR: Sami Tammilehto / Fennosoftec OY
;** DOCUMENT: ?
;** VERSION: 1.0
;** REFERENCE: -
;** REVISED BY: -
;*****************************************************************************
;**
;** Video driver for 320x200x256 (tweak)
;** included to avid.asm
;**
;****************************************************************************/
;======== public routines ========
m1_init PROC NEAR
mov ds:_vramseg,0a000h
call tweak320x200
mov dx,320/4
mov cx,200
call setrows
mov ds:vr[PSET],OFFSET m1_pset
mov ds:vr[CLEAR],OFFSET m1_clear
mov ds:vr[SWITCH],OFFSET m1_switch
mov ds:vr[WAITB],OFFSET m1_waitb
mov ds:_projclipz[CLIPMIN],256
mov ds:_projclipz[CLIPMAX],1000000000
;these affected by oversampling
mov ds:_projclipx[CLIPMIN],0
mov ds:_projclipx[CLIPMAX],319
mov ds:_projclipy[CLIPMIN],0
mov ds:_projclipy[CLIPMAX],199
mov ds:_projmulx,250
mov ds:_projmuly,220
mov ds:_projaddx,160
mov ds:_projaddy,100
mov ds:_projoversampleshr,0
;
mov ds:_projaspect,225
ret
m1_init ENDP
m11_init PROC NEAR
mov ds:_vramseg,0a000h
; call tweak320x200
mov dx,320/4
mov cx,200
call setrows
mov ds:vr[PSET],OFFSET m1_pset
mov ds:vr[CLEAR],OFFSET m1_clear
mov ds:vr[SWITCH],OFFSET m1_switch
mov ds:vr[WAITB],OFFSET m1_waitb
mov ds:_projclipz[CLIPMIN],256
mov ds:_projclipz[CLIPMAX],1000000000
;these affected by oversampling
mov ds:_projclipx[CLIPMIN],0
mov ds:_projclipx[CLIPMAX],319
mov ds:_projclipy[CLIPMIN],0
mov ds:_projclipy[CLIPMAX],199
mov ds:_projmulx,250
mov ds:_projmuly,220
mov ds:_projaddx,160
mov ds:_projaddy,100
mov ds:_projoversampleshr,0
;
mov ds:_projaspect,225
ret
m11_init ENDP
m1o_init PROC NEAR ;oversampling version
mov ds:_vramseg,0a000h
;call tweak320x200
mov dx,320/4
mov cx,200
call setrows
mov ds:vr[PSET],OFFSET m1_pset
mov ds:vr[CLEAR],OFFSET m1_clear
mov ds:vr[SWITCH],OFFSET m1_switch
mov ds:vr[WAITB],OFFSET m1_waitb
mov ds:_projclipz[CLIPMIN],256
mov ds:_projclipz[CLIPMAX],1000000000
;these affected by oversampling
mov ds:_projclipx[CLIPMIN],0
mov ds:_projclipx[CLIPMAX],319
mov ds:_projclipy[CLIPMIN],0
mov ds:_projclipy[CLIPMAX],199
mov ds:_projmulx,250
mov ds:_projmuly,220
mov ds:_projaddx,160
mov ds:_projaddy,100
mov ds:_projoversampleshr,0
;
mov ds:_projaspect,225
ret
m1o_init ENDP
;======== public routines called through the vr[] pointers ========
;dx=X, bx=Y, ah=color
m1_pset PROC NEAR
;requires ES=vram, OUT 3C4,2 [set by vidstart]
shl bx,1
mov bx,ds:_rows[bx]
mov cx,3
and cx,dx
sar dx,2
add bx,dx
mov al,1
shl al,cl
mov dx,3c5h
out dx,al
mov es:[bx],ah
ret
m1_pset ENDP
m1_waitb PROC NEAR
mov dx,3dah
@@1: in al,dx
test al,8
jnz @@1
@@2: in al,dx
test al,8
jz @@2
ret
m1_waitb ENDP
m1_clear PROC NEAR ;clear current page
push di
cmp ax,9
je @@bgd
cmp ax,2
je @@bgc
mov dx,3c4h
mov ax,0f02h
out dx,ax
xor di,di
xor eax,eax
mov cx,200
@@1: REPT 320/4/4
mov es:[di],eax
add di,4
ENDM
dec cx
jnz @@1
pop di
ret
@@bgd: mov dx,3c4h
mov ax,0f02h
out dx,ax
xor di,di
mov eax,0ffffffffh
mov cx,200
@@9: REPT 320/4/4
mov es:[di],eax
add di,4
ENDM
dec cx
jnz @@9
pop di
ret
@@bgc: zzpl=1
push ds
mov ax,fs
mov ds,ax
REPT 4
local l1
push di
mov dx,3c4h
mov ax,02h+100h*zzpl
out dx,ax
xor di,di
xor eax,eax
mov cx,200
l1: REPT 320/4/4
mov eax,ds:[si]
add si,4
mov es:[di],eax
add di,4
ENDM
loop l1
pop di
zzpl=zzpl*2
ENDM
pop ds
pop di
ret
m1_clear ENDP
m1_switch PROC NEAR
mov ax,ds:_vramseg
cmp ax,0a140h
jne @@1
;---[
mov ds:_vramseg,0a5f0h
mov ah,014h
;---]
jmp @@0
@@1: cmp ax,0a5f0h
jne @@2
;---[
mov ds:_vramseg,0aaa0h
mov ah,05fh
;---]
jmp @@0
@@2: ;---[
mov ds:_vramseg,0a140h
mov ah,0aah
;---]
@@0: mov dx,3d4h
mov al,0ch
out dx,ax
ret
m1_switch ENDP
;======== internal routines ========
;sets up 320x200x256 tweak
tweak320x200 PROC NEAR
mov ax,0013h
int 10h
mov dx,3c8h
mov al,0
out dx,al
inc dx
mov cx,768
@@1: out dx,al
loop @@1
mov dx,3c4h
mov al,4
out dx,al
inc dx
in al,dx
and al,not 08h
or al,04h
out dx,al
mov dx,3ceh
mov al,5
out dx,al
inc dx
in al,dx
and al,not 10h
out dx,al
dec dx
mov al,6
out dx,al
inc dx
in al,dx
and al,not 02h
out dx,al
mov dx,3d4h
mov al,9
inc dx
and al,not 5fh
or al,1
dec dx
mov al,14h
out dx,al
inc dx
in al,dx
and al,not 40h
out dx,al
dec dx
mov al,17h
out dx,al
inc dx
in al,dx
or al,40h
out dx,al
;clear vram
mov dx,3c4h
mov ax,0f02h
out dx,ax
mov cx,32768
mov ax,ds:_vramseg
mov es,ax
xor di,di
xor ax,ax
rep stosw
ret
tweak320x200 ENDP

272
VISU/AVIDM2.ASM Normal file
View file

@ -0,0 +1,272 @@
;/****************************************************************************
;** MODULE: avidm2.asm
;** AUTHOR: Sami Tammilehto / Fennosoftec OY
;** DOCUMENT: ?
;** VERSION: 1.0
;** REFERENCE: -
;** REVISED BY: -
;*****************************************************************************
;**
;** Video driver for 640x400x256 (tweak)
;** included to avid.asm
;**
;****************************************************************************/
;======== public routines ========
m2_init PROC NEAR
mov ds:_vramseg,0a000h
call tweak640x400
mov dx,640/4
mov cx,400
call setrows
mov ds:vr[PSET],OFFSET m2_pset
mov ds:vr[CLEAR],OFFSET m2_clear
mov ds:vr[SWITCH],OFFSET m2_switch
mov ds:vr[WAITB],OFFSET m2_waitb
mov ds:_projclipx[CLIPMIN],0
mov ds:_projclipx[CLIPMAX],639
mov ds:_projclipy[CLIPMIN],0
mov ds:_projclipy[CLIPMAX],399
mov ds:_projclipz[CLIPMIN],512*1
mov ds:_projclipz[CLIPMAX],1000000000
mov ds:_projmulx,480*1
mov ds:_projmuly,400*1
mov ds:_projaddx,320
mov ds:_projaddy,200
mov ds:_projaspect,256
ret
m2_init ENDP
;======== public routines called through the vr[] pointers ========
;dx=X, bx=Y, ah=color
m2_pset PROC NEAR
;requires ES=vram, OUT 3C4,2 [set by vidstart]
shl bx,1
mov bx,ds:_rows[bx]
mov cx,3
and cx,dx
sar dx,2
add bx,dx
mov al,1
shl al,cl
mov dx,3c5h
out dx,al
mov es:[bx],ah
ret
m2_pset ENDP
m2_waitb PROC NEAR
mov dx,3dah
@@1: in al,dx
test al,8
jnz @@1
@@2: in al,dx
test al,8
jz @@2
ret
m2_waitb ENDP
ALIGN 2
tmptest dw 0
m2_clear PROC NEAR ;clear current page
inc cs:tmptest
push di
cmp ax,1
je @@sky
mov dx,3c4h
mov ax,0f02h
out dx,ax
mov cx,640*400/4/4
xor di,di
xor eax,eax
rep stosd
pop di
ret
@@sky: mov dx,3c4h
mov ax,0f02h
out dx,ax
mov cx,400
xor di,di
@@1: mov al,fs:[si]
cmp al,1
je @@colr
cmp al,2
je @@bitm
cmp al,4
je @@depth
jmp @@noth
@@depth:
push si
push ds
mov dx,3c4h
mov ax,0f02h
out dx,ax
mov ax,fs:[si+2]
xor dx,dx
mov bx,320
div bx
lds ax,fs:[si+4]
mov si,ax
add si,dx
zzz=0;
REPT 640/4/4
mov eax,ds:[si+zzz]
mov es:[di+zzz],eax
zzz=zzz+4
ENDM
pop ds
pop si
jmp @@noth
@@colr: mov al,fs:[si+2]
mov ah,al
mov bx,ax
shl eax,16
mov ax,bx
zzz=0;
REPT 640/4/4
mov es:[di+zzz],eax
zzz=zzz+4
ENDM
jmp @@noth
@@bitm: push cx
push ds
push si
@@bc: lds ax,fs:[si+4]
mov si,ax
mov ax,cs:tmptest
mov dx,ax
shr dx,2
add si,dx
and ax,3
shl ax,11
add si,ax
mov cx,4
mov ax,0102h
@@b1: push ax
mov dx,3c4h
out dx,ax
zzz=0
REPT 640/4/4
mov eax,ds:[si+zzz]
mov es:[di+zzz],eax
zzz=zzz+4
ENDM
add si,2048
cmp si,8192
jb @@b3
sub si,8192-1
@@b3: pop ax
shl ah,1
loop @@b1
pop si
pop ds
pop cx
mov dx,3c4h
mov ax,0f02h
out dx,ax
jmp @@noth
@@noth: add di,640/4
add si,8
loop @@1
pop di
ret
m2_clear ENDP
ALIGN 2
pagep dw 0
wpage dw 1,2,3
spage dw 3,1,2
m2_switch PROC NEAR
mov ax,0a000h
mov ds:_vramseg,ax
mov bx,cs:pagep
inc bx
cmp bx,3
jb sws1
xor bx,bx
sws1: mov cs:pagep,bx
shl bx,1
mov dx,3d4h
mov al,33h
mov ah,byte ptr cs:spage[bx]
out dx,ax ;spage
;set wpage
mov al,byte ptr cs:wpage[bx]
mov ah,al
rol ah,4
or al,ah
mov dx,3cdh
out dx,al
;page low offset
mov dx,3d4h
mov ax,000dh
out dx,ax
mov ax,000ch
out dx,ax
ret
m2_switch ENDP
;======== internal routines ========
;sets up 640x400x256 tweak
tweak640x400 PROC NEAR
mov ax,002fh
int 10h
mov dx,3c8h
mov al,0
out dx,al
inc dx
mov cx,768
@@1: out dx,al
loop @@1
mov dx,3c4h
mov al,4
out dx,al
inc dx
in al,dx
and al,not 08h
or al,04h
out dx,al
mov dx,3ceh
mov al,5
out dx,al
inc dx
in al,dx
and al,not 10h
out dx,al
dec dx
mov al,6
out dx,al
inc dx
in al,dx
and al,not 02h
out dx,al
mov dx,3d4h
mov al,9
inc dx
and al,not 5fh
or al,1
dec dx
mov al,14h
out dx,al
inc dx
in al,dx
and al,not 40h
out dx,al
dec dx
mov al,17h
out dx,al
inc dx
in al,dx
or al,40h
out dx,al
ret
tweak640x400 ENDP

425
VISU/AVIDPOLY.OLD Normal file
View file

@ -0,0 +1,425 @@
;/****************************************************************************
;** MODULE: avidpoly.asm
;** AUTHOR: Sami Tammilehto / Fennosoftec OY
;** DOCUMENT: ?
;** VERSION: 1.0
;** REFERENCE: -
;** REVISED BY: -
;*****************************************************************************
;**
;** Assembler / Video (polygon drawing)
;**
;****************************************************************************/
;borders - can be found in asm.asm at the tmp work area (size 8K = 1024 rows)
ALIGN 4
polysides dw 0 ;polygon sides
polyxy dw MAXPOLYSIDES dup(0,0) ;x1,y1,x2,y2,...
polycolor db 1
ALIGN 4
leftside db 1111b,1110b,1100b,1000b
rightside db 0001b,0011b,0111b,1111b
middledot db 0001b,0010b,0100b,1000b
poly PROC NEAR
;NOTE Changes about all!
push ds
call vidstart
mov ax,cs:polysides
cmp ax,3
jb polret
call polyf
polret: pop ds
ret
poly ENDP
;*** POLYF / POLYFT
ALIGN 4
feax dd 0
fedx dd 0
fleftaddl dd 0 ;+0
fleftaddh dw 0 ;+4
fleftrown dw 0 ;+6
fleftzb dd 0 ;+8
fleftze dd 0 ;+12
flefttx0 dw 0 ;+16
fleftty0 dw 0 ;+18
flefttxa dw 0 ;+20
flefttya dw 0 ;+22
fleftcnt dw 0 ;+24
fleftcnta dw 0 ;+26
fleftd3a dw 0 ;+28
frightaddl dd 0 ;+0
frightaddh dw 0 ;+4
frightrown dw 0 ;+6
frightzb dd 0 ;+8
frightze dd 0 ;+12
frighttx0 dw 0 ;+16
frightty0 dw 0 ;+18
frighttxa dw 0 ;+20
frighttya dw 0 ;+22
frightcnt dw 0 ;+24
frightcnta dw 0 ;+26
frightd3a dw 0 ;+28
finfolen dw 0
finfo0 dw 0
finfo1 dw 0
fwmaxy1 dw 0
finfo dw 32 dup(0,0,0,0,0,0,0,0)
;x,y,zlo,zhi,tx,ty,0,0
polyf PROC NEAR ;ONLY CONVEX POLYGONS - FAST?
;input: polysides/polyxy
;requirements: vidstart
;cpolysides>=3 (not checked)
;**COPY/SEEK UPPERMOST**
mov ax,ds
mov gs,ax
mov ax,cs
mov ds,ax
mov cx,ds:polysides
mov ax,cx
shl ax,4 ;*16
mov ds:finfolen,ax
add ax,OFFSET finfo
mov ds:finfo1,ax
mov ax,word ptr gs:_projclipy[CLIPMAX]
inc ax
mov ds:fwmaxy1,ax
mov edx,077770000h
xor bx,bx
mov si,OFFSET polyxy
mov di,OFFSET finfo
mov ds:finfo0,di
pfn1: mov eax,dword ptr ds:[si]
cmp eax,edx
jg pfn2
mov edx,eax
mov bx,di
pfn2: mov dword ptr ds:[di],eax
add si,4
add di,16
loop pfn1
;[bx]=uppermost
;**SETUP REGS**
mov ds:fleftrown,-32767
mov ds:frightrown,-32767
mov si,bx
mov di,bx
mov bp,ds:[si+2]
mov bx,OFFSET _borders
mov ax,bp
cmp ax,word ptr gs:_projclipy[CLIPMIN]
jge pfn35
mov ax,word ptr gs:_projclipy[CLIPMIN]
pfn35: mov gs:[bx],ax
add bx,2
mov cx,16 ;max tmp count to avoid hanging on illegal polygons
;eax=left
;bx=pointer to borders[]
;cx=count
;edx=right
;si=left
;di=right
;bp=y
pfn63: push cx
push bx
cmp bp,ds:fleftrown
jl pfn42
push edx
push di
mov di,si
sub di,16
cmp di,ds:finfo0
jae pfn41
add di,ds:finfolen
pfn41: mov bx,OFFSET fleftaddl
call polyfcalc
add cx,bp
mov ds:fleftrown,cx
movzx eax,word ptr ds:[si+0]
mov ebx,ds:fleftaddl
mov dx,ds:fleftaddh
sar dx,1
rcr ebx,1
xor bx,bx
sub eax,ebx
sbb ax,dx
mov si,di
pop di
pop edx
pfn42:
cmp bp,ds:frightrown
jl pfn52
push eax
push si
mov si,di
add di,16
cmp di,ds:finfo1
jb pfn51
sub di,ds:finfolen
pfn51: mov bx,OFFSET frightaddl
call polyfcalc
add cx,bp
mov ds:frightrown,cx
movzx edx,word ptr ds:[si+0]
mov ebx,ds:frightaddl
mov ax,ds:frightaddh
sar ax,1
rcr ebx,1
xor bx,bx
sub edx,ebx
sbb dx,ax
pop si
pop eax
pfn52: mov bx,ds:fleftrown
mov cx,ds:frightrown
cmp cx,bx
jl pfn61
mov cx,bx
pfn61: sub cx,bp
pop bx
cmp cx,0
jg pfn71
pfn6: pop cx
cmp bp,ds:fwmaxy1
jg pfn64
cmp si,di
je pfn64
dec cx
jz pfn64
jmp pfn63
pfn64: mov word ptr gs:[bx],-32767
mov si,OFFSET _borders
LOADDS
call doborders
ret
pfn65: ;above screen
;entering screen, cut.
add bp,cx
push bp
push cx
cmp bp,word ptr gs:_projclipy[CLIPMIN]
jl pfn66
sub bp,cx
mov cx,word ptr gs:_projclipy[CLIPMIN]
sub cx,bp
pfn66: ;
movsx ecx,cx
ror eax,16
mov ds:feax,eax
ror edx,16
mov ds:fedx,edx
;
mov ax,ds:fleftaddh
shl eax,16
mov ax,word ptr ds:fleftaddl[2]
imul ecx
add ds:feax,eax
;
mov ax,ds:frightaddh
shl eax,16
mov ax,word ptr ds:frightaddl[2]
imul ecx
add ds:fedx,eax
;
mov eax,ds:feax
ror eax,16
mov edx,ds:fedx
ror edx,16
mov bp,cx
pop cx
sub cx,bp
pop bp
cmp cx,0
jne pfn6b
jmp pfn6
pfn6b: mov bp,word ptr gs:_projclipy[CLIPMIN]
pfn71: ;process segment
cmp bp,word ptr gs:_projclipy[CLIPMIN]
jl pfn65 ;above screen still
add bp,cx
;clip max to maxy
cmp bp,ds:fwmaxy1
jle pfn72
sub bp,cx
mov cx,ds:fwmaxy1
sub cx,bp
mov bp,ds:fwmaxy1
pfn72: cmp cx,0
jle pfn6
push si
push di
push bp
ror ebx,16
neg cx
mov bx,cx
ror ebx,16
mov esi,ds:fleftaddl
mov edi,ds:frightaddl
mov bp,ds:fleftaddh
mov cx,ds:frightaddh
pfn7: add eax,esi
adc ax,bp
add edx,edi
adc dx,cx
mov gs:[bx],ax
mov gs:[bx+2],dx
add ebx,10004h
jnc pfn7
pop bp
pop di
pop si
jmp pfn6
polyfcalc: ;**** subroutine ****
;calc slope for line [SI]->[DI] to [BX], returns CX=len
mov cx,ds:[di+2]
sub cx,bp ;ds:[si+2]
jle pfc1
mov ax,ds:[di+0]
sub ax,ds:[si+0]
jl pfc2
xor dx,dx
div cx
mov ds:[bx+4],ax
xor ax,ax
div cx
mov ds:[bx+2],ax
;dec cx
ret
pfc1: xor cx,cx
ret
pfc2: neg ax
xor dx,dx
div cx
push ax
xor ax,ax
div cx
pop dx
neg ax
adc dx,0
neg dx
mov ds:[bx+4],dx
mov ds:[bx+2],ax
;dec cx
ret
polyf ENDP
doborders PROC NEAR
push bp
mov bx,ds:[si]
add si,2
dec bx
push bx
hlg92: pop bx
inc bx
push bx
mov ax,ds:[si]
add si,2
cmp ax,-32767
jne hlg91
pop bx
pop bp
ret
hlg91: mov dx,ax
mov ax,ds:[si]
add si,2
cmp ax,dx
jl hlg1
xchg ax,dx
hlg1:
cmp ax,word ptr ds:_projclipx[CLIPMIN]
jnl hlg2
cmp dx,word ptr ds:_projclipx[CLIPMIN]
jl hlg0
mov ax,word ptr ds:_projclipx[CLIPMIN]
hlg2: cmp dx,word ptr ds:_projclipx[CLIPMAX]
jng hlg21
cmp ax,word ptr ds:_projclipx[CLIPMAX]
jg hlg0
mov dx,word ptr ds:_projclipx[CLIPMAX]
hlg21: mov di,ax
sar di,2
mov cx,dx
sar cx,2
sub cx,di
shl bx,1
add di,ds:_rows[bx]
mov bp,3
and bp,ax
mov bh,cs:leftside[bp]
mov bp,3
and bp,dx
mov bl,cs:rightside[bp]
mov dx,3c5h
;(di..si,bx)
cmp cx,0
je hlg30
;left side
mov al,bh
out dx,al
mov al,cs:polycolor
stosb
dec cx
mov ah,al
;middle
jcxz hlg33
mov al,0fh
out dx,al
cmp cx,8
jae @@long
mov al,ah
shr cx,1
rep stosw
adc cx,cx
rep stosb
jmp hlg33
@@long: mov al,ah
mov bp,ax
shl eax,16
mov ax,bp
;align
test di,3
jz hlg32
stosb
dec cx
test di,3
jz hlg32
stosb
dec cx
test di,3
jz hlg32
stosb
dec cx
hlg32: mov bp,cx
shr cx,2
rep stosd ;fill
mov cx,3
and cx,bp
rep stosb ;fill rest
hlg33: ;right side
mov al,bl
out dx,al
mov al,ah
mov es:[di],al
hlg0: jmp hlg92
hlg30: ;end and beg in same byte
mov al,bl
and al,bh
out dx,al
mov al,cs:polycolor
mov es:[di],al
jmp hlg92
doborders ENDP

88
VISU/AVIDTIMR.OLD Normal file
View file

@ -0,0 +1,88 @@
ALIGN 4
_olddostimer dd ?
timerspeed dw 0
timercount dw 0
vidtimer PROC FAR
push ax
push cx
push dx
push ds
IF 0
mov dx,3dah
in al,dx
mov dx,3c0h
mov al,11h+20h
out dx,al
mov al,4
out dx,al
mov cx,1000
@@pp: loop @@pp
mov dx,3dah
in al,dx
mov dx,3c0h
mov al,11h+20h
out dx,al
mov al,0
out dx,al
ENDIF
inc cs:framecounter
pop ds
pop dx
pop cx
mov ax,cs:timerspeed
add cs:timercount,ax
jnc @@x
pop ax
jmp cs:_olddostimer
@@x: mov al,20h
out 20h,al
pop ax
iret
vidtimer ENDP
;±±±±±±±± _vid_inittimer() ±±±±±±±±
;entry: -
; exit: -
;descr: Captures the system timer and sets it to 70hz
_vid_inittimer PROC FAR
CBEG
xor ax,ax
mov es,ax
mov eax,es:[8h*4+0]
mov cs:_olddostimer,eax
cli
mov word ptr es:[8h*4+0],OFFSET vidtimer
mov es:[8h*4+2],cs
mov al,36h
out 43h,al
mov ax,119318/7
mov cs:timerspeed,ax
out 40h,al
mov al,ah
out 40h,al
sti
CEND
_vid_inittimer ENDP
;±±±±±±±± _vid_deinittimer() ±±±±±±±±
;entry: -
; exit: -
;descr: Restores the system timer to its original state
_vid_deinittimer PROC FAR
CBEG
xor ax,ax
mov es,ax
cli
mov eax,cs:_olddostimer
mov es:[8h*4+0],eax
mov al,36h
out 43h,al
mov ax,0
out 40h,al
mov al,ah
out 40h,al
sti
CEND
_vid_deinittimer ENDP

23
VISU/AVISTAN.INC Normal file
View file

@ -0,0 +1,23 @@
;Visual angle tangent table (256 words = 90 degrees)
dw 32767,32767,20859,13905,10428, 8341, 6950, 5956, 5210, 4631, 4166, 3787
dw 3470, 3202, 2972, 2773, 2599, 2445, 2308, 2185, 2075, 1975, 1884, 1801
dw 1725, 1655, 1591, 1531, 1475, 1423, 1374, 1329, 1286, 1246, 1209, 1173
dw 1140, 1108, 1077, 1049, 1022, 996, 971, 947, 925, 903, 882, 862
dw 843, 825, 808, 791, 774, 759, 744, 729, 715, 701, 688, 675
dw 663, 651, 640, 628, 618, 607, 597, 587, 577, 568, 558, 549
dw 541, 532, 524, 516, 508, 500, 493, 486, 478, 471, 465, 458
dw 451, 445, 439, 433, 427, 421, 415, 409, 404, 398, 393, 388
dw 383, 378, 373, 368, 363, 358, 354, 349, 345, 340, 336, 332
dw 328, 323, 319, 315, 311, 308, 304, 300, 296, 293, 289, 285
dw 282, 278, 275, 272, 268, 265, 262, 259, 256, 252, 249, 246
dw 243, 240, 237, 234, 232, 229, 226, 223, 220, 218, 215, 212
dw 210, 207, 204, 202, 199, 197, 194, 192, 189, 187, 185, 182
dw 180, 177, 175, 173, 171, 168, 166, 164, 162, 159, 157, 155
dw 153, 151, 149, 147, 145, 142, 140, 138, 136, 134, 132, 130
dw 128, 126, 124, 123, 121, 119, 117, 115, 113, 111, 109, 107
dw 106, 104, 102, 100, 98, 96, 95, 93, 91, 89, 88, 86
dw 84, 82, 81, 79, 77, 75, 74, 72, 70, 69, 67, 65
dw 64, 62, 60, 59, 57, 55, 54, 52, 50, 49, 47, 46
dw 44, 42, 41, 39, 37, 36, 34, 33, 31, 29, 28, 26
dw 25, 23, 22, 20, 18, 17, 15, 14, 12, 11, 9, 7
dw 6, 4, 3, 1

97
VISU/C.H Normal file
View file

@ -0,0 +1,97 @@
;/****************************************************************************
;** MODULE: c.h
;** AUTHOR: Sami Tammilehto / Fennosoftec OY
;** DOCUMENT: ?
;** VERSION: 1.0
;** REFERENCE: -
;** REVISED BY: -
;*****************************************************************************
;**
;** C / Include
;** - variable definitions
;** - constant definitions
;**
;****************************************************************************/
#ifndef INCLUDED_C
/*####### Data types ########*/
#ifndef INCLUDED_CD
#include "cd.h"
#endif
/*####### Prototypes for *EXTERNAL* c routines ########*/
extern void * getmem(long bytes); // SHOULD BE PROVIDED EXTERNALLY
extern void freemem(void *); // SHOULD BE PROVIDED EXTERNALLY
extern char * readfile(char *name); // SHOULD BE PROVIDED EXTERNALLY
/*####### Prototypes for c routines ########*/
object * vis_loadobject(char *fname); // visu.c
void vis_drawobject(object *o); // visu.c
/*####### Prototypes for asm routines ########*/
void vid_init(int mode);
void vid_window(long x1,long x2,long y1,long y2,long z1,long z2);
void vid_cameraangle(angle a);
void vid_inittimer(void);
void vid_deinittimer(void);
void vid_deinit(void);
void vid_setpal(char *pal);
void vid_clear(void);
void vid_clearbg(char *);
void vid_skyclear(char *sky);
void vid_switch(void);
void vid_waitb(void);
void vid_drawpolylist(polylist *,polydata *,vlist *,pvlist *,nlist *); // OBSOLOTE, USE draw_polylist
void vid_pic320200(char *,int,int);
void vid_drawsight(char *);
void vid_pset(int x,int y,int color);
void vid_dotdisplay_pvlist(int count,pvlist *list);
void vid_dotdisplay_zcolor(int count,pvlist *list1,vlist *list2);
void vid_poly(int color,int sides,...);
int calc_project(int count,pvlist *dest,vlist *source);
int calc_project16(int count,pvlist *dest,vlist *source); // for 16 bits
void calc_setrmatrix_rotyxz(rmatrix *matrix,angle rotx,angle roty,angle rotz);
void calc_setrmatrix_rotxyz(rmatrix *matrix,angle rotx,angle roty,angle rotz);
void calc_setrmatrix_rotzyx(rmatrix *matrix,angle rotx,angle roty,angle rotz);
void calc_setrmatrix_ident(rmatrix *matrix);
void calc_sftranslate(int count,vlist *dest,long xt,long yt,long zt);
void calc_rotate(int count,vlist *dest,vlist *source,rmatrix *matrix);
void calc_rotate16(int count,vlist *dest,vlist *source,rmatrix *matrix);
void calc_nrotate(int count,nlist *dest,nlist *source,rmatrix *matrix);
void calc_mulrmatrix(rmatrix *dest,rmatrix *source);
int calc_invrmatrix(rmatrix *dest);
void calc_applyrmatrix(rmatrix *dest,rmatrix *apply);
long calc_singlez(int vertexnum,vlist *vertexlist,rmatrix *matrix);
void calc_setrmatrix_camera(rmatrix *,long,long,long,long,long,long,int);
void draw_polylist(polylist *,polydata *,vlist *,pvlist *,nlist *,int);
void draw_setfillroutine(void (*)(int *));
/*####### Constants ########*/
#define MAXROWS 480
#define UNIT 16384
#define UNITSHR 14
/*####### External Assembler variables ########*/
extern long datanull;
extern int rows[MAXROWS];
extern int vramseg;
extern long projclipx[2];
extern long projclipy[2];
extern long projclipz[2];
extern long projmulx;
extern long projmuly;
extern long projaddx;
extern long projaddy;
#define INCLUDED_CD
#endif

8
VISU/C/AMIGACIT Normal file
View file

@ -0,0 +1,8 @@
Amiga city: 90-140341
Elusive:
317 452 5897
317 452 1257
317 868 9465 55?
317 868 9454

BIN
VISU/C/C.EXE Normal file

Binary file not shown.

3
VISU/C/CALKU.BAT Normal file
View file

@ -0,0 +1,3 @@
cd scene
..\c -s10.0 u2a
cd ..

3
VISU/C/CCITY.BAT Normal file
View file

@ -0,0 +1,3 @@
cd scene
..\c -s10.0 u2e
cd ..

BIN
VISU/C/CITY.3DS Normal file

Binary file not shown.

368
VISU/C/CITY.C Normal file
View file

@ -0,0 +1,368 @@
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <malloc.h>
#include "..\cd.h"
#include "..\c.h"
#define noDEBUG
int indemo=0;
char scene[64]={"CITY"};
char tmpname[64];
char huge *scene0;
char huge *scenem;
int city=0;
#define LONGAT(zz) *((long huge *)(zz))
#define INTAT(zz) *((int huge *)(zz))
#define CHARAT(zz) *((char huge *)(zz))
#define MAXOBJ 256
struct s_co
{
object *o;
long dist;
int index;
int on;
} co[MAXOBJ];
int conum;
FILE *fr;
object camobject;
rmatrix cam;
int order[MAXOBJ],ordernum;
unsigned char huge *sp;
long lsget(unsigned char f)
{
long l;
switch(f&3)
{
case 0 : l=0;
break;
case 1 : l=(long)(char)(*sp++);
break;
case 2 : l=*sp++;
l|=(long)(char)(*sp++)<<8;
break;
case 3 : l=*sp++;
l|=(long)(*sp++)<<8;
l|=(long)(*sp++)<<16;
l|=(long)(char)(*sp++)<<24;
break;
}
return(l);
}
void resetscene(void)
{
int a;
sp=(unsigned char *)(scene0+16);
for(a=0;a<conum;a++)
{
memset(co[a].o->r,0,sizeof(rmatrix));
memset(co[a].o->r0,0,sizeof(rmatrix));
}
}
main(int argc,char *argv[])
{
char huge *sptemp;
int huge *ip;
char huge *cp;
int a,b,c,d,e,f,g;
#ifdef DEBUG
fr=fopen("tmp","wt");
#endif
indemo=1;
_asm int 3
sprintf(tmpname,"%s.00M",scene);
if(!indemo) printf("Loading materials %s...\n",tmpname);
scenem=readfile(tmpname);
sprintf(tmpname,"%s.00A",scene);
if(!indemo) printf("Loading animation %s...\n",tmpname);
scene0=readfile(tmpname);
if(scene0[15]=='C') city=1;
ip=(int huge *)(scene0+LONGAT(scene0+4));
conum=d=*ip++;
for(f=-1,c=1;c<d;c++)
{
e=*ip++;
if(e>f)
{
f=e;
sprintf(tmpname,"%s.%03i",scene,e);
if(!indemo) printf("Loading %s... ",tmpname);
co[c].o=vis_loadobject(tmpname);
memset(co[c].o->r,0,sizeof(rmatrix));
memset(co[c].o->r0,0,sizeof(rmatrix));
co[c].index=e;
co[c].on=0;
if(!indemo) printf("(co[%i]:%s)\n",c,co[c].o->name);
}
else
{
if(!indemo) printf("Copying %s.%03i... ",scene,e);
for(g=0;g<c;g++) if(co[g].index==e) break;
memcpy(co+c,co+g,sizeof(struct s_co));
co[c].o=getmem(sizeof(object));
memcpy(co[c].o,co[g].o,sizeof(object));
co[c].o->r=getmem(sizeof(rmatrix));
co[c].o->r0=getmem(sizeof(rmatrix));
memset(co[c].o->r,0,sizeof(rmatrix));
memset(co[c].o->r0,0,sizeof(rmatrix));
co[c].on=0;
if(!indemo) printf("(co[%i]:%s)\n",c,co[c].o->name);
}
}
co[0].o=&camobject;
camobject.r=&cam;
camobject.r0=&cam;
if(!indemo)
{
printf("Press any key to continue...");
getch();
}
vid_init(1);
cp=(char *)(scenem+16);
vid_setpal(cp);
_asm int 3
resetscene();
for(;;)
{
int fov;
int onum;
long pflag;
long dis;
long l;
object *o;
rmatrix *r;
_asm mov bx,2
_asm int 0fch // exit?
_asm mov a,ax
if(a) break;
vid_switch();
_asm mov bx,1
_asm int 0fch // waitb
vid_clear();
// parse animation stream
onum=0;
for(;;)
{
sptemp=sp;
_asm
{
mov ax,word ptr sptemp[0]
cmp ax,1000h
jb l1
sub word ptr sptemp[0],1000h
add word ptr sptemp[2],100h
l1:
}
sp=sptemp;
a=*sp++;
if(a==0xff)
{
a=*sp++;
if(a<=0x7f)
{
fov=a<<8;
break;
}
else if(a==0xff)
{
if(indemo) break;
resetscene();
continue;
}
}
if((a&0xc0)==0xc0)
{
onum=((a&0x3f)<<4);
a=*sp++;
}
onum=(onum&0xff0)|(a&0xf);
b=0;
switch(a&0xc0)
{
case 0x80 : b=1; co[onum].on=1; break;
case 0x40 : b=1; co[onum].on=0; break;
}
#ifdef DEBUG
if(b) fprintf(fr,"[%i (%s) ",onum,co[onum].on?"on":"off");
else fprintf(fr,"[%i (--) ",onum,co[onum].on?"on":"off");
#endif
if(onum>=conum) return(3);
r=co[onum].o->r0;
pflag=0;
switch(a&0x30)
{
case 0x00 : break;
case 0x10 : pflag|=*sp++; break;
case 0x20 : pflag|=sp[0];
pflag|=(long)sp[1]<<8;
sp+=2; break;
case 0x30 : pflag|=sp[0];
pflag|=(long)sp[1]<<8;
pflag|=(long)sp[2]<<16;
sp+=3; break;
}
#ifdef DEBUG
fprintf(fr,"pfl:%06lX",pflag);
#endif
l=lsget(pflag);
r->x+=l;
l=lsget(pflag>>2);
r->y+=l;
l=lsget(pflag>>4);
r->z+=l;
#ifdef DEBUG
fprintf(fr," XYZ:(%li,%li,%li)",r->x,r->y,r->z);
#endif
if(pflag&0x40)
{ // word matrix
for(b=0;b<9;b++) if(pflag&(0x80<<b))
{
r->m[b]+=lsget(2);
}
}
else
{ // byte matrix
for(b=0;b<9;b++) if(pflag&(0x80<<b))
{
r->m[b]+=lsget(1);
}
}
#ifdef DEBUG
fprintf(fr,"]\n");
#endif
}
// Field of vision
vid_cameraangle(fov);
// Calc matrices and add to order list (only enabled objects)
ordernum=0;
/* start at 1 to skip camera */
for(a=1;a<conum;a++) if(co[a].on)
{
order[ordernum++]=a;
o=co[a].o;
memcpy(o->r,o->r0,sizeof(rmatrix));
calc_applyrmatrix(o->r,&cam);
b=o->pl[0][1]; // center vertex
co[a].dist=calc_singlez(b,o->v0,o->r);
}
// Zsort
if(city)
{
co[2].dist=1000000000L; // for CITY scene, test
co[7].dist=1000000000L; // for CITY scene, test
co[13].dist=1000000000L; // for CITY scene, test
}
for(a=0;a<ordernum;a++)
{
dis=co[c=order[a]].dist;
for(b=a-1;b>=0 && dis>co[order[b]].dist;b--)
order[b+1]=order[b];
order[b+1]=c;
}
// Draw
for(a=0;a<ordernum;a++)
{
int x,y;
o=co[order[a]].o;
#ifdef DEBUG
fprintf(fr,"%s (i:%i Z:%li)\n",o->name,order[a],co[order[a]].dist);
#endif
vis_drawobject(o);
}
#ifdef DEBUG
fprintf(fr,"\n");
#endif
}
vid_deinit();
#ifdef DEBUG
fclose(fr);
#endif
return(0);
}
//////////////////////////////////////////////////////////////////////////////
void *getmem(long size)
{
void *p;
if(size>160000L)
{
printf("GETMEM: attempting to reserved >160K (%li byte block)\n",size);
exit(3);
}
p=halloc(size/16L+1,16);
if(!p)
{
printf("GETMEM: out of memory (%li byte block)\n",size);
exit(3);
}
return(p);
}
void freemem(void *p)
{
hfree(p);
}
char *readfile(char *name)
{
FILE *f1;
long size;
char huge *p,*p0;
f1=fopen(name,"rb");
if(!f1)
{
printf("File '%s' not found.",name);
exit(3);
}
fseek(f1,0L,SEEK_END);
p0=p=getmem(size=ftell(f1));
fseek(f1,0L,SEEK_SET);
if(size>64000)
{
fread(p,64000,1,f1);
size-=64000;
_asm
{
add word ptr p[2],4000
}
fread(p,(size_t)size,1,f1);
}
else fread(p,(size_t)size,1,f1);
fclose(f1);
return(p0);
}

BIN
VISU/C/CITY.EXE Normal file

Binary file not shown.

BIN
VISU/C/CITY.LBM Normal file

Binary file not shown.

11
VISU/C/CITY.MAT Normal file
View file

@ -0,0 +1,11 @@
;format: MATERIAL-NAME <parameters>
;parameters:
;#(number) first color in fade
;L# length of color fade (#=32/16/8/1=no fading)
;G gouraud
;X Two sided material
GRAYCEMENT 0 L32
GREENGRASS 32 L32 G
BLUEMETAL 64 L32 G
CYANMETAL 96 L32 G
GOLDMETAL 128 L32 G

198
VISU/C/CITY.NFO Normal file
View file

@ -0,0 +1,198 @@
Mesh objects: Total vertices:764 Total faces:1204
Building01
Vertices:32 Faces:60
Materials:
GOLDMETAL
Smoothing:
1, 2, 3, 4, 5, 6, 10, 11, 12, 17
platform01
Vertices:64 Faces:96
Materials:
GRAYCEMENT
Building03
Vertices:16 Faces:24
Materials:
CYANMETAL
Building04
Vertices:8 Faces:12
Materials:
BLUEMETAL
Building06
Vertices:9 Faces:14
Materials:
BLUEMETAL
BuildingH
Vertices:40 Faces:60
Materials:
CYANMETAL
platform02
Vertices:120 Faces:178
Materials:
GRAYCEMENT
GREENGRASS
Building05
Vertices:8 Faces:12
Materials:
BLUEMETAL
Building08
Vertices:8 Faces:12
Materials:
BLUEMETAL
Building09
Vertices:9 Faces:14
Materials:
BLUEMETAL
Building10
Vertices:8 Faces:12
Materials:
BLUEMETAL
Building11
Vertices:16 Faces:24
Materials:
CYANMETAL
Building12
Vertices:16 Faces:24
Materials:
CYANMETAL
Car02
Vertices:12 Faces:20
Materials:
CYANMETAL
Page 1
platform03
Vertices:128 Faces:192
Materials:
GRAYCEMENT
GREENGRASS
Building02
Vertices:9 Faces:14
Materials:
BLUEMETAL
Building13
Vertices:9 Faces:14
Materials:
BLUEMETAL
Building14
Vertices:9 Faces:14
Materials:
BLUEMETAL
Building15
Vertices:8 Faces:12
Materials:
BLUEMETAL
Building16
Vertices:8 Faces:12
Materials:
BLUEMETAL
Building17
Vertices:8 Faces:12
Materials:
BLUEMETAL
Building18
Vertices:8 Faces:12
Materials:
BLUEMETAL
Building19
Vertices:8 Faces:12
Materials:
BLUEMETAL
BuildingC
Vertices:18 Faces:32
Materials:
CYANMETAL
Smoothing:
1, 2, 3, 10, 11, 12, 17
Building20
Vertices:14 Faces:24
Materials:
CYANMETAL
Building21
Vertices:19 Faces:34
Materials:
CYANMETAL
fclogo
Vertices:36 Faces:64
Smoothing:
1, 2, 3, 10, 11, 12, 17
Lamppost
Vertices:8 Faces:8
Materials:
GOLDMETAL
Helicopter
Vertices:72 Faces:140
Page 2
Materials:
GOLDMETAL
Smoothing:
1, 2, 3, 4, 5, 6, 10, 11, 12, 17
HeliRotor
Vertices:12 Faces:10
Materials:
GOLDMETAL
Smoothing:
17
Building07
Vertices:8 Faces:12
Materials:
BLUEMETAL
Building22
Vertices:8 Faces:12
Materials:
BLUEMETAL
Building23
Vertices:8 Faces:12
Materials:
BLUEMETAL
Materials summary:
GRAYCEMENT
GREENGRASS
BLUEMETAL
CYANMETAL
GOLDMETAL
Lights:
Light01
Cameras:
FlyCam (50.00mm)
Page 3

BIN
VISU/C/CITY.OBJ Normal file

Binary file not shown.

BIN
VISU/C/CITY.PAL Normal file

Binary file not shown.

BIN
VISU/C/CITY0A.OK Normal file

Binary file not shown.

BIN
VISU/C/CITYPAL.PAL Normal file

Binary file not shown.

407
VISU/C/CPLAY.C Normal file
View file

@ -0,0 +1,407 @@
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <malloc.h>
#include "..\cd.h"
#include "..\c.h"
#define DEBUG
int indemo=0;
char scene[64]={"CITY"};
char tmpname[64];
char huge *scene0;
char huge *scenem;
int city=0;
#define LONGAT(zz) *((long huge *)(zz))
#define INTAT(zz) *((int huge *)(zz))
#define CHARAT(zz) *((char huge *)(zz))
struct s_scl
{
char *data;
} scenelist[64];
int scl=0,sclp=0;
#define MAXOBJ 256
struct s_co
{
object *o;
long dist;
int index;
int on;
} co[MAXOBJ];
int conum;
FILE *fr;
object camobject;
rmatrix cam;
int order[MAXOBJ],ordernum;
unsigned char huge *sp;
long lsget(unsigned char f)
{
long l;
switch(f&3)
{
case 0 : l=0;
break;
case 1 : l=(long)(char)(*sp++);
break;
case 2 : l=*sp++;
l|=(long)(char)(*sp++)<<8;
break;
case 3 : l=*sp++;
l|=(long)(*sp++)<<8;
l|=(long)(*sp++)<<16;
l|=(long)(char)(*sp++)<<24;
break;
}
return(l);
}
void resetscene(void)
{
int a;
sp=(unsigned char *)(scenelist[sclp].data);
for(a=0;a<conum;a++)
{
memset(co[a].o->r,0,sizeof(rmatrix));
memset(co[a].o->r0,0,sizeof(rmatrix));
}
sclp++;
if(sclp>=scl)
{
sclp=0;
}
}
main(int argc,char *argv[])
{
char huge *sptemp;
int huge *ip;
char huge *cp;
int a,b,c,d,e,f,g;
#ifdef DEBUG
fr=fopen("tmp","wt");
#endif
if(argc>1)
{
strcpy(scene,argv[1]);
strupr(scene);
}
else indemo=1;
sprintf(tmpname,"%s.00M",scene);
if(!indemo) printf("Loading materials %s...\n",tmpname);
scene0=scenem=readfile(tmpname);
if(scene0[15]=='C') city=1;
if(scene0[15]=='R') city=2;
ip=(int huge *)(scene0+LONGAT(scene0+4));
conum=d=*ip++;
for(f=-1,c=1;c<d;c++)
{
e=*ip++;
if(e>f)
{
f=e;
sprintf(tmpname,"%s.%03i",scene,e);
if(!indemo) printf("Loading %s... ",tmpname);
co[c].o=vis_loadobject(tmpname);
memset(co[c].o->r,0,sizeof(rmatrix));
memset(co[c].o->r0,0,sizeof(rmatrix));
co[c].index=e;
co[c].on=0;
if(!indemo) printf("(co[%i]:%s)\n",c,co[c].o->name);
}
else
{
if(!indemo) printf("Copying %s.%03i... ",scene,e);
for(g=0;g<c;g++) if(co[g].index==e) break;
memcpy(co+c,co+g,sizeof(struct s_co));
co[c].o=getmem(sizeof(object));
memcpy(co[c].o,co[g].o,sizeof(object));
co[c].o->r=getmem(sizeof(rmatrix));
co[c].o->r0=getmem(sizeof(rmatrix));
memset(co[c].o->r,0,sizeof(rmatrix));
memset(co[c].o->r0,0,sizeof(rmatrix));
co[c].on=0;
if(!indemo) printf("(co[%i]:%s)\n",c,co[c].o->name);
}
}
co[0].o=&camobject;
camobject.r=&cam;
camobject.r0=&cam;
sprintf(tmpname,"%s.0AA",scene);
if(!indemo) printf("Loading animations...\n",tmpname);
ip=readfile(tmpname);
while(*ip)
{
a=*ip;
if(a==-1) break;
sprintf(tmpname,"%s.0%c%c",scene,a/10+'A',a%10+'A');
if(!indemo) printf("Scene: %s ",tmpname);
scenelist[scl].data=readfile(tmpname);
printf("(%i:@%Fp)\n",scl,scenelist[scl].data);
scl++;
ip+=2;
}
if(!indemo)
{
printf("Press any key to continue...");
getch();
}
resetscene();
vid_init(1); ////// oversample x 4
cp=(char *)(scenem+16);
vid_setpal(cp);
outp(0x3c8,0);
outp(0x3c9,0);
outp(0x3c9,0);
outp(0x3c9,0);
while(!kbhit())
{
int fov;
int onum;
long pflag;
long dis;
long l;
object *o;
rmatrix *r;
vid_switch();
vid_waitb();
vid_clear();
// parse animation stream
onum=0;
for(;;)
{
/*
sptemp=sp;
_asm
{
mov ax,word ptr sptemp[0]
cmp ax,1000h
jb l1
sub word ptr sptemp[0],1000h
add word ptr sptemp[2],100h
l1:
}
sp=sptemp;
*/
a=*sp++;
if(a==0xff)
{
a=*sp++;
if(a<=0x7f)
{
fov=a<<8;
break;
}
else if(a==0xff)
{
resetscene();
continue;
}
}
if((a&0xc0)==0xc0)
{
onum=((a&0x3f)<<4);
a=*sp++;
}
onum=(onum&0xff0)|(a&0xf);
b=0;
switch(a&0xc0)
{
case 0x80 : b=1; co[onum].on=1; break;
case 0x40 : b=1; co[onum].on=0; break;
}
#ifdef DEBUG
if(b) fprintf(fr,"[%i (%s) ",onum,co[onum].on?"on":"off");
else fprintf(fr,"[%i (--) ",onum,co[onum].on?"on":"off");
#endif
if(onum>=conum) return(3);
r=co[onum].o->r0;
pflag=0;
switch(a&0x30)
{
case 0x00 : break;
case 0x10 : pflag|=*sp++; break;
case 0x20 : pflag|=sp[0];
pflag|=(long)sp[1]<<8;
sp+=2; break;
case 0x30 : pflag|=sp[0];
pflag|=(long)sp[1]<<8;
pflag|=(long)sp[2]<<16;
sp+=3; break;
}
#ifdef DEBUG
fprintf(fr,"pfl:%06lX",pflag);
#endif
l=lsget(pflag);
r->x+=l;
l=lsget(pflag>>2);
r->y+=l;
l=lsget(pflag>>4);
r->z+=l;
#ifdef DEBUG
fprintf(fr," XYZ:(%li,%li,%li)",r->x,r->y,r->z);
#endif
if(pflag&0x40)
{ // word matrix
for(b=0;b<9;b++) if(pflag&(0x80<<b))
{
r->m[b]+=lsget(2);
}
}
else
{ // byte matrix
for(b=0;b<9;b++) if(pflag&(0x80<<b))
{
r->m[b]+=lsget(1);
}
}
#ifdef DEBUG
fprintf(fr,"]\n");
#endif
}
// Field of vision
vid_cameraangle(fov);
// Calc matrices and add to order list (only enabled objects)
ordernum=0;
/* start at 1 to skip camera */
for(a=1;a<conum;a++) if(co[a].on)
{
order[ordernum++]=a;
o=co[a].o;
memcpy(o->r,o->r0,sizeof(rmatrix));
calc_applyrmatrix(o->r,&cam);
b=o->pl[0][1]; // center vertex
if(co[a].o->name[1]=='_') co[a].dist=1000000000L;
else co[a].dist=calc_singlez(b,o->v0,o->r);
}
// Zsort
if(city==1)
{
co[2].dist=1000000000L; // for CITY scene, test
co[7].dist=1000000000L; // for CITY scene, test
co[13].dist=1000000000L; // for CITY scene, test
}
if(city==2)
{
co[14].dist=1000000000L; // for CITY scene, test
}
for(a=0;a<ordernum;a++)
{
dis=co[c=order[a]].dist;
for(b=a-1;b>=0 && dis>co[order[b]].dist;b--)
order[b+1]=order[b];
order[b+1]=c;
}
// Draw
for(a=0;a<ordernum;a++)
{
int x,y;
o=co[order[a]].o;
#ifdef DEBUG
fprintf(fr,"%s (i:%i Z:%li)\n",o->name,order[a],co[order[a]].dist);
#endif
vis_drawobject(o);
}
#ifdef DEBUG
fprintf(fr,"\n");
#endif
}
vid_deinit();
#ifdef DEBUG
fclose(fr);
#endif
return(0);
}
//////////////////////////////////////////////////////////////////////////////
void *getmem(long size)
{
void *p;
if(size>160000L)
{
printf("GETMEM: attempting to reserved >160K (%li byte block)\n",size);
exit(3);
}
p=halloc(size/16L+1,16);
if(!p)
{
printf("GETMEM: out of memory (%li byte block)\n",size);
exit(3);
}
return(p);
}
void freemem(void *p)
{
hfree(p);
}
char *readfile(char *name)
{
FILE *f1;
long size;
char huge *p,*p0;
f1=fopen(name,"rb");
if(!f1)
{
printf("File '%s' not found.",name);
exit(3);
}
fseek(f1,0L,SEEK_END);
p0=p=getmem(size=ftell(f1));
fseek(f1,0L,SEEK_SET);
if(size>128000)
{
fread(p,64000,1,f1);
size-=64000;
_asm add word ptr p[2],4000
fread(p,64000,1,f1);
size-=64000;
_asm add word ptr p[2],4000
fread(p,(size_t)size,1,f1);
}
else if(size>64000)
{
fread(p,64000,1,f1);
size-=64000;
_asm
{
add word ptr p[2],4000
}
fread(p,(size_t)size,1,f1);
}
else fread(p,(size_t)size,1,f1);
fclose(f1);
return(p0);
}

BIN
VISU/C/CPLAY.EXE Normal file

Binary file not shown.

BIN
VISU/C/CPLAY.OBJ Normal file

Binary file not shown.

165
VISU/C/DEBUG.1 Normal file
View file

@ -0,0 +1,165 @@
face 2: 0 1 2 3
face 16: 0 4 5 1
face 30: 2 6 3
face 42: 3 6 4 0
face 56: 8 7 9
face 68: 11 10 12
30 56 2 16
compare f1(56) with f4(42)
camera at -68915832, d1=0, d2=4037, d1a=0 d2a=4037
returns -1
30 56 2 16
compare f1(56) with f3(16)
camera at -68915832, d1=0, d2=39093, d1a=0 d2a=39093
returns -1
2 30 16 42
compare f0(2) with f1(30)
camera at 82536286, d1=-22283, d2=0, d1a=22283 d2a=0
returns -1
30 2 16 42
compare f0(30) with f2(16)
camera at -128617788, d1=-61200, d2=0, d1a=61200 d2a=0
returns 1
30 2 16 42
compare f0(30) with f3(42)
camera at -128617788, d1=-40798, d2=0, d1a=40798 d2a=0
returns 1
30 2 16 42
compare f0(30) with f4(68)
camera at -128617788, d1=-28494, d2=0, d1a=28494 d2a=0
returns 1
30 2 16 42
compare f0(30) with f5(56)
camera at -128617788, d1=-29454, d2=0, d1a=29454 d2a=0
returns 1
30 2 16 42
compare f0(30) with f1(2)
camera at -128617788, d1=-30602, d2=0, d1a=30602 d2a=0
returns 1
30 2 16 42
compare f0(30) with f2(16)
camera at -128617788, d1=-61200, d2=0, d1a=61200 d2a=0
returns 1
30 2 16 42
compare f0(30) with f3(42)
camera at -128617788, d1=-40798, d2=0, d1a=40798 d2a=0
returns 1
30 2 16 42
compare f0(30) with f4(68)
camera at -128617788, d1=-28494, d2=0, d1a=28494 d2a=0
returns 1
30 2 16 42
compare f0(30) with f5(56)
camera at -128617788, d1=-29454, d2=0, d1a=29454 d2a=0
returns 1
30 2 16 42
compare f1(2) with f2(16)
camera at 82536286, d1=-22287, d2=0, d1a=22287 d2a=0
returns -1
30 16 2 42
compare f1(16) with f3(42)
camera at 67413648, d1=-30605, d2=0, d1a=30605 d2a=0
returns -1
30 42 2 16
compare f1(42) with f4(68)
camera at 72956014, d1=-37256, d2=0, d1a=37256 d2a=0
returns -1
30 68 2 16
compare f1(68) with f5(56)
camera at 80004026, d1=-25569, d2=0, d1a=25569 d2a=0
returns -1
30 56 2 16
compare f1(56) with f2(2)
camera at -68915832, d1=0, d2=39091, d1a=0 d2a=39091
returns -1
30 56 2 16
compare f1(56) with f3(16)
camera at -68915832, d1=0, d2=39093, d1a=0 d2a=39093
returns -1
30 56 2 16
compare f1(56) with f5(68)
camera at -68915832, d1=0, d2=41296, d1a=0 d2a=41296
returns -1
30 56 2 16
compare f2(2) with f3(16)
camera at 82536286, d1=-22287, d2=0, d1a=22287 d2a=0
returns -1
30 56 16 2
compare f2(16) with f4(42)
camera at 67413648, d1=-30605, d2=0, d1a=30605 d2a=0
returns -1
30 56 42 2
compare f2(42) with f5(68)
camera at 72956014, d1=-37256, d2=0, d1a=37256 d2a=0
returns -1
30 56 68 2
compare f2(68) with f3(2)
camera at 80004026, d1=-2539, d2=0, d1a=2539 d2a=0
returns -1
30 56 68 2
compare f2(68) with f4(16)
camera at 80004026, d1=-24819, d2=0, d1a=24819 d2a=0
returns -1
30 56 68 2
compare f2(68) with f5(42)
camera at 80004026, d1=-24819, d2=0, d1a=24819 d2a=0
returns -1
30 56 68 2
compare f3(2) with f4(16)
camera at 82536286, d1=-22287, d2=0, d1a=22287 d2a=0
returns -1
30 56 68 16
compare f3(16) with f5(42)
camera at 67413648, d1=-30605, d2=0, d1a=30605 d2a=0
returns -1
30 56 68 42
compare f3(42) with f4(2)
camera at 72956014, d1=-46736, d2=5, d1a=46736 d2a=5
returns -1
30 56 68 42
compare f3(42) with f5(16)
camera at 72956014, d1=-46738, d2=0, d1a=46738 d2a=0
returns -1
30 56 68 42
compare f4(2) with f5(16)
camera at 82536286, d1=-22287, d2=0, d1a=22287 d2a=0
returns -1
30 56 68 42
compare f4(16) with f5(2)
camera at 67413648, d1=-40801, d2=1, d1a=40801 d2a=1
returns -1

BIN
VISU/C/DIS.EXE Normal file

Binary file not shown.

45
VISU/C/DOC Normal file
View file

@ -0,0 +1,45 @@
Files in general:
*.00A Animation
*.00M Materials (palette)
*.### Object ### (###=number prefixed with zeros)
OBJECT FILE:
SCENE.00A FILE:
word: number of objects
word: file number for object 0
word: file number for object 1
...
word: file number for object N
Stream of frame data starts.
word X
x&0xfff = number of object
bits:
0x0F Low 4 bits of the object to modify
0x30 Bytes of flags to read (0..3)
0xC0 Command:
0x00 0=Leave to list
0x40 1=Remove from list
0x80 2=Add to list
0xC0 3=Hi change. X&0x3F=Object number/16. (high bits)
Hi change 0x3F (X=0xFF) means special. Next byte Y:
<0x80=next frame, Y=hi byte of camera angle (field of vision)
0=next frame
0xFF=end of anim
Position: 3 x DWORD
Rotation: 9 x WORD
###
Flags:
bits:
0..1 0=X coordinate same, 1=byte change, 2=word change, 3=dword chnage (all start out zero)
2..3 -"- for Y coordinate
4..5 -"- for Z coordinate
6 1=Matrix stored with word changes (0=bytes)
7..15 1=This entry in matrix changed
All objects start hidden (except camera)

BIN
VISU/C/DOOBJ.EXE Normal file

Binary file not shown.

BIN
VISU/C/DP_PREFS Normal file

Binary file not shown.

BIN
VISU/C/FAKE.EXE Normal file

Binary file not shown.

BIN
VISU/C/FLY.3DS Normal file

Binary file not shown.

BIN
VISU/C/GLVP.EXE Normal file

Binary file not shown.

569
VISU/C/MAIN.C Normal file
View file

@ -0,0 +1,569 @@
// 3DS converter V2.0
#include <stdio.h>
#include <stdarg.h>
#include <conio.h>
#include <ctype.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <math.h>
#include "..\cd.h"
#include "..\c.h"
void vDraw(void);
void vDeinit(void);
void vClear(void);
void vNext(void);
void vInit(void);
void vPalette(void);
int drawpass=0;
void doscene(int scene);
int addvx(long x,long y,long z);
int addnr(long x,long y,long z);
char far *vram=(char far *)0xa0000000L;
char fill_color[64000];
char fill_object[64000];
char fill_curobj;
//----------------------------------------------------------------
// filenames
char *inname="NoName";
char ascname[64];
char vuename[64];
char tmpname[64];
char scenename[64];
// flags
int cityflag=0;
int debug=0;
int printon=0;
int reporton=1;
int playloop=0;
int materials=0;
int vuedone=0;
// variables
float fxadd,fxmul;
float fyadd,fymul;
float fzadd,fzmul;
float scale=100.0F;
#define BIGLONG 2000000000L
#define MAXMAT 32
#define MAXFACE 16 // in a polygon
#define MAXOBJ 256
#define MAXVX 500
#define MAXNR 500
#define MAXFC 500
#define NORMALSIZE UNIT // length of normals
//----------------------------------------------------------------
// globals
rmatrix camera;
FILE *in,*in2;
FILE *outb,*outb2,*outb3;
FILE *freport=NULL;
FILE *fdeb;
int debcount=0;
char palette[768];
// prototypes
void readvue(void);
void readasc(void);
// world structs
struct s_cobject
{
char name[18];
int index;
int duplicate;
int original;
int lastused;
int f1,f2,n1,n2,v1,v2,ng;
long size;
char fname[16];
object *o;
long dist;
int on;
int last_on;
long last_x,last_y,last_z;
long last_m[9];
} co[MAXOBJ];
int conum=0;
struct s_material
{
char name[32];
int flags;
int color;
int colorlen;
} mat[MAXMAT];
int matnum=0;
char matpal[768];
int matpalenabled=0;
int usefov;
object camobject;
// other c code included
#include "save.c"
#include "util.c"
#include "osort.c"
#include "readasc.c"
#include "readvue.c"
#include "readmat.c"
#include "readinf.c"
// main
main(int argc,char *argv[])
{
char tmpfname[64];
int pause=0;
int a;
int totalfaces=0,totalvertices=0,totalnormals=0;
fdeb=fopen("debug.tmp","wt");
if(argc==1)
{
printf("\n"
"usage: C [options] <scenename(no extensions)>\n"
"-c Set Cityflag\n"
"-w Set Runflag\n"
"-r Generate report (to file REPORT)\n"
"-p Print report to screen as well\n"
"-l Loop the animation phase until key pressed\n"
"-s### Specify scale factor (default 100.0)\n"
);
return(0);
}
reporton=0;
for(a=1;a<argc;a++) if(argv[a][0]=='-') switch(argv[a][1])
{
case 'c' :
case 'C' : cityflag=1; break;
case 'w' :
case 'W' : cityflag=2; break;
case 'r' :
case 'R' : reporton=1; break;
case 'p' :
case 'P' : reporton=printon=1; break;
case 's' :
case 'S' : sscanf(argv[a]+2,"%f",&scale); break;
case 'l' :
case 'L' : playloop=1; break;
}
else strcpy(inname,argv[a]);
// defaults
strupr(inname);
strcpy(ascname,inname);
strcat(ascname,".ASC");
strcpy(vuename,inname);
strcat(vuename,".VUE");
strcpy(scenename,inname);
fxmul=scale; fxadd=0.0F;
fymul=scale; fyadd=0.0F;
fzmul=scale; fzadd=0.0F;
in=fopen(ascname,"rt");
if(!in)
{
printf("%s not found!\n",ascname);
exit(3);
}
fclose(in);
if(reporton) freport=fopen("report","wt");
// blue screen
printf( "\n");
printf( "Analyzing and converting (while screen is blue)\n");
printf( " Scene name: %s\n",inname);
printf( "Scale factor: %f\n",scale);
if(pause)
{
printf("Press any key to start.\n");
getch();
}
else printf("\n");
outp(0x3c8,0); outp(0x3c9,0); outp(0x3c9,0); outp(0x3c9,32);
strcpy(co[0].name,"CAMERA");
co[0].on=1; // camera is always on
co[0].index=-1;
co[0].duplicate=1; // let's lie
co[0].original=0;
co[0].lastused=0;
co[0].o=&camobject;
camobject.r=&camera;
camobject.r0=&camera;
conum=1;
strcpy(tmpname,inname);
strcat(tmpname,".INF");
in=fopen(tmpname,"rt");
if(in) fclose(in);
else
{
printf("%s.INF file not found!\n",inname);
exit(3);
}
strcpy(tmpname,inname);
strcat(tmpname,".MAT");
in=fopen(tmpname,"rt");
if(in)
{
readmat();
fclose(in);
}
strcpy(tmpname,inname);
strcat(tmpname,".PAL");
in=fopen(tmpname,"rb");
if(in)
{
matpalenabled=1;
fread(matpal,768,1,in);
fclose(in);
}
else
{
for(a=0;a<32;a++)
{
matpal[a*3+0]=a*2;
matpal[a*3+1]=a*2;
matpal[a*3+2]=a*2;
}
}
sprintf(tmpfname,"%s.00M",scenename);
outb3=fopen(tmpfname,"wb");
putw(0,outb3);
putw(0,outb3);
putw(0,outb3);
putw(0,outb3);
putw(0,outb3);
putw(0,outb3);
putw(0,outb3);
putw(0,outb3);
fwrite(matpal,768,1,outb3);
in=fopen(ascname,"rt");
if(!in)
{
printf("%s not found!\n",ascname);
exit(3);
}
readasc();
fclose(in);
vInit();
printon=0;
for(a=1;a<conum;a++)
{
objectsort(co[a].o);
}
_asm mov ax,13h
_asm int 10h
vPalette();
sprintf(tmpfname,"%s.0AA",scenename);
outb2=fopen(tmpfname,"wb");
strcpy(tmpname,inname);
strcat(tmpname,".INF");
in=fopen(tmpname,"rt");
readinf();
fclose(in);
putw(0xffff,outb2);
putw(0xffff,outb2);
fclose(outb2);
{ // init stuff for script
int coi;
long l,l2;
struct s_cobject *cop;
l=ftell(outb3);
putw(conum,outb3);
for(coi=1;coi<conum;coi++)
{
cop=co+coi;
putw(cop->index,outb3);
}
fseek(outb3,0L,SEEK_SET);
putc('F',outb3);
putc('C',outb3);
putc(0xfc,outb3);
putc(0x1a,outb3);
putl(l,outb3);
putw(0,outb3);
putw(0,outb3);
putw(0,outb3);
putc(0,outb3);
if(cityflag==1) putc('C',outb3);
else if(cityflag==2) putc('R',outb3);
else putc(0,outb3);
}
if(!kbhit()) vuedone=1;
if(kbhit()) getch();
vDeinit();
{
if(vuedone) printf("Saving scenery: (%s.00O,%s.00M,%s.0$$)\n\n",scenename,scenename,scenename);
else printf("Saving objects: (%s.00M)\n\n",scenename);
for(a=1;a<conum;a++)
{
if(!co[a].duplicate)
{
printf("Object: %s",co[a].name);
saveobject(co+a); // save object to disk
printf(" File: %s Size:%li\n",co[a].fname,co[a].size);
printf(" Faces:%i=>%i Vertices:%i=>%i Normals:%i Gouraudnormals:%i\n",
co[a].f1,co[a].f2,
co[a].v1,co[a].v2,
co[a].n2,co[a].ng-co[a].n2);
}
totalfaces+=co[co[a].index].f1;
totalvertices+=co[co[a].index].v1;
totalnormals+=co[co[a].index].n2;
}
}
print("Conversion finished (or escaped)!\n");
printf("Total sum of stuff in animation:\n"
" faces: %i\n"
"vertices: %i\n"
" normals: %i\n",
totalfaces,
totalvertices,
totalnormals);
if(freport) fclose(freport);
fclose(fdeb);
return(0);
}
void doscene(int scene)
{
int a;
char tmpfname[64];
sprintf(tmpfname,"%s-%i.vue",inname,scene);
in=fopen(tmpfname,"rt");
if(!in)
{
print("Scene %s not found.\n",tmpfname);
return;
}
vuedone=1;
putw(scene,outb2);
putw(0,outb2);
sprintf(tmpfname,"%s.0%c%c",inname,scene/10+'A',scene%10+'A');
outb=fopen(tmpfname,"wb");
readvue();
fclose(in);
fclose(outb);
}
void vPalette(void)
{
int a,b;
if(matpalenabled)
{
vid_setpal(matpal);
return;
}
for(a=0;a<256;a++)
{
palette[a*3+0]=(char)((a&15)*3+((a/16)&3)*0);
palette[a*3+1]=(char)((a&15)*3+((a/16)&3)*2);
palette[a*3+2]=(char)((a&15)*3+((a/16)&3)*4);
}
for(a=0;a<32;a++)
{
palette[16*3+a*3+0]=(char)(63-a*2);
palette[16*3+a*3+1]=(char)(63-a*2);
palette[16*3+a*3+2]=(char)(63-a*2);
}
palette[2]=32;
palette[255*3+0]=63;
palette[255*3+1]=32;
palette[255*3+2]=16;
vid_setpal(palette);
}
void vInit(void)
{
vid_init(1);
vPalette();
}
void vDeinit(void)
{
vid_deinit();
}
void vNext(void)
{
vid_switch();
vid_waitb();
vid_clear();
}
void vClear(void)
{
vid_clear();
}
#pragma check_stack(off)
void _loadds cfill(int *fd)
{
int color,y,a,x,cnt;
long lx,la,rx,ra;
char *p,*pp;
a=*fd++;
if(a!=0) return; // not flat shading!
color=*fd++;
y=*fd++;
for(;;)
{
a=*fd++;
if(a<0) break;
if(a)
{
lx=(unsigned)(*fd++);
lx|=(long)(*fd++)<<16;
la=(unsigned)(*fd++);
la|=(long)(*fd++)<<16;
}
a=*fd++;
if(a<0) break;
if(a)
{
rx=(unsigned)(*fd++);
rx|=(long)(*fd++)<<16;
ra=(unsigned)(*fd++);
ra|=(long)(*fd++)<<16;
}
a=*fd++;
while(a--)
{
lx+=la;
rx+=ra;
if(lx<rx)
{
x=lx>>16;
cnt=(rx>>16)-x;
}
else
{
x=rx>>16;
cnt=(lx>>16)-x;
}
p=fill_color+x+y*320;
pp=fill_object+x+y*320;
#if 0
p[0]=color;
p[cnt-1]=color;
#else
while(cnt--)
{
*p++=color;
*pp++=fill_curobj;
}
#endif
y++;
}
}
}
#pragma check_stack(on)
int order[MAXOBJ],ordernum;
void vDraw(void)
{
rmatrix cam;
rmatrix tmp;
object *o;
long dis;
int a,b,c;
if(!drawpass)
{
vid_waitb();
memcpy(vram,fill_color,64000);
memset(fill_color,0,64000);
memset(fill_object,0,64000);
draw_setfillroutine(cfill);
}
else
{
vNext();
draw_setfillroutine(NULL);
}
memcpy(&cam,&camera,sizeof(rmatrix));
{
ordernum=0;
for(a=1;a<conum;a++)
{
order[ordernum++]=a;
o=co[a].o;
memcpy(o->r,o->r0,sizeof(rmatrix));
calc_applyrmatrix(o->r,&cam);
b=o->pl[0][1]; // center vertex
if(co[a].name[1]=='_') co[a].dist=100000000L;
else co[a].dist=calc_singlez(b,o->v0,o->r);
}
for(a=0;a<ordernum;a++)
{
dis=co[c=order[a]].dist;
for(b=a-1;b>=0 && dis>co[order[b]].dist;b--)
order[b+1]=order[b];
order[b+1]=c;
}
if(!drawpass)
{
print("[Zsort order: (conum=%i)]\n",conum);
}
for(a=0;a<ordernum;a++)
{
int x,y;
o=co[order[a]].o;
fill_curobj=order[a];
vis_drawobject(o);
co[order[a]].on=!o->vf;
if(!drawpass)
{
print("[%s(%i): %li (v%i)]\n",co[order[a]].name,order[a],co[order[a]].dist,o->pl[0][1]);
if(!o->vf)
{
x=o->pv[o->pl[0][1]].x;
y=o->pv[o->pl[0][1]].y;
x=x+y*320;
vram[x]=255;
vram[x-1]=255;
vram[x+1]=255;
vram[x-320]=255;
vram[x+320]=255;
}
}
}
if(!drawpass)
{
print("\n");
}
}
}

BIN
VISU/C/MAIN.OBJ Normal file

Binary file not shown.

4
VISU/C/MAK.BAT Normal file
View file

@ -0,0 +1,4 @@
cd ..
nmake
cd c
nmake c.exe

46
VISU/C/MAKEFILE Normal file
View file

@ -0,0 +1,46 @@
all : c.exe cplay.exe city.exe srvec.exe u2a.exe u2e.exe
#all : u2e.exe
# objects
objs=main.obj
main.c : readvue.c readinf.c readmat.c readasc.c util.c opt.c save.c osort.c
# option flags
asm_f = /ML /m9 /s /JJUMPS
cdeb_f = /AL /c /W2 /Zi
c_f = /AL /Oxaz /W2 /c
# general compile orders
.asm.obj :
tasm $(asm_f) $<
.c.obj :
cl /qc $(c_f) $<
c.exe : $(objs) ..\visu.lib
link /CO /E /ST:8192 $(objs),c.exe,nul,..\visu.lib;
cplay.obj : cplay.c
cl $(c_f) cplay.c
cplay.exe : cplay.obj ..\visu.lib
link /CO /E /ST:2048 cplay.obj,cplay.exe,nul,..\visu.lib;
city.exe : city.obj ..\visu.lib
link /CO /E /ST:2048 city.obj,city.exe,nul,..\visu.lib;
srvec.exe : srvec.obj ..\visu.lib
link /CO /E /ST:2048 srvec.obj,srvec.exe,nul,..\visu.lib;
u2a.exe : u2a.obj ..\visu.lib
link /E /ST:2048 u2a.obj+_bg.obk+..\..\dis\disc.obj,u2a.exe,nul,..\visu.lib;
copy u2a.exe ..\..\main\data
u2e.exe : u2e.obj ..\visu.lib
link /E /ST:2048 u2e.obj ..\..\dis\disc.obj,u2e.exe,nul,..\visu.lib;
copy u2e.exe ..\..\main\data

132
VISU/C/OPT.C Normal file
View file

@ -0,0 +1,132 @@
/* ASC optimization from:
char oname[64];
struct s_tmpvx *vx;
struct s_tmpfc *fc;
int vxnum,fcnum,vxleft,fcleft;
to:
int facedata[32767],facedatalen;
int faceoff[MAXFC],facenum;
*/
int currentface;
int connects[256],connectp;
int pvnum;
int pv[MAXFACE];
void padd(int v) // add vertex to pv
{
if(pvnum && pv[pvnum-1]==v) return;
pv[pvnum++]=v;
if(pvnum>=MAXFACE)
{
int a;
printf("FATAL ERROR: FACE OVERFLOW (SEE REPORT)");
print("FATAL: FACE %i OVERFLOWS (max %i sides) [",currentface,MAXFACE);
for(a=0;a<connectp;a++) print("%i ",connects[a]);
print("]");
exit(3);
}
}
void pexpand(struct s_tmpfc *f,int i,int cntn) // add face to pv
{
int k,l,v1,v2,cnt;
if(f->used) return;
f->used=1;
for(cnt=0;cnt<cntn;cnt++)
{
if(f->vv[i]) padd(f->v[i]);
else
{ // find the polygon on side and recurse
l=-1; // nothing found
v1=f->v[(i==2)?0:i+1];
v2=f->v[i];
for(k=0;k<fcnum;k++) if(!fc[k].used)
{
if(fc[k].v[0]==v1 && fc[k].v[1]==v2)
{
l=1; break;
}
if(fc[k].v[1]==v1 && fc[k].v[2]==v2)
{
l=2; break;
}
if(fc[k].v[2]==v1 && fc[k].v[0]==v2)
{
l=0; break;
}
}
if(l==-1)
{ // failed to find
padd(f->v[i]);
}
else
{
connects[connectp++]=k;
pexpand(fc+k,l,2);
}
}
i=(i==2)?0:i+1;
}
}
void optimize(void)
{
int nrm,i,j,flags,a;
facedatalen=facenum=0;
facedata[facedatalen++]=0; // 'null' face
for(j=0;j<vxnum;j++)
{
gvx[j].x=gvx[j].y=gvx[j].z=gvx[j].power=0;
}
for(i=0;i<fcnum;i++)
{
currentface=i;
connectp=0;
pvnum=0;
connects[connectp++]=i;
pexpand(fc+i,0,3);
if(pvnum)
{
long x=0,y=0,z=0;
// calc normal
{
struct s_tmpvx *v;
struct s_tmpvx *w;
int a,b;
double dl;
for(a=0;a<pvnum;a++)
{
v=vx+pv[a];
w=vx+pv[a?(a-1):(pvnum-1)];
x+=(v->y-w->y)*(v->z+w->z);
y+=(v->z-w->z)*(v->x+w->x);
z+=(v->x-w->x)*(v->y+w->y);
}
dl=sqrt((double)x*(double)x+(double)y*(double)y+(double)z*(double)z);
if(dl<-1 || dl>1)
{
x=-(long)((double)x*NORMALSIZE/dl);
y=-(long)((double)y*NORMALSIZE/dl);
z=-(long)((double)z*NORMALSIZE/dl);
}
nrm=addnr(x,y,z);
}
// write stuff
flags=mat[fc[i].material].flags;
faceoff[facenum++]=facedatalen*2; // char offset
facedata[facedatalen++]=pvnum|flags; // sides | flags
facedata[facedatalen++]=mat[fc[i].material].color; // color
facedata[facedatalen++]=nrm; // normal
for(j=0;j<pvnum;j++)
{
a=pv[j];
gvx[a].x+=x;
gvx[a].y+=y;
gvx[a].z+=z;
gvx[a].power++;
facedata[facedatalen++]=a;
}
}
}
}

271
VISU/C/OSORT.BBK Normal file
View file

@ -0,0 +1,271 @@
// object sorting
long osx,osy,osz; // sorting eye
long aosx,aosy,aosz; // sorting eye
long bosx,bosy,bosz; // sorting eye
static long osd=0;
void osetup(object *o,int flag)
{ // sets up camera distance etc for good viewing
long cx,cy,cz;
long ox,oy,oz;
long d=osd;
int a,c;
vlist *v;
for(c=0;c<64;c++)
{
ox=osx*d/256L;
oy=osy*d/256L;
oz=osz*d/256L;
v=o->v0+o->pl[0][1];
cx=v->x;
cy=v->y;
cz=v->z;
calc_setrmatrix_camera(o->r,ox+cx,oy+cy,oz+cz,cx,cy,cz);
calc_nrotate(o->nnum1,o->n,o->n0,o->r);
calc_rotate(o->vnum,o->v,o->v0,o->r);
calc_project(o->vnum,o->pv,o->v);
if(!flag) break;
for(a=0;a<o->vnum;a++) if(o->pv[a].vf) break;
if(a==o->vnum) break;
d=d*4/3;
}
if(osd<d) osd=d;
}
void sortdir(int d,long *osx,long *osy,long *osz)
{
switch(d)
{
case 0 : *osx=-256; *osy=-256; *osz=-256; break;
case 1 : *osx=256; *osy=-256; *osz=-256; break;
case 2 : *osx=256; *osy=256; *osz=-256; break;
case 3 : *osx=-256; *osy=256; *osz=-256; break;
case 4 : *osx=-256; *osy=-256; *osz=256; break;
case 5 : *osx=256; *osy=-256; *osz=256; break;
case 6 : *osx=256; *osy=256; *osz=256; break;
case 7 : *osx=-256; *osy=256; *osz=256; break;
default : *osx=*osy=*osz=0; break;
}
}
struct s_osp
{
long dis; // distance maximum
long dismin; // distance minimum
long a,b,c,d; // plane equation
int o; // offset
int swapped;
} osp[MAXFC];
struct s_osp osptmp;
int qcmp(struct s_osp *a,struct s_osp *b)
{
if(a->dis>b->dis) return(-1);
if(a->dis<b->dis) return(1);
return(0);
}
// -1=j farther than i (swap)
// 0==indetermined
// 1==i farther than j (ok)
// 2==i farther than j.. (next)}
int planecompare(struct s_osp *i,struct s_osp *j,object *o)
{
int *ip,*pp;
long d1=0,d2=0,dc=0,d,d1a,d2a;
int d1c=0,d2c=0;
int a,c;
if(i->dismin>j->dis) return(2);
pp=(int *)(j->o+(char *)(o->pd));
c=*pp++; // sides
c&=0xff;
pp++; // skip color
pp++; // skip normal
while(c--)
{
a=*pp++;
d=(long)(((double)o->v[a].x*(double)i->a+(double)o->v[a].y*(double)i->b+(double)o->v[a].z*(double)i->c+(double)i->d)/10000.0);
if(debcount<100)
{
fprintf(fdeb,"%id:%li\n",c,d);
debcount++;
}
if(d<0) { d1+=d; d1c++; }
else { d2+=d; d2c++; }
}
if(d1c) d1/=d1c;
if(d2c) d2/=d2c;
// camera at zero, so dc=i->d;
dc=i->d;
if(d1<0) d1a=-d1; else d1a=d1;
if(d2<0) d2a=-d2; else d2a=d2;
if(d1a>d2a)
{
if(d1>0 && dc>0) return(1);
return(-1);
}
else
{
if(d2>0 && dc>0) return(1);
return(-1);
}
}
void objectsort(object *o)
{
static int skipw=0;
long z,z1,z2;
long px,py,pz,pa,pb,pc,pd,td;
int fbak,i,j;
int d,a,c,b,n,onum;
int changed;
int *ip,*pp;
osd=256;
for(d=0;d<8;d++)
{
sortdir(d,&osx,&osy,&osz);
osetup(o,1);
}
for(d=0;d<8;d++)
{
aosx=osx;
aosy=osy;
aosz=osz;
sortdir(d,&osx,&osy,&osz);
bosx=osx;
bosy=osy;
bosz=osz;
if(d && !skipw)
{
for(a=0;a<=64;a+=2)
{
b=64-a;
osx=(aosx*(long)b+bosx*(long)a)>>6;
osy=(aosy*(long)b+bosy*(long)a)>>6;
osz=(aosz*(long)b+bosz*(long)a)>>6;
osetup(o,0);
fbak=o->flags;
o->flags&=~(F_GOURAUD);
vNext();
vis_drawobject(o);
o->flags=fbak;
}
}
osx=bosx;
osy=bosy;
osz=bosz;
osetup(o,0);
ip=o->pl[0]+2;
onum=0;
while(*ip)
{
osp[onum].o=*ip++;
pp=(int *)(osp[onum].o+(char *)o->pd);
c=*pp++; // sides
c&=0xff;
pp++; // skip color
n=*pp++; // skip normal
z=0; z2=0x7fffffff;
while(c--)
{
a=*pp++;
if(c==1)
{
px=o->v[a].x;
py=o->v[a].y;
pz=o->v[a].z;
}
z1=o->v[a].z;
if(z1>z) z=z1;
if(z1<z2) z2=z1;
}
osp[onum].a=pa=o->n[n].x;
osp[onum].b=pb=o->n[n].y;
osp[onum].c=pc=o->n[n].z;
osp[onum].d=pd=-px*pa-py*pb-pz*pc;
osp[onum].dis=z;
osp[onum].dismin=z2;
pp=(int *)(osp[onum].o+(char *)o->pd);
c=*pp++; // sides
c&=0xff;
pp++; // skip color
pp++; // skip normal
while(c--)
{
a=*pp++;
td=o->v[a].x*pa+o->v[a].y*pb+o->v[a].z*pc+pd;
/*
if(debcount<100)
{
fprintf(fdeb,"%id:%li\n",c,td);
debcount++;
}
*/
}
onum++;
}
qsort(osp,onum,sizeof(osp[0]),qcmp);
//resort by planes
#if 1
for(j=0;j<onum;j++) osp[j].swapped=0;
for(i=0;i<onum;i++)
{
changed=0;
for(j=i+1;j<onum;j++)
{
a=planecompare(osp+i,osp+j,o);
// -1=j farther than i (swap)
// 0==indetermined
// 1==i farther than j (ok)
// 2==i farther than j.. (next)
if(a==2) break;
else if(a==-1)
{
if(osp[j].swapped) continue; // no double swap
changed=1;
memcpy(&osptmp,osp+j,sizeof(osptmp));
memcpy(osp+j,osp+i,sizeof(osptmp));
memcpy(osp+i,&osptmp,sizeof(osptmp));
osp[j].swapped=1;
j=-1;
}
}
if(changed) i--;
else for(j=i+1;j<onum;j++) osp[j].swapped=0;
}
#endif
o->plnum=d+2;
ip=o->pl[d+1];
*ip++=onum+3;
ip++; // skip center vertex id
for(a=0;a<onum;a++)
{
*ip++=osp[a].o;
}
*ip++=0;
fbak=o->flags;
o->flags&=~(F_GOURAUD);
vNext();
vis_drawobject(o);
if(!skipw)
{
vNext();
vis_drawobject(o);
vNext();
vis_drawobject(o);
vNext();
vis_drawobject(o);
a=getch();
if(a==13) skipw=1;
}
o->flags=fbak;
}
}

322
VISU/C/OSORT.C Normal file
View file

@ -0,0 +1,322 @@
// object sorting
//#define SORTDIRS 6
#define SORTDIRS 8
long osx,osy,osz; // sorting eye
long aosx,aosy,aosz; // sorting eye
long bosx,bosy,bosz; // sorting eye
static long osd=0;
void osetup(object *o,int flag)
{ // sets up camera distance etc for good viewing
long cx,cy,cz;
long ox,oy,oz;
long d=osd;
int a,c;
vlist *v;
for(c=0;c<64;c++)
{
ox=osx*d/256L;
oy=osy*d/256L;
oz=osz*d/256L;
v=o->v0+o->pl[0][1];
cx=v->x;
cy=v->y;
cz=v->z;
calc_setrmatrix_camera(o->r,ox+cx,oy+cy,oz+cz,cx,cy,cz,0);
calc_nrotate(o->nnum1,o->n,o->n0,o->r);
calc_rotate(o->vnum,o->v,o->v0,o->r);
calc_project(o->vnum,o->pv,o->v);
if(!flag) break;
for(a=0;a<o->vnum;a++) if(o->pv[a].vf) break;
if(a==o->vnum) break;
d=d*4/3;
}
if(osd<d) osd=d;
}
void sortdir(int d,long *osx,long *osy,long *osz)
{
switch(d)
{
/*
case 0 : *osx=-256; *osy=0; *osz=0; break;
case 1 : *osy=-256; *osz=0; *osx=0; break;
case 2 : *osz=-256; *osx=30; *osy=30; break;
case 3 : *osx=256; *osy=0; *osz=0; break;
case 4 : *osy=256; *osz=0; *osx=0; break;
case 5 : *osz=256; *osx=30; *osy=30; break;
*/
case 0 : *osx=-256; *osy=-256; *osz=-256; break;
case 1 : *osx=256; *osy=-256; *osz=-256; break;
case 2 : *osx=256; *osy=256; *osz=-256; break;
case 3 : *osx=-256; *osy=256; *osz=-256; break;
case 4 : *osx=-256; *osy=-256; *osz=256; break;
case 5 : *osx=256; *osy=-256; *osz=256; break;
case 6 : *osx=256; *osy=256; *osz=256; break;
case 7 : *osx=-256; *osy=256; *osz=256; break;
case 8 : *osx=-366; *osy=0; *osz=0; break;
/*
case 0 : *osx=-256; *osy=-256; *osz=-256; break;
case 1 : *osx=256; *osy=-256; *osz=-256; break;
case 2 : *osx=256; *osy=256; *osz=-256; break;
case 3 : *osx=-256; *osy=256; *osz=-256; break;
case 4 : *osx=-256; *osy=-256; *osz=256; break;
case 5 : *osx=0; *osy=366; *osz=0; break;
case 6 : *osx=256; *osy=-256; *osz=256; break;
case 7 : *osx=0; *osy=-366; *osz=0; break;
case 8 : *osx=256; *osy=256; *osz=256; break;
case 9 : *osx=-366; *osy=0; *osz=0; break;
case 10 : *osx=-256; *osy=256; *osz=256; break;
case 11 : *osx=366; *osy=0; *osz=0; break;
case 12 : *osx=30; *osy=30; *osz=-366; break;
case 13 : *osx=30; *osy=30; *osz=366; break;
*/
default : *osx=*osy=*osz=0; break;
}
}
struct s_osp
{
long dis; // distance maximum
long dismin; // distance minimum
long a,b,c,d; // plane equation
int o; // offset
int swapped;
} osp[MAXFC];
struct s_osp osptmp;
int qcmp(struct s_osp *a,struct s_osp *b)
{
if(a->dis>b->dis) return(-1);
if(a->dis<b->dis) return(1);
return(0);
}
// -1=j farther than i (swap)
// 0==indetermined
// 1==i farther than j (ok)
// 2==i farther than j.. (next)}
int planecompare(struct s_osp *i,struct s_osp *j,object *o,int flag)
{
int *ip,*pp;
long d1=0,d2=0,dc=0,d,d1a,d2a,dd;
int d1c=0,d2c=0;
int a,c,r;
if(i->dismin>j->dis) return(2);
pp=(int *)(j->o+(char *)(o->pd));
c=*pp++; // sides
c&=0xff;
pp++; // skip color
pp++; // skip normal
//fprintf(fdeb,"compare i=f%i(%i) with j=f%i(%i)\n",i-osp,i->o,j-osp,j->o);
while(c--)
{
a=*pp++;
d=(long)(((double)o->v[a].x*(double)i->a+(double)o->v[a].y*(double)i->b+(double)o->v[a].z*(double)i->c+(double)i->d)/1000.0);
if(debcount<1000)
{
//fprintf(fdeb,"v%i:%li ",a,d);
debcount++;
}
if(d<0) { d1+=d; d1c++; }
else { d2+=d; d2c++; }
}
if(d1c) d1/=d1c;
if(d2c) d2/=d2c;
// camera at zero, so dc=i->d;
dc=i->d;
if(d1<0) d1a=-d1; else d1a=d1;
if(d2<0) d2a=-d2; else d2a=d2;
d=d1a-d2a; if(d<0) d=-d;
dd=(d1a+d2a)/8;
if(d<dd) return(0); // comaparator face cuts this one in middle
//fprintf(fdeb,"\ncamera at %li, d1=%li, d1c=%i, d2=%li, d2c=%i, d1a=%li d2a=%li\n",dc,d1,d1c,d2,d2c,d1a,d2a);
if(d1a>d2a)
{
if(d1>0 && dc>0) r=1;
else if(d1<0 && dc<0) r=1;
else r=-1;
}
else
{
if(d2>0 && dc>0) r=1;
else if(d2<0 && dc<0) r=1;
else r=-1;
}
if(flag)
{
a=planecompare(j,i,o,0);
if(a==r) r=0;
//fprintf(fdeb,"returns %i\n\n",r);
}
return(r);
}
void objectsort(object *o)
{
static int skipw=0;
long z,z1,z2;
long px,py,pz,pa,pb,pc,pd,td;
int fbak,i,j,k;
int d,a,c,b,n,onum;
int changed;
int *ip,*pp;
osd=256;
for(d=0;d<SORTDIRS;d++)
{
sortdir(d,&osx,&osy,&osz);
osetup(o,1);
}
for(d=0;d<SORTDIRS;d++)
{
aosx=osx;
aosy=osy;
aosz=osz;
sortdir(d,&osx,&osy,&osz);
bosx=osx;
bosy=osy;
bosz=osz;
if(d && !skipw)
{
for(a=0;a<=64;a+=2)
{
b=64-a;
osx=(aosx*(long)b+bosx*(long)a)>>6;
osy=(aosy*(long)b+bosy*(long)a)>>6;
osz=(aosz*(long)b+bosz*(long)a)>>6;
osetup(o,0);
fbak=o->flags;
o->flags&=~(F_GOURAUD);
vNext();
vis_drawobject(o);
o->flags=fbak;
}
}
osx=bosx;
osy=bosy;
osz=bosz;
osetup(o,0);
ip=o->pl[0]+2;
onum=0;
while(*ip)
{
a=osp[onum].o=*ip++;
pp=(int *)(osp[onum].o+(char *)o->pd);
c=*pp++; // sides
c&=0xff;
if(a!=68 && a!=56)
{
// *pp=-1;
}
pp++; // skip color
n=*pp++; // skip normal
z=0; z2=0x7fffffff;
//fprintf(fdeb,"face %i: ",osp[onum].o);
while(c--)
{
a=*pp++;
//fprintf(fdeb,"%i ",a);
if(c==1)
{
px=o->v[a].x;
py=o->v[a].y;
pz=o->v[a].z;
}
z1=o->v[a].z;
if(z1>z) z=z1;
if(z1<z2) z2=z1;
}
//fprintf(fdeb,"\n");
osp[onum].a=pa=o->n[n].x/4;
osp[onum].b=pb=o->n[n].y/4;
osp[onum].c=pc=o->n[n].z/4;
osp[onum].d=pd=-px*pa-py*pb-pz*pc;
osp[onum].dis=z;
osp[onum].dismin=z2;
pp=(int *)(osp[onum].o+(char *)o->pd);
c=*pp++; // sides
c&=0xff;
pp++; // skip color
pp++; // skip normal
while(c--)
{
a=*pp++;
td=o->v[a].x*pa+o->v[a].y*pb+o->v[a].z*pc+pd;
}
onum++;
}
qsort(osp,onum,sizeof(osp[0]),qcmp);
//resort by planes
#if 0
for(i=0;i<onum;i++)
{
for(k=i+1;k<onum;k++)
{
for(j=k;j<onum;j++)
{
for(a=0;a<8;a++)
{
//fprintf(fdeb,"%i%c ",osp[a].o,osp[a].swapped?'*':'.');
}
//fprintf(fdeb,"\n");
a=planecompare(osp+i,osp+j,o,1);
// -1=j farther than i (swap)
// 0==indetermined
// 1==i farther than j (ok)
// 2==i farther than j.. (next)
/*
if(a==2)
{
j=onum;
break;
}
else */
if(a==-1)
{
break;
}
}
if(j==onum) break; //all faces after i were before it
memcpy(&osptmp,osp+k,sizeof(osptmp));
memcpy(osp+k,osp+i,sizeof(osptmp));
memcpy(osp+i,&osptmp,sizeof(osptmp));
}
}
#endif
o->plnum=d+2;
ip=o->pl[d+1];
*ip++=onum+3;
ip++; // skip center vertex id
for(a=0;a<onum;a++)
{
*ip++=osp[a].o;
}
*ip++=0;
fbak=o->flags;
o->flags&=~(F_GOURAUD);
vNext();
vis_drawobject(o);
if(!skipw)
{
vNext();
vis_drawobject(o);
vNext();
vis_drawobject(o);
vNext();
vis_drawobject(o);
a=getch();
if(a==27) break;
if(a==13) skipw=1;
}
o->flags=fbak;
}
}

BIN
VISU/C/PIC003.UH Normal file

Binary file not shown.

2
VISU/C/PLAY.BAT Normal file
View file

@ -0,0 +1,2 @@
fake " "
plays3m -xplaycity musa.s3m

1
VISU/C/PLAYCITY.BAT Normal file
View file

@ -0,0 +1 @@
cplay city

BIN
VISU/C/PLAYS3M.EXE Normal file

Binary file not shown.

396
VISU/C/READASC.C Normal file
View file

@ -0,0 +1,396 @@
// temporary structs for loading
struct s_tmpvx
{
long x;
long y;
long z;
int power; // for center
};
struct s_tmpnr
{
long x;
long y;
long z;
};
struct s_tmpgnr // gouraud normal
{
long x;
long y;
long z;
int power;
};
struct s_tmpfc
{
int v[3]; // vertex number
char vv[3]; // vertex (edge) visible
char used;
char material;
};
// buffers for reading objects from asc
char oname[64];
int vxleft,fcleft;
int vxmap[MAXVX];
struct s_tmpvx vxdata[MAXVX];
struct s_tmpnr nrdata[MAXNR];
struct s_tmpgnr gvxdata[MAXVX];
struct s_tmpfc fcdata[MAXFC];
struct s_tmpvx *vx=vxdata;
struct s_tmpnr *nr=nrdata;
struct s_tmpfc *fc=fcdata;
struct s_tmpgnr *gvx=gvxdata;
int vxnum,fcnum,nrnum,nrnum1;
int vxcount,fccount; // original in 3DS
int facedata[16384],facedatalen; // len=words
int faceoff[MAXFC],facenum;
#include "opt.c"
int addvx(long x,long y,long z)
{
int i;
for(i=0;i<vxnum;i++)
{
if(vx[i].x==x && vx[i].y==y && vx[i].z==z)
{
vx[i].power++;
return(i);
}
}
vx[vxnum].power=1;
gvx[vxnum].power=0;
vx[vxnum].x=x;
vx[vxnum].y=y;
vx[vxnum].z=z;
return(vxnum++);
}
int addnr(long x,long y,long z)
{
int i;
for(i=0;i<nrnum;i++)
{
if(nr[i].x==x && nr[i].y==y && nr[i].z==z)
{
return(i);
}
}
nr[nrnum].x=x;
nr[nrnum].y=y;
nr[nrnum].z=z;
return(nrnum++);
}
void resetscene(void)
{
struct s_cobject *co1;
int i,a;
co1=co;
for(i=0;i<conum;i++)
{
co1->last_on=0;
co1->last_x=0;
co1->last_y=0;
co1->last_z=0;
for(a=0;a<9;a++) co1->last_m[a]=0;
co1++;
}
}
int duplicate(struct s_cobject *co0)
{
int a;
struct s_cobject *co1;
co1=co+conum;
co1->index=co0->index;
strcpy(co1->name,co0->name);
co1->last_on=0;
co1->last_x=0;
co1->last_y=0;
co1->last_z=0;
for(a=0;a<9;a++) co1->last_m[a]=0;
co1->lastused=-1;
co1->duplicate=1;
co1->original=co0-co;
co1->size=co0->size;
strcpy(co1->fname,co0->fname);
co1->o=getmem(sizeof(object));
memcpy(co1->o,co0->o,sizeof(object));
// new object needs new matrices
co1->o->r=getmem(sizeof(rmatrix));
co1->o->r0=getmem(sizeof(rmatrix));
memset(co1->o->r,0,sizeof(rmatrix));
memset(co1->o->r0,0,sizeof(rmatrix));
return(conum++);
}
struct s_cobject *create(void)
{
int a;
object *o;
co[conum].o=o=getmem(sizeof(object));
memcpy(co[conum].name,oname,17);
co[conum].name[17]=0;
co[conum].index=conum;
co[conum].last_on=0;
co[conum].last_x=0;
co[conum].last_y=0;
co[conum].last_z=0;
for(a=0;a<9;a++) co[conum].last_m[a]=0;
o->flags=F_DEFAULT;
o->r=getmem(sizeof(rmatrix));
o->r0=getmem(sizeof(rmatrix));
calc_setrmatrix_ident(o->r0);
o->r0->x=o->r0->y=o->r0->z=0;
o->pd=getmem(facedatalen*2);
o->pdlen=facedatalen*2;
o->plnum=1;
for(a=0;a<SORTDIRS+1;a++)
{
o->pl[a]=getmem((3+facenum)*2);
}
o->nnum=nrnum;
o->nnum1=nrnum1;
o->vnum=vxnum;
o->v0=getmem(vxnum*sizeof(vlist));
o->n0=getmem(nrnum*sizeof(nlist));
o->v=getmem(vxnum*sizeof(vlist));
o->n=getmem(nrnum*sizeof(nlist));
o->pv=getmem(vxnum*sizeof(pvlist));
o->vf=0;
// copy vertices etc to just allocated object
for(a=0;a<vxnum;a++)
{
o->v0[a].x=vx[a].x;
o->v0[a].y=vx[a].y;
o->v0[a].z=vx[a].z;
o->v0[a].normal=vx[a].power; // power=normal
o->v0[a].RESERVED=0xfc;
}
for(a=0;a<nrnum;a++)
{
o->n0[a].x=(int)nr[a].x;
o->n0[a].y=(int)nr[a].y;
o->n0[a].z=(int)nr[a].z;
o->n0[a].RESERVED=0xfc;
}
memcpy(o->pd,facedata,facedatalen*2);
memcpy(o->pl[0]+2,faceoff,2*facenum);
o->pl[0][0]=facenum+3; // words in list
o->pl[0][1]=0; // closest=center in list 0 (set later)
o->pl[0][facenum+2]=0; // end
return(co+(conum++));
}
int calccenter(void)
{
long x,y,z,p;
int a;
for(x=y=z=0,a=1;a<vxnum;a++)
{
p=vx[a].power;
x+=vx[a].x*p; y+=vx[a].y*p; z+=vx[a].z*p;
}
if(vxnum>1)
{
x/=vxnum-1; y/=vxnum-1; z/=vxnum-1;
}
print("Centerxyz: %li,%li,%li\n",x,y,z);
return(addvx(x,y,z));
}
void unify(long *x,long *y,long *z)
{
double d;
d=sqrt((double)*x*(double)*x+(double)*y*(double)*y+(double)*z*(double)*z);
if(!d) return;
d=1/d;
*x=(long)(NORMALSIZE*(double)*x*d);
*y=(long)(NORMALSIZE*(double)*y*d);
*z=(long)(NORMALSIZE*(double)*z*d);
}
void objectdone(void)
{
long x,y,z;
long cx,cy,cz;
int svx[SORTDIRS+1];
int a,center;
struct s_cobject *co;
if(vxleft || fcleft) error("Not all vertices (%i missing) or faces (%i missing) found!",vxleft,fcleft);
optimize(); // combines triangles to larger faces and creates polydata
center=calccenter(); // calculate center
cx=vx[center].x;
cy=vx[center].y;
cz=vx[center].z;
for(a=0;a<SORTDIRS;a++) // calculate box for Z sort
{
sortdir(a,&x,&y,&z);
svx[a]=addvx(x+cx,y+cy,z+cz);
}
nrnum1=nrnum;
// add gouraud normals
for(a=0;a<vxnum;a++) if(gvx[a].power)
{
x=gvx[a].x/gvx[a].power;
y=gvx[a].y/gvx[a].power;
z=gvx[a].z/gvx[a].power;
unify(&x,&y,&z);
vx[a].power=addnr(x,y,z);
}
else vx[a].power=-1;
// all vertices & normals should be in tmp structs now!
co=create(); // allocate memory for object and copy data to it
co->duplicate=0;
co->original=conum-1;
co->lastused=-1;
co->o->pl[0][1]=center; // sortlist0's closest vertex should be center
for(a=0;a<SORTDIRS;a++) co->o->pl[a+1][1]=svx[a];
print(" Faces: %i => %i\n",fccount,facenum);
print(" Normals: %i => %i (%i)\n",fccount,nrnum1,nrnum);
print("Vertices: %i => %i\n",vxcount,vxnum);
co->f1=fccount; co->f2=facenum;
co->n1=fccount; co->n2=nrnum1; co->ng=nrnum;
co->v1=vxcount; co->v2=vxnum;
*oname=0;
}
void readasc(void)
{
char tmp[256];
int a,b,i1,i2,i3;
int i1v,i2v,i3v;
long x,y,z;
float f,fx,fy,fz;
char *p,*p0,*t;
print("\n");
print(">>>>>>>>>>>>>>>> ASC file <<<<<<<<<<<<<<<<\n");
print("\n");
while(!feof(in))
{
p0=p=getline();
if(emptyline(p)) continue;
// process line
t=getfirsttoken(&p);
IFT("Named")
{
if(*oname)
{
objectdone();
print("}\n");
print("\n");
}
gettoken(&p); // 'object:'
t=gettoken(&p);
strcpy(tmp,t);
do
{
p0=p=getline();
}
while(emptyline(p));
IFS(p,"Tri-mesh")
{
print("TRIMESH %s\n",tmp);
strcpy(oname,tmp);
p=p0;
getseek(&p,"Vertices:");
i1=getint(&p);
p=p0;
getseek(&p,"Faces:");
i2=getint(&p);
print("vertices:%i faces:%i\n",i1,i2);
print("{\n");
//
vxnum=0;
nrnum=0;
fcnum=0;
vxcount=vxleft=i1;
fccount=fcleft=i2;
//
}
else
{
print("SKIPPING OBJECT %s (%s)\n",tmp,p);
}
continue;
}
if(!*oname) continue; // no object being processed!
IFT("Vertex")
{
t=gettoken(&p);
IFT("list:") continue;
i1=atoi(t);
//if(i1!=vxnum) error("Vertex indices out of order");
getxxyyzz(&p,&x,&y,&z);
vxmap[i1]=addvx(x,y,z);
print("vertex %i (%li,%li,%li)\n",i1,x,y,z);
vxleft--;
}
else IFT("Smoothing:")
{
// skip smoothing groups for now
}
else IFT("Material:")
{
t=p0+10;
for(a=0;a<strlen(t);a++) if(t[a]=='\"')
{
t[a]=0;
break;
}
b=strlen(t);
for(a=0;a<matnum;a++)
{
if(!memcmp(t,mat[a].name,b))
{
fc[fcnum-1].material=a;
break;
}
}
}
else IFT("Face")
{
t=gettoken(&p);
IFT("list:") continue;
a=atoi(t);
if(a!=fcnum) error("Face indices out of order");
t=gettoken(&p);
i1=atoi(t+2);
t=gettoken(&p);
i2=atoi(t+2);
t=gettoken(&p);
i3=atoi(t+2);
t=gettoken(&p);
i1v=t[3]-'0';
t=gettoken(&p);
i2v=t[3]-'0';
t=gettoken(&p);
i3v=t[3]-'0';
fc[fcnum].v[0]=vxmap[i1];
fc[fcnum].v[1]=vxmap[i2];
fc[fcnum].v[2]=vxmap[i3];
fc[fcnum].vv[0]=(char)i1v;
fc[fcnum].vv[1]=(char)i2v;
fc[fcnum].vv[2]=(char)i3v;
fc[fcnum].used=0;
fc[fcnum].material=0;
print("face %i (%c%i,%c%i,%c%i)\n",a,
i1v?'+':'-',i1,
i2v?'+':'-',i2,
i3v?'+':'-',i3);
fcnum++;
fcleft--;
}
else print("Unknown: %s\n",t);
if(debug) print(" (%s)\n",p0);
}
if(*oname)
{
objectdone();
print("}\n");
print("\n");
}
}

43
VISU/C/READINF.C Normal file
View file

@ -0,0 +1,43 @@
void readinf(void)
{
char tmp[256];
int a,b,c,d;
object *o;
char *p,*p0,*t;
matnum=0;
while(!feof(in))
{
p0=p=getline();
if(*p==';') continue;
t=gettoken(&p);
IFT("scene")
{
t=gettoken(&p);
a=atoi(t);
in2=in;
resetscene();
doscene(a);
in=in2;
}
else IFT("hide")
{
t=gettoken(&p);
o=findobject(t,-9);
o->flags&=~(F_VISIBLE);
}
else IFT("show")
{
t=gettoken(&p);
o=findobject(t,-9);
o->flags|=(F_VISIBLE);
}
else IFT("fov")
{
t=gettoken(&p);
a=atoi(t);
usefov=a;
}
}
printf("\n\n");
}

61
VISU/C/READMAT.C Normal file
View file

@ -0,0 +1,61 @@
void readmat(void)
{
char tmp[256];
int a,b,c,d;
char *p,*p0,*t;
matnum=0;
printf("Materials:\n");
while(!feof(in))
{
p0=p=getline();
if(*p==';') continue;
if(*p)
{
t=gettoken(&p);
for(a=0;a<strlen(t);a++) if(t[a]=='#') t[a]=' ';
strcpy(mat[matnum].name,t);
mat[matnum].color=0;
mat[matnum].flags=0;
mat[matnum].colorlen=1;
while(*p)
{
t=gettoken(&p);
a=toupper(*t);
switch(a)
{
case 'X' :
mat[matnum].flags|=F_2SIDE;
break;
case 'L' :
mat[matnum].colorlen=atoi(t+1);
break;
case 'G' :
mat[matnum].flags|=F_GOURAUD;
break;
default :
if(a>='0' && a<='9')
{
mat[matnum].color=atoi(t);
}
break;
}
}
switch(mat[matnum].colorlen)
{
case 32 : mat[matnum].flags|=F_SHADE32; break;
case 16 : mat[matnum].flags|=F_SHADE16; break;
case 8 : mat[matnum].flags|=F_SHADE8; break;
case 1 : break;
default : printf("ILLEGAL COLOR LENGTH>> "); break;
}
sscanf(p,"%s %i %i",mat[matnum].name,&mat[matnum].color,&mat[matnum].colorlen);
printf("%s colors:%i..%i ",mat[matnum].name,mat[matnum].color,
mat[matnum].color+mat[matnum].colorlen-1);
if(mat[matnum].flags&F_GOURAUD) printf("Gouraud ");
if(mat[matnum].flags&F_TEXTURE) printf("Texture ");
printf("\n");
matnum++;
}
}
}

255
VISU/C/READVUE.C Normal file
View file

@ -0,0 +1,255 @@
int findobject_co;
object *findobject(char *t,int frame)
{
int i,l=strlen(t);
int found1=-1;
for(i=1;i<conum;i++)
{
if(!memcmp(co[i].name,t,l))
{
if(found1==-1) found1=i;
if(co[i].lastused!=frame)
{
findobject_co=i;
co[i].lastused=frame;
return(co[i].o);
}
}
}
if(found1!=-1)
{
print("^ Object %s duplicated.\n",t);
i=duplicate(co+found1);
co[i].lastused=frame;
findobject_co=i;
return(co[i].o);
}
print("ERROR: object %s not found!\n",t);
return(co[0].o);
}
int lsize(long l)
{
if(!l) return(0);
if(l>=-127 && l<=127) return(1);
if(l>=-32767 && l<=32767) return(2);
return(3);
}
void putl(long l,FILE *f)
{
putw(l&0xffff,f);
putw(l>>16,f);
}
void lwrite(int f,long l)
{
switch(f&3)
{
case 0 : break;
case 1 : putc(l,outb); break;
case 2 : putw(l,outb); break;
case 3 : putl(l,outb); break;
}
}
void readvue(void)
{
static int lastobject_co=0;
int a,ix,iy,visfield;
int frame;
long x,y,z,x2,y2,z2,ll;
float f,fx,fy,fz;
rmatrix tmpm;
rmatrix tmpm2;
char *p,*p0,*t;
object *o;
print("\n");
print(">>>>>>>>>>>>>>>> VUE file <<<<<<<<<<<<<<<<\n");
print("\n");
while(!feof(in))
{
p0=p=getline();
if(emptyline(p)) continue;
// process line
t=gettoken(&p);
IFT("frame")
{
t=gettoken(&p);
frame=a=atoi(t);
if(!drawpass)
{ // init stuff for script
lastobject_co=0;
}
print("FRAME %i\n",a);
if(kbhit()) break;
}
else IFT("transform")
{
t=gettoken(&p);
print("TRANSFORM %s",t);
o=findobject(t,frame);
o->r0->m[0]=(long)(UNIT*getfloat(&p));
o->r0->m[3]=(long)(UNIT*getfloat(&p));
o->r0->m[6]=(long)(UNIT*getfloat(&p));
o->r0->m[1]=(long)(UNIT*getfloat(&p));
o->r0->m[4]=(long)(UNIT*getfloat(&p));
o->r0->m[7]=(long)(UNIT*getfloat(&p));
o->r0->m[2]=(long)(UNIT*getfloat(&p));
o->r0->m[5]=(long)(UNIT*getfloat(&p));
o->r0->m[8]=(long)(UNIT*getfloat(&p));
getxyz(&p,&x,&y,&z);
o->r0->x=x;
o->r0->y=y;
o->r0->z=z;
print(" (xyz: %li %li %li)\n",x,y,z);
o->flags&=~(F_GOURAUD);
}
else IFT("camera")
{
getxyz(&p,&x2,&y2,&z2);
print("CAMERA (%li,%li,%li)->",x2,y2,z2);
getxyz(&p,&x,&y,&z);
print("(%li,%li,%li) ",x,y,z);
f=getfloat(&p); // roll
print("Roll:%f ",f);
a=(angle)f*65536L/360L;
calc_setrmatrix_camera(&camera,x2,y2,z2,x,y,z,a);
f=getfloat(&p); // field of vision
f=(float)usefov;
print("FOV:%f \n",f);
f=f*65536.0/360.0;
visfield=(angle)f;
visfield&=0xff00;
vid_cameraangle(visfield);
vDraw();
if(!drawpass)
{
int coi,coilast=0;
unsigned int u;
struct s_cobject *cop;
object *o;
for(coi=1;coi<conum;coi++)
{
co[coi].on=0;
}
// scan fill_object for truely visible objects
for(u=0;u<64000;u++)
{
a=fill_object[u];
if(a) co[a].on=1;
}
// camera always on!
co[0].on=1;
co[0].last_on=1;
fprintf(fdeb,"%i\n",conum);
for(coi=0;coi<conum;coi++)
{
int flag,a,b,pflaglen;
long pflag,mbytes;
long wx,wy,wz;
long l;
flag=pflag=pflaglen=0;
cop=co+coi;
o=cop->o;
fprintf(fdeb,"%s:%i\n",cop->name,cop->on);
if(!cop->on)
{ // object hidden
if(cop->last_on)
{
flag=0x40;
cop->last_on=0;
}
}
else
{ // visible
if(!cop->last_on)
{
flag=0x80;
cop->last_on=1;
}
l=o->r0->z - cop->last_z;
a=lsize(l); wz=l;
pflag<<=2; pflag|=a;
l=o->r0->y - cop->last_y;
a=lsize(l); wy=l;
pflag<<=2; pflag|=a;
l=o->r0->x - cop->last_x;
a=lsize(l); wx=l;
pflag<<=2; pflag|=a;
mbytes=1;
print("[pfl:%06lX]",pflag);
for(a=0;a<9;a++)
{
b=o->r0->m[a] - cop->last_m[a];
if(b<-127 || b>127) mbytes=0;
if(b) pflag|=0x80L<<a;
}
print("[pfl:%06lX]",pflag);
if(!mbytes) pflag|=0x40;
if(!pflag) pflaglen=0;
else if(!(pflag&0xffffff00L)) pflaglen=1;
else if(!(pflag&0xffff0000L)) pflaglen=2;
else pflaglen=3;
flag|=0x10*pflaglen;
}
if(flag)
{
if( (coi&0xff0)!=(coilast&0xff0) )
{
putc(0xC0|(coi>>4),outb);
putc((coi&0x0f)|flag,outb);
}
else
{
putc((coi&0x0f)|flag,outb);
}
coilast=coi;
if(pflaglen)
{
l=pflag;
while(pflaglen--)
{
putc(l,outb);
l>>=8;
}
print("[pfl:%06lX wxyz:%li,%li,%li]\n",pflag,wx,wy,wz);
lwrite(pflag,wx);
lwrite(pflag>>2,wy);
lwrite(pflag>>4,wz);
for(a=0;a<9;a++) if(pflag&(0x80<<a))
{
b=o->r0->m[a] - cop->last_m[a];
if(mbytes) putc(b,outb);
else putw(b,outb);
}
}
for(a=0;a<9;a++) cop->last_m[a]=o->r0->m[a];
cop->last_x=o->r0->x;
cop->last_y=o->r0->y;
cop->last_z=o->r0->z;
}
}
putc(0xff,outb);
putc(visfield>>8,outb);
}
}
else print("Unknown: %s\n",t);
if(debug) print(" (%s)\n",p0);
}
putc(0xff,outb);
putc(0xff,outb);
}

92
VISU/C/REPORT Normal file
View file

@ -0,0 +1,92 @@
Norton Disk Doctor II
Norton Utilities, 5.0
Sunday, 25 July 1993 23.38
*************************
* Report for Drive C: *
*************************
DISK TOTALS
-----------------------------------------
62 181 376 bytes Total Disk Space
60 704 768 bytes in 3 119 User Files
555 008 bytes in 263 Directories
337 920 bytes in 19 Hidden Files
583 680 bytes Available on the Disk
LOGICAL DISK INFORMATION
-----------------------------------------
Media Descriptor: F8
Large Partition: Yes
FAT Type: 16-bit
Total Sectors: 121 720
Total Clusters: 30 362
Bytes Per Sector: 512
Sectors Per Cluster: 4
Bytes Per Cluster: 2 048
Number of FATs: 2
First Sector of FAT: 1
Number of Sectors Per FAT: 119
First Sector of Root Dir: 239
Number of Sectors in Root Dir: 32
Maximum Root Dir File Entries: 512
First Sector of Data Area: 271
PHYSICAL DISK INFORMATION
-----------------------------------------
Drive Number: 80
Heads: 7
Cylinders: 1 023
Sectors Per Track: 17
Starting Head: 1
Starting Cylinder: 0
Starting Sector: 1
Ending Head: 6
Ending Cylinder: 1 022
Ending Sector: 17
SYSTEM AREA STATUS
-----------------------------------------
No Errors in the System Area
FILE STRUCTURE STATUS
-----------------------------------------
******************** Entries with an Invalid Cluster *******************
\MINCODE\VISU\C\c.exe
Status: Truncated
****************************** Lost Chains *****************************
Lost cluster chain at cluster 30 174
Status: Deleted
Lost cluster chain at cluster 30 175
Status: Deleted
Lost cluster chain at cluster 30 363
Status: Deleted
SURFACE TEST STATUS
-----------------------------------------
Test Settings
-----------------------
Test: Disk Test
Test Type: Daily
Repair Setting: Prompt before Repairing
Passes Requested: 1
Passes Completed: 1
Elapsed Time: 1 minute; 58 seconds
No Errors encountered in Surface Test

90
VISU/C/SAVE.C Normal file
View file

@ -0,0 +1,90 @@
long blockstack[16];
int blockstackp=0;
void beginblock(char *label)
{
blockstack[blockstackp]=ftell(outb);
blockstackp++;
putc(label[0],outb);
putc(label[1],outb);
putc(label[2],outb);
putc(label[3],outb);
putc(0xff,outb);
putc(0xff,outb);
putc(0xff,outb);
putc(0xff,outb);
}
void endblock(void)
{
long op,l;
op=ftell(outb);
while(op&3)
{
op++;
putc(0,outb);
}
blockstackp--;
l=blockstack[blockstackp];
fseek(outb,l+4,SEEK_SET);
l=op-l-8;
putc((int)l&255,outb); l>>=8;
putc((int)l&255,outb); l>>=8;
putc((int)l&255,outb); l>>=8;
putc((int)l&255,outb);
fseek(outb,op,SEEK_SET);
}
void saveobject(struct s_cobject *co)
{
object *o;
char fname[32];
long l;
int a,b;
o=co->o;
sprintf(fname,"%s.%03i",scenename,co->index);
outb=fopen(fname,"wb");
strcpy(co->fname,fname);
beginblock("VERS");
putw(0x0100,outb);
endblock();
beginblock("NAME");
fprintf(outb,co->name);
putc(0,outb);
endblock();
beginblock("VERT");
putw(o->vnum,outb);
putw(0,outb);
fwrite(o->v0,sizeof(vlist),o->vnum,outb);
endblock();
beginblock("NORM");
putw(o->nnum,outb);
putw(o->nnum1,outb);
fwrite(o->n0,sizeof(nlist),o->nnum,outb);
endblock();
beginblock("POLY");
fwrite(o->pd,1,o->pdlen,outb);
endblock();
for(b=0;b<o->plnum;b++)
{
if(!b) beginblock("ORD0");
else beginblock("ORDE");
fwrite(o->pl[b],2,o->pl[b][0],outb);
endblock();
}
beginblock("END ");
endblock();
co->size=ftell(outb);
fclose(outb);
}

BIN
VISU/C/SCENE.3DS Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2A.001 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2A.002 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2A.003 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2A.00M Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2A.0AA Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2A.0AB Normal file

Binary file not shown.

3
VISU/C/SCENE/U2A.INF Normal file
View file

@ -0,0 +1,3 @@
fov 48
scene 1

BIN
VISU/C/SCENE/U2A.LBM Normal file

Binary file not shown.

15
VISU/C/SCENE/U2A.MAT Normal file
View file

@ -0,0 +1,15 @@
;format: MATERIAL-NAME <parameters>
;parameters:
;#(number) first color in fade
;L# length of color fade (#=32/16/8/1=no fading)
;G gouraud
;X Two sided material
DEFAULT 96 L32
LIGHT_BLUE 32 L32 G
BLACK 0 L16 G
ORANGE 64 L32
GREY 128 L32 G
MOTOR 64 L32 G
POHJA 4 L16
COLOR00 0 L16

BIN
VISU/C/SCENE/U2A.PAL Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2A.PRJ Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2AOLD.PRJ Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.001 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.002 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.003 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.004 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.005 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.006 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.007 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.008 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.009 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.00M Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.010 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.011 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.012 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.013 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.014 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.015 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.016 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.017 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.018 Normal file

Binary file not shown.

BIN
VISU/C/SCENE/U2E.019 Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more