/* 3d Window - Aug 97 - by Sylvain HUET */ /* Dec 99 - by Christophe LOREK */ struct Win3d= [chWin3d:Chn,winWin3d:ObjWin,flagsWin3d:I, endWin3d:fun [] I,clickWin3d:fun[H3d HMat3d I] I,moveWin3d:fun[H3d HMat3d] I, bufWin3d:ObjSurface,sizeWin3d:[I I],kWin3d:[I I],fondWin3d:I, vectorWin3d:[I I I],angularWin3d:[I I I], refWin3d:[I I], timerWin3d:Timer, s3dWin3d:S3d, camWin3d:H3d, objWin3d:H3d, movobjWin3d:fun [[I I I] [I I I]] I, CBtimerWin3d:fun [] I,CBpostRenderWin3d:fun [ObjSurface [I I]] I, cursWin3d:[I I],lastWin3d:H3d,lastmWin3d:HMat3d,modWin3d:I ]mkWin3d;; var WIN3D_RESIZE=1;; var WIN3D_INTERF=2;; var WIN3D_CONT=4;; var WIN3D_CHILD=8;; var D3DErrorDialog = 0;; /* Error Dialog not created yet */ proto _ClockE=fun[Timer Win3d] I;; fun _go(b)= /* _showconsole;*/ if b.s3dWin3d!=nil && b.timerWin3d==nil then set b.timerWin3d = _rfltimer _starttimer b.chWin3d 1 @_ClockE b else nil;; fun _stop(b)= if b.timerWin3d==nil then nil else (_deltimer b.timerWin3d; set b.timerWin3d=nil);; fun _PaintE(x,b)= let b.sizeWin3d ->[w h] in _BLTsurface b.winWin3d 0 0 b.bufWin3d 0 0 w h;; fun _ClockE(t,b)= if b.s3dWin3d==nil || b.camWin3d==nil then (_stop b; nil) else (exec b.CBtimerWin3d with []; let exec b.movobjWin3d with [b.vectorWin3d b.angularWin3d] -> changed in (let b.cursWin3d->[x y] in let MX3renderm b.s3dWin3d b.bufWin3d b.camWin3d x y b.fondWin3d -> [h m] in if b.refWin3d!=nil || (h==b.lastWin3d && m==b.lastmWin3d) then nil else (set b.lastWin3d=h; set b.lastmWin3d=m; exec b.moveWin3d with [h m]); let b.sizeWin3d ->[w h] in (exec b.CBpostRenderWin3d with [b.bufWin3d b.sizeWin3d]; _BLTsurface b.winWin3d 0 0 b.bufWin3d 0 0 w h; /* _PAINTrectangle b.winWin3d 0 0 20 20 DRAW_SOLID 2 0 DRAW_SOLID */0xff); if changed || (b.flagsWin3d&WIN3D_CONT) || b.refWin3d!=nil then nil else _stop b); 0 );; fun _UnclickE(a,b,x,y,button)= if b.flagsWin3d&WIN3D_CONT then nil else _stop b; set b.vectorWin3d=set b.angularWin3d=[0 0 0]; set b.refWin3d=nil;; fun _ClickE(a,b,x,y,button)= _go b; _SETfocus b.winWin3d ; set b.refWin3d=[x y]; let b.cursWin3d->[xp yp] in let MX3renderInfo b.s3dWin3d b.camWin3d xp yp ->[o m _ _ _] in if exec b.clickWin3d with [o m button] then nil else set b.refWin3d=nil; 0;; fun movecurs(b,x,y)= let b.kWin3d ->[kv ka] in let b.refWin3d ->[xr yr] in (set x=x-xr; set y=yr-y; set b.vectorWin3d= if b.modWin3d then if _keybdstate&1 then [0 0 0] else [x*kv y*kv 0] else if _keybdstate&2 then [x*kv y*kv 0] else if _keybdstate&1 then [0 0 0] else [0 0 y*kv]; set b.angularWin3d= if b.modWin3d then if _keybdstate&1 then [x*ka 0 0] else [0 0 0] else if _keybdstate&2 then [0 0 0] else if _keybdstate&1 then [0 y*ka 0] else [(-x*ka) 0 0] );; fun _CursorE(a,b,x,y,c)= let b.sizeWin3d->[w h] in set b.cursWin3d=[x-(w>>1) (h>>1)-y]; _go b; if b.refWin3d==nil then nil else (_go b; movecurs b x y) ;; fun _keydownE (t,b,code,val)= _go b; let b.kWin3d ->[lv la] in let [lv*128 la*128] -> [kv ka] in (set b.vectorWin3d= if _keybdstate&2 then if val==0xff51 then [(-kv) 0 0] else if val==0xff53 then [kv 0 0] else if val==0xff52 then [0 kv 0] else if val==0xff54 then [0 (-kv) 0] else [0 0 0] else if _keybdstate&1 then [0 0 0] else if val==0xff52 then [0 0 kv] else if val==0xff54 then [0 0 (-kv)] else [0 0 0]; set b.angularWin3d= if _keybdstate&2 then [0 0 0] else if _keybdstate&1 then if val==0xff52 then [0 ka 0] else if val==0xff54 then [0 (-ka) 0] else [0 0 0] else if val==0xff51 then [ka 0 0] else if val==0xff53 then [-ka 0 0] else [0 0 0]) ;; fun _keyupE (a,b,code)= if b.flagsWin3d&WIN3D_CONT then nil else _stop b; set b.vectorWin3d=set b.angularWin3d=[0 0 0] ;; fun _DestroyE(x,b)= exec b.endWin3d with [];; fun D3DErrorDialogOK(b,win)= _DSwindow win; set D3DErrorDialog = 0; 0;; fun _ResizeE(a,b,x,y)= _go b; set b.sizeWin3d=[x y]; let b.sizeWin3d->[w h] in (_DSsurface b.bufWin3d; set b.bufWin3d=_CRsurface b.chWin3d w h; if (b.bufWin3d == nil && !D3DErrorDialog && w>5 && h>5) then let _GETscreenSize -> [wscr hscr] in let _CRwindow _channel b.winWin3d (wscr-250)/2 (hscr-100)/2 250 100 WN_DIALOG "Direct3D HAL Error" -> popup in let _CRtext _channel popup 10 10 230 40 ET_ALIGN_CENTER "you no longer have enough video memory to have a 3D display of this size"-> text in let _CRbutton _channel popup 85 60 80 20 ET_ALIGN_CENTER "OK"-> button in ( if w > 320 then set w = w-200 else nil; if h > 240 then set h = h-200 else nil; set b.bufWin3d=_CRsurface b.chWin3d w h; set D3DErrorDialog = 1; _CBbutton button @D3DErrorDialogOK popup ) else nil; if b.camWin3d==nil || b.s3dWin3d==nil then nil else let M3getCamera b.s3dWin3d b.camWin3d -> [[d _] [x _] z] in M3setCamera b.s3dWin3d b.camWin3d [[d*(w>>1)/x d*(w>>1)/x] [w>>1 h>>1] z]);; fun iniWin3d(ch,father,pos,wh,title,end,flag)= let pos->[x y] in let wh -> [w h] in let _CRwindow ch father x y w h (if flag&WIN3D_CHILD then WN_CHILDINSIDE|WN_NOCAPTION|WN_NOBORDER else WN_MENU+WN_MINBOX)+ (if flag&WIN3D_RESIZE then WN_SIZEBOX else 0) title -> win in let _CRsurface ch w h ->buf in ( if (buf == nil && !D3DErrorDialog) then let _GETscreenSize -> [wscr hscr] in let _CRwindow _channel win (wscr-250)/2 (hscr-100)/2 250 100 WN_DIALOG "Direct3D HAL Error" -> popup in let _CRtext _channel popup 10 10 230 40 ET_ALIGN_CENTER "you no longer have enough video memory to have a 3D display of this size"-> text in let _CRbutton _channel popup 85 60 80 20 ET_ALIGN_CENTER "OK"-> button in ( if w > 320 then set w = w-200 else nil; if h > 240 then set h = h-200 else nil; set buf=_CRsurface ch w h; set D3DErrorDialog = 1; _CBbutton button @D3DErrorDialogOK popup ) else nil; let mkWin3d [ch win flag end nil nil buf wh [1 20] 0 nil nil nil nil nil nil nil nil nil nil [0 0] nil nil 0] -> b in (_CBwinDestroy win @_DestroyE b; _CBwinPaint win @_PaintE b; _CBwinSize win @_ResizeE b; _CBwinClick win @_ClickE b; _CBwinUnclick win @_UnclickE b; if flag&WIN3D_INTERF then (_CBwinKeydown win @_keydownE b; _CBwinKeyup win @_keyupE b) else nil; _CBcursorMove win @_CursorE b; set b.vectorWin3d=set b.angularWin3d=[0 0 0]; b ); );; fun setSceneWin3d(b,s,c)= set b.s3dWin3d=s; set b.camWin3d=c; if s==nil then _stop b else (let b.sizeWin3d->[w h] in if b.camWin3d==nil || b.s3dWin3d==nil then nil else let M3getCamera b.s3dWin3d b.camWin3d -> [[d _] [x _] z] in M3setCamera b.s3dWin3d b.camWin3d [[d*(w>>1)/x d*(w>>1)/x] [w>>1 h>>1] z]; _go b) ;; fun setTitleWin3d(b,s)= _SETwindowName b.winWin3d s;; fun setInterfWin3d(b,kv,ka)= set b.kWin3d=[kv ka];; fun setBackgWin3d(b,col)= set b.fondWin3d=col; _go b; 0;; fun setCBWin3d(b,click,move)= set b.clickWin3d=click; set b.moveWin3d=move;; fun setCBtimerWin3d(b,t)= set b.CBtimerWin3d=t;; fun setCBpostRenderWin3d(b,t)= set b.CBpostRenderWin3d=t;; fun setMovobjWin3d(b,o,f)= set b.objWin3d=o; set b.movobjWin3d=f;; fun setModWin3d(b,i)= set b.modWin3d=i;; fun destroyWin3d(b)= set b.s3dWin3d=nil; _DSwindow b.winWin3d; _DSsurface b.bufWin3d;; fun refreshWin3d(b)= _go b;;