433 lines
9.0 KiB
PHP
433 lines
9.0 KiB
PHP
; drawing code for aclock
|
|
;
|
|
; Copyright (c) 2003 Thomas Mathys
|
|
; killer@vantage.ch
|
|
;
|
|
; This program is free software; you can redistribute it and/or modify
|
|
; it under the terms of the GNU General Public License as published by
|
|
; the Free Software Foundation; either version 2 of the License, or
|
|
; (at your option) any later version.
|
|
;
|
|
; This program is distributed in the hope that it will be useful,
|
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
; GNU General Public License for more details.
|
|
;
|
|
; You should have received a copy of the GNU General Public License
|
|
; along with this program; if not, write to the Free Software
|
|
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
;
|
|
%ifndef _DRAW_INC
|
|
%define _DRAW_INC
|
|
|
|
|
|
TMR1_FACTOR dd 0.45
|
|
TMR2_FACTOR dd 0.426315789
|
|
SECR_FACTOR dd 0.378947368
|
|
MINR_FACTOR dd 0.355263158
|
|
HOURR_FACTOR dd 0.189473684
|
|
DATE_FACTOR dd 0.1
|
|
|
|
|
|
monthNames:
|
|
db "Jan"
|
|
db "Feb"
|
|
db "Mar"
|
|
db "Apr"
|
|
db "May"
|
|
db "Jun"
|
|
db "Jul"
|
|
db "Aug"
|
|
db "Sep"
|
|
db "Oct"
|
|
db "Nov"
|
|
db "Dec"
|
|
|
|
|
|
;********************************************************************
|
|
; draws the clock
|
|
; input : nothing
|
|
; output : nothing
|
|
; destroys : nothing
|
|
;********************************************************************
|
|
drawClock:
|
|
%push drawClock_context
|
|
%stacksize flat
|
|
%assign %$localsize 0
|
|
|
|
%local i:dword, \
|
|
TMR1X:dword, \
|
|
TMR1Y:dword, \
|
|
TMR2X:dword, \
|
|
TMR2Y:dword, \
|
|
SECRX:dword, \
|
|
SECRY:dword, \
|
|
MINRX:dword, \
|
|
MINRY:dword, \
|
|
HOURRX:dword, \
|
|
HOURRY:dword, \
|
|
workwidth:dword, \
|
|
workheight:dword, \
|
|
foo:dword
|
|
|
|
enter %$localsize,0
|
|
pushad
|
|
pushfd
|
|
|
|
; get window dimensions
|
|
mov eax,MOS_SC_GETPROCESSINFO
|
|
mov ebx,procInfo
|
|
mov ecx,-1
|
|
int 0x40
|
|
|
|
; calculate work area size (width/height = ecx/edx)
|
|
; if the work area is too small (maybe the window is shaded)
|
|
; we don't draw anything.
|
|
mov eax,MOS_SC_WINDOWPROPERTIES
|
|
mov ebx,4 ; get skin height (eax)
|
|
int 0x40
|
|
mov ecx,[procInfo + MOS_PROCESSINFO.wndWidth]
|
|
sub ecx,MOS_WND_SKIN_BORDER_LEFT+MOS_WND_SKIN_BORDER_RIGHT
|
|
mov edx,[procInfo + MOS_PROCESSINFO.wndHeight]
|
|
sub edx,eax
|
|
sub edx,MOS_WND_SKIN_BORDER_BOTTOM
|
|
cmp ecx,0 ; width too small ?
|
|
jle .bye
|
|
cmp edx,0 ; height too small ?
|
|
jnle .continue
|
|
.bye:
|
|
jmp .byebye
|
|
.continue:
|
|
mov [workwidth],ecx ; save for later (for fpu)
|
|
mov [workheight],edx
|
|
|
|
; calculate center of clock (x/y = esi/edi)
|
|
mov esi,[procInfo + MOS_PROCESSINFO.wndWidth]
|
|
shr esi,1
|
|
mov edi,[procInfo + MOS_PROCESSINFO.wndHeight]
|
|
sub edi,MOS_WND_SKIN_BORDER_BOTTOM
|
|
sub edi,eax
|
|
shr edi,1
|
|
add edi,eax
|
|
|
|
; clear work area
|
|
pushad
|
|
mov ebx,(MOS_WND_SKIN_BORDER_LEFT)*0x10000 ; x start
|
|
or ebx,ecx ; width
|
|
inc ebx
|
|
mov ecx,eax ; y start
|
|
shl ecx,16 ; (=skin height)
|
|
or ecx,edx ; height
|
|
inc ecx
|
|
mov edx,[wndColors + MOS_WNDCOLORS.work]
|
|
mov eax,MOS_SC_DRAWBAR
|
|
int 0x40
|
|
popad
|
|
|
|
; calculate second hand radii
|
|
fild dword [workwidth]
|
|
fmul dword [SECR_FACTOR]
|
|
fstp dword [SECRX]
|
|
fild dword [workheight]
|
|
fmul dword [SECR_FACTOR]
|
|
fstp dword [SECRY]
|
|
|
|
; calculate minute hand radii
|
|
fild dword [workwidth]
|
|
fmul dword [MINR_FACTOR]
|
|
fstp dword [MINRX]
|
|
fild dword [workheight]
|
|
fmul dword [MINR_FACTOR]
|
|
fstp dword [MINRY]
|
|
|
|
; calculate hour hand radii
|
|
fild dword [workwidth]
|
|
fmul dword [HOURR_FACTOR]
|
|
fstp dword [HOURRX]
|
|
fild dword [workheight]
|
|
fmul dword [HOURR_FACTOR]
|
|
fstp dword [HOURRY]
|
|
|
|
; calculate tick mark radii
|
|
fild dword [workwidth]
|
|
fmul dword [TMR1_FACTOR]
|
|
fstp dword [TMR1X]
|
|
fild dword [workheight]
|
|
fmul dword [TMR1_FACTOR]
|
|
fstp dword [TMR1Y]
|
|
fild dword [workwidth]
|
|
fmul dword [TMR2_FACTOR]
|
|
fstp dword [TMR2X]
|
|
fild dword [workheight]
|
|
fmul dword [TMR2_FACTOR]
|
|
fstp dword [TMR2Y]
|
|
|
|
; get system clock (edx)
|
|
mov eax,MOS_SC_GETSYSCLOCK
|
|
int 0x40
|
|
mov edx,eax
|
|
|
|
; draw second hand
|
|
push edx
|
|
mov eax,edx
|
|
shr eax,16
|
|
call bcdbin
|
|
mov ecx,eax ; save seconds for later
|
|
push ecx
|
|
push eax
|
|
fpush32 0.104719755 ; 2*pi/60
|
|
push dword [SECRX]
|
|
push dword [SECRY]
|
|
push esi
|
|
push edi
|
|
call getHandCoords
|
|
mov eax,MOS_SC_DRAWLINE
|
|
shl ebx,16
|
|
or ebx,esi
|
|
shl ecx,16
|
|
or ecx,edi
|
|
mov edx,[wndColors + MOS_WNDCOLORS.workText]
|
|
int 0x40
|
|
pop ecx
|
|
pop edx
|
|
|
|
; draw minute hand
|
|
push edx
|
|
mov eax,edx
|
|
shr eax,8
|
|
call bcdbin
|
|
mov edx,60
|
|
mul edx
|
|
add eax,ecx
|
|
mov ecx,eax ; save for later
|
|
push ecx
|
|
push eax
|
|
fpush32 0.001745329 ; 2*pi/60/60
|
|
push dword [MINRX]
|
|
push dword [MINRY]
|
|
push esi
|
|
push edi
|
|
call getHandCoords
|
|
mov eax,MOS_SC_DRAWLINE
|
|
shl ebx,16
|
|
or ebx,esi
|
|
shl ecx,16
|
|
or ecx,edi
|
|
mov edx,[wndColors + MOS_WNDCOLORS.workText]
|
|
int 0x40
|
|
pop ecx
|
|
pop edx
|
|
|
|
; draw hour hand
|
|
push edx
|
|
mov eax,edx
|
|
call bcdbin
|
|
cmp eax,11 ; % 12 (just to be sure)
|
|
jnae .hoursok
|
|
sub eax,12
|
|
.hoursok:
|
|
mov edx,60*60
|
|
mul edx
|
|
add eax,ecx
|
|
push eax
|
|
fpush32 0.000145444 ; 2*pi/60/60/12
|
|
push dword [HOURRX]
|
|
push dword [HOURRY]
|
|
push esi
|
|
push edi
|
|
call getHandCoords
|
|
mov eax,MOS_SC_DRAWLINE
|
|
shl ebx,16
|
|
or ebx,esi
|
|
shl ecx,16
|
|
or ecx,edi
|
|
mov edx,[wndColors + MOS_WNDCOLORS.workText]
|
|
int 0x40
|
|
pop edx
|
|
|
|
; draw tick marks
|
|
mov dword [i],11 ; draw 12 marks
|
|
.drawtickmarks:
|
|
push dword [i] ; calculate start point
|
|
fpush32 0.523598776 ; 2*pi/12
|
|
push dword [TMR1X]
|
|
push dword [TMR1Y]
|
|
push esi
|
|
push edi
|
|
call getHandCoords
|
|
mov eax,ebx ; save in eax and edx
|
|
mov edx,ecx
|
|
push dword [i]
|
|
fpush32 0.523598776 ; 2*pi/12
|
|
push dword [TMR2X]
|
|
push dword [TMR2Y]
|
|
push esi
|
|
push edi
|
|
call getHandCoords
|
|
shl eax,16
|
|
shl edx,16
|
|
or ebx,eax ; ebx = x start and end
|
|
or ecx,edx ; ecx = y start and end
|
|
mov edx,[wndColors + MOS_WNDCOLORS.workText]
|
|
mov eax,MOS_SC_DRAWLINE
|
|
int 0x40
|
|
dec dword [i]
|
|
jns .drawtickmarks
|
|
|
|
%define DATE_WIDTH 48
|
|
|
|
; calculate text start position
|
|
mov eax,[procInfo+MOS_PROCESSINFO.wndWidth]
|
|
sub eax,DATE_WIDTH ; x = (wndwidth-textwidth)/2
|
|
shr eax,1 ; eax = x
|
|
fild dword [workheight] ; y = DATE_FACTOR*workheight...
|
|
fmul dword [DATE_FACTOR]
|
|
mov [foo],edi ; ... + y_clockcenter
|
|
fiadd dword [foo]
|
|
fistp dword [foo]
|
|
mov ebx,[foo] ; ebx = y
|
|
|
|
; draw text at all ?
|
|
cmp dword [workwidth],DATE_WIDTH ; text too wide ?
|
|
jb .goodbye
|
|
mov ecx,ebx ; text too high ?
|
|
add ecx,10-1
|
|
mov edx,[procInfo+MOS_PROCESSINFO.wndHeight]
|
|
sub edx,MOS_WND_SKIN_BORDER_BOTTOM
|
|
cmp ecx,edx
|
|
jnae .yousuck
|
|
.goodbye:
|
|
jmp .bye
|
|
.yousuck:
|
|
|
|
|
|
; ebx = (x << 16) | y
|
|
shl eax,16
|
|
or ebx,eax
|
|
|
|
; get date (edi)
|
|
mov eax,MOS_SC_GETDATE
|
|
int 0x40
|
|
mov edi,eax
|
|
|
|
; display month
|
|
mov eax,edi ; get month
|
|
shr eax,8
|
|
call bcdbin
|
|
; ebx contains already position
|
|
mov ecx,[wndColors+MOS_WNDCOLORS.workText]
|
|
lea edx,[monthNames-3+eax*2+eax]; -3 because eax = 1..12 =]
|
|
mov esi,3 ; text length
|
|
mov eax,MOS_SC_WRITETEXT
|
|
int 0x40
|
|
|
|
; display date
|
|
add ebx,MOS_DWORD(3*6+3,0)
|
|
mov eax,edi ; get date
|
|
shr eax,16
|
|
call bcdbin
|
|
mov edx,ebx ; position must be in edx
|
|
mov ebx,0x00020000 ; number, display two digits
|
|
mov ecx,eax ; number to display
|
|
mov esi,[wndColors+MOS_WNDCOLORS.workText]
|
|
mov eax,MOS_SC_WRITENUMBER
|
|
int 0x40
|
|
|
|
; display year. the way we avoid the y2k bug is even
|
|
; simpler, yet much better than in the last version:
|
|
; now we simply display the last two digits and let the
|
|
; user decide wether it's the year 1903 or 2003 =]
|
|
add edx,MOS_DWORD(2*6+3,0)
|
|
mov eax,edi ; get year
|
|
call bcdbin
|
|
mov ebx,0x00020000 ; number, display two digits
|
|
mov ecx,eax ; number to display
|
|
; edx contains already position
|
|
mov esi,[wndColors+MOS_WNDCOLORS.workText]
|
|
mov eax,MOS_SC_WRITENUMBER
|
|
int 0x40
|
|
|
|
.byebye:
|
|
popfd
|
|
popad
|
|
leave
|
|
ret
|
|
%pop
|
|
|
|
|
|
;**********************************************************
|
|
; bcdbin
|
|
; converts a 8 bit bcd number into a 32 bit binary number
|
|
;
|
|
; in al = 8 bit bcd number
|
|
; out eax = 32 bit binary number
|
|
; destroys dl,flags
|
|
;**********************************************************
|
|
bcdbin:
|
|
push edx
|
|
pushfd
|
|
mov dl,al ; save bcd number
|
|
shr al,4 ; convert upper nibble
|
|
mov ah,10
|
|
mul ah
|
|
and dl,15 ; add lower nibble
|
|
add al,dl
|
|
and eax,255 ; !
|
|
popfd
|
|
pop edx
|
|
ret
|
|
|
|
|
|
;********************************************************************
|
|
; getHandCoords
|
|
; calculates the end point of a hand
|
|
;
|
|
; input (on stack, push from top to bottom):
|
|
; ANGLE angle (integer)
|
|
; DEG2RAD conversion factor for ANGLE (32 bit real)
|
|
; RADIUSX x radius (32 bit real)
|
|
; RADIUSY y radius (32 bit real)
|
|
; CENTERX x center of the clock (integer)
|
|
; CENTERY y center of the clock (integer)
|
|
;
|
|
; output:
|
|
; ebx x coordinate in bits 0..15, bits 16..31 are zero
|
|
; ecx y coordinate in bits 0..15, bits 16..31 are zero
|
|
;
|
|
; destroys:
|
|
; nothing
|
|
;********************************************************************
|
|
getHandCoords:
|
|
|
|
ANGLE equ 28
|
|
DEG2RAD equ 24
|
|
RADIUSX equ 20
|
|
RADIUSY equ 16
|
|
CENTERX equ 12
|
|
CENTERY equ 8
|
|
|
|
enter 0,0
|
|
pushfd
|
|
|
|
fild dword [ebp+ANGLE] ; get angle
|
|
fmul dword [ebp+DEG2RAD] ; convert to radians
|
|
fsincos
|
|
fmul dword [ebp+RADIUSY] ; -y * radius + clockcy
|
|
fchs
|
|
fiadd dword [ebp+CENTERY]
|
|
fistp dword [ebp+CENTERY]
|
|
fmul dword [ebp+RADIUSX] ; x * radius + clockcx
|
|
fiadd dword [ebp+CENTERX]
|
|
fistp dword [ebp+CENTERX]
|
|
|
|
mov ebx,[ebp+CENTERX]
|
|
mov ecx,[ebp+CENTERY]
|
|
|
|
popfd
|
|
leave
|
|
ret 4*6
|
|
|
|
|
|
%endif
|
|
|