;
;   application     :  3d shaking waved spiral
;   compilator      :  fasm
;   system          :  MenuetOS
;   author          :  macgub
;   email           :  macgub3@wp

timeout equ 3
maxx equ 600        ; window size
maxy equ 420
use32

               org    0x0

               db     'MENUET01'              ; 8 byte id
               dd     0x01                    ; header version
               dd     START                   ; start of code
               dd     I_END                   ; size of image
               dd     0x100000                ; memory for app
               dd     0xbffff                 ; esp
               dd     0x0 , 0x0               ; I_Param , I_Icon

START:                          ; start of execution

     call draw_window

still:

;    mov  eax,23                 ; wait here for event
;    mov  ebx,timeout
;    int  0x40
    mov eax,11                   ; check for event no wait
    int 0x40

    cmp  eax,1                  ; redraw request ?
    je   red
    cmp  eax,2                  ; key in buffer ?
    je   key
    cmp  eax,3                  ; button in buffer ?
    je   button

    jmp  noclose

  red:                          ; redraw
    call draw_window
    jmp  still

  key:                          ; key
    mov  eax,2                  ; just read it and ignore
    int  0x40
    jmp  still

  button:                       ; button
    mov  eax,17                 ; get id
    int  0x40

    cmp  ah,1                   ; button id=1 ?
    jne  noclose

    mov  eax,-1                 ; close this program
    int  0x40
  noclose:

; mov eax,13
; mov ebx,20*65536+maxx-25
; mov ecx,20*65536+maxy-25
; xor edx,edx
; int 0x40

 mov edi,screen_buf
 mov ecx,maxx*maxy*3/4
 xor eax,eax
 cld
 rep stosd


 call calc_deg
 mov [z],0
 mov [sin_counter],0
 finit
oopz:
 mov [x],0
 push [z]
 call calc_sin_variable
oop:
  push [x]
;  call getcol  ;(x,z)
  call fun                       ; calculates y and y1
;  call rotateY
  mov eax,[sin_variable]
  add eax,[vector_x]                     ;  vector_x
  add [x],eax
  mov eax,[vector_y]
  add [y],eax                     ;  vector_y
  add [y1],eax
  call point_perspective
  call draw_point_3d
 pop [x]
 inc [x]
 mov eax,[x]
 cmp eax,[loop_counter]
 jne oop
 inc [sin_counter]
 pop [z]
 inc [z]
 cmp [z],200
 jne oopz

 mov eax,7
 mov ebx,screen_buf
 mov ecx,maxx*65536+maxy
 mov edx,20*65536+20
 int 0x40

 call set_elipse_dim
 call set_vectors

jmp still
;-----------------++++++PROCEDURES
getcol:
 mov eax,[x_resolution]
 mul [z]
 add eax,[x]
 mov ebx,eax
 mov eax,35
 int 0x40
 mov [col],eax
ret

set_vectors:
 cmp [vector_x],55
 jne vec1
 mov [vector_dir_x],1
 vec1:
 cmp [vector_x],250
 jne vec2
 mov [vector_dir_x],0
 vec2:
 cmp [vector_dir_x],1
 jne vec3
 inc [vector_x]
 jmp end_x
 vec3:
 dec [vector_x]
 end_x:
 cmp [vector_y],195
 jne vec4
 mov [vector_dir_y],1
 vec4:
 cmp [vector_y],205
 jne vec5
 mov [vector_dir_y],0
 vec5:
 cmp [vector_dir_y],1
 jne vec6
 inc [vector_y]
 ret
 vec6:
 dec [vector_y]
ret
set_elipse_dim:
 cmp [b],60
 jne go11
 mov [elipse_dir],0
 go11:
 cmp [b],10
 jne go12
 mov [elipse_dir],1
 go12:
 cmp [elipse_dir],1
 jne go13
 inc [b]
 dec [a]
 mov eax,[a]
 mov [xo],eax
 shl eax,1
 inc eax
 mov [loop_counter],eax
 ret
 go13:
 dec [b]
 inc [a]
 mov eax,[a]
 mov [xo],eax
 shl eax,1
 inc eax
 mov [loop_counter],eax
ret

calc_deg:
 cmp [deg_counter], 360
 jne go_deg
 mov [deg_counter],0
 go_deg:
 fldpi
 fidiv [deg_div]
 fimul [deg_counter]
 fstp [current_deg]
; fsincos
; fstp [cosbeta]
; fstp [sinbeta]
 inc [deg_counter]
 ret

;rotateY:
; mov eax,[z]
; sub eax,[zoo]
; mov [subz],eax
; mov eax,[x]
; sub eax,[xoo]
; mov [subx],eax
;
; fld [sinbeta]
; fimul [subz]
; fchs
; fld [cosbeta]
; fimul[subx]
; faddp
; fiadd [xoo]
; fistp [x]

; fld [sinbeta]
; fimul [subx]
; fld [cosbeta]
; fimul [subz]
; faddp
; fiadd [zoo]
; fistp [z]
; finit

; ret

point_perspective:
  mov eax,[x]
  sub eax,[xobs]
  mov [xobssub],eax
  mov eax,[z]
  sub eax,[zobs]
  mov [zobssub],eax

  mov eax,[y]
  sub eax,[yobs]
  mov [yobssub],eax
  mov eax,[y1]
  sub eax,[yobs]
  mov [y1obssub],eax

  finit
  fild [xobssub]
  fidiv [zobssub]
  fimul [zobs]
  fchs
  fiadd [xobs]
  fistp [x]
  fild [yobssub]
  fidiv [zobssub]
  fimul [zobs]
  fchs
  fiadd [yobs]
  fistp [y]

;  mov eax,[xobssub]
; idiv [zobssub]
;; mov eax,edx
; imul [zobs]
; neg eax
;  add eax,[xobs]
;  mov [x],eax
;  mov eax,[yobssub]
;  idiv [zobssub]
;;  mov eax,edx
;  imul [zobs]
;  neg eax
;  add eax,[yobs]
;  mov [y],eax

  fild [y1obssub]
  fidiv [zobssub]
  fimul [zobs]
  fchs
  fiadd [yobs]
  fistp [y1]
ret
calc_sin_variable:
                     ;calculate sinus variable
 fldpi
 fidiv [sin_gran]
 fimul [sin_counter]
 fadd  [current_deg]
 fsin
 fimul [sin_mul]
 fistp [sin_variable]
ret

fun:
; finit
 fild [x]
 fisub [xo]
; fchs
; faddp
 fild [a]
 fdivp st1,st
 fmul st,st0
 fchs
 fld1
 faddp
 fsqrt
 fimul [b]
 fld st
 fchs
 fiadd [yo]
 fistp [y]
 fiadd [yo]
 fistp [y1]
ret
draw_point_3d:
 mov eax,[z]
 imul [sq]
 shr eax,10
 mov ebx,eax
 neg eax
 push eax
 add eax,[y]
 mov [y],eax
 pop eax
 add eax,[y1]
 mov [y1],eax
 mov eax,ebx
 add eax,[x]
 mov [x],eax
 ;mov eax,1
 ;mov ebx,[x]
 ;mov ecx,[y]
 ;mov edx,[col]
 ;int 0x40
 ;mov ecx,[y1]
 ;int 0x40
 mov eax,maxx
 mul [y]
 add eax,[x]
 mov ebx,eax
 shl ebx,1
 add eax,ebx
 add eax,screen_buf
 mov ebx,[col]
 or [eax],ebx
 mov eax,maxx
 mul [y1]
 add eax,[x]
 mov ebx,eax
 shl ebx,1
 add eax,ebx
 add eax,screen_buf
 mov ebx,[col]
 or [eax],ebx
ret

;   *********************************************
;   *******  WINDOW DEFINITIONS AND DRAW ********
;   *********************************************
draw_window:

    mov  eax,12                    ; function 12:tell os about windowdraw
    mov  ebx,1                     ; 1, start of draw
    int  0x40
                                   ; DRAW WINDOW
    mov  eax,0                     ; function 0 : define and draw window
    mov  ebx,100*65536+maxx+25         ; [x start] *65536 + [x size]
    mov  ecx,100*65536+maxy+25         ; [y start] *65536 + [y size]
    mov  edx,0x04000000            ; color of work area RRGGBB,8->color gl
    mov  esi,0x805080d0            ; color of grab bar  RRGGBB,8->color gl
    mov  edi,0x005080d0            ; color of frames    RRGGBB
    int  0x40
                                   ; WINDOW LABEL
    mov  eax,4                     ; function 4 : write text to window
    mov  ebx,8*65536+8             ; [x start] *65536 + [y start]
    mov  ecx,0x10ddeeff            ; font 1 & color ( 0xF0RRGGBB )
    mov  edx,labelt                ; pointer to text beginning
    mov  esi,labellen-labelt       ; text length
    int  0x40

    mov  eax,12                    ; function 12:tell os about windowdraw
    mov  ebx,2                     ; 2, end of draw
    int  0x40

    ret

x_resolution dd 800
vector_x dd 200
vector_y dd 200
vector_dir_x db 1
vector_dir_y db 1
elipse_dir db 1

deg_counter dd ?   ; rotation variables
deg_div dd 20
current_deg dd ?
;cosbeta dd ?
;sinbeta dd ?
;zoo dd 100            ; rotation axle
;xoo dd 40
;yoo dd 20
;subx dd ?
;suby dd ?
;subz dd ?

xobs dd maxx/2    ; 320     observer variables
yobs dd maxy/2    ; 175
zobs dd -200
xobssub dd ?
yobssub dd ?
y1obssub dd ?
zobssub dd ?

sin_variable dd ?
sin_mul dd 60
sin_gran dd 30
sin_counter dd  0
sq dd 724          ; round( (sqrt2)/2*1024 )
z dd ?
x dd ?
y dd ?
y1 dd ?
xo dd 70           ; center point  , (loop counter-1)/2
yo dd 20
a dd 70            ; vertical half-axle
b dd 20            ; horizontal half-axle
loop_counter dd 141 ; axle granularity
col dd 0x00ffffff

labelt:
     db   ' 3D SHAKING WAVED SPIRAL'
labellen:
screen_buf:

I_END:




