From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- Doc/doxygen/html/_window_8cpp_source.html | 1053 +++++++++++++++++++++++++++++ 1 file changed, 1053 insertions(+) create mode 100644 Doc/doxygen/html/_window_8cpp_source.html (limited to 'Doc/doxygen/html/_window_8cpp_source.html') diff --git a/Doc/doxygen/html/_window_8cpp_source.html b/Doc/doxygen/html/_window_8cpp_source.html new file mode 100644 index 0000000..da65436 --- /dev/null +++ b/Doc/doxygen/html/_window_8cpp_source.html @@ -0,0 +1,1053 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/nGenEx/Window.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
Window.cpp
+
+
+Go to the documentation of this file.
1 /* Project nGenEx
+
2  Destroyer Studios LLC
+
3  Copyright © 1997-2004. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: nGenEx.lib
+
6  FILE: Window.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12  Window class
+
13 */
+
14 
+
15 #include "MemDebug.h"
+
16 #include "Window.h"
+
17 #include "Bitmap.h"
+
18 #include "Color.h"
+
19 #include "Fix.h"
+
20 #include "Font.h"
+
21 #include "Polygon.h"
+
22 #include "Screen.h"
+
23 #include "Video.h"
+
24 #include "View.h"
+
25 
+
26 static VertexSet vset4(4);
+
27 
+
28 // +--------------------------------------------------------------------+
+
29 
+
30 Window::Window(Screen* s, int ax, int ay, int aw, int ah)
+
31 : screen(s), rect(ax, ay, aw, ah), shown(true), font(0)
+
32 { }
+
33 
+
34 // +--------------------------------------------------------------------+
+
35 
+ +
37 {
+ +
39 }
+
40 
+
41 // +--------------------------------------------------------------------+
+
42 
+
43 bool
+ +
45 {
+
46  if (!v) return false;
+
47 
+
48  if (!view_list.contains(v))
+
49  view_list.append(v);
+
50 
+
51  return true;
+
52 }
+
53 
+
54 bool
+ +
56 {
+
57  if (!v) return false;
+
58 
+
59  return view_list.remove(v) == v;
+
60 }
+
61 
+
62 void
+ +
64 {
+
65  if (rect.x == r.x &&
+
66  rect.y == r.y &&
+
67  rect.w == r.w &&
+
68  rect.h == r.h)
+
69  return;
+
70 
+
71  rect = r;
+
72 
+ +
74  while (++v)
+
75  v->OnWindowMove();
+
76 }
+
77 
+
78 // +--------------------------------------------------------------------+
+
79 
+
80 void
+ +
82 {
+ +
84  while (++v)
+
85  v->Refresh();
+
86 }
+
87 
+
88 // +--------------------------------------------------------------------+
+
89 
+
90 static inline void swap(int& a, int& b) { int tmp=a; a=b; b=tmp; }
+
91 static inline void sort(int& a, int& b) { if (a>b) swap(a,b); }
+
92 static inline void swap(double& a, double& b) { double tmp=a; a=b; b=tmp; }
+
93 static inline void sort(double& a, double& b) { if (a>b) swap(a,b); }
+
94 
+
95 Rect
+ +
97 {
+
98  Rect clip_rect = r;
+
99 
+
100  clip_rect.x += rect.x;
+
101  clip_rect.y += rect.y;
+
102 
+
103  if (clip_rect.x < rect.x) {
+
104  clip_rect.w -= rect.x - clip_rect.x;
+
105  clip_rect.x = rect.x;
+
106  }
+
107 
+
108  if (clip_rect.y < rect.y) {
+
109  clip_rect.h -= rect.y - clip_rect.y;
+
110  clip_rect.y = rect.y;
+
111  }
+
112 
+
113  if (clip_rect.x + clip_rect.w > rect.x + rect.w)
+
114  clip_rect.w = rect.x + rect.w - clip_rect.x;
+
115 
+
116  if (clip_rect.y + clip_rect.h > rect.y + rect.h)
+
117  clip_rect.h = rect.y + rect.h - clip_rect.y;
+
118 
+
119  return clip_rect;
+
120 }
+
121 
+
122 // +--------------------------------------------------------------------+
+
123 
+
124 bool
+
125 Window::ClipLine(int& x1, int& y1, int& x2, int& y2)
+
126 {
+
127  // vertical lines:
+
128  if (x1==x2) {
+
129  clip_vertical:
+
130  sort(y1,y2);
+
131  if (x1 < 0 || x1 >= rect.w) return false;
+
132  if (y1 < 0) y1 = 0;
+
133  if (y2 >= rect.h) y2 = rect.h;
+
134  return true;
+
135  }
+
136 
+
137  // horizontal lines:
+
138  if (y1==y2) {
+
139  clip_horizontal:
+
140  sort(x1,x2);
+
141  if (y1 < 0 || y1 >= rect.h) return false;
+
142  if (x1 < 0) x1 = 0;
+
143  if (x2 > rect.w) x2 = rect.w;
+
144  return true;
+
145  }
+
146 
+
147  // general lines:
+
148 
+
149  // sort left to right:
+
150  if (x1 > x2) {
+
151  swap(x1,x2);
+
152  swap(y1,y2);
+
153  }
+
154 
+
155  double m = (double)(y2-y1) / (double)(x2-x1);
+
156  double b = (double) y1 - (m * x1);
+
157 
+
158  // clip:
+
159  if (x1 < 0) { x1 = 0; y1 = (int) b; }
+
160  if (x1 >= rect.w) return false;
+
161  if (x2 < 0) return false;
+
162  if (x2 > rect.w-1) { x2 = rect.w-1; y2 = (int) (m * x2 + b); }
+
163 
+
164  if (y1 < 0 && y2 < 0) return false;
+
165  if (y1 >= rect.h && y2 >= rect.h) return false;
+
166 
+
167  if (y1 < 0) { y1 = 0; x1 = (int) (-b/m); }
+
168  if (y1 >= rect.h) { y1 = rect.h-1; x1 = (int) ((y1-b)/m); }
+
169  if (y2 < 0) { y2 = 0; x2 = (int) (-b/m); }
+
170  if (y2 >= rect.h) { y2 = rect.h-1; x2 = (int) ((y2-b)/m); }
+
171 
+
172  if (x1 == x2)
+
173  goto clip_vertical;
+
174 
+
175  if (y1 == y2)
+
176  goto clip_horizontal;
+
177 
+
178  return true;
+
179 }
+
180 
+
181 // +--------------------------------------------------------------------+
+
182 
+
183 bool
+
184 Window::ClipLine(double& x1, double& y1, double& x2, double& y2)
+
185 {
+
186  // vertical lines:
+
187  if (x1==x2) {
+
188  clip_vertical:
+
189  sort(y1,y2);
+
190  if (x1 < 0 || x1 >= rect.w) return false;
+
191  if (y1 < 0) y1 = 0;
+
192  if (y2 >= rect.h) y2 = rect.h;
+
193  return true;
+
194  }
+
195 
+
196  // horizontal lines:
+
197  if (y1==y2) {
+
198  clip_horizontal:
+
199  sort(x1,x2);
+
200  if (y1 < 0 || y1 >= rect.h) return false;
+
201  if (x1 < 0) x1 = 0;
+
202  if (x2 > rect.w) x2 = rect.w;
+
203  return true;
+
204  }
+
205 
+
206  // general lines:
+
207 
+
208  // sort left to right:
+
209  if (x1 > x2) {
+
210  swap(x1,x2);
+
211  swap(y1,y2);
+
212  }
+
213 
+
214  double m = (double)(y2-y1) / (double)(x2-x1);
+
215  double b = (double) y1 - (m * x1);
+
216 
+
217  // clip:
+
218  if (x1 < 0) { x1 = 0; y1 = b; }
+
219  if (x1 >= rect.w) return false;
+
220  if (x2 < 0) return false;
+
221  if (x2 > rect.w-1) { x2 = rect.w-1; y2 = (m * x2 + b); }
+
222 
+
223  if (y1 < 0 && y2 < 0) return false;
+
224  if (y1 >= rect.h && y2 >= rect.h) return false;
+
225 
+
226  if (y1 < 0) { y1 = 0; x1 = (-b/m); }
+
227  if (y1 >= rect.h) { y1 = rect.h-1; x1 = ((y1-b)/m); }
+
228  if (y2 < 0) { y2 = 0; x2 = (-b/m); }
+
229  if (y2 >= rect.h) { y2 = rect.h-1; x2 = ((y2-b)/m); }
+
230 
+
231  if (x1 == x2)
+
232  goto clip_vertical;
+
233 
+
234  if (y1 == y2)
+
235  goto clip_horizontal;
+
236 
+
237  return true;
+
238 }
+
239 
+
240 // +--------------------------------------------------------------------+
+
241 
+
242 void
+
243 Window::DrawLine(int x1, int y1, int x2, int y2, Color color, int blend)
+
244 {
+
245  if (!screen || !screen->GetVideo()) return;
+
246 
+
247  if (ClipLine(x1,y1,x2,y2)) {
+
248  float points[4];
+
249 
+
250  points[0] = (float) (rect.x + x1);
+
251  points[1] = (float) (rect.y + y1);
+
252  points[2] = (float) (rect.x + x2);
+
253  points[3] = (float) (rect.y + y2);
+
254 
+
255  Video* video = screen->GetVideo();
+
256  video->DrawScreenLines(1, points, color, blend);
+
257  }
+
258 }
+
259 
+
260 // +--------------------------------------------------------------------+
+
261 
+
262 void
+
263 Window::DrawRect(int x1, int y1, int x2, int y2, Color color, int blend)
+
264 {
+
265  if (!screen || !screen->GetVideo()) return;
+
266 
+
267  sort(x1,x2);
+
268  sort(y1,y2);
+
269 
+
270  if (x1 > rect.w || x2 < 0 || y1 > rect.h || y2 < 0)
+
271  return;
+
272 
+
273  float points[16];
+
274 
+
275  points[ 0] = (float) (rect.x + x1);
+
276  points[ 1] = (float) (rect.y + y1);
+
277  points[ 2] = (float) (rect.x + x2);
+
278  points[ 3] = (float) (rect.y + y1);
+
279 
+
280  points[ 4] = (float) (rect.x + x2);
+
281  points[ 5] = (float) (rect.y + y1);
+
282  points[ 6] = (float) (rect.x + x2);
+
283  points[ 7] = (float) (rect.y + y2);
+
284 
+
285  points[ 8] = (float) (rect.x + x2);
+
286  points[ 9] = (float) (rect.y + y2);
+
287  points[10] = (float) (rect.x + x1);
+
288  points[11] = (float) (rect.y + y2);
+
289 
+
290  points[12] = (float) (rect.x + x1);
+
291  points[13] = (float) (rect.y + y2);
+
292  points[14] = (float) (rect.x + x1);
+
293  points[15] = (float) (rect.y + y1);
+
294 
+
295  Video* video = screen->GetVideo();
+
296  video->DrawScreenLines(4, points, color, blend);
+
297 }
+
298 
+
299 void
+
300 Window::DrawRect(const Rect& r, Color color, int blend)
+
301 {
+
302  DrawRect(r.x, r.y, r.x+r.w, r.y+r.h, color, blend);
+
303 }
+
304 
+
305 // +--------------------------------------------------------------------+
+
306 
+
307 void
+
308 Window::FillRect(int x1, int y1, int x2, int y2, Color color, int blend)
+
309 {
+
310  if (!screen || !screen->GetVideo()) return;
+
311 
+
312  sort(x1,x2);
+
313  sort(y1,y2);
+
314 
+
315  if (x1 > rect.w || x2 < 0 || y1 > rect.h || y2 < 0)
+
316  return;
+
317 
+ +
319  for (int i = 0; i < 4; i++) {
+
320  vset4.diffuse[i] = color.Value();
+
321  }
+
322 
+
323  vset4.s_loc[0].x = (float) (rect.x + x1) - 0.5f;
+
324  vset4.s_loc[0].y = (float) (rect.y + y1) - 0.5f;
+
325  vset4.s_loc[0].z = 0.0f;
+
326  vset4.rw[0] = 1.0f;
+
327  vset4.tu[0] = 0.0f;
+
328  vset4.tv[0] = 0.0f;
+
329 
+
330  vset4.s_loc[1].x = (float) (rect.x + x2) - 0.5f;
+
331  vset4.s_loc[1].y = (float) (rect.y + y1) - 0.5f;
+
332  vset4.s_loc[1].z = 0.0f;
+
333  vset4.rw[1] = 1.0f;
+
334  vset4.tu[1] = 1.0f;
+
335  vset4.tv[1] = 0.0f;
+
336 
+
337  vset4.s_loc[2].x = (float) (rect.x + x2) - 0.5f;
+
338  vset4.s_loc[2].y = (float) (rect.y + y2) - 0.5f;
+
339  vset4.s_loc[2].z = 0.0f;
+
340  vset4.rw[2] = 1.0f;
+
341  vset4.tu[2] = 1.0f;
+
342  vset4.tv[2] = 1.0f;
+
343 
+
344  vset4.s_loc[3].x = (float) (rect.x + x1) - 0.5f;
+
345  vset4.s_loc[3].y = (float) (rect.y + y2) - 0.5f;
+
346  vset4.s_loc[3].z = 0.0f;
+
347  vset4.rw[3] = 1.0f;
+
348  vset4.tu[3] = 0.0f;
+
349  vset4.tv[3] = 1.0f;
+
350 
+
351  Poly poly(0);
+
352  poly.nverts = 4;
+
353  poly.vertex_set = &vset4;
+
354  poly.verts[0] = 0;
+
355  poly.verts[1] = 1;
+
356  poly.verts[2] = 2;
+
357  poly.verts[3] = 3;
+
358 
+
359  Video* video = screen->GetVideo();
+
360  video->DrawScreenPolys(1, &poly, blend);
+
361 }
+
362 
+
363 void
+
364 Window::FillRect(const Rect& r, Color color, int blend)
+
365 {
+
366  FillRect(r.x, r.y, r.x+r.w, r.y+r.h, color, blend);
+
367 }
+
368 
+
369 // +--------------------------------------------------------------------+
+
370 
+
371 void
+
372 Window::DrawLines(int nPts, POINT* pts, Color color, int blend)
+
373 {
+
374  if (nPts < 2 || nPts > 16)
+
375  return;
+
376 
+
377  if (!screen || !screen->GetVideo())
+
378  return;
+
379 
+
380  float f[64];
+
381  int n = 0;
+
382 
+
383  for (int i = 0; i < nPts-1; i++) {
+
384  f[n++] = (float) rect.x + pts[i].x;
+
385  f[n++] = (float) rect.y + pts[i].y;
+
386  f[n++] = (float) rect.x + pts[i+1].x;
+
387  f[n++] = (float) rect.y + pts[i+1].y;
+
388  }
+
389 
+
390  Video* video = screen->GetVideo();
+
391  video->DrawScreenLines(nPts-1, f, color, blend);
+
392 }
+
393 
+
394 void
+
395 Window::DrawPoly(int nPts, POINT* pts, Color color, int blend)
+
396 {
+
397  if (nPts < 3 || nPts > 8)
+
398  return;
+
399 
+
400  if (!screen || !screen->GetVideo())
+
401  return;
+
402 
+
403  float f[32];
+
404  int n = 0;
+
405 
+
406  for (int i = 0; i < nPts-1; i++) {
+
407  f[n++] = (float) rect.x + pts[i].x;
+
408  f[n++] = (float) rect.y + pts[i].y;
+
409  f[n++] = (float) rect.x + pts[i+1].x;
+
410  f[n++] = (float) rect.y + pts[i+1].y;
+
411  }
+
412 
+
413  f[n++] = (float) rect.x + pts[nPts-1].x;
+
414  f[n++] = (float) rect.y + pts[nPts-1].y;
+
415  f[n++] = (float) rect.x + pts[0].x;
+
416  f[n++] = (float) rect.y + pts[0].y;
+
417 
+
418  Video* video = screen->GetVideo();
+
419  video->DrawScreenLines(nPts, f, color, blend);
+
420 }
+
421 
+
422 void
+
423 Window::FillPoly(int nPts, POINT* pts, Color color, int blend)
+
424 {
+
425  if (nPts < 3 || nPts > 4)
+
426  return;
+
427 
+
428  if (!screen || !screen->GetVideo())
+
429  return;
+
430 
+ +
432  for (int i = 0; i < nPts; i++) {
+
433  vset4.diffuse[i] = color.Value();
+
434  vset4.s_loc[i].x = (float) (rect.x + pts[i].x) - 0.5f;
+
435  vset4.s_loc[i].y = (float) (rect.y + pts[i].y) - 0.5f;
+
436  vset4.s_loc[i].z = 0.0f;
+
437  vset4.rw[i] = 1.0f;
+
438  vset4.tu[i] = 0.0f;
+
439  vset4.tv[i] = 0.0f;
+
440  }
+
441 
+
442  Poly poly(0);
+
443  poly.nverts = nPts;
+
444  poly.vertex_set = &vset4;
+
445  poly.verts[0] = 0;
+
446  poly.verts[1] = 1;
+
447  poly.verts[2] = 2;
+
448  poly.verts[3] = 3;
+
449 
+
450  Video* video = screen->GetVideo();
+
451  video->DrawScreenPolys(1, &poly, blend);
+
452 }
+
453 
+
454 // +--------------------------------------------------------------------+
+
455 
+
456 void
+
457 Window::DrawBitmap(int x1, int y1, int x2, int y2, Bitmap* img, int blend)
+
458 {
+
459  Rect clip_rect;
+
460  clip_rect.w = rect.w;
+
461  clip_rect.h = rect.h;
+
462 
+
463  ClipBitmap(x1,y1,x2,y2,img,Color::White,blend,clip_rect);
+
464 }
+
465 
+
466 void
+
467 Window::FadeBitmap(int x1, int y1, int x2, int y2, Bitmap* img, Color c, int blend)
+
468 {
+
469  Rect clip_rect;
+
470  clip_rect.w = rect.w;
+
471  clip_rect.h = rect.h;
+
472 
+
473  ClipBitmap(x1,y1,x2,y2,img,c,blend,clip_rect);
+
474 }
+
475 
+
476 void
+
477 Window::ClipBitmap(int x1, int y1, int x2, int y2, Bitmap* img, Color c, int blend, const Rect& clip_rect)
+
478 {
+
479  if (!screen || !screen->GetVideo() || !img) return;
+
480 
+
481  Rect clip = clip_rect;
+
482 
+
483  // clip the clip rect to the window rect:
+
484  if (clip.x < 0) {
+
485  clip.w -= clip.x;
+
486  clip.x = 0;
+
487  }
+
488 
+
489  if (clip.x + clip.w > rect.w) {
+
490  clip.w -= (clip.x + clip.w - rect.w);
+
491  }
+
492 
+
493  if (clip.y < 0) {
+
494  clip.h -= clip.y;
+
495  clip.y = 0;
+
496  }
+
497 
+
498  if (clip.y + clip.h > rect.h) {
+
499  clip.h -= (clip.y + clip.h - rect.h);
+
500  }
+
501 
+
502  // now clip the bitmap to the validated clip rect:
+
503  sort(x1,x2);
+
504  sort(y1,y2);
+
505 
+
506  if (x1 > clip.x + clip.w || x2 < clip.x || y1 > clip.y + clip.h || y2 < clip.y)
+
507  return;
+
508 
+ +
510  for (int i = 0; i < 4; i++) {
+
511  vset4.diffuse[i] = c.Value();
+
512  }
+
513 
+
514  float u1 = 0.0f;
+
515  float u2 = 1.0f;
+
516  float v1 = 0.0f;
+
517  float v2 = 1.0f;
+
518  float iw = (float) (x2-x1);
+
519  float ih = (float) (y2-y1);
+
520  int x3 = clip.x + clip.w;
+
521  int y3 = clip.y + clip.h;
+
522 
+
523  if (x1 < clip.x) {
+
524  u1 = (clip.x - x1) / iw;
+
525  x1 = clip.x;
+
526  }
+
527 
+
528  if (x2 > x3) {
+
529  u2 = 1.0f - (x2 - x3) / iw;
+
530  x2 = x3;
+
531  }
+
532 
+
533  if (y1 < clip.y) {
+
534  v1 = (clip.y - y1) / ih;
+
535  y1 = clip.y;
+
536  }
+
537 
+
538  if (y2 > y3) {
+
539  v2 = 1.0f - (y2 - y3) / ih;
+
540  y2 = y3;
+
541  }
+
542 
+
543  vset4.s_loc[0].x = (float) (rect.x + x1) - 0.5f;
+
544  vset4.s_loc[0].y = (float) (rect.y + y1) - 0.5f;
+
545  vset4.s_loc[0].z = 0.0f;
+
546  vset4.rw[0] = 1.0f;
+
547  vset4.tu[0] = u1;
+
548  vset4.tv[0] = v1;
+
549 
+
550  vset4.s_loc[1].x = (float) (rect.x + x2) - 0.5f;
+
551  vset4.s_loc[1].y = (float) (rect.y + y1) - 0.5f;
+
552  vset4.s_loc[1].z = 0.0f;
+
553  vset4.rw[1] = 1.0f;
+
554  vset4.tu[1] = u2;
+
555  vset4.tv[1] = v1;
+
556 
+
557  vset4.s_loc[2].x = (float) (rect.x + x2) - 0.5f;
+
558  vset4.s_loc[2].y = (float) (rect.y + y2) - 0.5f;
+
559  vset4.s_loc[2].z = 0.0f;
+
560  vset4.rw[2] = 1.0f;
+
561  vset4.tu[2] = u2;
+
562  vset4.tv[2] = v2;
+
563 
+
564  vset4.s_loc[3].x = (float) (rect.x + x1) - 0.5f;
+
565  vset4.s_loc[3].y = (float) (rect.y + y2) - 0.5f;
+
566  vset4.s_loc[3].z = 0.0f;
+
567  vset4.rw[3] = 1.0f;
+
568  vset4.tu[3] = u1;
+
569  vset4.tv[3] = v2;
+
570 
+
571  Material mtl;
+
572  mtl.tex_diffuse = img;
+
573 
+
574  Poly poly(0);
+
575  poly.nverts = 4;
+
576  poly.vertex_set = &vset4;
+
577  poly.material = &mtl;
+
578  poly.verts[0] = 0;
+
579  poly.verts[1] = 1;
+
580  poly.verts[2] = 2;
+
581  poly.verts[3] = 3;
+
582 
+
583  Video* video = screen->GetVideo();
+
584 
+ +
586  video->DrawScreenPolys(1, &poly, blend);
+ +
588 }
+
589 
+
590 // +--------------------------------------------------------------------+
+
591 
+
592 void
+
593 Window::TileBitmap(int x1, int y1, int x2, int y2, Bitmap* img, int blend)
+
594 {
+
595  if (!screen || !screen->GetVideo()) return;
+
596  if (!img || !img->Width() || !img->Height()) return;
+
597 
+ +
599  for (int i = 0; i < 4; i++) {
+
600  vset4.diffuse[i] = Color::White.Value();
+
601  }
+
602 
+
603  float xscale = (float) rect.w / (float) img->Width();
+
604  float yscale = (float) rect.h / (float) img->Height();
+
605 
+
606  vset4.s_loc[0].x = (float) (rect.x + x1) - 0.5f;
+
607  vset4.s_loc[0].y = (float) (rect.y + y1) - 0.5f;
+
608  vset4.s_loc[0].z = 0.0f;
+
609  vset4.rw[0] = 1.0f;
+
610  vset4.tu[0] = 0.0f;
+
611  vset4.tv[0] = 0.0f;
+
612 
+
613  vset4.s_loc[1].x = (float) (rect.x + x2) - 0.5f;
+
614  vset4.s_loc[1].y = (float) (rect.y + y1) - 0.5f;
+
615  vset4.s_loc[1].z = 0.0f;
+
616  vset4.rw[1] = 1.0f;
+
617  vset4.tu[1] = xscale;
+
618  vset4.tv[1] = 0.0f;
+
619 
+
620  vset4.s_loc[2].x = (float) (rect.x + x2) - 0.5f;
+
621  vset4.s_loc[2].y = (float) (rect.y + y2) - 0.5f;
+
622  vset4.s_loc[2].z = 0.0f;
+
623  vset4.rw[2] = 1.0f;
+
624  vset4.tu[2] = xscale;
+
625  vset4.tv[2] = yscale;
+
626 
+
627  vset4.s_loc[3].x = (float) (rect.x + x1) - 0.5f;
+
628  vset4.s_loc[3].y = (float) (rect.y + y2) - 0.5f;
+
629  vset4.s_loc[3].z = 0.0f;
+
630  vset4.rw[3] = 1.0f;
+
631  vset4.tu[3] = 0.0f;
+
632  vset4.tv[3] = yscale;
+
633 
+
634  Material mtl;
+
635  mtl.tex_diffuse = img;
+
636 
+
637  Poly poly(0);
+
638  poly.nverts = 4;
+
639  poly.vertex_set = &vset4;
+
640  poly.material = &mtl;
+
641  poly.verts[0] = 0;
+
642  poly.verts[1] = 1;
+
643  poly.verts[2] = 2;
+
644  poly.verts[3] = 3;
+
645 
+
646  Video* video = screen->GetVideo();
+
647  video->DrawScreenPolys(1, &poly, blend);
+
648 }
+
649 
+
650 // +--------------------------------------------------------------------+
+
651 
+
652 static float ellipse_pts[256];
+
653 
+
654 void
+
655 Window::DrawEllipse(int x1, int y1, int x2, int y2, Color color, int blend)
+
656 {
+
657  Video* video = screen->GetVideo();
+
658 
+
659  if (!video)
+
660  return;
+
661 
+
662  sort(x1,x2);
+
663  sort(y1,y2);
+
664 
+
665  if (x1 > rect.w || x2 < 0 || y1 > rect.h || y2 < 0)
+
666  return;
+
667 
+
668  double w2 = (x2-x1)/2.0;
+
669  double h2 = (y2-y1)/2.0;
+
670  double cx = rect.x + x1 + w2;
+
671  double cy = rect.y + y1 + h2;
+
672  double r = w2;
+
673  int ns = 4;
+
674  int np = 0;
+
675 
+
676  if (h2 > r)
+
677  r = h2;
+
678 
+
679  if (r > 2*ns)
+
680  ns = (int) (r/2);
+
681 
+
682  if (ns > 64)
+
683  ns = 64;
+
684 
+
685  double theta = 0;
+
686  double dt = (PI/2) / ns;
+
687 
+
688  // quadrant 1 (lower right):
+
689  if (cx < (rect.x+rect.w) && cy < (rect.y + rect.h)) {
+
690  theta = 0;
+
691  np = 0;
+
692 
+
693  for (int i = 0; i < ns; i++) {
+
694  double ex1 = x1 + w2 + cos(theta) * w2;
+
695  double ey1 = y1 + h2 + sin(theta) * h2;
+
696 
+
697  theta += dt;
+
698 
+
699  double ex2 = x1 + w2 + cos(theta) * w2;
+
700  double ey2 = y1 + h2 + sin(theta) * h2;
+
701 
+
702  if (ClipLine(ex1, ey1, ex2, ey2)) {
+
703  ellipse_pts[np++] = (float) (rect.x + ex1);
+
704  ellipse_pts[np++] = (float) (rect.y + ey1);
+
705  ellipse_pts[np++] = (float) (rect.x + ex2);
+
706  ellipse_pts[np++] = (float) (rect.y + ey2);
+
707  }
+
708  }
+
709 
+
710  video->DrawScreenLines(np/4, ellipse_pts, color, blend);
+
711  }
+
712 
+
713  // quadrant 2 (lower left):
+
714  if (cx > rect.x && cy < (rect.y + rect.h)) {
+
715  theta = 90*DEGREES;
+
716  np = 0;
+
717 
+
718  for (int i = 0; i < ns; i++) {
+
719  double ex1 = x1 + w2 + cos(theta) * w2;
+
720  double ey1 = y1 + h2 + sin(theta) * h2;
+
721 
+
722  theta += dt;
+
723 
+
724  double ex2 = x1 + w2 + cos(theta) * w2;
+
725  double ey2 = y1 + h2 + sin(theta) * h2;
+
726 
+
727  if (ClipLine(ex1, ey1, ex2, ey2)) {
+
728  ellipse_pts[np++] = (float) (rect.x + ex1);
+
729  ellipse_pts[np++] = (float) (rect.y + ey1);
+
730  ellipse_pts[np++] = (float) (rect.x + ex2);
+
731  ellipse_pts[np++] = (float) (rect.y + ey2);
+
732  }
+
733  }
+
734 
+
735  video->DrawScreenLines(np/4, ellipse_pts, color, blend);
+
736  }
+
737 
+
738  // quadrant 3 (upper left):
+
739  if (cx > rect.x && cy > rect.y) {
+
740  theta = 180*DEGREES;
+
741  np = 0;
+
742 
+
743  for (int i = 0; i < ns; i++) {
+
744  double ex1 = x1 + w2 + cos(theta) * w2;
+
745  double ey1 = y1 + h2 + sin(theta) * h2;
+
746 
+
747  theta += dt;
+
748 
+
749  double ex2 = x1 + w2 + cos(theta) * w2;
+
750  double ey2 = y1 + h2 + sin(theta) * h2;
+
751 
+
752  if (ClipLine(ex1, ey1, ex2, ey2)) {
+
753  ellipse_pts[np++] = (float) (rect.x + ex1);
+
754  ellipse_pts[np++] = (float) (rect.y + ey1);
+
755  ellipse_pts[np++] = (float) (rect.x + ex2);
+
756  ellipse_pts[np++] = (float) (rect.y + ey2);
+
757  }
+
758  }
+
759 
+
760  video->DrawScreenLines(np/4, ellipse_pts, color, blend);
+
761  }
+
762 
+
763  // quadrant 4 (upper right):
+
764  if (cx < (rect.x+rect.w) && cy > rect.y) {
+
765  theta = 270*DEGREES;
+
766  np = 0;
+
767 
+
768  for (int i = 0; i < ns; i++) {
+
769  double ex1 = x1 + w2 + cos(theta) * w2;
+
770  double ey1 = y1 + h2 + sin(theta) * h2;
+
771 
+
772  theta += dt;
+
773 
+
774  double ex2 = x1 + w2 + cos(theta) * w2;
+
775  double ey2 = y1 + h2 + sin(theta) * h2;
+
776 
+
777  if (ClipLine(ex1, ey1, ex2, ey2)) {
+
778  ellipse_pts[np++] = (float) (rect.x + ex1);
+
779  ellipse_pts[np++] = (float) (rect.y + ey1);
+
780  ellipse_pts[np++] = (float) (rect.x + ex2);
+
781  ellipse_pts[np++] = (float) (rect.y + ey2);
+
782  }
+
783  }
+
784 
+
785  video->DrawScreenLines(np/4, ellipse_pts, color, blend);
+
786  }
+
787 
+
788 }
+
789 
+
790 void
+
791 Window::FillEllipse(int x1, int y1, int x2, int y2, Color color, int blend)
+
792 {
+
793  Video* video = screen->GetVideo();
+
794 
+
795  if (!video)
+
796  return;
+
797 
+
798  sort(x1,x2);
+
799  sort(y1,y2);
+
800 
+
801  if (x1 > rect.w || x2 < 0 || y1 > rect.h || y2 < 0)
+
802  return;
+
803 
+
804  double w2 = (x2-x1)/2.0;
+
805  double h2 = (y2-y1)/2.0;
+
806  double cx = x1 + w2;
+
807  double cy = y1 + h2;
+
808  double r = w2;
+
809  int ns = 4;
+
810  int np = 0;
+
811 
+
812  if (h2 > r)
+
813  r = h2;
+
814 
+
815  if (r > 2*ns)
+
816  ns = (int) (r/2);
+
817 
+
818  if (ns > 64)
+
819  ns = 64;
+
820 
+
821  double theta = -PI / 2;
+
822  double dt = PI / ns;
+
823 
+
824  for (int i = 0; i < ns; i++) {
+
825  double ex1 = cos(theta) * w2;
+
826  double ey1 = sin(theta) * h2;
+
827 
+
828  theta += dt;
+
829 
+
830  double ex2 = cos(theta) * w2;
+
831  double ey2 = sin(theta) * h2;
+
832 
+
833  POINT pts[4];
+
834 
+
835  pts[0].x = (int) (cx - ex1);
+
836  pts[0].y = (int) (cy + ey1);
+
837 
+
838  pts[1].x = (int) (cx + ex1);
+
839  pts[1].y = (int) (cy + ey1);
+
840 
+
841  pts[2].x = (int) (cx + ex2);
+
842  pts[2].y = (int) (cy + ey2);
+
843 
+
844  pts[3].x = (int) (cx - ex2);
+
845  pts[3].y = (int) (cy + ey2);
+
846 
+
847  if (pts[0].x > rect.w && pts[3].x > rect.w)
+
848  continue;
+
849 
+
850  if (pts[1].x < 0 && pts[2].x < 0)
+
851  continue;
+
852 
+
853  if (pts[0].y > rect.h)
+
854  return;
+
855 
+
856  if (pts[2].y < 0)
+
857  continue;
+
858 
+
859  if (pts[0].x < 0) pts[0].x = 0;
+
860  if (pts[3].x < 0) pts[3].x = 0;
+
861  if (pts[1].x > rect.w) pts[1].x = rect.w;
+
862  if (pts[2].x > rect.w) pts[2].x = rect.w;
+
863 
+
864  if (pts[0].y < 0) pts[0].y = 0;
+
865  if (pts[1].y < 0) pts[1].y = 0;
+
866  if (pts[2].y > rect.h) pts[2].y = rect.h;
+
867  if (pts[3].y > rect.h) pts[3].y = rect.h;
+
868 
+
869  FillPoly(4, pts, color, blend);
+
870  }
+
871 }
+
872 
+
873 // +--------------------------------------------------------------------+
+
874 
+
875 void
+
876 Window::Print(int x1, int y1, const char* fmt, ...)
+
877 {
+
878  if (!font || x1<0 || y1<0 || x1>=rect.w || y1>=rect.h || !fmt)
+
879  return;
+
880 
+
881  x1 += rect.x;
+
882  y1 += rect.y;
+
883 
+
884  char msgbuf[512];
+
885  vsprintf_s(msgbuf, fmt, (char *)(&fmt+1));
+
886  font->DrawString(msgbuf, strlen(msgbuf), x1, y1, rect);
+
887 }
+
888 
+
889 void
+
890 Window::DrawText(const char* txt, int count, Rect& txt_rect, DWORD flags)
+
891 {
+
892  if (!font)
+
893  return;
+
894 
+
895  if (txt && !count)
+
896  count = strlen(txt);
+
897 
+
898  // clip the rect:
+
899  Rect clip_rect = txt_rect;
+
900 
+
901  if (clip_rect.x < 0) {
+
902  int dx = -clip_rect.x;
+
903  clip_rect.x += dx;
+
904  clip_rect.w -= dx;
+
905  }
+
906 
+
907  if (clip_rect.y < 0) {
+
908  int dy = -clip_rect.y;
+
909  clip_rect.y += dy;
+
910  clip_rect.h -= dy;
+
911  }
+
912 
+
913  if (clip_rect.w < 1 || clip_rect.h < 1)
+
914  return;
+
915 
+
916  if (clip_rect.x + clip_rect.w > rect.w)
+
917  clip_rect.w = rect.w - clip_rect.x;
+
918 
+
919  if (clip_rect.y + clip_rect.h > rect.h)
+
920  clip_rect.h = rect.h - clip_rect.y;
+
921 
+
922  clip_rect.x += rect.x;
+
923  clip_rect.y += rect.y;
+
924 
+
925  if (font && txt && count) {
+
926  font->DrawText(txt, count, clip_rect, flags);
+
927  font->SetAlpha(1);
+
928  }
+
929 
+
930  // if calc only, update the rectangle:
+
931  if (flags & DT_CALCRECT) {
+
932  txt_rect.h = clip_rect.h;
+
933  txt_rect.w = clip_rect.w;
+
934  }
+
935 }
+
936 
+
+
+ + + + -- cgit v1.1