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 |