Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
31 halyavin 1
; drawing code for aclock
2
;
3
; Copyright (c) 2003 Thomas Mathys
4
; killer@vantage.ch
5
;
6
; This program is free software; you can redistribute it and/or modify
7
; it under the terms of the GNU General Public License as published by
8
; the Free Software Foundation; either version 2 of the License, or
9
; (at your option) any later version.
10
;
11
; This program is distributed in the hope that it will be useful,
12
; but WITHOUT ANY WARRANTY; without even the implied warranty of
13
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
; GNU General Public License for more details.
15
;
16
; You should have received a copy of the GNU General Public License
17
; along with this program; if not, write to the Free Software
18
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
;
20
%ifndef _DRAW_INC
21
%define _DRAW_INC
22
 
23
 
24
TMR1_FACTOR	dd	0.45
25
TMR2_FACTOR	dd	0.426315789
26
SECR_FACTOR	dd	0.378947368
27
MINR_FACTOR	dd	0.355263158
28
HOURR_FACTOR	dd	0.189473684
29
DATE_FACTOR	dd	0.1
30
 
31
 
32
monthNames:
33
		db "Jan"
34
		db "Feb"
35
		db "Mar"
36
		db "Apr"
37
		db "May"
38
		db "Jun"
39
		db "Jul"
40
		db "Aug"
41
		db "Sep"
42
		db "Oct"
43
		db "Nov"
44
		db "Dec"
45
 
46
 
47
;********************************************************************
48
;	draws the clock
49
;	input		:	nothing
50
;	output		:	nothing
51
;	destroys	:	nothing
52
;********************************************************************
53
drawClock:
54
	%push	drawClock_context
55
	%stacksize flat
56
	%assign	%$localsize 0
57
 
58
	%local	i:dword,		\
59
		TMR1X:dword,		\
60
		TMR1Y:dword,		\
61
		TMR2X:dword,		\
62
		TMR2Y:dword,		\
63
		SECRX:dword,		\
64
		SECRY:dword,		\
65
		MINRX:dword,		\
66
		MINRY:dword,		\
67
		HOURRX:dword,		\
68
		HOURRY:dword,		\
69
		workwidth:dword,	\
70
		workheight:dword,	\
71
		foo:dword
72
 
73
	enter	%$localsize,0
74
	pushad
75
	pushfd
76
 
77
	; get window dimensions
78
	mov	eax,MOS_SC_GETPROCESSINFO
79
	mov	ebx,procInfo
80
	mov	ecx,-1
81
	int	0x40
82
 
83
	; calculate work area size (width/height = ecx/edx)
84
	; if the work area is too small (maybe the window is shaded)
85
	; we don't draw anything.
86
	mov	eax,MOS_SC_WINDOWPROPERTIES
87
	mov	ebx,4			; get skin height (eax)
88
	int	0x40
89
	mov	ecx,[procInfo + MOS_PROCESSINFO.wndWidth]
90
	sub	ecx,MOS_WND_SKIN_BORDER_LEFT+MOS_WND_SKIN_BORDER_RIGHT
91
	mov	edx,[procInfo + MOS_PROCESSINFO.wndHeight]
92
	sub	edx,eax
93
	sub	edx,MOS_WND_SKIN_BORDER_BOTTOM
94
	cmp	ecx,0			; width too small ?
95
	jle	.bye
96
	cmp	edx,0			; height too small ?
97
	jnle	.continue
98
.bye:
99
	jmp	.byebye
100
.continue:
101
	mov	[workwidth],ecx		; save for later (for fpu)
102
	mov	[workheight],edx
103
 
104
	; calculate center of clock (x/y = esi/edi)
105
	mov	esi,[procInfo + MOS_PROCESSINFO.wndWidth]
106
	shr	esi,1
107
	mov	edi,[procInfo + MOS_PROCESSINFO.wndHeight]
108
	sub	edi,MOS_WND_SKIN_BORDER_BOTTOM
109
	sub	edi,eax
110
	shr	edi,1
111
	add	edi,eax
112
 
113
	; clear work area
114
	pushad
115
	mov	ebx,(MOS_WND_SKIN_BORDER_LEFT)*0x10000	; x start
116
	or	ebx,ecx					; width
117
	mov	ecx,eax					; y start
118
	shl	ecx,16					; (=skin height)
119
	or	ecx,edx					; height
120
	mov	edx,[wndColors + MOS_WNDCOLORS.work]
121
	mov	eax,MOS_SC_DRAWBAR
122
	int	0x40
123
	popad
124
 
125
	; calculate second hand radii
126
	fild	dword [workwidth]
127
	fmul	dword [SECR_FACTOR]
128
	fstp	dword [SECRX]
129
	fild	dword [workheight]
130
	fmul	dword [SECR_FACTOR]
131
	fstp	dword [SECRY]
132
 
133
	; calculate minute hand radii
134
	fild	dword [workwidth]
135
	fmul	dword [MINR_FACTOR]
136
	fstp	dword [MINRX]
137
	fild	dword [workheight]
138
	fmul	dword [MINR_FACTOR]
139
	fstp	dword [MINRY]
140
 
141
	; calculate hour hand radii
142
	fild	dword [workwidth]
143
	fmul	dword [HOURR_FACTOR]
144
	fstp	dword [HOURRX]
145
	fild	dword [workheight]
146
	fmul	dword [HOURR_FACTOR]
147
	fstp	dword [HOURRY]
148
 
149
	; calculate tick mark radii
150
	fild	dword [workwidth]
151
	fmul	dword [TMR1_FACTOR]
152
	fstp	dword [TMR1X]
153
	fild	dword [workheight]
154
	fmul	dword [TMR1_FACTOR]
155
	fstp	dword [TMR1Y]
156
	fild	dword [workwidth]
157
	fmul	dword [TMR2_FACTOR]
158
	fstp	dword [TMR2X]
159
	fild	dword [workheight]
160
	fmul	dword [TMR2_FACTOR]
161
	fstp	dword [TMR2Y]
162
 
163
	; get system clock (edx)
164
	mov	eax,MOS_SC_GETSYSCLOCK
165
	int	0x40
166
	mov	edx,eax
167
 
168
	; draw second hand
169
	push	edx
170
	mov	eax,edx
171
	shr	eax,16
172
	call	bcdbin
173
	mov	ecx,eax			; save seconds for later
174
	push	ecx
175
	push	eax
176
	fpush32	0.104719755		; 2*pi/60
177
	push	dword [SECRX]
178
	push	dword [SECRY]
179
	push	esi
180
	push	edi
181
	call	getHandCoords
182
	mov	eax,MOS_SC_DRAWLINE
183
	shl	ebx,16
184
	or	ebx,esi
185
	shl	ecx,16
186
	or	ecx,edi
187
	mov	edx,[wndColors + MOS_WNDCOLORS.workText]
188
	int	0x40
189
	pop	ecx
190
	pop	edx
191
 
192
	; draw minute hand
193
	push	edx
194
	mov	eax,edx
195
	shr	eax,8
196
	call	bcdbin
197
	mov	edx,60
198
	mul	edx
199
	add	eax,ecx
200
	mov	ecx,eax			; save for later
201
	push	ecx
202
	push	eax
203
	fpush32 0.001745329		; 2*pi/60/60
204
	push	dword [MINRX]
205
	push	dword [MINRY]
206
	push	esi
207
	push	edi
208
	call	getHandCoords
209
	mov	eax,MOS_SC_DRAWLINE
210
	shl	ebx,16
211
	or	ebx,esi
212
	shl	ecx,16
213
	or	ecx,edi
214
	mov	edx,[wndColors + MOS_WNDCOLORS.workText]
215
	int	0x40
216
	pop	ecx
217
	pop	edx
218
 
219
	; draw hour hand
220
	push	edx
221
	mov	eax,edx
222
	call	bcdbin
223
	cmp	eax,11			; % 12 (just to be sure)
224
	jnae	.hoursok
225
	sub	eax,12
226
.hoursok:
227
	mov	edx,60*60
228
	mul	edx
229
	add	eax,ecx
230
	push	eax
231
	fpush32	0.000145444		; 2*pi/60/60/12
232
	push	dword [HOURRX]
233
	push	dword [HOURRY]
234
	push	esi
235
	push	edi
236
	call	getHandCoords
237
	mov	eax,MOS_SC_DRAWLINE
238
	shl	ebx,16
239
	or	ebx,esi
240
	shl	ecx,16
241
	or	ecx,edi
242
	mov	edx,[wndColors + MOS_WNDCOLORS.workText]
243
	int	0x40
244
	pop	edx
245
 
246
	; draw tick marks
247
	mov	dword [i],11		; draw 12 marks
248
.drawtickmarks:
249
	push	dword [i]		; calculate start point
250
	fpush32	0.523598776		; 2*pi/12
251
	push	dword [TMR1X]
252
	push	dword [TMR1Y]
253
	push	esi
254
	push	edi
255
	call	getHandCoords
256
	mov	eax,ebx			; save in eax and edx
257
	mov	edx,ecx
258
	push	dword [i]
259
	fpush32	0.523598776		; 2*pi/12
260
	push	dword [TMR2X]
261
	push	dword [TMR2Y]
262
	push	esi
263
	push	edi
264
	call	getHandCoords
265
	shl	eax,16
266
	shl	edx,16
267
	or	ebx,eax			; ebx = x start and end
268
	or	ecx,edx			; ecx = y start and end
269
	mov	edx,[wndColors + MOS_WNDCOLORS.workText]
270
	mov	eax,MOS_SC_DRAWLINE
271
	int	0x40
272
	dec	dword [i]
273
	jns	.drawtickmarks
274
 
275
	%define	DATE_WIDTH	48
276
 
277
	; calculate text start position
278
	mov	eax,[procInfo+MOS_PROCESSINFO.wndWidth]
279
	sub	eax,DATE_WIDTH		; x = (wndwidth-textwidth)/2
280
	shr	eax,1			; eax = x
281
	fild	dword [workheight]	; y = DATE_FACTOR*workheight...
282
	fmul	dword [DATE_FACTOR]
283
	mov	[foo],edi		; ... + y_clockcenter
284
	fiadd	dword [foo]
285
	fistp	dword [foo]
286
	mov	ebx,[foo]		; ebx = y
287
 
288
	; draw text at all ?
289
	cmp	dword [workwidth],DATE_WIDTH	; text too wide ?
290
	jb	.goodbye
291
	mov	ecx,ebx				; text too high ?
292
	add	ecx,10-1
293
	mov	edx,[procInfo+MOS_PROCESSINFO.wndHeight]
294
	sub	edx,MOS_WND_SKIN_BORDER_BOTTOM
295
	cmp	ecx,edx
296
	jnae	.yousuck
297
.goodbye:
298
	jmp	.bye
299
.yousuck:
300
 
301
 
302
	; ebx = (x << 16) | y
303
	shl	eax,16
304
	or	ebx,eax
305
 
306
	; get date (edi)
307
	mov	eax,MOS_SC_GETDATE
308
	int	0x40
309
	mov	edi,eax
310
 
311
	; display month
312
	mov	eax,edi			; get month
313
	shr	eax,8
314
	call	bcdbin
315
					; ebx contains already position
316
	mov	ecx,[wndColors+MOS_WNDCOLORS.workText]
317
	lea	edx,[monthNames-3+eax*2+eax]; -3 because eax = 1..12 =]
318
	mov	esi,3			; text length
319
	mov	eax,MOS_SC_WRITETEXT
320
	int	0x40
321
 
322
	; display date
323
	add	ebx,MOS_DWORD(3*6+3,0)
324
	mov	eax,edi			; get date
325
	shr	eax,16
326
	call	bcdbin
327
	mov	edx,ebx			; position must be in edx
328
	mov	ebx,0x00020000		; number, display two digits
329
	mov	ecx,eax			; number to display
330
	mov	esi,[wndColors+MOS_WNDCOLORS.workText]
331
	mov	eax,MOS_SC_WRITENUMBER
332
	int	0x40
333
 
334
	; display year. the way we avoid the y2k bug is even
335
	; simpler, yet much better than in the last version:
336
	; now we simply display the last two digits and let the
337
	; user decide wether it's the year 1903 or 2003 =]
338
	add	edx,MOS_DWORD(2*6+3,0)
339
	mov	eax,edi			; get year
340
	call	bcdbin
341
	mov	ebx,0x00020000		; number, display two digits
342
	mov	ecx,eax			; number to display
343
					; edx contains already position
344
	mov	esi,[wndColors+MOS_WNDCOLORS.workText]
345
	mov	eax,MOS_SC_WRITENUMBER
346
	int	0x40
347
 
348
.byebye:
349
	popfd
350
	popad
351
	leave
352
	ret
353
	%pop
354
 
355
 
356
;**********************************************************
357
; bcdbin
358
; converts a 8 bit bcd number into a 32 bit binary number
359
;
360
; in		al = 8 bit bcd number
361
; out		eax = 32 bit binary number
362
; destroys	dl,flags
363
;**********************************************************
364
bcdbin:
365
	push	edx
366
	pushfd
367
	mov	dl,al			; save bcd number
368
	shr	al,4			; convert upper nibble
369
	mov	ah,10
370
	mul	ah
371
	and	dl,15			; add lower nibble
372
	add	al,dl
373
	and	eax,255			; !
374
	popfd
375
	pop	edx
376
	ret
377
 
378
 
379
;********************************************************************
380
; getHandCoords
381
; calculates the end point of a hand
382
;
383
; input (on stack, push from top to bottom):
384
; ANGLE		angle (integer)
385
; DEG2RAD	conversion factor for ANGLE (32 bit real)
386
; RADIUSX	x radius (32 bit real)
387
; RADIUSY	y radius (32 bit real)
388
; CENTERX	x center of the clock (integer)
389
; CENTERY	y center of the clock (integer)
390
;
391
; output:
392
; ebx		x coordinate in bits 0..15, bits 16..31 are zero
393
; ecx		y coordinate in bits 0..15, bits 16..31 are zero
394
;
395
; destroys:
396
; nothing
397
;********************************************************************
398
getHandCoords:
399
 
400
ANGLE	equ	28
401
DEG2RAD	equ	24
402
RADIUSX	equ	20
403
RADIUSY	equ	16
404
CENTERX	equ	12
405
CENTERY	equ	8
406
 
407
	enter	0,0
408
	pushfd
409
 
410
	fild dword [ebp+ANGLE]		; get angle
411
	fmul dword [ebp+DEG2RAD]	; convert to radians
412
	fsincos
413
	fmul dword [ebp+RADIUSY]	; -y * radius + clockcy
414
	fchs
415
	fiadd dword [ebp+CENTERY]
416
	fistp dword [ebp+CENTERY]
417
	fmul dword [ebp+RADIUSX]	; x * radius + clockcx
418
	fiadd dword [ebp+CENTERX]
419
	fistp dword [ebp+CENTERX]
420
 
421
	mov ebx,[ebp+CENTERX]
422
	mov ecx,[ebp+CENTERY]
423
 
424
	popfd
425
	leave
426
	ret	4*6
427
 
428
 
429
%endif
430