00001
00002
00003
00004
00005
00006 #include "lcconfig.h"
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <math.h>
00010 #include <assert.h>
00011 #include "lcstring.h"
00012 #include "lcintl.h"
00013 #include "lin-city.h"
00014 #include "common.h"
00015 #include "lctypes.h"
00016 #include "pixmap.h"
00017 #include "screen.h"
00018
00019 #define USE_WINDOWS_FONT 1
00020 #undef USE_WINDOWS_FONT
00021
00022 int
00023 AdjustX (int x)
00024 {
00025 x <<= pix_double;
00026 x += borderx;
00027 return x;
00028 }
00029
00030 int
00031 AdjustY (int y)
00032 {
00033 y <<= pix_double;
00034 y += bordery;
00035 return y;
00036 }
00037
00038 int
00039 UnAdjustX (int x)
00040 {
00041 x -= borderx;
00042 x >>= pix_double;
00043 return x;
00044 }
00045
00046 int
00047 UnAdjustY (int y)
00048 {
00049 y -= bordery;
00050 y >>= pix_double;
00051 return y;
00052 }
00053
00054 void
00055 HandleError (char *description, int degree)
00056 {
00057 MessageBox (NULL, description, _("ERROR"), MB_OK);
00058 if (degree == FATAL)
00059 {
00060 exit (-1);
00061 }
00062 }
00063
00064 void
00065 setcustompalette (void)
00066 {
00067 char s[100];
00068 unsigned int n, r, g, b;
00069 int i, flag[256];
00070 FILE *inf;
00071
00072 for (i = 0; i < 256; i++)
00073 flag[i] = 0;
00074 if ((inf = fopen (colour_pal_file, "r")) == 0)
00075 HandleError ("Can't find the colour pallet file", FATAL);
00076
00077 while (feof (inf) == 0) {
00078 fgets (s, 99, inf);
00079 if (sscanf (s, "%u %u %u %u", &n, &r, &g, &b) == 4)
00080 {
00081 r = ((r * (1 - gamma_correct_red))
00082 + (64 * sin ((float) r * M_PI / 128))
00083 * gamma_correct_red);
00084 g = ((g * (1 - gamma_correct_green))
00085 + (64 * sin ((float) g * M_PI / 128))
00086 * gamma_correct_green);
00087 b = ((b * (1 - gamma_correct_blue))
00088 + (64 * sin ((float) b * M_PI / 128))
00089 * gamma_correct_blue);
00090 AddPaletteEntry (n, r, g, b);
00091 flag[n] = 1;
00092 }
00093 }
00094 fclose (inf);
00095 for (i = 0; i < 256; i++) {
00096 if (flag[i] == 0) {
00097 printf ("Colour %d not loaded\n", i);
00098 HandleError ("Can't continue", FATAL);
00099 }
00100 }
00101 UpdatePalette ();
00102 }
00103
00104 COLORREF
00105 GetPaletteColorref (int col)
00106 {
00107 assert (col >= 0 || col <= 255);
00108 if (display.hasPalette)
00109 return PALETTEINDEX (col);
00110 else
00111 return display.colorrefPal[col];
00112 }
00113
00114 HBRUSH
00115 GetPaletteBrush (int col)
00116 {
00117 assert (col >= 0 || col <= 255);
00118 if (display.brushPal[col] == 0)
00119 display.brushPal[col] = CreateSolidBrush (GetPaletteColorref (col));
00120 return display.brushPal[col];
00121 }
00122
00123 int CALLBACK
00124 EnumFontFamProc (ENUMLOGFONT FAR * lpelf,
00125 NEWTEXTMETRIC FAR * lpntm,
00126 int FontType,
00127 LPARAM lParam
00128 )
00129 {
00130 int i = 0;
00131
00132 if (0 != strcmp (lpelf->elfLogFont.lfFaceName, "Lincity"))
00133
00134
00135
00136 return 0;
00137
00138
00139
00140
00141
00142
00143 *(LOGFONT *) lParam = lpelf->elfLogFont;
00144 return 1;
00145 }
00146
00147 void
00148 init_windows_font (void)
00149 {
00150 #if defined (USE_WINDOWS_FONT)
00151 int rc;
00152 LOGFONT logfont;
00153 int fonts_added = AddFontResource (windowsfontfile);
00154 if (fonts_added != 1) {
00155 HandleError ("Can't open the font file", FATAL);
00156 }
00157 SendMessage (HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
00158 ProcessPendingEvents ();
00159
00160
00161
00162
00163 #if defined (commentout)
00164 typedef int (FAR WINAPI * voidfnptr) (const struct tagLOGFONTA *, const struct tagTEXTMETRICA *, unsigned long, long);
00165 EnumFontFamilies (display.hdcMem, "Lincity", (voidfnptr) EnumFontFamProc, (LPARAM) & logfont);
00166 #endif
00167
00168
00169
00170
00171 rc = EnumFontFamilies (display.hdcMem, "Lincity", (FONTENUMPROC) EnumFontFamProc, (LPARAM) & logfont);
00172
00173 display.hFont = CreateFontIndirect (&logfont);
00174 if (!display.hFont) {
00175 HandleError ("Error executing CreateFontIndirect", FATAL);
00176 }
00177 SelectObject (display.hdcMem, display.hFont);
00178 #endif
00179 }
00180
00181 void
00182 gl_setpalettecolor (long x, long r, long g, long b)
00183 {
00184 if (x >= 0 && x <= 255) {
00185 AddPaletteEntry (x, r, g, b);
00186 }
00187 }
00188
00189 void
00190 Fgl_setfontcolors (int bg, int fg)
00191 {
00192 text_fg = fg;
00193 text_bg = bg;
00194 }
00195
00196 void
00197 Fgl_setfont (int fw, int fh, void *fp)
00198 {
00199 open_font = fp;
00200 open_font_height = fh;
00201 }
00202
00203 void
00204 Fgl_setpixel (int x, int y, int col)
00205 {
00206 int i;
00207
00208 if (clipping_flag)
00209 if (x < xclip_x1 || x > xclip_x2 || y < xclip_y1 || y > xclip_y2)
00210 return;
00211 col &= 0xff;
00212
00213
00214 i = pixmap_index(x,y);
00215 pixmap[i] = (unsigned char) col;
00216
00217
00218 if (display.useDIB) {
00219 BYTE *pixel = display.pBits;
00220 unsigned long row = display.pbminfo->bmiHeader.biHeight - (y + bordery);
00221 unsigned long rowlength = display.pbminfo->bmiHeader.biWidth;
00222 unsigned long mod = rowlength % sizeof (DWORD);
00223 if (mod) {
00224 rowlength += (sizeof (DWORD) - mod);
00225 }
00226 pixel += row * rowlength + x + borderx;
00227 *pixel = col;
00228 } else {
00229 if (pix_double) {
00230 RECT rect;
00231 HBRUSH hbr, hbrOld;
00232 rect.left = AdjustX (x);
00233 rect.top = AdjustY (y);
00234 rect.right = AdjustX (x + 1);
00235 rect.bottom = AdjustY (y + 1);
00236 hbr = GetPaletteBrush (col);
00237 hbrOld = (HBRUSH) SelectObject (display.hdcMem, hbr);
00238 FillRect (display.hdcMem, &rect, hbr);
00239 hbr = (HBRUSH) SelectObject (display.hdcMem, hbrOld);
00240 } else {
00241 SetPixel (display.hdcMem, x + borderx, y + bordery, GetPaletteColorref (col));
00242 }
00243 }
00244
00245
00246 }
00247
00248
00249 int
00250 Fgl_getpixel (int x, int y)
00251 {
00252 return pixmap_getpixel (x, y);
00253 }
00254
00255
00256 void
00257 Fgl_hline (int x1, int y1, int x2, int col)
00258 {
00259 int xor = 0;
00260 RECT rect;
00261
00262 if (col == -1) {
00263 xor = 1;
00264 }
00265 col &= 0xff;
00266 pixmap_hline (x1, y1, x2, col);
00267
00268
00269 rect.left = AdjustX (x1);
00270 rect.top = AdjustY (y1);
00271 rect.right = AdjustX (x2);
00272 rect.bottom = AdjustY (y1 + 1);
00273
00274
00275 if (display.useDIB) {
00276 HPEN hpen, hpenOld;
00277 HBITMAP hOldBitmapMem;
00278 int oldrop2;
00279 hpen = CreatePen (PS_SOLID, 0, GetPaletteColorref (col));
00280 hpenOld = (HPEN) SelectObject (display.hdcMem, hpen);
00281 hOldBitmapMem = (HBITMAP) SelectObject (display.hdcMem, display.hDIB);
00282 MoveToEx (display.hdcMem, x1 + borderx, y1 + bordery, NULL);
00283 if (xor)
00284 oldrop2 = SetROP2 (display.hdcMem, R2_NOT);
00285 LineTo (display.hdcMem, x2 + borderx, y1 + bordery);
00286 if (xor)
00287 SetROP2 (display.hdcMem, oldrop2);
00288 display.hDIB = (HBITMAP) SelectObject (display.hdcMem, hOldBitmapMem);
00289 hpen = (HPEN) SelectObject (display.hdcMem, hpenOld);
00290 DeleteObject (hpen);
00291 } else {
00292 if (pix_double) {
00293 HBRUSH hbr, hbrOld;
00294 int oldrop2;
00295 hbr = GetPaletteBrush (col);
00296 hbrOld = (HBRUSH) SelectObject (display.hdcMem, hbr);
00297 if (xor)
00298 oldrop2 = SetROP2 (display.hdcMem, R2_NOT);
00299 FillRect (display.hdcMem, &rect, hbr);
00300 if (xor)
00301 SetROP2 (display.hdcMem, oldrop2);
00302 hbr = (HBRUSH) SelectObject (display.hdcMem, hbrOld);
00303 } else {
00304 HPEN hpen, hpenOld;
00305 int oldrop2;
00306 hpen = CreatePen (PS_SOLID, 0, GetPaletteColorref (col));
00307 hpenOld = (HPEN) SelectObject (display.hdcMem, hpen);
00308 MoveToEx (display.hdcMem, x1 + borderx, y1 + bordery, NULL);
00309 if (xor)
00310 oldrop2 = SetROP2 (display.hdcMem, R2_NOT);
00311 LineTo (display.hdcMem, x2 + borderx, y1 + bordery);
00312 if (xor)
00313 SetROP2 (display.hdcMem, oldrop2);
00314 hpen = (HPEN) SelectObject (display.hdcMem, hpenOld);
00315 DeleteObject (hpen);
00316 }
00317 }
00318
00319
00320 InvalidateRect (display.hWnd, &rect, FALSE);
00321 }
00322
00323 void
00324 Fgl_line (int x1, int y1, int dummy, int y2, int col)
00325
00326 {
00327 RECT rect;
00328 col &= 0xff;
00329 pixmap_vline (x1, y1, y2, col);
00330
00331
00332 rect.left = AdjustX (x1);
00333 rect.top = AdjustY (y1);
00334 rect.right = AdjustX (x1 + 1);
00335 rect.bottom = AdjustY (y2);
00336
00337
00338 if (display.useDIB) {
00339 HPEN hpen, hpenOld;
00340 HBITMAP hOldBitmapMem;
00341 hpen = CreatePen (PS_SOLID, 0, GetPaletteColorref (col));
00342 hpenOld = (HPEN) SelectObject (display.hdcMem, hpen);
00343 hOldBitmapMem = (HBITMAP) SelectObject (display.hdcMem, display.hDIB);
00344 MoveToEx (display.hdcMem, x1 + borderx, y1 + bordery, NULL);
00345 LineTo (display.hdcMem, x1 + borderx, y2 + bordery);
00346 display.hDIB = (HBITMAP) SelectObject (display.hdcMem, hOldBitmapMem);
00347 hpen = (HPEN) SelectObject (display.hdcMem, hpenOld);
00348 DeleteObject (hpen);
00349 } else {
00350 if (pix_double) {
00351 HBRUSH hbr, hbrOld;
00352 hbr = GetPaletteBrush (col);
00353 hbrOld = (HBRUSH) SelectObject (display.hdcMem, hbr);
00354 FillRect (display.hdcMem, &rect, hbr);
00355 hbr = (HBRUSH) SelectObject (display.hdcMem, hbrOld);
00356 } else {
00357 HPEN hpen, hpenOld;
00358 hpen = CreatePen (PS_SOLID, 0, GetPaletteColorref (col));
00359 hpenOld = (HPEN) SelectObject (display.hdcMem, hpen);
00360 MoveToEx (display.hdcMem, AdjustX (x1), AdjustY (y1), NULL);
00361 LineTo (display.hdcMem, AdjustX (x1), AdjustY (y2));
00362 hpen = (HPEN) SelectObject (display.hdcMem, hpenOld);
00363 DeleteObject (hpen);
00364 }
00365 }
00366
00367
00368 InvalidateRect (display.hWnd, &rect, FALSE);
00369 }
00370
00371
00372 void
00373 Fgl_write (int x, int y, char *s)
00374 {
00375 int i;
00376 RECT rect;
00377 #if defined (USE_WINDOWS_FONT)
00378 SIZE size;
00379
00380 SetTextColor (display.hdcMem, GetPaletteColorref (text_fg));
00381 SetBkColor (display.hdcMem, GetPaletteColorref (text_bg));
00382
00383
00384 ExtTextOut (display.hdcMem, AdjustX (x), AdjustY (y), 0, NULL,
00385 s, strlen (s), NULL);
00386
00387
00388 GetTextExtentPoint32 (display.hdcMem, s, strlen (s), &size);
00389 #endif
00390
00391
00392 for (i = 0; i < (int) (strlen (s)); i++)
00393 my_x_putchar (x + i * 8, y, s[i]);
00394
00395
00396 #if defined (USE_WINDOWS_FONT)
00397 rect.left = AdjustX (x);
00398 rect.top = AdjustY (y);
00399 rect.right = AdjustX (x + size.cx);
00400 rect.bottom = AdjustY (y + size.cy);
00401 InvalidateRect (display.hWnd, &rect, FALSE);
00402 #else
00403 rect.left = AdjustX (x);
00404 rect.top = AdjustY (y);
00405 rect.right = AdjustX (x + i * 8);
00406 rect.bottom = AdjustY (y + 8);
00407 InvalidateRect (display.hWnd, &rect, FALSE);
00408 #endif
00409 }
00410
00411
00412 void
00413 open_write (int x, int y, char *s)
00414 {
00415 int i;
00416 RECT rect;
00417 for (i = 0; i < (int) (strlen (s)); i++)
00418 open_x_putchar (x + i * 8, y, s[i]);
00419
00420
00421 rect.left = AdjustX (x);
00422 rect.top = AdjustY (y);
00423 rect.right = AdjustX (x + i * 8);
00424 rect.bottom = AdjustY (y + open_font_height);
00425 InvalidateRect (display.hWnd, &rect, FALSE);
00426 }
00427
00428 void
00429 my_x_putchar (int xx, int yy, unsigned char c)
00430 {
00431 int x, y, b;
00432 for (y = 0; y < 8; y++) {
00433 b = main_font[c * 8 + y];
00434 for (x = 0; x < 8; x++) {
00435 if ((b & 0x80) == 0) {
00436 #if defined (USE_WINDOWS_FONT)
00437 pixmap_setpixel (xx + x, yy + y, text_bg);
00438 #else
00439 Fgl_setpixel (xx + x, yy + y, text_bg);
00440 #endif
00441 } else {
00442 #if defined (USE_WINDOWS_FONT)
00443 pixmap_setpixel (xx + x, yy + y, text_fg);
00444 #else
00445 Fgl_setpixel (xx + x, yy + y, text_fg);
00446 #endif
00447 }
00448 b = b << 1;
00449 }
00450 }
00451 }
00452
00453
00454 void
00455 open_x_putchar (int xx, int yy, unsigned char c)
00456 {
00457 int x, y, b;
00458 for (y = 0; y < open_font_height; y++) {
00459 b = open_font[c * open_font_height + y];
00460 for (x = 0; x < 8; x++) {
00461 if ((b & 0x80) == 0)
00462 Fgl_setpixel (xx + x, yy + y, text_bg);
00463 else
00464 Fgl_setpixel (xx + x, yy + y, text_fg);
00465 b = b << 1;
00466 }
00467 }
00468 }
00469
00470
00471 void
00472 Fgl_fillbox (int x1, int y1, int w, int h, int col)
00473 {
00474 RECT rect;
00475 if (clipping_flag) {
00476 if (x1 < xclip_x1)
00477 x1 = xclip_x1;
00478 if (x1 + w > xclip_x2)
00479 w = xclip_x2 - x1;
00480 if (y1 < xclip_y1)
00481 y1 = xclip_y1;
00482 if (y1 + h > xclip_y2)
00483 h = xclip_y2 - y1;
00484 }
00485 col &= 0xff;
00486 pixmap_fillbox (x1, y1, w, h, col);
00487
00488
00489 if (display.useDIB) {
00490 HBITMAP hOldBitmapMem;
00491 HBRUSH hbr, hbrOld;
00492 rect.left = x1 + borderx;
00493 rect.top = y1 + bordery;
00494 rect.right = x1 + borderx + w;
00495 rect.bottom = y1 + bordery + h;
00496 hbr = GetPaletteBrush (col);
00497 hbrOld = (HBRUSH) SelectObject (display.hdcMem, hbr);
00498 hOldBitmapMem = (HBITMAP) SelectObject (display.hdcMem, display.hDIB);
00499 FillRect (display.hdcMem, &rect, hbr);
00500 display.hDIB = (HBITMAP) SelectObject (display.hdcMem, hOldBitmapMem);
00501 hbr = (HBRUSH) SelectObject (display.hdcMem, hbrOld);
00502 } else {
00503 HBRUSH hbr, hbrOld;
00504 rect.left = AdjustX (x1);
00505 rect.top = AdjustY (y1);
00506 rect.right = AdjustX (x1 + w);
00507 rect.bottom = AdjustY (y1 + h);
00508 hbr = GetPaletteBrush (col);
00509 hbrOld = (HBRUSH) SelectObject (display.hdcMem, hbr);
00510 FillRect (display.hdcMem, &rect, hbr);
00511 hbr = (HBRUSH) SelectObject (display.hdcMem, hbrOld);
00512 }
00513
00514
00515 InvalidateRect (display.hWnd, &rect, FALSE);
00516 }
00517
00518 void
00519 Fgl_putbox (int x1, int y1, int w, int h, void *buf)
00520 {
00521 unsigned char *b = (unsigned char *) buf;
00522 RECT rect;
00523 int x, y;
00524 for (y = y1; y < y1 + h; y++)
00525 for (x = x1; x < x1 + w; x++)
00526 Fgl_setpixel (x, y, *(b++));
00527
00528
00529 rect.left = AdjustX (x1);
00530 rect.top = AdjustY (y1);
00531 rect.right = AdjustX (x1 + w);
00532 rect.bottom = AdjustY (y1 + h);
00533 InvalidateRect (display.hWnd, &rect, FALSE);
00534
00535
00536
00537 }
00538
00539 void
00540 Fgl_getbox (int x1, int y1, int w, int h, void *buf)
00541 {
00542 unsigned char *b = (unsigned char *) buf;
00543 int x, y;
00544 for (y = y1; y < y1 + h; y++)
00545 for (x = x1; x < x1 + w; x++)
00546 *(b++) = (unsigned char) Fgl_getpixel (x, y);
00547 }
00548
00549 void
00550 RefreshScreen ()
00551 {
00552 InvalidateRect (display.hWnd, NULL, FALSE);
00553 ProcessNextEvent ();
00554 }
00555
00556 void
00557 RefreshArea (int x1, int y1, int x2, int y2)
00558 {
00559 RECT rect;
00560 rect.left = AdjustX (x1);
00561 rect.top = AdjustY (y1);
00562 rect.right = AdjustX (x2);
00563 rect.bottom = AdjustY (y2);
00564 InvalidateRect (display.hWnd, &rect, FALSE);
00565 UpdateWindow (display.hWnd);
00566 }
00567
00568 void
00569 Fgl_enableclipping (void)
00570 {
00571 clipping_flag = 1;
00572 }
00573
00574 void
00575 Fgl_setclippingwindow (int x1, int y1, int x2, int y2)
00576 {
00577 xclip_x1 = x1;
00578 xclip_y1 = y1;
00579 xclip_x2 = x2;
00580 xclip_y2 = y2;
00581 }
00582
00583 void
00584 Fgl_disableclipping (void)
00585 {
00586 clipping_flag = 0;
00587 }
00588
00589 void
00590 do_call_event (int wait)
00591 {
00592 if (wait)
00593 lc_usleep (1000);
00594 HandleMouse ();
00595 }
00596
00597 void
00598 call_event (void)
00599 {
00600 do_call_event (0);
00601 }
00602
00603 void
00604 call_wait_event (void)
00605 {
00606 do_call_event (1);
00607 }
00608
00609 #ifdef USE_PIXMAPS
00610 void
00611 init_icon_pixmap (short type)
00612 {
00613 unsigned char *g;
00614 int x, y;
00615 HBITMAP hOldBitmapMem;
00616 int w, h;
00617 int grp;
00618
00619 grp = get_group_of_type(type);
00620
00621 if( grp >= 0) {
00622 w = main_groups[grp].size * 16;
00623 h = main_groups[grp].size * 16;
00624 w <<= pix_double;
00625 h <<= pix_double;
00626 icon_pixmap[type] = CreateCompatibleBitmap (display.hdcMem, w, h);
00627 hOldBitmapMem = (HBITMAP) SelectObject (display.hdcMem, icon_pixmap[type]);
00628
00629
00630 g = (unsigned char *) main_types[type].graphic;
00631 for (y = 0; y < main_groups[grp].size * 16; y++) {
00632 for (x = 0; x < main_groups[grp].size * 16; x++) {
00633 if (pix_double) {
00634 RECT rect;
00635 HBRUSH hbr, hbrOld;
00636 rect.left = x << 1;
00637 rect.top = y << 1;
00638 rect.right = (x + 1) << 1;
00639 rect.bottom = (y + 1) << 1;
00640 hbr = GetPaletteBrush (*g++);
00641 hbrOld = (HBRUSH) SelectObject (display.hdcMem, hbr);
00642 FillRect (display.hdcMem, &rect, hbr);
00643 hbr = (HBRUSH) SelectObject (display.hdcMem, hbrOld);
00644 } else {
00645 SetPixel (display.hdcMem, x, y, GetPaletteColorref (*g++));
00646 }
00647 }
00648 }
00649 icon_pixmap[type] = (HBITMAP) SelectObject (display.hdcMem, hOldBitmapMem);
00650 }
00651 }
00652 #endif
00653
00654 int
00655 lc_get_keystroke (void)
00656 {
00657 return GetKeystroke ();
00658 }
00659
00660 void
00661 draw_border (void)
00662 {
00663 }
00664
00665 void
00666 init_mouse (void)
00667 {
00668 }