Subversion Repositories Kolibri OS

Rev

Rev 109 | Details | Compare with Previous | 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
2741 dunkaist 117
	inc	ebx
31 halyavin 118
	mov	ecx,eax					; y start
119
	shl	ecx,16					; (=skin height)
120
	or	ecx,edx					; height
2741 dunkaist 121
	inc	ecx
31 halyavin 122
	mov	edx,[wndColors + MOS_WNDCOLORS.work]
123
	mov	eax,MOS_SC_DRAWBAR
124
	int	0x40
125
	popad
126
 
127
	; calculate second hand radii
128
	fild	dword [workwidth]
129
	fmul	dword [SECR_FACTOR]
130
	fstp	dword [SECRX]
131
	fild	dword [workheight]
132
	fmul	dword [SECR_FACTOR]
133
	fstp	dword [SECRY]
134
 
135
	; calculate minute hand radii
136
	fild	dword [workwidth]
137
	fmul	dword [MINR_FACTOR]
138
	fstp	dword [MINRX]
139
	fild	dword [workheight]
140
	fmul	dword [MINR_FACTOR]
141
	fstp	dword [MINRY]
142
 
143
	; calculate hour hand radii
144
	fild	dword [workwidth]
145
	fmul	dword [HOURR_FACTOR]
146
	fstp	dword [HOURRX]
147
	fild	dword [workheight]
148
	fmul	dword [HOURR_FACTOR]
149
	fstp	dword [HOURRY]
150
 
151
	; calculate tick mark radii
152
	fild	dword [workwidth]
153
	fmul	dword [TMR1_FACTOR]
154
	fstp	dword [TMR1X]
155
	fild	dword [workheight]
156
	fmul	dword [TMR1_FACTOR]
157
	fstp	dword [TMR1Y]
158
	fild	dword [workwidth]
159
	fmul	dword [TMR2_FACTOR]
160
	fstp	dword [TMR2X]
161
	fild	dword [workheight]
162
	fmul	dword [TMR2_FACTOR]
163
	fstp	dword [TMR2Y]
164
 
165
	; get system clock (edx)
166
	mov	eax,MOS_SC_GETSYSCLOCK
167
	int	0x40
168
	mov	edx,eax
169
 
170
	; draw second hand
171
	push	edx
172
	mov	eax,edx
173
	shr	eax,16
174
	call	bcdbin
175
	mov	ecx,eax			; save seconds for later
176
	push	ecx
177
	push	eax
178
	fpush32	0.104719755		; 2*pi/60
179
	push	dword [SECRX]
180
	push	dword [SECRY]
181
	push	esi
182
	push	edi
183
	call	getHandCoords
184
	mov	eax,MOS_SC_DRAWLINE
185
	shl	ebx,16
186
	or	ebx,esi
187
	shl	ecx,16
188
	or	ecx,edi
189
	mov	edx,[wndColors + MOS_WNDCOLORS.workText]
190
	int	0x40
191
	pop	ecx
192
	pop	edx
193
 
194
	; draw minute hand
195
	push	edx
196
	mov	eax,edx
197
	shr	eax,8
198
	call	bcdbin
199
	mov	edx,60
200
	mul	edx
201
	add	eax,ecx
202
	mov	ecx,eax			; save for later
203
	push	ecx
204
	push	eax
205
	fpush32 0.001745329		; 2*pi/60/60
206
	push	dword [MINRX]
207
	push	dword [MINRY]
208
	push	esi
209
	push	edi
210
	call	getHandCoords
211
	mov	eax,MOS_SC_DRAWLINE
212
	shl	ebx,16
213
	or	ebx,esi
214
	shl	ecx,16
215
	or	ecx,edi
216
	mov	edx,[wndColors + MOS_WNDCOLORS.workText]
217
	int	0x40
218
	pop	ecx
219
	pop	edx
220
 
221
	; draw hour hand
222
	push	edx
223
	mov	eax,edx
224
	call	bcdbin
225
	cmp	eax,11			; % 12 (just to be sure)
226
	jnae	.hoursok
227
	sub	eax,12
228
.hoursok:
229
	mov	edx,60*60
230
	mul	edx
231
	add	eax,ecx
232
	push	eax
233
	fpush32	0.000145444		; 2*pi/60/60/12
234
	push	dword [HOURRX]
235
	push	dword [HOURRY]
236
	push	esi
237
	push	edi
238
	call	getHandCoords
239
	mov	eax,MOS_SC_DRAWLINE
240
	shl	ebx,16
241
	or	ebx,esi
242
	shl	ecx,16
243
	or	ecx,edi
244
	mov	edx,[wndColors + MOS_WNDCOLORS.workText]
245
	int	0x40
246
	pop	edx
247
 
248
	; draw tick marks
249
	mov	dword [i],11		; draw 12 marks
250
.drawtickmarks:
251
	push	dword [i]		; calculate start point
252
	fpush32	0.523598776		; 2*pi/12
253
	push	dword [TMR1X]
254
	push	dword [TMR1Y]
255
	push	esi
256
	push	edi
257
	call	getHandCoords
258
	mov	eax,ebx			; save in eax and edx
259
	mov	edx,ecx
260
	push	dword [i]
261
	fpush32	0.523598776		; 2*pi/12
262
	push	dword [TMR2X]
263
	push	dword [TMR2Y]
264
	push	esi
265
	push	edi
266
	call	getHandCoords
267
	shl	eax,16
268
	shl	edx,16
269
	or	ebx,eax			; ebx = x start and end
270
	or	ecx,edx			; ecx = y start and end
271
	mov	edx,[wndColors + MOS_WNDCOLORS.workText]
272
	mov	eax,MOS_SC_DRAWLINE
273
	int	0x40
274
	dec	dword [i]
275
	jns	.drawtickmarks
276
 
277
	%define	DATE_WIDTH	48
278
 
279
	; calculate text start position
280
	mov	eax,[procInfo+MOS_PROCESSINFO.wndWidth]
281
	sub	eax,DATE_WIDTH		; x = (wndwidth-textwidth)/2
282
	shr	eax,1			; eax = x
283
	fild	dword [workheight]	; y = DATE_FACTOR*workheight...
284
	fmul	dword [DATE_FACTOR]
285
	mov	[foo],edi		; ... + y_clockcenter
286
	fiadd	dword [foo]
287
	fistp	dword [foo]
288
	mov	ebx,[foo]		; ebx = y
289
 
290
	; draw text at all ?
291
	cmp	dword [workwidth],DATE_WIDTH	; text too wide ?
292
	jb	.goodbye
293
	mov	ecx,ebx				; text too high ?
294
	add	ecx,10-1
295
	mov	edx,[procInfo+MOS_PROCESSINFO.wndHeight]
296
	sub	edx,MOS_WND_SKIN_BORDER_BOTTOM
297
	cmp	ecx,edx
298
	jnae	.yousuck
299
.goodbye:
300
	jmp	.bye
301
.yousuck:
302
 
303
 
304
	; ebx = (x << 16) | y
305
	shl	eax,16
306
	or	ebx,eax
307
 
308
	; get date (edi)
309
	mov	eax,MOS_SC_GETDATE
310
	int	0x40
311
	mov	edi,eax
312
 
313
	; display month
314
	mov	eax,edi			; get month
315
	shr	eax,8
316
	call	bcdbin
317
					; ebx contains already position
318
	mov	ecx,[wndColors+MOS_WNDCOLORS.workText]
319
	lea	edx,[monthNames-3+eax*2+eax]; -3 because eax = 1..12 =]
320
	mov	esi,3			; text length
321
	mov	eax,MOS_SC_WRITETEXT
322
	int	0x40
323
 
324
	; display date
325
	add	ebx,MOS_DWORD(3*6+3,0)
326
	mov	eax,edi			; get date
327
	shr	eax,16
328
	call	bcdbin
329
	mov	edx,ebx			; position must be in edx
330
	mov	ebx,0x00020000		; number, display two digits
331
	mov	ecx,eax			; number to display
332
	mov	esi,[wndColors+MOS_WNDCOLORS.workText]
333
	mov	eax,MOS_SC_WRITENUMBER
334
	int	0x40
335
 
336
	; display year. the way we avoid the y2k bug is even
337
	; simpler, yet much better than in the last version:
338
	; now we simply display the last two digits and let the
339
	; user decide wether it's the year 1903 or 2003 =]
340
	add	edx,MOS_DWORD(2*6+3,0)
341
	mov	eax,edi			; get year
342
	call	bcdbin
343
	mov	ebx,0x00020000		; number, display two digits
344
	mov	ecx,eax			; number to display
345
					; edx contains already position
346
	mov	esi,[wndColors+MOS_WNDCOLORS.workText]
347
	mov	eax,MOS_SC_WRITENUMBER
348
	int	0x40
349
 
350
.byebye:
351
	popfd
352
	popad
353
	leave
354
	ret
355
	%pop
356
 
357
 
358
;**********************************************************
359
; bcdbin
360
; converts a 8 bit bcd number into a 32 bit binary number
361
;
362
; in		al = 8 bit bcd number
363
; out		eax = 32 bit binary number
364
; destroys	dl,flags
365
;**********************************************************
366
bcdbin:
367
	push	edx
368
	pushfd
369
	mov	dl,al			; save bcd number
370
	shr	al,4			; convert upper nibble
371
	mov	ah,10
372
	mul	ah
373
	and	dl,15			; add lower nibble
374
	add	al,dl
375
	and	eax,255			; !
376
	popfd
377
	pop	edx
378
	ret
379
 
380
 
381
;********************************************************************
382
; getHandCoords
383
; calculates the end point of a hand
384
;
385
; input (on stack, push from top to bottom):
386
; ANGLE		angle (integer)
387
; DEG2RAD	conversion factor for ANGLE (32 bit real)
388
; RADIUSX	x radius (32 bit real)
389
; RADIUSY	y radius (32 bit real)
390
; CENTERX	x center of the clock (integer)
391
; CENTERY	y center of the clock (integer)
392
;
393
; output:
394
; ebx		x coordinate in bits 0..15, bits 16..31 are zero
395
; ecx		y coordinate in bits 0..15, bits 16..31 are zero
396
;
397
; destroys:
398
; nothing
399
;********************************************************************
400
getHandCoords:
401
 
402
ANGLE	equ	28
403
DEG2RAD	equ	24
404
RADIUSX	equ	20
405
RADIUSY	equ	16
406
CENTERX	equ	12
407
CENTERY	equ	8
408
 
409
	enter	0,0
410
	pushfd
411
 
412
	fild dword [ebp+ANGLE]		; get angle
413
	fmul dword [ebp+DEG2RAD]	; convert to radians
414
	fsincos
415
	fmul dword [ebp+RADIUSY]	; -y * radius + clockcy
416
	fchs
417
	fiadd dword [ebp+CENTERY]
418
	fistp dword [ebp+CENTERY]
419
	fmul dword [ebp+RADIUSX]	; x * radius + clockcx
420
	fiadd dword [ebp+CENTERX]
421
	fistp dword [ebp+CENTERX]
422
 
423
	mov ebx,[ebp+CENTERX]
424
	mov ecx,[ebp+CENTERY]
425
 
426
	popfd
427
	leave
428
	ret	4*6
429
 
430
 
431
%endif
432