;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                         ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ideal
p386
model flat
stack 8000h
codeseg

extrn debug           : near
Zero_Addr             dd ?
Environment_Address   dd ?
PSP_Address           dd ?
_0B8000h              dd ?
_0A0000h              dd ?

include "..\sine.asm"
include "..\vesa_l.asm"
include "..\r2sr_l.asm"
include "pg3asm.asm"

ISR_event             db ?
ISR_pc                dd ?

pic_mt1               dd ?
angle1                dd 0
angle2                dd 0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                         ;
; edx = filename                                                          ;
;                                                                         ;
; returns esi = VGA bitmap, eax = VGA palette                             ;
;                                                                         ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
proc load_VGAbitmap
  mov    eax,3d00h
  int    21h
  mov    ebx,eax
  mov    eax,4202h
  xor    edx,edx
  int    21h
  push   eax eax
  mov    eax,4200h
  xor    edx,edx
  int    21h
  pop    edx
  mov    eax,0EE42h          ; allocate a DOS32 memory block
  Int    31h                 ;  expects EDX = size; ret EAX=size, EDX->pointer
  mov    esi,edx
  mov    ah,3fh
  pop    ecx
  int    21h
  push   eax
  mov    ah,3eh
  int    21h
  pop    eax
  sub    eax,768
  add    eax,esi
  ret
endp

pet1_fn               db "..\pb\pet1.vga",0
pet1_pic              dd ?

pet2_fn               db "..\pb\pet2.vga",0
pet2_pic              dd ?

proc load_data
  lea    edx,[pet1_fn]
  call   load_VGAbitmap
  mov    [pet1_pic],esi

  lea    edx,[pet2_fn]
  call   load_VGAbitmap
  mov    [pet2_pic],esi
  ret
endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                         ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
three_show_pal:
  X = 16 * 256
rept 64
  db                  (X / 256),(X / 256),(X / 256)
  X = X + 80h
endm

prism1_data:
include "prism.txt"

prism1_3d_info:
dd 230
dd 0,-100,0
dd 0,0,0
dd 1500
dd -150
dd 480/2

prism2_data:
include "prism2.txt"

prism2_3d_info:
dd 80
dd 0,-100,0
dd 0,0,0
dd 1500
dd 640/2
dd 500

prism_pos             dd 500 shl 1

threed_ISR_event      db ?
threed_ISR_pc         dd ?

THREED_PRISM2         = 0
THREED_SETUP_PRISM1   = 1
THREED_PRISM1         = 2

threed_x_r            dd 0
threed_y_r            dd 0
threed_z_r            dd 0

proc prism2_3d_calc
  cmp    [byte threed_ISR_event],THREED_PRISM2
  je     @@prism2
  cmp    [byte threed_ISR_event],THREED_SETUP_PRISM1
  je     @@prism1_setup
  cmp    [byte threed_ISR_event],THREED_PRISM1
  je     @@prism1
  ret
@@prism2:
  mov    esi,offset prism2_3d_info
  add    [threed_x_r],3
  add    [threed_y_r],3
  add    [threed_z_r],3

  dec    [prism_pos]

  cmp    [prism_pos],-220
  jl     @@next_event
  ret
@@prism1_setup:
  mov    [prism_pos],-200 shl 1
  jmp    @@next_event
@@prism1:
  mov    esi,offset prism1_3d_info
  add    [threed_x_r],3
;  add    [threed_y_r],4
;  add    [threed_z_r],3

  add    [prism_pos],2
  cmp    [prism_pos],800 shl 1
  jg     @@next_event
  ret
@@next_event:
  mov    [dword threed_ISR_pc],0
  inc    [byte threed_ISR_event]
  ret
endp

proc threed_sani_init
  mov    [byte _threed_pal_base],20
  mov    [byte _threed_pal_size],64

  mov    esi,offset three_show_pal
  mov    ecx,64*3
  mov    al,20
  @WritePalette

  mov    edx,(size tfacet_sort)*300
  mov    eax,0EE42h         ; allocate a DOS32 memory block
  Int    31h                ;  expects EDX = size; ret EAX=size, EDX->pointer
  mov    [_facet_sort],edx

  mov    edx,(size ttranstrifacet)*300
  mov    eax,0EE42h         ; allocate a DOS32 memory block
  Int    31h                ;  expects EDX = size; ret EAX=size, EDX->pointer
  mov    [_transformed],edx

  mov    eax,offset prism1_3d_info
  push   eax
  mov    eax,offset prism1_data
  push   eax
  call   _calc_normals
  add    esp,8

  mov    eax,offset prism2_3d_info
  push   eax
  mov    eax,offset prism2_data
  push   eax
  call   _calc_normals
  add    esp,8

  mov    [threed_ISR_event],THREED_PRISM2
  mov    [threed_ISR_pc],0
;  mov    eax,offset prism2_3d_calc
;  mov    [fg_calc],eax
  ret
endp

proc threed_sani_deinit
  mov    eax,0EE40h
  int    31h
  mov    eax,0EE40h
  int    31h
  ret
endp

proc threed_sani
;  call   threed_sani_init
;@@l:
;;;;;;;;;;;; set values
  cli

  mov    eax,[prism_pos]
  sar    eax,1

  cmp    [byte threed_ISR_event],THREED_PRISM1
  je     @@prism1_set
  cmp    [byte threed_ISR_event],THREED_PRISM2
  je     @@prism2_set

@@prism1_set:
  mov    esi,offset prism1_3d_info
  mov    [esi+tg3d_info.xpos],eax
  jmp    @@set_v
@@prism2_set:
  mov    esi,offset prism2_3d_info
  mov    [esi+tg3d_info.ypos],eax
  jmp    @@set_v

@@set_v:
  mov    eax,[threed_x_r]
  mov    [esi+tg3d_info.vangles.x],eax
  mov    eax,[threed_y_r]
  mov    [esi+tg3d_info.vangles.y],eax
  mov    eax,[threed_z_r]
  mov    [esi+tg3d_info.vangles.z],eax

  sti
;;;;;;;;;;;;

  cmp    [byte threed_ISR_event],THREED_PRISM1
  je     @@prism1
  cmp    [byte threed_ISR_event],THREED_PRISM2
  je     @@prism2
  jmp    @@done
@@prism1:
  mov    eax,offset prism1_3d_info
  push   eax
  mov    eax,offset prism1_data
  push   eax
  call   _paint_world
  add    esp,8
  jmp    @@done
@@prism2:
  mov    eax,offset prism2_3d_info
  push   eax
  mov    eax,offset prism2_data
  push   eax
  call   _paint_world
  add    esp,8
@@done:

;  call   sync_screen
;  call   key_pressed2
;  jnc    @@l
;  call   get_key
;  cmp    al,27
;  jne    @@l
;
;  call   threed_sani_deinit
  ret
endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                         ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
no_stars              = 100

struc tstar_map
  type                db ?
  x                   dd ?
  y                   dd ?
ends
star_map              tstar_map no_stars dup(<-1,0,0>)

proc create_star
  call   random
  and    eax,003h
  jz     @@cont
  ret
@@cont:
  xor    ecx,ecx
@@create_stars:
  lea    esi,[ecx*8+ecx]
  cmp    [byte esi+star_map.type],-1
  jne    @@ignore
  call   random
  and    eax,03ffh
  cmp    eax,640
  jge    @@ignore
  mov    [dword esi+star_map.x],eax
  mov    [dword esi+star_map.y],0
  call   random
  and    al,0fh
  mov    [esi+star_map.type],al
  jmp    @@end
@@ignore:
  inc    ecx
  cmp    ecx,no_stars
  jb     @@create_stars
@@end:
  ret
endp

proc mapp_star_calc
  xor    ecx,ecx
@@display_stars:
  lea    esi,[ecx*8+ecx]
  cmp    [byte esi+star_map.type],-1
  je     @@done
  cmp    [dword esi+star_map.y],480
  jl     @@display_star
  mov    [byte esi+star_map.type],-1
  jmp    @@done
@@display_star:
  inc    [dword esi+star_map.y]
@@done:
  inc    ecx
  cmp    ecx,no_stars
  jb     @@display_stars
  ret
endp

proc mapp_star_init
  mov    edx,480
@@l:
  push   edx
  call   create_star
  call   mapp_star_calc
  pop    edx
  dec    edx
  jnz    @@l
  ret
endp

proc mapp_star
  call   clear_screen
  call   create_star
  xor    ecx,ecx
@@display_stars:
  push   ecx
  lea    esi,[ecx*8+ecx]
  cmp    [byte esi+star_map.type],-1
  je     @@done
  mov    edi,[dword esi+star_map.y]
  cmp    edi,480
  jl     @@pd
  mov    [byte esi+star_map.type],-1
  jmp    @@done
@@pd:
  shl    edi,7
  mov    ebx,edi
  lea    edi,[edi*4]
  add    edi,ebx
  add    edi,[dword esi+star_map.x]
  add    edi,[dword Rendbuff]
  mov    al,[byte esi+star_map.type]
  mov    [edi],al
@@done:
  pop    ecx
  inc    ecx
  cmp    ecx,no_stars
  jb     @@display_stars
  ret
endp


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                         ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
star_palette2:
  X = 0
rept 16
  db                  (X / 256),(X / 256),((X + 800h) / 256)
  X = X + 2d0h
endm

TDPS_FADEIN           = 0
TDPS_WAIT             = 1
TDPS_FADEOUT          = 2
TDPS_DONE             = 3

TDPS_fadep            dd 0h

proc TDPS_ISR
  call   prism2_3d_calc

  cmp    [byte @@star_calc_miss],2
  je     @@calc_s
  inc    [byte @@star_calc_miss]
  jmp    @@cont
@@calc_s:
  mov    [byte @@star_calc_miss],0
  call   mapp_star_calc
@@cont:

  cmp    [byte ISR_event],TDPS_FADEIN
  je     @@jFADEIN
  cmp    [byte ISR_event],TDPS_WAIT
  je     @@jWAIT
  cmp    [byte ISR_event],TDPS_FADEOUT
  je     @@jFADEOUT
  ret
@@next_event:
  mov    [dword ISR_pc],0
  inc    [byte ISR_event]
  ret
@@jFADEIN:
  cmp    [dword ISR_pc],100h
  jae    @@next_event
  add    [dword ISR_pc],2
  mov    ebx,[TDPS_fadep]
  mov    eax,2
  call   clip_ipal
  mov    [TDPS_fadep],ebx
  ret
@@jWAIT:
  cmp    [dword ISR_pc],400h
  jae    @@next_event
  inc    [dword ISR_pc]
  ret
@@jFADEOUT:
  cmp    [dword ISR_pc],100h
  jae    @@next_event
  inc    [dword ISR_pc]
  mov    ebx,[TDPS_fadep]
  mov    eax,2
  call   clip_dpal
  mov    [TDPS_fadep],ebx
  ret
@@star_calc_miss      db 0
endp

proc TDPS_paint_star
  call   totally_clear_screen

  mov    esi,offset star_palette2
  xor    eax,eax
  mov    ecx,16
  call   fade_pal_init
  xor    eax,eax
  mov    ecx,16
  xor    ebx,ebx
  call   fade_pal

  call   mapp_star_init
  mov    [ISR_event],TDPS_FADEIN
  mov    [ISR_pc],0
  mov    eax,offset TDPS_ISR
  mov    [fg_calc],eax
@@l:
  cmp    [byte ISR_event],TDPS_FADEIN
  jne    @@fade
  cmp    [byte ISR_event],TDPS_FADEOUT
  jne    @@fade
  jmp    @@ign_fadeout
@@fade:
  xor    eax,eax
  mov    ecx,16
  mov    ebx,[dword TDPS_fadep]
  call   fade_pal
@@ign_fadeout:

  call   mapp_star
  call   threed_sani
  call   sync_screen
  cmp    [byte ISR_event],TDPS_DONE
  je     @@end
  call   key_pressed2
  jnc    @@l
  call   get_key
  cmp    al,27
  jne    @@l
@@end:
  ret
endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                         ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PET_PAL_SHIFTER       = 2

pet_pal:
db  0,0,0,58 shr 2,46 shr 2,46 shr 2,66 shr 2,53 shr 2,53 shr 2,74 shr 2,59 shr 2,59 shr 2

pet1_col              dd -79 shl PET_PAL_SHIFTER
pet2_col              dd 0   shl PET_PAL_SHIFTER

TDPS2_FADEIN          = 0
TDPS2_WAIT            = 1
TDPS2_FADEOUT         = 2
TDPS2_DONE            = 3

proc TDPS2_ISR
  call   prism2_3d_calc

  add    [angle1],10
  and    [angle1],0ffffh ;shl PET_PAL_SHIFTER

  add    [angle2],-3
  and    [angle2],0ffffh ;shl PET_PAL_SHIFTER

  inc    [pet1_col]
  cmp    [pet1_col],0
  jl     @@dont_rpet1
  mov    [pet1_col],-79 shl PET_PAL_SHIFTER
@@dont_rpet1:

  dec    [pet2_col]
  cmp    [pet2_col],-79 shl PET_PAL_SHIFTER
  jg     @@dont_rpet2
  mov    [pet2_col],0
@@dont_rpet2:

  cmp    [byte ISR_event],TDPS2_FADEIN
  je     @@jFADEIN
  cmp    [byte ISR_event],TDPS2_WAIT
  je     @@jWAIT
  cmp    [byte ISR_event],TDPS2_FADEOUT
  je     @@jFADEOUT
  ret
@@next_event:
  mov    [dword ISR_pc],0
  inc    [byte ISR_event]
  ret
@@jFADEIN:
  cmp    [dword ISR_pc],100h
  jae    @@next_event
  add    [dword ISR_pc],2
  mov    ebx,[TDPS_fadep]
  mov    eax,2
  call   clip_ipal
  mov    [TDPS_fadep],ebx
  ret
@@jWAIT:
  cmp    [dword ISR_pc],300h
  jae    @@next_event
  inc    [dword ISR_pc]
  ret
@@jFADEOUT:
  cmp    [dword ISR_pc],100h
  jae    @@next_event
  inc    [dword ISR_pc]
  mov    ebx,[TDPS_fadep]
  mov    eax,2
  call   clip_dpal
  mov    [TDPS_fadep],ebx
  ret
@@star_calc_miss      db 0
endp

proc TDPS2_pet_paint
  mov    [angle1],0
  mov    [angle2],0
  mov    [TDPS_fadep],0

  mov    edx,79*79*2
  mov    eax,0EE42h         ; allocate a DOS32 memory block
  Int    31h                ;  expects EDX = size; ret EAX=size, EDX->pointer
  mov    [pic_mt1],edx

  mov    edi,[pic_mt1]                ; init bm rotator
  mov    eax,79
  mov    ebx,79
  call   BM_rotate_init

  mov    edx,79*79          ; allocate pettle rotated block
  mov    eax,0EE42h
  Int    31h
  mov    [Rendbuff2],edx

  mov    edx,79*79          ; allocate pettle rotated block
  mov    eax,0EE42h
  Int    31h
  mov    [Rendbuff3],edx

  mov    esi,offset pet_pal
  xor    eax,eax
  mov    ecx,4
  call   fade_pal_init
  xor    eax,eax
  mov    ecx,4
  xor    ebx,ebx
  call   fade_pal

  mov    [ISR_event],TDPS2_FADEIN
  mov    [ISR_pc],0
  mov    eax,offset TDPS2_ISR
  mov    [fg_calc],eax
@@l:
;--------fade etc
  cmp    [byte ISR_event],TDPS2_FADEIN
  jne    @@fade
  cmp    [byte ISR_event],TDPS2_FADEOUT
  jne    @@fade
  jmp    @@ign_fadeout
@@fade:
  xor    eax,eax
  mov    ecx,4
  mov    ebx,[dword TDPS_fadep]
  call   fade_pal
@@ign_fadeout:

;clear screen
  mov    edi,[Rendbuff]
  mov    ecx,(640*480)/4
  mov    eax,01010101h
  rep    stosd

;petal 1 rotate
  mov    eax,[pet1_pic]
  add    eax,4
  push   eax
  push   [Rendbuff2]
  push   [pic_mt1]
  push   0
  push   0
  mov    eax,[angle1]
  sar    eax,PET_PAL_SHIFTER
  push   eax
  push   79
  push   79
  push   79
  call   BM_rotate
  add    esp,(size BM_rotate_stack)-4
;petal 2 rotate
  mov    eax,[pet2_pic]
  add    eax,4
  push   eax
  push   [Rendbuff3]
  push   [pic_mt1]
  push   0
  push   0
  mov    eax,[angle2]
  sar    eax,PET_PAL_SHIFTER
  push   eax
  push   79
  push   79
  push   79
  call   BM_rotate
  add    esp,(size BM_rotate_stack)-4

  mov    edx,[pet1_col]
  sar    edx,PET_PAL_SHIFTER
;create column stars
  xor    ebx,ebx
  mov    ch,3
@@paint_starrow:
  push   edx
  mov    cl,9
@@paint_starcol:
  push   ecx edx ebx
  push   [Rendbuff2]
  push   [Rendbuff]
  push   edx
  push   ebx
  push   79
  push   79
  push   640
  call   RBBitmap_TRANS
  add    esp,(size RBBitmap_stack)-8
  pop    ebx edx ecx
  add    edx,79
  dec    cl
  jnz    @@paint_starcol
  add    ebx,79*2
  pop    edx
  dec    ch
  jnz    @@paint_starrow

  mov    edx,[pet2_col]
  sar    edx,PET_PAL_SHIFTER
;create column petals
  mov    ebx,80
  mov    ch,3
@@paint_petrow:
  push   edx
  mov    cl,9
@@paint_petcol:
  push   ecx edx
  push   [Rendbuff3]
  push   [Rendbuff]
  push   edx
  push   ebx
  push   79
  push   79
  push   640
  call   RBBitmap_TRANS
  add    esp,(size RBBitmap_stack)-8
  pop    edx ecx
  add    edx,79
  dec    cl
  jnz    @@paint_petcol
  add    ebx,79*2
  pop    edx
  dec    ch
  jnz    @@paint_petrow

  call   threed_sani

  call   sync_screen
  cmp    [byte ISR_event],TDPS2_DONE
  je     @@end
  call   key_pressed2
  jnc    @@l
  call   get_key
  cmp    al,27
  jne    @@l
@@end:
  mov    eax,0EE40h
  int    31h
  mov    eax,0EE40h
  int    31h
  mov    eax,0EE40h
  int    31h
  ret
endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                         ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
proc do_3d_show
  call   threed_sani_init
  call   TDPS_paint_star
  call   TDPS2_pet_paint
  call   threed_sani_deinit
  ret
endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                         ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Start_3d_show:
  call   debug
  cld
  mov    eax,0EE02h      ; get DOS32 address information
  int    31h
  neg    ebx
  mov    [Zero_Addr],ebx
  add    ebx,0A0000h
  mov    [_0A0000h],ebx
  add    ebx,0B8000h-0A0000h
  mov    [_0B8000h],ebx
  mov    [Environment_Address],edi
  mov    [PSP_Address],esi

  call   load_data

  call   setup_vesa
  call   set_IRQ00

  call   do_3d_show

  call   reset_IRQ00
  mov    eax,3h
  int    10h
  mov    eax,4c00h
  int    21h
ends

end Start_3d_show
