47 #endif |
47 #endif |
48 |
48 |
49 static void MakePalette(void) |
49 static void MakePalette(void) |
50 { |
50 { |
51 LOGPALETTE *pal; |
51 LOGPALETTE *pal; |
52 int i; |
52 uint i; |
53 byte *b; |
53 byte *b; |
54 |
54 |
55 pal = alloca(sizeof(LOGPALETTE) + (256-1) * sizeof(PALETTEENTRY)); |
55 pal = alloca(sizeof(LOGPALETTE) + (256-1) * sizeof(PALETTEENTRY)); |
56 |
56 |
57 pal->palVersion = 0x300; |
57 pal->palVersion = 0x300; |
58 pal->palNumEntries = 256; |
58 pal->palNumEntries = 256; |
59 |
59 |
60 for(i=0,b=_cur_palette; i!=256;i++,b+=3) { |
60 for (i = 0, b = _cur_palette; i != 256; i++, b += 3) { |
61 pal->palPalEntry[i].peRed = b[0]; |
61 pal->palPalEntry[i].peRed = b[0]; |
62 pal->palPalEntry[i].peGreen = b[1]; |
62 pal->palPalEntry[i].peGreen = b[1]; |
63 pal->palPalEntry[i].peBlue = b[2]; |
63 pal->palPalEntry[i].peBlue = b[2]; |
64 pal->palPalEntry[i].peFlags = 0; |
64 pal->palPalEntry[i].peFlags = 0; |
65 |
65 |
159 static void MakeWindow(bool full_screen); |
159 static void MakeWindow(bool full_screen); |
160 static bool AllocateDibSection(int w, int h); |
160 static bool AllocateDibSection(int w, int h); |
161 |
161 |
162 static void ClientSizeChanged(int w, int h) |
162 static void ClientSizeChanged(int w, int h) |
163 { |
163 { |
164 if (_wnd.double_size) { w >>= 1; h >>= 1; } |
164 if (_wnd.double_size) { |
|
165 w /= 2; |
|
166 h /= 2; |
|
167 } |
165 |
168 |
166 // allocate new dib section of the new size |
169 // allocate new dib section of the new size |
167 if (AllocateDibSection(w, h)) { |
170 if (AllocateDibSection(w, h)) { |
168 // mark all palette colors dirty |
171 // mark all palette colors dirty |
169 _pal_first_dirty = 0; |
172 _pal_first_dirty = 0; |
306 r = ToAscii(wParam, scan, ks, &w, 0); |
309 r = ToAscii(wParam, scan, ks, &w, 0); |
307 if (r == 0) w = 0; // no translation was possible |
310 if (r == 0) w = 0; // no translation was possible |
308 |
311 |
309 _pressed_key = w | MapWindowsKey(wParam) << 16; |
312 _pressed_key = w | MapWindowsKey(wParam) << 16; |
310 |
313 |
311 if( scancode == 41 ) |
314 if (scancode == 41) |
312 _pressed_key = w | WKC_BACKQUOTE << 16; |
315 _pressed_key = w | WKC_BACKQUOTE << 16; |
313 |
316 |
314 if ((_pressed_key>>16) == ('D' | WKC_CTRL) && !_wnd.fullscreen) { |
317 if ((_pressed_key >> 16) == ('D' | WKC_CTRL) && !_wnd.fullscreen) { |
315 _double_size ^= 1; |
318 _double_size ^= 1; |
316 _wnd.double_size = _double_size; |
319 _wnd.double_size = _double_size; |
317 ClientSizeChanged(_wnd.width, _wnd.height); |
320 ClientSizeChanged(_wnd.width, _wnd.height); |
318 MarkWholeScreenDirty(); |
321 MarkWholeScreenDirty(); |
319 } |
322 } |
320 } break; |
323 } break; |
321 |
324 |
322 |
325 |
323 case WM_SYSKEYDOWN: /* user presses F10 or Alt, both activating the title-menu */ |
326 case WM_SYSKEYDOWN: /* user presses F10 or Alt, both activating the title-menu */ |
324 switch(wParam) { |
327 switch (wParam) { |
325 case VK_RETURN: /* Full Screen */ |
328 case VK_RETURN: /* Full Screen */ |
326 MakeWindow(!_wnd.fullscreen); |
329 MakeWindow(!_wnd.fullscreen); |
327 return 0; |
330 return 0; |
328 case VK_MENU: /* Just ALT */ |
331 case VK_MENU: /* Just ALT */ |
329 return 0; // do nothing |
332 return 0; // do nothing |
350 SetRect(&r2, 0, 0, 0, 0); |
353 SetRect(&r2, 0, 0, 0, 0); |
351 AdjustWindowRect(&r2, GetWindowLong(hwnd, GWL_STYLE), FALSE); |
354 AdjustWindowRect(&r2, GetWindowLong(hwnd, GWL_STYLE), FALSE); |
352 |
355 |
353 w = r->right - r->left - (r2.right - r2.left); |
356 w = r->right - r->left - (r2.right - r2.left); |
354 h = r->bottom - r->top - (r2.bottom - r2.top); |
357 h = r->bottom - r->top - (r2.bottom - r2.top); |
355 if (_wnd.double_size) { w >>= 1; h >>= 1; } |
358 if (_wnd.double_size) { |
|
359 w /= 2; |
|
360 h /= 2; |
|
361 } |
356 w = clamp(w, 64, MAX_SCREEN_WIDTH); |
362 w = clamp(w, 64, MAX_SCREEN_WIDTH); |
357 h = clamp(h, 64, MAX_SCREEN_HEIGHT); |
363 h = clamp(h, 64, MAX_SCREEN_HEIGHT); |
358 if (_wnd.double_size) { w <<= 1; h <<= 1; } |
364 if (_wnd.double_size) { |
|
365 w *= 2; |
|
366 h *= 2; |
|
367 } |
359 SetRect(&r2, 0, 0, w, h); |
368 SetRect(&r2, 0, 0, w, h); |
360 |
369 |
361 AdjustWindowRect(&r2, GetWindowLong(hwnd, GWL_STYLE), FALSE); |
370 AdjustWindowRect(&r2, GetWindowLong(hwnd, GWL_STYLE), FALSE); |
362 w = r2.right - r2.left; |
371 w = r2.right - r2.left; |
363 h = r2.bottom - r2.top; |
372 h = r2.bottom - r2.top; |
467 settings.dmBitsPerPel = _fullscreen_bpp; |
477 settings.dmBitsPerPel = _fullscreen_bpp; |
468 settings.dmFields |= DM_BITSPERPEL; |
478 settings.dmFields |= DM_BITSPERPEL; |
469 } |
479 } |
470 settings.dmPelsWidth = _wnd.width_org; |
480 settings.dmPelsWidth = _wnd.width_org; |
471 settings.dmPelsHeight = _wnd.height_org; |
481 settings.dmPelsHeight = _wnd.height_org; |
472 if ((settings.dmDisplayFrequency = _display_hz) != 0) |
482 settings.dmDisplayFrequency = _display_hz; |
|
483 if (settings.dmDisplayFrequency != 0) |
473 settings.dmFields |= DM_DISPLAYFREQUENCY; |
484 settings.dmFields |= DM_DISPLAYFREQUENCY; |
474 if ( !ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL ) { |
485 if (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { |
475 MakeWindow(false); |
486 MakeWindow(false); |
476 return; |
487 return; |
477 } |
488 } |
478 } else if (_wnd.fullscreen) { |
489 } else if (_wnd.fullscreen) { |
479 // restore display? |
490 // restore display? |
483 { |
494 { |
484 RECT r; |
495 RECT r; |
485 uint style; |
496 uint style; |
486 int x, y, w, h; |
497 int x, y, w, h; |
487 |
498 |
488 if ((_wnd.fullscreen=full_screen) != false) { |
499 _wnd.fullscreen = full_screen; |
|
500 if (_wnd.fullscreen) { |
489 style = WS_POPUP | WS_VISIBLE; |
501 style = WS_POPUP | WS_VISIBLE; |
490 SetRect(&r, 0, 0, _wnd.width_org, _wnd.height_org); |
502 SetRect(&r, 0, 0, _wnd.width_org, _wnd.height_org); |
491 } else { |
503 } else { |
492 style = WS_OVERLAPPEDWINDOW | WS_VISIBLE; |
504 style = WS_OVERLAPPEDWINDOW | WS_VISIBLE; |
493 SetRect(&r, 0, 0, _wnd.width, _wnd.height); |
505 SetRect(&r, 0, 0, _wnd.width, _wnd.height); |
494 } |
506 } |
495 |
507 |
496 AdjustWindowRect(&r, style, FALSE); |
508 AdjustWindowRect(&r, style, FALSE); |
497 w = r.right - r.left; |
509 w = r.right - r.left; |
498 h = r.bottom - r.top; |
510 h = r.bottom - r.top; |
499 x = (GetSystemMetrics(SM_CXSCREEN)-w)>>1; |
511 x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2; |
500 y = (GetSystemMetrics(SM_CYSCREEN)-h)>>1; |
512 y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2; |
501 |
513 |
502 if (_wnd.main_wnd) { |
514 if (_wnd.main_wnd) { |
503 SetWindowPos(_wnd.main_wnd, 0, x, y, w, h, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER); |
515 SetWindowPos(_wnd.main_wnd, 0, x, y, w, h, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER); |
504 } else { |
516 } else { |
505 char Windowtitle[50] = "OpenTTD "; |
517 char Windowtitle[50] = "OpenTTD "; |
506 // also show revision number/release in window title |
518 |
507 strncat(Windowtitle, _openttd_revision, sizeof(Windowtitle)-(strlen(Windowtitle) + 1)); |
519 snprintf(Windowtitle, lengthof(Windowtitle), "OpenTTD %s", |
|
520 _openttd_revision); |
508 |
521 |
509 _wnd.main_wnd = CreateWindow("TTD", Windowtitle, style, x, y, w, h, 0, 0, _inst, 0); |
522 _wnd.main_wnd = CreateWindow("TTD", Windowtitle, style, x, y, w, h, 0, 0, _inst, 0); |
510 if (_wnd.main_wnd == NULL) |
523 if (_wnd.main_wnd == NULL) |
511 error("CreateWindow failed"); |
524 error("CreateWindow failed"); |
512 } |
525 } |
538 memset(bi, 0, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256); |
551 memset(bi, 0, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256); |
539 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
552 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
540 |
553 |
541 if (_wnd.double_size) { |
554 if (_wnd.double_size) { |
542 w = (w + 3) & ~0x3; |
555 w = (w + 3) & ~0x3; |
543 _wnd.alloced_bits = _wnd.buffer_bits = (byte*)malloc(w * h); |
556 _wnd.alloced_bits = _wnd.buffer_bits = malloc(w * h); |
544 w *= 2; |
557 w *= 2; |
545 h *= 2; |
558 h *= 2; |
546 } |
559 } |
547 |
560 |
548 bi->bmiHeader.biWidth = _wnd.width = w; |
561 bi->bmiHeader.biWidth = _wnd.width = w; |
586 int i = 0, n = 0; |
599 int i = 0, n = 0; |
587 DEVMODE dm; |
600 DEVMODE dm; |
588 |
601 |
589 while (EnumDisplaySettings(NULL, i++, &dm)) { |
602 while (EnumDisplaySettings(NULL, i++, &dm)) { |
590 if (dm.dmBitsPerPel == 8 && |
603 if (dm.dmBitsPerPel == 8 && |
591 IS_INT_INSIDE(dm.dmPelsWidth, 640, MAX_SCREEN_WIDTH+1) && |
604 IS_INT_INSIDE(dm.dmPelsWidth, 640, MAX_SCREEN_WIDTH + 1) && |
592 IS_INT_INSIDE(dm.dmPelsHeight, 480, MAX_SCREEN_HEIGHT+1) && |
605 IS_INT_INSIDE(dm.dmPelsHeight, 480, MAX_SCREEN_HEIGHT + 1) && ( |
593 (n == 0 || _resolutions[n-1][0] != dm.dmPelsWidth || _resolutions[n-1][1] != dm.dmPelsHeight)) { |
606 n == 0 || |
|
607 _resolutions[n - 1][0] != dm.dmPelsWidth || |
|
608 _resolutions[n - 1][1] != dm.dmPelsHeight |
|
609 )) { |
594 _resolutions[n][0] = dm.dmPelsWidth; |
610 _resolutions[n][0] = dm.dmPelsWidth; |
595 _resolutions[n][1] = dm.dmPelsHeight; |
611 _resolutions[n][1] = dm.dmPelsHeight; |
596 if (++n == sizeof(_resolutions) / (sizeof(uint16)*2)) break; |
612 if (++n == lengthof(_resolutions)) break; |
597 } |
613 } |
598 } |
614 } |
599 |
615 |
600 if (n == 0) { |
616 if (n == 0) { |
601 memcpy(_resolutions, default_resolutions, sizeof(default_resolutions)); |
617 memcpy(_resolutions, default_resolutions, sizeof(default_resolutions)); |
602 n = 6; |
618 n = lengthof(default_resolutions); |
603 } |
619 } |
604 |
620 |
605 _num_resolutions = n; |
621 _num_resolutions = n; |
606 } |
622 } |
607 |
623 |
644 static void filter(int left, int top, int width, int height) |
658 static void filter(int left, int top, int width, int height) |
645 { |
659 { |
646 uint p = _screen.pitch; |
660 uint p = _screen.pitch; |
647 byte *s = (byte*)_wnd.buffer_bits + top * p + left; |
661 byte *s = (byte*)_wnd.buffer_bits + top * p + left; |
648 byte *d = (byte*)_wnd.bitmap_bits + top * p * 4 + left * 2; |
662 byte *d = (byte*)_wnd.bitmap_bits + top * p * 4 + left * 2; |
649 int i; |
663 |
650 |
664 for (; height > 0; height--) { |
651 while (height) { |
665 int i; |
652 for(i=0; i!=width; i++) { |
666 |
653 d[i*2] = d[i*2+1] = d[i*2+p*2] = d[i*2+1+p*2] = s[i]; |
667 for (i = 0; i != width; i++) { |
|
668 d[i * 2] = d[i * 2 + 1] = d[i * 2 + p * 2] = d[i * 2 + 1 + p * 2] = s[i]; |
654 } |
669 } |
655 s += p; |
670 s += p; |
656 d += p * 4; |
671 d += p * 4; |
657 height--; |
|
658 } |
672 } |
659 } |
673 } |
660 |
674 |
661 static void Win32GdiMakeDirty(int left, int top, int width, int height) |
675 static void Win32GdiMakeDirty(int left, int top, int width, int height) |
662 { |
676 { |
663 RECT r = {left, top, left+width, top+height}; |
677 RECT r = { left, top, left + width, top + height }; |
|
678 |
664 if (_wnd.double_size) { |
679 if (_wnd.double_size) { |
665 filter(left, top, width, height); |
680 filter(left, top, width, height); |
666 //filter(0, 0, 640, 480); |
681 r.left *= 2; |
667 r.left *= 2;r.top *= 2;r.right *= 2;r.bottom *= 2; |
682 r.top *= 2; |
|
683 r.right *= 2; |
|
684 r.bottom *= 2; |
668 } |
685 } |
669 InvalidateRect(_wnd.main_wnd, &r, FALSE); |
686 InvalidateRect(_wnd.main_wnd, &r, FALSE); |
670 } |
687 } |
671 |
688 |
672 static void CheckPaletteAnim(void) |
689 static void CheckPaletteAnim(void) |
697 #else |
714 #else |
698 if (_wnd.has_focus && GetAsyncKeyState(VK_TAB) < 0) { |
715 if (_wnd.has_focus && GetAsyncKeyState(VK_TAB) < 0) { |
699 #endif |
716 #endif |
700 /* Disable speeding up game with ALT+TAB (if syskey is pressed, the |
717 /* Disable speeding up game with ALT+TAB (if syskey is pressed, the |
701 * real key is in the upper 16 bits (see WM_SYSKEYDOWN in WndProcGdi()) */ |
718 * real key is in the upper 16 bits (see WM_SYSKEYDOWN in WndProcGdi()) */ |
702 if (((_pressed_key>>16) & WKC_TAB) && !_networking && _game_mode != GM_MENU) _fast_forward |= 2; |
719 if ((_pressed_key >> 16) & WKC_TAB && !_networking && |
|
720 _game_mode != GM_MENU) |
|
721 _fast_forward |= 2; |
703 } else if (_fast_forward & 2) |
722 } else if (_fast_forward & 2) |
704 _fast_forward = 0; |
723 _fast_forward = 0; |
705 |
724 |
706 cur_ticks = GetTickCount(); |
725 cur_ticks = GetTickCount(); |
707 if ((_fast_forward && !_pause) || cur_ticks > next_tick) |
726 if ((_fast_forward && !_pause) || cur_ticks > next_tick) |
841 return strcmp(buf, "playing") == 0 || strcmp(buf, "seeking") == 0; |
861 return strcmp(buf, "playing") == 0 || strcmp(buf, "seeking") == 0; |
842 } |
862 } |
843 |
863 |
844 static DWORD WINAPI MidiThread(LPVOID arg) |
864 static DWORD WINAPI MidiThread(LPVOID arg) |
845 { |
865 { |
846 char *s; |
|
847 int vol; |
|
848 |
|
849 _midi.wait_obj = CreateEvent(NULL, FALSE, FALSE, NULL); |
866 _midi.wait_obj = CreateEvent(NULL, FALSE, FALSE, NULL); |
850 |
867 |
851 do { |
868 do { |
852 if ((vol=_midi.new_vol) != -1) { |
869 char *s; |
|
870 int vol; |
|
871 |
|
872 vol = _midi.new_vol; |
|
873 if (vol != -1) { |
853 _midi.new_vol = -1; |
874 _midi.new_vol = -1; |
854 MidiIntSetVolume(vol); |
875 MidiIntSetVolume(vol); |
855 |
876 } |
856 } |
877 |
857 if ((s=_midi.start_song)[0]) { |
878 s = _midi.start_song; |
|
879 if (s[0] != '\0') { |
858 _midi.playing = MidiIntPlaySong(s); |
880 _midi.playing = MidiIntPlaySong(s); |
859 s[0] = 0; |
881 s[0] = '\0'; |
860 |
882 |
861 // Delay somewhat in case we don't manage to play. |
883 // Delay somewhat in case we don't manage to play. |
862 if (!_midi.playing) { |
884 if (!_midi.playing) { |
863 Sleep(5000); |
885 Sleep(5000); |
864 } |
886 } |
865 } |
887 } |
866 if (_midi.stop_song != false && _midi.playing) { |
888 |
|
889 if (_midi.stop_song && _midi.playing) { |
867 _midi.stop_song = false; |
890 _midi.stop_song = false; |
868 _midi.playing = false; |
891 _midi.playing = false; |
869 MidiIntStopSong(); |
892 MidiIntStopSong(); |
870 } |
893 } |
871 |
894 |
908 static HWAVEOUT _waveout; |
932 static HWAVEOUT _waveout; |
909 static WAVEHDR _wave_hdr[2]; |
933 static WAVEHDR _wave_hdr[2]; |
910 static int _bufsize; |
934 static int _bufsize; |
911 static void PrepareHeader(WAVEHDR *hdr) |
935 static void PrepareHeader(WAVEHDR *hdr) |
912 { |
936 { |
913 hdr->dwBufferLength = _bufsize*4; |
937 hdr->dwBufferLength = _bufsize * 4; |
914 hdr->dwFlags = 0; |
938 hdr->dwFlags = 0; |
915 hdr->lpData = malloc(_bufsize*4); |
939 hdr->lpData = malloc(_bufsize * 4); |
916 if (hdr->lpData == NULL || waveOutPrepareHeader(_waveout, hdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) |
940 if (hdr->lpData == NULL || |
|
941 waveOutPrepareHeader(_waveout, hdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) |
917 error("waveOutPrepareHeader failed"); |
942 error("waveOutPrepareHeader failed"); |
918 } |
943 } |
919 |
944 |
920 static void FillHeaders(void) |
945 static void FillHeaders(void) |
921 { |
946 { |
922 WAVEHDR *hdr; |
947 WAVEHDR *hdr; |
923 for(hdr=_wave_hdr; hdr != endof(_wave_hdr); hdr++) { |
948 |
|
949 for (hdr = _wave_hdr; hdr != endof(_wave_hdr); hdr++) { |
924 if (!(hdr->dwFlags & WHDR_INQUEUE)) { |
950 if (!(hdr->dwFlags & WHDR_INQUEUE)) { |
925 MxMixSamples(_mixer, hdr->lpData, hdr->dwBufferLength >> 2); |
951 MxMixSamples(_mixer, hdr->lpData, hdr->dwBufferLength / 4); |
926 if (waveOutWrite(_waveout, hdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) |
952 if (waveOutWrite(_waveout, hdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) |
927 error("waveOutWrite failed"); |
953 error("waveOutWrite failed"); |
928 } |
954 } |
929 } |
955 } |
930 } |
956 } |
931 |
957 |
932 static void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) |
958 static void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, |
933 { |
959 DWORD dwParam1, DWORD dwParam2) |
934 switch(uMsg) { |
960 { |
935 case WOM_DONE: |
961 switch (uMsg) { |
936 if (_waveout) |
962 case WOM_DONE: |
937 FillHeaders(); |
963 if (_waveout) FillHeaders(); |
938 break; |
964 break; |
|
965 |
|
966 default: |
|
967 break; |
939 } |
968 } |
940 } |
969 } |
941 |
970 |
942 static const char *Win32SoundStart(const char * const *parm) |
971 static const char *Win32SoundStart(const char * const *parm) |
943 { |
972 { |
961 } |
990 } |
962 |
991 |
963 static void Win32SoundStop(void) |
992 static void Win32SoundStop(void) |
964 { |
993 { |
965 HWAVEOUT waveout = _waveout; |
994 HWAVEOUT waveout = _waveout; |
|
995 |
966 _waveout = NULL; |
996 _waveout = NULL; |
967 waveOutReset(waveout); |
997 waveOutReset(waveout); |
968 waveOutUnprepareHeader(waveout, &_wave_hdr[0], sizeof(WAVEHDR)); |
998 waveOutUnprepareHeader(waveout, &_wave_hdr[0], sizeof(WAVEHDR)); |
969 waveOutUnprepareHeader(waveout, &_wave_hdr[1], sizeof(WAVEHDR)); |
999 waveOutUnprepareHeader(waveout, &_wave_hdr[1], sizeof(WAVEHDR)); |
970 waveOutClose(waveout); |
1000 waveOutClose(waveout); |
1034 uint32 crc, poly = 0xEDB88320L; |
1064 uint32 crc, poly = 0xEDB88320L; |
1035 int i, j; |
1065 int i, j; |
1036 |
1066 |
1037 _crc_table = table; |
1067 _crc_table = table; |
1038 |
1068 |
1039 for (i=0; i!=256; i++) { |
1069 for (i = 0; i != 256; i++) { |
1040 crc = i; |
1070 crc = i; |
1041 for (j=8; j!=0; j--) { |
1071 for (j = 8; j != 0; j--) { |
1042 if (crc & 1) |
1072 if (crc & 1) |
1043 crc = (crc >> 1) ^ poly; |
1073 crc = (crc >> 1) ^ poly; |
1044 else |
1074 else |
1045 crc>>=1; |
1075 crc >>= 1; |
1046 } |
1076 } |
1047 table[i] = crc; |
1077 table[i] = crc; |
1048 } |
1078 } |
1049 } |
1079 } |
1050 |
1080 |
1051 static uint32 CalcCRC(byte *data, uint size, uint32 crc) { |
1081 static uint32 CalcCRC(byte *data, uint size, uint32 crc) { |
1052 do { |
1082 for (; size > 0; size--) { |
1053 crc = ((crc>>8) & 0x00FFFFFF) ^ _crc_table[ (crc^(*data++)) & 0xFF ]; |
1083 crc = ((crc >> 8) & 0x00FFFFFF) ^ _crc_table[(crc ^ *data++) & 0xFF]; |
1054 } while (--size); |
1084 } |
1055 return crc; |
1085 return crc; |
1056 } |
1086 } |
1057 |
1087 |
1058 static void GetFileInfo(DebugFileInfo *dfi, const char *filename) |
1088 static void GetFileInfo(DebugFileInfo *dfi, const char *filename) |
1059 { |
1089 { |
1065 DWORD numread; |
1095 DWORD numread; |
1066 uint32 filesize = 0; |
1096 uint32 filesize = 0; |
1067 FILETIME write_time; |
1097 FILETIME write_time; |
1068 uint32 crc = (uint32)-1; |
1098 uint32 crc = (uint32)-1; |
1069 |
1099 |
1070 file = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); |
1100 file = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, |
|
1101 OPEN_EXISTING, 0, 0); |
1071 if (file != INVALID_HANDLE_VALUE) { |
1102 if (file != INVALID_HANDLE_VALUE) { |
1072 while(true) { |
1103 while(true) { |
1073 if (ReadFile(file, buffer, sizeof(buffer), &numread, NULL) == 0 || numread==0) |
1104 if (ReadFile(file, buffer, sizeof(buffer), &numread, NULL) == 0 || |
|
1105 numread == 0) |
1074 break; |
1106 break; |
1075 filesize += numread; |
1107 filesize += numread; |
1076 crc = CalcCRC(buffer, numread, crc); |
1108 crc = CalcCRC(buffer, numread, crc); |
1077 } |
1109 } |
1078 dfi->size = filesize; |
1110 dfi->size = filesize; |
1089 |
1121 |
1090 static char *PrintModuleInfo(char *output, HMODULE mod) |
1122 static char *PrintModuleInfo(char *output, HMODULE mod) |
1091 { |
1123 { |
1092 char buffer[MAX_PATH]; |
1124 char buffer[MAX_PATH]; |
1093 DebugFileInfo dfi; |
1125 DebugFileInfo dfi; |
|
1126 |
1094 GetModuleFileName(mod, buffer, MAX_PATH); |
1127 GetModuleFileName(mod, buffer, MAX_PATH); |
1095 GetFileInfo(&dfi, buffer); |
1128 GetFileInfo(&dfi, buffer); |
1096 output += sprintf(output, " %-20s handle: %.8X size: %d crc: %.8X date: %d-%.2d-%.2d %.2d:%.2d:%.2d\r\n", |
1129 output += sprintf(output, " %-20s handle: %.8X size: %d crc: %.8X date: %d-%.2d-%.2d %.2d:%.2d:%.2d\r\n", |
1097 buffer, |
1130 buffer, |
1098 mod, |
1131 mod, |
1121 proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()); |
1154 proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()); |
1122 if (proc) { |
1155 if (proc) { |
1123 res = EnumProcessModules(proc, modules, sizeof(modules), &needed); |
1156 res = EnumProcessModules(proc, modules, sizeof(modules), &needed); |
1124 CloseHandle(proc); |
1157 CloseHandle(proc); |
1125 if (res) { |
1158 if (res) { |
1126 count = min(needed/sizeof(HMODULE*), sizeof(modules)/sizeof(HMODULE*)); |
1159 count = |
1127 for(i=0; i!=count; i++) |
1160 min(needed / sizeof(HMODULE), lengthof(modules)); |
|
1161 for (i = 0; i != count; i++) |
1128 output = PrintModuleInfo(output, modules[i]); |
1162 output = PrintModuleInfo(output, modules[i]); |
1129 return output; |
1163 return output; |
1130 } |
1164 } |
1131 } |
1165 } |
1132 } |
1166 } |
1135 } |
1169 } |
1136 |
1170 |
1137 static const char _crash_desc[] = |
1171 static const char _crash_desc[] = |
1138 "A serious fault condition occured in the game. The game will shut down.\n" |
1172 "A serious fault condition occured in the game. The game will shut down.\n" |
1139 "Press \"Submit report\" to send crash information to the developers. " |
1173 "Press \"Submit report\" to send crash information to the developers. " |
1140 "This will greatly help debugging. The information contained in the report is " |
1174 "This will greatly help debugging. " |
1141 "displayed below.\n" |
1175 "The information contained in the report is displayed below.\n" |
1142 "Press \"Emergency save\" to attempt saving the game."; |
1176 "Press \"Emergency save\" to attempt saving the game."; |
1143 |
1177 |
1144 static const char _save_succeeded[] = |
1178 static const char _save_succeeded[] = |
1145 "Emergency save succeeded.\nBe aware that critical parts of the internal game state " |
1179 "Emergency save succeeded.\n" |
1146 "may have become corrupted. The saved game is not guaranteed to work."; |
1180 "Be aware that critical parts of the internal game state may have become " |
|
1181 "corrupted. The saved game is not guaranteed to work."; |
1147 |
1182 |
1148 bool EmergencySave(); |
1183 bool EmergencySave(); |
1149 |
1184 |
1150 |
1185 |
1151 typedef struct { |
1186 typedef struct { |
1253 SetDlgItemText(wnd, 15, _expand_texts[mode == 1]); |
1288 SetDlgItemText(wnd, 15, _expand_texts[mode == 1]); |
1254 |
1289 |
1255 if (mode >= 0) { |
1290 if (mode >= 0) { |
1256 GetWindowRect(GetDlgItem(wnd, 11), &r2); |
1291 GetWindowRect(GetDlgItem(wnd, 11), &r2); |
1257 offs = r2.bottom - r2.top + 10; |
1292 offs = r2.bottom - r2.top + 10; |
1258 if (!mode) offs=-offs; |
1293 if (!mode) offs = -offs; |
1259 SetWindowPos(wnd, HWND_TOPMOST, 0, 0, r.right - r.left, r.bottom - r.top + offs, SWP_NOMOVE | SWP_NOZORDER); |
1294 SetWindowPos(wnd, HWND_TOPMOST, 0, 0, |
|
1295 r.right - r.left, r.bottom - r.top + offs, SWP_NOMOVE | SWP_NOZORDER); |
1260 } else { |
1296 } else { |
1261 SetWindowPos(wnd, HWND_TOPMOST, |
1297 SetWindowPos(wnd, HWND_TOPMOST, |
1262 (GetSystemMetrics(SM_CXSCREEN) - (r.right - r.left)) >> 1, |
1298 (GetSystemMetrics(SM_CXSCREEN) - (r.right - r.left)) / 2, |
1263 (GetSystemMetrics(SM_CYSCREEN) - (r.bottom - r.top)) >> 1, |
1299 (GetSystemMetrics(SM_CYSCREEN) - (r.bottom - r.top)) / 2, |
1264 0, 0, SWP_NOSIZE); |
1300 0, 0, SWP_NOSIZE); |
1265 } |
1301 } |
1266 } |
1302 } |
1267 |
1303 |
1268 static bool DoEmergencySave(HWND wnd) |
1304 static bool DoEmergencySave(HWND wnd) |
1398 ); |
1435 ); |
1399 |
1436 |
1400 { |
1437 { |
1401 byte *b = (byte*)ep->ContextRecord->Eip; |
1438 byte *b = (byte*)ep->ContextRecord->Eip; |
1402 int i; |
1439 int i; |
1403 for(i=0; i!=24; i++) { |
1440 for (i = 0; i != 24; i++) { |
1404 if (IsBadReadPtr(b, 1)) { |
1441 if (IsBadReadPtr(b, 1)) { |
1405 output += sprintf(output, " ??"); // OCR: WAS: , 0); |
1442 output += sprintf(output, " ??"); // OCR: WAS: , 0); |
1406 } else { |
1443 } else { |
1407 output += sprintf(output, " %.2X", *b); |
1444 output += sprintf(output, " %.2X", *b); |
1408 } |
1445 } |
1415 } |
1452 } |
1416 |
1453 |
1417 { |
1454 { |
1418 int i,j; |
1455 int i,j; |
1419 uint32 *b = (uint32*)ep->ContextRecord->Esp; |
1456 uint32 *b = (uint32*)ep->ContextRecord->Esp; |
1420 for(j=0; j!=24; j++) { |
1457 for (j = 0; j != 24; j++) { |
1421 for(i=0; i!=8; i++) { |
1458 for (i = 0; i != 8; i++) { |
1422 if (IsBadReadPtr(b,sizeof(uint32))) { |
1459 if (IsBadReadPtr(b,sizeof(uint32))) { |
1423 output += sprintf(output, " ????????"); //OCR: WAS - , 0); |
1460 output += sprintf(output, " ????????"); //OCR: WAS - , 0); |
1424 } else { |
1461 } else { |
1425 output += sprintf(output, " %.8X", *b); |
1462 output += sprintf(output, " %.8X", *b); |
1426 } |
1463 } |
1436 { |
1473 { |
1437 OSVERSIONINFO os; |
1474 OSVERSIONINFO os; |
1438 os.dwOSVersionInfoSize = sizeof(os); |
1475 os.dwOSVersionInfoSize = sizeof(os); |
1439 GetVersionEx(&os); |
1476 GetVersionEx(&os); |
1440 output += sprintf(output, "\r\nSystem information:\r\n" |
1477 output += sprintf(output, "\r\nSystem information:\r\n" |
1441 " Windows version %d.%d %d %s\r\n", os.dwMajorVersion, os.dwMinorVersion, os.dwBuildNumber, os.szCSDVersion); |
1478 " Windows version %d.%d %d %s\r\n", |
|
1479 os.dwMajorVersion, os.dwMinorVersion, os.dwBuildNumber, os.szCSDVersion); |
1442 } |
1480 } |
1443 |
1481 |
1444 { |
1482 { |
1445 HANDLE file = CreateFile("crash.log", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); |
1483 HANDLE file = CreateFile("crash.log", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); |
1446 DWORD num_written; |
1484 DWORD num_written; |
1505 sprintf(paths, "%s\\%s", path, file); |
1543 sprintf(paths, "%s\\%s", path, file); |
1506 return FindFirstFile(paths, fd); |
1544 return FindFirstFile(paths, fd); |
1507 } |
1545 } |
1508 |
1546 |
1509 int CDECL compare_FiosItems (const void *a, const void *b) { |
1547 int CDECL compare_FiosItems (const void *a, const void *b) { |
1510 const FiosItem *da = (const FiosItem *) a; |
1548 const FiosItem *da = (const FiosItem *)a; |
1511 const FiosItem *db = (const FiosItem *) b; |
1549 const FiosItem *db = (const FiosItem *)b; |
1512 int r; |
1550 int r; |
1513 |
1551 |
1514 if (_savegame_sort_order < 2) // sort by date |
1552 if (_savegame_sort_order < 2) // sort by date |
1515 r = da->mtime < db->mtime ? -1 : 1; |
1553 r = da->mtime < db->mtime ? -1 : 1; |
1516 else |
1554 else |
1517 r = stricmp(da->title[0] ? da->title : da->name, db->title[0] ? db->title : db->name); |
1555 r = stricmp( |
|
1556 da->title[0] != '\0' ? da->title : da->name, |
|
1557 db->title[0] != '\0' ? db->title : db->name |
|
1558 ); |
1518 |
1559 |
1519 if (_savegame_sort_order & 1) r = -r; |
1560 if (_savegame_sort_order & 1) r = -r; |
1520 return r; |
1561 return r; |
1521 } |
1562 } |
1522 |
1563 |
1550 // Show subdirectories first |
1591 // Show subdirectories first |
1551 h = MyFindFirstFile(_fios_path, "*.*", &fd); |
1592 h = MyFindFirstFile(_fios_path, "*.*", &fd); |
1552 if (h != INVALID_HANDLE_VALUE) { |
1593 if (h != INVALID_HANDLE_VALUE) { |
1553 do { |
1594 do { |
1554 if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && |
1595 if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && |
1555 !(fd.cFileName[0] == '.' && (fd.cFileName[1] == 0 || (fd.cFileName[1] == '.' && fd.cFileName[2] == 0)))) { |
1596 strcmp(fd.cFileName, ".") != 0 && |
|
1597 strcmp(fd.cFileName, "..") != 0) { |
1556 fios = FiosAlloc(); |
1598 fios = FiosAlloc(); |
1557 fios->type = FIOS_TYPE_DIR; |
1599 fios->type = FIOS_TYPE_DIR; |
1558 strcpy(fios->name, fd.cFileName); |
1600 strcpy(fios->name, fd.cFileName); |
1559 sprintf(fios->title, "\\%s (Directory)", fd.cFileName); |
1601 sprintf(fios->title, "\\%s (Directory)", fd.cFileName); |
1560 } |
1602 } |
1583 fios->type = FIOS_TYPE_FILE; |
1625 fios->type = FIOS_TYPE_FILE; |
1584 fios->title[0] = 0; |
1626 fios->title[0] = 0; |
1585 ttd_strlcpy(fios->name, fd.cFileName, strlen(fd.cFileName)-3); |
1627 ttd_strlcpy(fios->name, fd.cFileName, strlen(fd.cFileName)-3); |
1586 } else if (mode == SLD_LOAD_GAME || mode == SLD_LOAD_SCENARIO) { |
1628 } else if (mode == SLD_LOAD_GAME || mode == SLD_LOAD_SCENARIO) { |
1587 int ext = 0; // start of savegame extensions in _old_extensions[] |
1629 int ext = 0; // start of savegame extensions in _old_extensions[] |
1588 if (t && ((ext++, !stricmp(t, ".SS1")) || (ext++, !stricmp(t, ".SV1")) || (ext++, !stricmp(t, ".SV2"))) ) { // TTDLX(Patch) |
1630 if (t != NULL && ( |
|
1631 (ext++, stricmp(t, ".SS1") == 0) || |
|
1632 (ext++, stricmp(t, ".SV1") == 0) || |
|
1633 (ext++, stricmp(t, ".SV2") == 0) |
|
1634 )) { // TTDLX(Patch) |
1589 fios = FiosAlloc(); |
1635 fios = FiosAlloc(); |
1590 fios->old_extension = ext-1; |
1636 fios->old_extension = ext-1; |
1591 fios->mtime = *(uint64*)&fd.ftLastWriteTime; |
1637 fios->mtime = *(uint64*)&fd.ftLastWriteTime; |
1592 sprintf(buf, "%s\\%s", _fios_path, fd.cFileName); |
1638 sprintf(buf, "%s\\%s", _fios_path, fd.cFileName); |
1593 fios->type = FIOS_TYPE_OLDFILE; |
1639 fios->type = FIOS_TYPE_OLDFILE; |
1637 } |
1683 } |
1638 |
1684 |
1639 _fios_path = _fios_scn_path; |
1685 _fios_path = _fios_scn_path; |
1640 |
1686 |
1641 // Parent directory, only if not of the type C:\. |
1687 // Parent directory, only if not of the type C:\. |
1642 if (_fios_path[3] != 0 && mode != SLD_NEW_GAME) { |
1688 if (_fios_path[3] != '\0' && mode != SLD_NEW_GAME) { |
1643 fios = FiosAlloc(); |
1689 fios = FiosAlloc(); |
1644 fios->type = FIOS_TYPE_PARENT; |
1690 fios->type = FIOS_TYPE_PARENT; |
1645 strcpy(fios->title, ".. (Parent directory)"); |
1691 strcpy(fios->title, ".. (Parent directory)"); |
1646 } |
1692 } |
1647 |
1693 |
1648 // Show subdirectories first |
1694 // Show subdirectories first |
1649 h = MyFindFirstFile(_fios_scn_path, "*.*", &fd); |
1695 h = MyFindFirstFile(_fios_scn_path, "*.*", &fd); |
1650 if (h != INVALID_HANDLE_VALUE && mode != SLD_NEW_GAME) { |
1696 if (h != INVALID_HANDLE_VALUE && mode != SLD_NEW_GAME) { |
1651 do { |
1697 do { |
1652 if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && |
1698 if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && |
1653 !(fd.cFileName[0] == '.' && (fd.cFileName[1] == 0 || (fd.cFileName[1] == '.' && fd.cFileName[2] == 0)))) { |
1699 strcmp(fd.cFileName, ".") != 0 && |
|
1700 strcmp(fd.cFileName, "..") != 0) { |
1654 fios = FiosAlloc(); |
1701 fios = FiosAlloc(); |
1655 fios->type = FIOS_TYPE_DIR; |
1702 fios->type = FIOS_TYPE_DIR; |
1656 strcpy(fios->name, fd.cFileName); |
1703 strcpy(fios->name, fd.cFileName); |
1657 sprintf(fios->title, "\\%s (Directory)", fd.cFileName); |
1704 sprintf(fios->title, "\\%s (Directory)", fd.cFileName); |
1658 } |
1705 } |
1671 h = MyFindFirstFile(_fios_scn_path, "*.*", &fd); |
1718 h = MyFindFirstFile(_fios_scn_path, "*.*", &fd); |
1672 if (h != INVALID_HANDLE_VALUE) { |
1719 if (h != INVALID_HANDLE_VALUE) { |
1673 do { |
1720 do { |
1674 if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { |
1721 if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { |
1675 char *t = strrchr(fd.cFileName, '.'); |
1722 char *t = strrchr(fd.cFileName, '.'); |
1676 if (t && !stricmp(t, ".SCN")) { // OpenTTD |
1723 |
|
1724 if (t != NULL && !stricmp(t, ".SCN")) { // OpenTTD |
1677 fios = FiosAlloc(); |
1725 fios = FiosAlloc(); |
1678 fios->mtime = *(uint64*)&fd.ftLastWriteTime; |
1726 fios->mtime = *(uint64*)&fd.ftLastWriteTime; |
1679 sprintf(buf, "%s\\%s", _fios_path, fd.cFileName); |
1727 sprintf(buf, "%s\\%s", _fios_path, fd.cFileName); |
1680 fios->type = FIOS_TYPE_SCENARIO; |
1728 fios->type = FIOS_TYPE_SCENARIO; |
1681 fios->title[0] = 0; |
1729 fios->title[0] = '\0'; |
1682 ttd_strlcpy(fios->name, fd.cFileName, strlen(fd.cFileName)-3); |
1730 ttd_strlcpy(fios->name, fd.cFileName, strlen(fd.cFileName)-3); |
1683 } else if (mode == SLD_LOAD_GAME || mode == SLD_LOAD_SCENARIO || mode == SLD_NEW_GAME) { |
1731 } else if (mode == SLD_LOAD_GAME || mode == SLD_LOAD_SCENARIO || |
|
1732 mode == SLD_NEW_GAME) { |
1684 int ext = 3; // start of scenario extensions in _old_extensions[] |
1733 int ext = 3; // start of scenario extensions in _old_extensions[] |
1685 if (t && ((ext++, !stricmp(t, ".SV0")) || (ext++, !stricmp(t, ".SS0"))) ) { // TTDLX(Patch) |
1734 |
|
1735 if (t != NULL && ( |
|
1736 (ext++, stricmp(t, ".SV0") == 0) || |
|
1737 (ext++, stricmp(t, ".SS0") == 0) |
|
1738 )) { // TTDLX(Patch) |
1686 fios = FiosAlloc(); |
1739 fios = FiosAlloc(); |
1687 fios->old_extension = ext-1; |
1740 fios->old_extension = ext-1; |
1688 fios->mtime = *(uint64*)&fd.ftLastWriteTime; |
1741 fios->mtime = *(uint64*)&fd.ftLastWriteTime; |
1689 sprintf(buf, "%s\\%s", _fios_path, fd.cFileName); |
1742 sprintf(buf, "%s\\%s", _fios_path, fd.cFileName); |
1690 fios->type = FIOS_TYPE_OLD_SCENARIO; |
1743 fios->type = FIOS_TYPE_OLD_SCENARIO; |
1700 qsort(_fios_items + sort_start, _fios_count - sort_start, sizeof(FiosItem), compare_FiosItems); |
1753 qsort(_fios_items + sort_start, _fios_count - sort_start, sizeof(FiosItem), compare_FiosItems); |
1701 |
1754 |
1702 // Drives |
1755 // Drives |
1703 if (mode != SLD_NEW_GAME) { |
1756 if (mode != SLD_NEW_GAME) { |
1704 char drives[256]; |
1757 char drives[256]; |
1705 char *s; |
1758 const char *s; |
|
1759 |
1706 GetLogicalDriveStrings(sizeof(drives), drives); |
1760 GetLogicalDriveStrings(sizeof(drives), drives); |
1707 s=drives; |
1761 for (s = drives; *s != '\0';) { |
1708 while (*s) { |
|
1709 fios = FiosAlloc(); |
1762 fios = FiosAlloc(); |
1710 fios->type = FIOS_TYPE_DRIVE; |
1763 fios->type = FIOS_TYPE_DRIVE; |
1711 fios->title[0] = s[0]; |
1764 sprintf(fios->title, "%c:", s[0]); |
1712 fios->title[1] = ':'; |
1765 while (*s++ != '\0') {} |
1713 fios->title[2] = 0; |
|
1714 while (*s++) {} |
|
1715 } |
1766 } |
1716 } |
1767 } |
1717 |
1768 |
1718 *num = _fios_count; |
1769 *num = _fios_count; |
1719 return _fios_items; |
1770 return _fios_items; |
1730 // Browse to |
1781 // Browse to |
1731 char *FiosBrowseTo(const FiosItem *item) |
1782 char *FiosBrowseTo(const FiosItem *item) |
1732 { |
1783 { |
1733 static char str_buffr[512]; |
1784 static char str_buffr[512]; |
1734 char *path = _fios_path; |
1785 char *path = _fios_path; |
1735 char *s; |
1786 |
1736 |
1787 switch (item->type) { |
1737 switch(item->type) { |
|
1738 case FIOS_TYPE_DRIVE: |
1788 case FIOS_TYPE_DRIVE: |
1739 sprintf(path, "%c:\\", item->title[0]); |
1789 sprintf(path, "%c:\\", item->title[0]); |
1740 break; |
1790 break; |
1741 |
1791 |
1742 case FIOS_TYPE_PARENT: |
1792 case FIOS_TYPE_PARENT: { |
|
1793 char *s; |
|
1794 |
1743 // Skip drive part |
1795 // Skip drive part |
1744 path += 3; |
1796 path += 3; |
1745 s = path; |
1797 s = path; |
1746 while (*path) { |
1798 for (; *path != '\0'; path++) { |
1747 if (*path== '\\') |
1799 if (*path== '\\') s = path; |
1748 s = path; |
1800 } |
1749 path++; |
1801 *s = '\0'; |
1750 } |
|
1751 *s = 0; |
|
1752 break; |
1802 break; |
|
1803 } |
1753 |
1804 |
1754 case FIOS_TYPE_DIR: |
1805 case FIOS_TYPE_DIR: |
1755 // Scan to end |
1806 // Scan to end |
1756 while (*++path); |
1807 while (*++path != '\0'); |
1757 // Add backslash? |
1808 // Add backslash? |
1758 if (path[-1] != '\\') *path++ = '\\'; |
1809 if (path[-1] != '\\') *path++ = '\\'; |
1759 |
1810 |
1760 strcpy(path, item->name); |
1811 strcpy(path, item->name); |
1761 break; |
1812 break; |
1763 case FIOS_TYPE_FILE: |
1814 case FIOS_TYPE_FILE: |
1764 FiosMakeSavegameName(str_buffr, item->name); |
1815 FiosMakeSavegameName(str_buffr, item->name); |
1765 return str_buffr; |
1816 return str_buffr; |
1766 |
1817 |
1767 case FIOS_TYPE_OLDFILE: |
1818 case FIOS_TYPE_OLDFILE: |
1768 sprintf(str_buffr, "%s\\%s.%s", _fios_path, item->name, _old_extensions[item->old_extension]); |
1819 sprintf(str_buffr, "%s\\%s.%s", |
|
1820 _fios_path, item->name, _old_extensions[item->old_extension]); |
1769 return str_buffr; |
1821 return str_buffr; |
1770 |
1822 |
1771 case FIOS_TYPE_SCENARIO: |
1823 case FIOS_TYPE_SCENARIO: |
1772 sprintf(str_buffr, "%s\\%s.scn", path, item->name); |
1824 sprintf(str_buffr, "%s\\%s.scn", path, item->name); |
1773 return str_buffr; |
1825 return str_buffr; |
|
1826 |
1774 case FIOS_TYPE_OLD_SCENARIO: |
1827 case FIOS_TYPE_OLD_SCENARIO: |
1775 sprintf(str_buffr, "%s\\%s.%s", path, item->name, _old_extensions[item->old_extension]); |
1828 sprintf(str_buffr, "%s\\%s.%s", |
|
1829 path, item->name, _old_extensions[item->old_extension]); |
1776 return str_buffr; |
1830 return str_buffr; |
1777 } |
1831 } |
1778 |
1832 |
1779 return NULL; |
1833 return NULL; |
1780 } |
1834 } |
1786 { |
1840 { |
1787 char root[4]; |
1841 char root[4]; |
1788 DWORD spc, bps, nfc, tnc; |
1842 DWORD spc, bps, nfc, tnc; |
1789 *path = _fios_path; |
1843 *path = _fios_path; |
1790 |
1844 |
1791 root[0] = _fios_path[0]; |
1845 sprintf(root, "%c:\\", _fios_path[0]); |
1792 root[1] = ':'; |
|
1793 root[2] = '\\'; |
|
1794 root[3] = 0; |
|
1795 if (GetDiskFreeSpace(root, &spc, &bps, &nfc, &tnc)) { |
1846 if (GetDiskFreeSpace(root, &spc, &bps, &nfc, &tnc)) { |
1796 uint32 tot = ((spc*bps)*(uint64)nfc) >> 20; |
1847 uint32 tot = ((spc * bps) * (uint64)nfc) >> 20; |
1797 SetDParam(0, tot); |
1848 SetDParam(0, tot); |
1798 return STR_4005_BYTES_FREE; |
1849 return STR_4005_BYTES_FREE; |
1799 } else { |
1850 } else { |
1800 return STR_4006_UNABLE_TO_READ_DRIVE; |
1851 return STR_4006_UNABLE_TO_READ_DRIVE; |
1801 } |
1852 } |
1802 } |
1853 } |
1803 |
1854 |
1804 void FiosMakeSavegameName(char *buf, const char *name) |
1855 void FiosMakeSavegameName(char *buf, const char *name) |
1805 { |
1856 { |
1806 if(_game_mode == GM_EDITOR) |
1857 if (_game_mode == GM_EDITOR) |
1807 sprintf(buf, "%s\\%s.scn", _fios_path, name); |
1858 sprintf(buf, "%s\\%s.scn", _fios_path, name); |
1808 else |
1859 else |
1809 sprintf(buf, "%s\\%s.sav", _fios_path, name); |
1860 sprintf(buf, "%s\\%s.sav", _fios_path, name); |
1810 } |
1861 } |
1811 |
1862 |
1926 // skip whitespace |
1977 // skip whitespace |
1927 while (*line == ' ' || *line == '\t') |
1978 while (*line == ' ' || *line == '\t') |
1928 line++; |
1979 line++; |
1929 |
1980 |
1930 // end? |
1981 // end? |
1931 if (*line == 0) |
1982 if (*line == '\0') |
1932 break; |
1983 break; |
1933 |
1984 |
1934 // special handling when quoted |
1985 // special handling when quoted |
1935 if (*line == '"') { |
1986 if (*line == '"') { |
1936 argv[n++] = ++line; |
1987 argv[n++] = ++line; |
1937 while (*line != '"') { |
1988 while (*line != '"') { |
1938 if (*line == 0) return n; |
1989 if (*line == '\0') return n; |
1939 line++; |
1990 line++; |
1940 } |
1991 } |
1941 } else { |
1992 } else { |
1942 argv[n++] = line; |
1993 argv[n++] = line; |
1943 while (*line != ' ' && *line != '\t') { |
1994 while (*line != ' ' && *line != '\t') { |
1944 if (*line == 0) return n; |
1995 if (*line == '\0') return n; |
1945 line++; |
1996 line++; |
1946 } |
1997 } |
1947 } |
1998 } |
1948 *line++ = 0; |
1999 *line++ = '\0'; |
1949 } while (n != max_argc); |
2000 } while (n != max_argc); |
1950 |
2001 |
1951 return n; |
2002 return n; |
1952 } |
2003 } |
1953 |
2004 |
1954 |
2005 |
1955 #if defined(_MSC_VER) |
2006 #if defined(_MSC_VER) |
1956 __int64 _declspec(naked) rdtsc() |
2007 static uint64 _declspec(naked) rdtsc(void) |
1957 { |
2008 { |
1958 _asm { |
2009 _asm { |
1959 rdtsc |
2010 rdtsc |
1960 ret |
2011 ret |
1961 } |
2012 } |
1988 *stdout = *fdopen(1, "w" ); |
2039 *stdout = *fdopen(1, "w" ); |
1989 *stdin = *fdopen(0, "r" ); |
2040 *stdin = *fdopen(0, "r" ); |
1990 *stderr = *fdopen(2, "w" ); |
2041 *stderr = *fdopen(2, "w" ); |
1991 #endif |
2042 #endif |
1992 |
2043 |
1993 setvbuf( stdin, NULL, _IONBF, 0 ); |
2044 setvbuf(stdin, NULL, _IONBF, 0); |
1994 setvbuf( stdout, NULL, _IONBF, 0 ); |
2045 setvbuf(stdout, NULL, _IONBF, 0); |
1995 setvbuf( stderr, NULL, _IONBF, 0 ); |
2046 setvbuf(stderr, NULL, _IONBF, 0); |
1996 } |
2047 } |
1997 |
2048 |
1998 void ShowInfo(const char *str) |
2049 void ShowInfo(const char *str) |
1999 { |
2050 { |
2000 if (_has_console) |
2051 if (_has_console) |
2029 |
2081 |
2030 // setup random seed to something quite random |
2082 // setup random seed to something quite random |
2031 #if defined(_MSC_VER) |
2083 #if defined(_MSC_VER) |
2032 { |
2084 { |
2033 uint64 seed = rdtsc(); |
2085 uint64 seed = rdtsc(); |
2034 _random_seeds[0][0] = ((uint32*)&seed)[0]; |
2086 _random_seeds[0][0] = seed & 0xffffffff; |
2035 _random_seeds[0][1] = ((uint32*)&seed)[1]; |
2087 _random_seeds[0][1] = seed >> 32; |
2036 } |
2088 } |
2037 #else |
2089 #else |
2038 _random_seeds[0][0] = GetTickCount(); |
2090 _random_seeds[0][0] = GetTickCount(); |
2039 _random_seeds[0][1] = _random_seeds[0][0] * 0x1234567; |
2091 _random_seeds[0][1] = _random_seeds[0][0] * 0x1234567; |
2040 #endif |
2092 #endif |
2068 _path.personal_dir = _path.game_data_dir = cfg = malloc(MAX_PATH); |
2120 _path.personal_dir = _path.game_data_dir = cfg = malloc(MAX_PATH); |
2069 GetCurrentDirectory(MAX_PATH - 1, cfg); |
2121 GetCurrentDirectory(MAX_PATH - 1, cfg); |
2070 |
2122 |
2071 |
2123 |
2072 s = strchr(cfg, 0); |
2124 s = strchr(cfg, 0); |
2073 if (s[-1] != '\\') { s[0] = '\\'; s[1] = 0; } |
2125 if (s[-1] != '\\') strcpy(s, "\\"); |
2074 |
2126 |
2075 _path.save_dir = str_fmt("%ssave", cfg); |
2127 _path.save_dir = str_fmt("%ssave", cfg); |
2076 _path.autosave_dir = str_fmt("%s\\autosave", _path.save_dir); |
2128 _path.autosave_dir = str_fmt("%s\\autosave", _path.save_dir); |
2077 _path.scenario_dir = str_fmt("%sscenario", cfg); |
2129 _path.scenario_dir = str_fmt("%sscenario", cfg); |
2078 _path.gm_dir = str_fmt("%sgm\\", cfg); |
2130 _path.gm_dir = str_fmt("%sgm\\", cfg); |