History

Merge remote-tracking branch 'upstream/master'

Sigrid Solveig Haflínudóttir committed 3 years ago

Commit dfe013b2 parents f6e05c9 0ee14b8168 files · +18209 −6088Browse files

Showing the changes to src (36 of 168 files). Show all

Unified · Split

36 files
  1. src/ft2_audio.c +11 −30
  2. src/ft2_audio.h +16 −6
  3. src/ft2_checkboxes.c +8 −2
  4. src/ft2_checkboxes.h +3 −0
  5. src/ft2_config.c +65 −25
  6. src/ft2_config.h +3 −1
  7. src/ft2_diskop.c +7 −2
  8. src/ft2_edit.c +9 −1
  9. src/ft2_events.c +18 −51
  10. src/ft2_events.h +0 −3
  11. src/ft2_header.h +4 −7
  12. src/ft2_hpc.c +163 −0
  13. src/ft2_hpc.h +24 −0
  14. src/ft2_inst_ed.c +2 −1
  15. src/ft2_keyboard.c +2 −2
  16. src/ft2_main.c +13 −35
  17. src/ft2_mouse.c +42 −6
  18. src/ft2_mouse.h +1 −1
  19. src/ft2_pushbuttons.c +1 −1
  20. src/ft2_replayer.c +22 −5
  21. src/ft2_sample_ed.c +31 −19
  22. src/ft2_sampling.c +1 −1
  23. src/ft2_sysreqs.c +2 −2
  24. src/ft2_textboxes.c +32 −29
  25. src/ft2_video.c +125 −93
  26. src/ft2_video.h +6 −7
  27. src/ft2_wav_renderer.c +37 −30
  28. src/ft2_wav_renderer.h +1 −2
  29. src/helpdata/FT2.HLP +11 −7
  30. src/helpdata/ft2_help_data.h +542 −532
  31. src/mixer/ft2_mix_macros.h +69 −0
  32. src/mixer/ft2_windowed_sinc.c +4 −7
  33. src/mixer/ft2_windowed_sinc.h +9 −8
  34. src/modloaders/ft2_load_digi.c +1 −1
  35. src/modloaders/ft2_load_mod.c +0 −3
  36. src/scopes/ft2_scopes.c +5 −42
src/ft2_audio.c+11−30
@@ -107,8 +107,6 @@ bool setNewAudioSettings(void) // only call this from the main input/video threa · 106 unmodified lines
107 107
108 resumeAudio();108 resumeAudio();
109 109
110 setWavRenderFrequency(audio.freq);
111 setWavRenderBitDepth((config.specialFlags & BITDEPTH_32) ? 32 : 16);
112 return true;110 return true;
113}111}
114 112
@@ -272,8 +270,7 @@ static void voiceUpdateVolumes(int32_t i, uint8_t status) · 157 unmodified lines
272 // if destination volume and current volume is the same (and we have no sample trigger), don't do ramp270 // if destination volume and current volume is the same (and we have no sample trigger), don't do ramp
273 if (fVolumeL == v->fVolumeL && fVolumeR == v->fVolumeR && !(status & IS_Trigger))271 if (fVolumeL == v->fVolumeL && fVolumeR == v->fVolumeR && !(status & IS_Trigger))
274 {272 {
275 // there is no volume change273 v->volumeRampLength = 0; // there is no volume change
276 v->volumeRampLength = 0;
277 }274 }
278 else275 else
279 {276 {
@@ -889,7 +886,7 @@ static void fillVisualsSyncBuffer(void) · 609 unmodified lines
889 pattSyncData.row = song.curReplayerRow;886 pattSyncData.row = song.curReplayerRow;
890 pattSyncData.pattNum = song.curReplayerPattNum;887 pattSyncData.pattNum = song.curReplayerPattNum;
891 pattSyncData.songPos = song.curReplayerSongPos;888 pattSyncData.songPos = song.curReplayerSongPos;
892 pattSyncData.BPM = song.BPM;889 pattSyncData.BPM = (uint8_t)song.BPM;
893 pattSyncData.speed = (uint8_t)song.speed;890 pattSyncData.speed = (uint8_t)song.speed;
894 pattSyncData.globalVolume = (uint8_t)song.globalVolume;891 pattSyncData.globalVolume = (uint8_t)song.globalVolume;
895 pattSyncData.timestamp = audio.tickTime64;892 pattSyncData.timestamp = audio.tickTime64;
@@ -985,41 +982,28 @@ static void SDLCALL audioCallback(void *userdata, Uint8 *stream, int len) · 89 unmodified lines
985 982
986static bool setupAudioBuffers(void)983static bool setupAudioBuffers(void)
987{984{
988 const uint32_t sampleSize = sizeof (float);985 audio.fMixBufferL = (float *)calloc(MAX_WAV_RENDER_SAMPLES_PER_TICK, sizeof (float));
989 986 audio.fMixBufferR = (float *)calloc(MAX_WAV_RENDER_SAMPLES_PER_TICK, sizeof (float));
990 audio.fMixBufferLUnaligned = (float *)MALLOC_PAD(MAX_WAV_RENDER_SAMPLES_PER_TICK * sampleSize, 256);
991 audio.fMixBufferRUnaligned = (float *)MALLOC_PAD(MAX_WAV_RENDER_SAMPLES_PER_TICK * sampleSize, 256);
992 987
993 if (audio.fMixBufferLUnaligned == NULL || audio.fMixBufferRUnaligned == NULL)988 if (audio.fMixBufferL == NULL || audio.fMixBufferR == NULL)
994 return false;989 return false;
995 990
996 // make aligned main pointers
997 audio.fMixBufferL = (float *)ALIGN_PTR(audio.fMixBufferLUnaligned, 256);
998 audio.fMixBufferR = (float *)ALIGN_PTR(audio.fMixBufferRUnaligned, 256);
999
1000 // clear buffers
1001 memset(audio.fMixBufferL, 0, MAX_WAV_RENDER_SAMPLES_PER_TICK * sampleSize);
1002 memset(audio.fMixBufferR, 0, MAX_WAV_RENDER_SAMPLES_PER_TICK * sampleSize);
1003
1004 return true;991 return true;
1005}992}
1006 993
1007static void freeAudioBuffers(void)994static void freeAudioBuffers(void)
1008{995{
1009 if (audio.fMixBufferLUnaligned != NULL)996 if (audio.fMixBufferL != NULL)
1010 {997 {
1011 free(audio.fMixBufferLUnaligned);998 free(audio.fMixBufferL);
1012 audio.fMixBufferLUnaligned = NULL;999 audio.fMixBufferL = NULL;
1013 }1000 }
1014 1001
1015 if (audio.fMixBufferRUnaligned != NULL)1002 if (audio.fMixBufferR != NULL)
1016 {1003 {
1017 free(audio.fMixBufferRUnaligned);1004 free(audio.fMixBufferR);
1018 audio.fMixBufferRUnaligned = NULL;1005 audio.fMixBufferR = NULL;
1019 }1006 }
1020
1021 audio.fMixBufferL = NULL;
1022 audio.fMixBufferR = NULL;
1023}1007}
1024 1008
1025void updateSendAudSamplesRoutine(bool lockMixer)1009void updateSendAudSamplesRoutine(bool lockMixer)
@@ -1214,9 +1198,6 @@ bool setupAudio(bool showErrorMsg) · 188 unmodified lines
1214 updateSendAudSamplesRoutine(false);1198 updateSendAudSamplesRoutine(false);
1215 audio.resetSyncTickTimeFlag = true;1199 audio.resetSyncTickTimeFlag = true;
1216 1200
1217 setWavRenderFrequency(audio.freq);
1218 setWavRenderBitDepth((config.specialFlags & BITDEPTH_32) ? 32 : 16);
1219
1220 return true;1201 return true;
1221}1202}
1222 1203
src/ft2_audio.h+16−6
@@ -40,7 +40,7 @@ typedef struct audio_t · 39 unmodified lines
40 uint32_t freq, audLatencyPerfValInt, audLatencyPerfValFrac, samplesPerTick, samplesPerTickFrac, musicTimeSpeedVal;40 uint32_t freq, audLatencyPerfValInt, audLatencyPerfValFrac, samplesPerTick, samplesPerTickFrac, musicTimeSpeedVal;
41 uint64_t tickTime64, tickTime64Frac;41 uint64_t tickTime64, tickTime64Frac;
42 float fRampQuickVolMul, fRampTickMul, fRampTickMulTab[(MAX_BPM-MIN_BPM)+1];42 float fRampQuickVolMul, fRampTickMul, fRampTickMulTab[(MAX_BPM-MIN_BPM)+1];
43 float *fMixBufferL, *fMixBufferR, *fMixBufferLUnaligned, *fMixBufferRUnaligned;43 float *fMixBufferL, *fMixBufferR;
44 double dHz2MixDeltaMul, dAudioLatencyMs;44 double dHz2MixDeltaMul, dAudioLatencyMs;
45 45
46 SDL_AudioDeviceID dev;46 SDL_AudioDeviceID dev;
@@ -57,7 +57,7 @@ typedef struct · 10 unmodified lines
57 uint32_t volumeRampLength;57 uint32_t volumeRampLength;
58 58
59 uintCPUWord_t positionFrac, delta, oldDelta, scopeDelta;59 uintCPUWord_t positionFrac, delta, oldDelta, scopeDelta;
60#60
61 // if (loopEnabled && hasLooped && samplingPos <= loopStart+SINC_LEFT_TAPS) readFixedTapsFromThisPointer();61 // if (loopEnabled && hasLooped && samplingPos <= loopStart+SINC_LEFT_TAPS) readFixedTapsFromThisPointer();
62 const int8_t *leftEdgeTaps8;62 const int8_t *leftEdgeTaps8;
63 const int16_t *leftEdgeTaps16;63 const int16_t *leftEdgeTaps16;
@@ -66,12 +66,22 @@ typedef struct · 2 unmodified lines
66 float fVolume, fVolumeL, fVolumeR, fVolumeLDelta, fVolumeRDelta, fVolumeLTarget, fVolumeRTarget;66 float fVolume, fVolumeL, fVolumeR, fVolumeLDelta, fVolumeRDelta, fVolumeLTarget, fVolumeRTarget;
67} voice_t;67} voice_t;
68 68
69typedef struct pattSyncData_t69#ifdef _MSC_VER
70#pragma pack(push)
71#pragma pack(1)
72#endif
73typedef struct pattSyncData_t // used for audio/video sync queue (pack to save RAM)
70{74{
71 uint8_t pattNum, globalVolume, songPos, tick, speed, row;75 uint8_t pattNum, globalVolume, songPos, tick, speed, row, BPM;
72 uint16_t BPM;
73 uint64_t timestamp;76 uint64_t timestamp;
74} pattSyncData_t;77}
78#ifdef __GNUC__
79__attribute__ ((packed))
80#endif
81pattSyncData_t;
82#ifdef _MSC_VER
83#pragma pack(pop)
84#endif
75 85
76typedef struct pattSync_t86typedef struct pattSync_t
77{87{
src/ft2_checkboxes.c+8−2
@@ -14,6 +14,7 @@ · 13 unmodified lines
14#include "ft2_mouse.h"14#include "ft2_mouse.h"
15#include "ft2_edit.h"15#include "ft2_edit.h"
16#include "ft2_bmp.h"16#include "ft2_bmp.h"
17#include "ft2_wav_renderer.h"
17#include "ft2_structs.h"18#include "ft2_structs.h"
18 19
19checkBox_t checkBoxes[NUM_CHECKBOXES] =20checkBox_t checkBoxes[NUM_CHECKBOXES] =
@@ -90,6 +91,7 @@ checkBox_t checkBoxes[NUM_CHECKBOXES] = · 70 unmodified lines
90 { 113, 79, 128, 12, cbConfigLineColors },91 { 113, 79, 128, 12, cbConfigLineColors },
91 { 113, 92, 126, 12, cbConfigChanNums },92 { 113, 92, 126, 12, cbConfigChanNums },
92 { 255, 14, 136, 12, cbConfigShowVolCol },93 { 255, 14, 136, 12, cbConfigShowVolCol },
94 { 237, 108, 13, 12, cbEnableCustomPointer },
93 { 255, 158, 111, 12, cbSoftwareMouse },95 { 255, 158, 111, 12, cbSoftwareMouse },
94 // ---------------------------------96 // ---------------------------------
95 { 212, 2, 150, 12, cbSampCutToBuff },97 { 212, 2, 150, 12, cbSampCutToBuff },
@@ -108,10 +110,14 @@ checkBox_t checkBoxes[NUM_CHECKBOXES] = · 12 unmodified lines
108 { 411, 119, 121, 12, cbMIDIRecTransp },110 { 411, 119, 121, 12, cbMIDIRecTransp },
109 { 411, 132, 109, 12, cbMIDIRecVelocity },111 { 411, 132, 109, 12, cbMIDIRecVelocity },
110 { 411, 145, 124, 12, cbMIDIRecAftert },112 { 411, 145, 124, 12, cbMIDIRecAftert },
111 { 113, 115, 74, 12, cbVsyncOff },113 { 113, 115, 75, 12, cbVsyncOff },
112 { 113, 128, 78, 12, cbFullScreen },114 { 113, 128, 78, 12, cbFullScreen },
113 { 113, 141, 75, 12, cbStretchImage },115 { 113, 141, 75, 12, cbStretchImage },
114 { 113, 154, 78, 12, cbPixelFilter }116 { 113, 154, 78, 12, cbPixelFilter },
117
118 // WAV RENDERER BPM MODE
119 //x, y, w, h, funcOnUp
120 { 3, 112, 71, 24, cbToggleWavRenderBPMMode }
115};121};
116 122
117void drawCheckBox(uint16_t checkBoxID)123void drawCheckBox(uint16_t checkBoxID)
src/ft2_checkboxes.h+3−0
@@ -65,6 +65,7 @@ enum // CHECKBOXES · 64 unmodified lines
65 CB_CONF_LINECOLORS,65 CB_CONF_LINECOLORS,
66 CB_CONF_CHANNUMS,66 CB_CONF_CHANNUMS,
67 CB_CONF_SHOW_VOLCOL,67 CB_CONF_SHOW_VOLCOL,
68 CB_CONF_ENABLE_CUSTOM_POINTER,
68 CB_CONF_SOFTWARE_MOUSE,69 CB_CONF_SOFTWARE_MOUSE,
69 70
70 // CONFIG MISCELLANEOUS71 // CONFIG MISCELLANEOUS
@@ -89,6 +90,8 @@ enum // CHECKBOXES · 18 unmodified lines
89 CB_CONF_STRETCH_IMAGE,90 CB_CONF_STRETCH_IMAGE,
90 CB_CONF_PIXEL_FILTER,91 CB_CONF_PIXEL_FILTER,
91 92
93 CB_WAV_BPM_MODE,
94
92 NUM_CHECKBOXES95 NUM_CHECKBOXES
93};96};
94 97
src/ft2_config.c+65−25
@@ -210,12 +210,40 @@ static void setDefaultConfigSettings(void) · 209 unmodified lines
210 loadConfigFromBuffer(true);210 loadConfigFromBuffer(true);
211}211}
212 212
213static void updateImageStretchAndPixelFilter(uint8_t oldWindowFlags, uint8_t oldSpecialFlags2)
214{
215 bool didFullscreenUpdate = false;
216
217 // handle pixel filter change
218 if ((oldWindowFlags & PIXEL_FILTER) != (config.windowFlags & PIXEL_FILTER))
219 {
220 recreateTexture();
221 if (video.fullscreen) // force an update if in fullscreen mode
222 {
223 leaveFullscreen();
224 enterFullscreen();
225 didFullscreenUpdate = true;
226 }
227 }
228
229 // handle image stretch change
230 if ((oldSpecialFlags2 & STRETCH_IMAGE) != (config.specialFlags2 & STRETCH_IMAGE))
231 {
232 if (video.fullscreen && !didFullscreenUpdate) // force an update if in fullscreen mode
233 {
234 leaveFullscreen();
235 enterFullscreen();
236 }
237 }
238}
239
213void resetConfig(void)240void resetConfig(void)
214{241{
215 if (okBox(2, "System request", "Are you sure you want to reset your FT2 configuration?") != 1)242 if (okBox(2, "System request", "Are you sure you want to reset your FT2 configuration?") != 1)
216 return;243 return;
217 244
218 const uint8_t oldWindowFlags = config.windowFlags;245 const uint8_t oldWindowFlags = config.windowFlags;
246 const uint8_t oldSpecialFlags2 = config.specialFlags2;
219 247
220 setDefaultConfigSettings();248 setDefaultConfigSettings();
221 setToDefaultAudioOutputDevice();249 setToDefaultAudioOutputDevice();
@@ -228,17 +256,7 @@ void resetConfig(void) · 6 unmodified lines
228 showBottomScreen();256 showBottomScreen();
229 257
230 setWindowSizeFromConfig(true);258 setWindowSizeFromConfig(true);
231 259 updateImageStretchAndPixelFilter(oldWindowFlags, oldSpecialFlags2);
232 // handle pixel filter change
233 if ((oldWindowFlags & PIXEL_FILTER) != (config.windowFlags & PIXEL_FILTER))
234 {
235 recreateTexture();
236 if (video.fullscreen)
237 {
238 leaveFullScreen();
239 enterFullscreen();
240 }
241 }
242 260
243 if (config.specialFlags2 & HARDWARE_MOUSE)261 if (config.specialFlags2 & HARDWARE_MOUSE)
244 SDL_ShowCursor(SDL_TRUE);262 SDL_ShowCursor(SDL_TRUE);
@@ -339,6 +357,7 @@ bool loadConfig(bool showErrorFlag) · 94 unmodified lines
339void loadConfig2(void) // called by "Load config" button357void loadConfig2(void) // called by "Load config" button
340{358{
341 const uint8_t oldWindowFlags = config.windowFlags;359 const uint8_t oldWindowFlags = config.windowFlags;
360 const uint8_t oldSpecialFlags2 = config.specialFlags2;
342 361
343 loadConfig(CONFIG_SHOW_ERRORS);362 loadConfig(CONFIG_SHOW_ERRORS);
344 363
@@ -346,16 +365,8 @@ void loadConfig2(void) // called by "Load config" button · 1 unmodified line
346 showTopScreen(false);365 showTopScreen(false);
347 showBottomScreen();366 showBottomScreen();
348 367
349 // handle pixel filter change368 setWindowSizeFromConfig(true);
350 if ((oldWindowFlags & PIXEL_FILTER) != (config.windowFlags & PIXEL_FILTER))369 updateImageStretchAndPixelFilter(oldWindowFlags, oldSpecialFlags2);
351 {
352 recreateTexture();
353 if (video.fullscreen)
354 {
355 leaveFullScreen();
356 enterFullscreen();
357 }
358 }
359 370
360 if (config.specialFlags2 & HARDWARE_MOUSE)371 if (config.specialFlags2 & HARDWARE_MOUSE)
361 SDL_ShowCursor(SDL_TRUE);372 SDL_ShowCursor(SDL_TRUE);
@@ -872,6 +883,7 @@ static void setConfigLayoutCheckButtonStates(void) · 510 unmodified lines
872 checkBoxes[CB_CONF_LINECOLORS].checked = config.ptnLineLight;883 checkBoxes[CB_CONF_LINECOLORS].checked = config.ptnLineLight;
873 checkBoxes[CB_CONF_CHANNUMS].checked = config.ptnChnNumbers;884 checkBoxes[CB_CONF_CHANNUMS].checked = config.ptnChnNumbers;
874 checkBoxes[CB_CONF_SHOW_VOLCOL].checked = config.ptnShowVolColumn;885 checkBoxes[CB_CONF_SHOW_VOLCOL].checked = config.ptnShowVolColumn;
886 checkBoxes[CB_CONF_ENABLE_CUSTOM_POINTER].checked = (config.specialFlags2 & USE_OS_MOUSE_POINTER) ? false : true;
875 checkBoxes[CB_CONF_SOFTWARE_MOUSE].checked = (config.specialFlags2 & HARDWARE_MOUSE) ? false : true;887 checkBoxes[CB_CONF_SOFTWARE_MOUSE].checked = (config.specialFlags2 & HARDWARE_MOUSE) ? false : true;
876 888
877 showCheckBox(CB_CONF_PATTSTRETCH);889 showCheckBox(CB_CONF_PATTSTRETCH);
@@ -882,6 +894,7 @@ static void setConfigLayoutCheckButtonStates(void) · 4 unmodified lines
882 showCheckBox(CB_CONF_LINECOLORS);894 showCheckBox(CB_CONF_LINECOLORS);
883 showCheckBox(CB_CONF_CHANNUMS);895 showCheckBox(CB_CONF_CHANNUMS);
884 showCheckBox(CB_CONF_SHOW_VOLCOL);896 showCheckBox(CB_CONF_SHOW_VOLCOL);
897 showCheckBox(CB_CONF_ENABLE_CUSTOM_POINTER);
885 showCheckBox(CB_CONF_SOFTWARE_MOUSE);898 showCheckBox(CB_CONF_SOFTWARE_MOUSE);
886}899}
887 900
@@ -1429,6 +1442,7 @@ void hideConfigScreen(void) · 541 unmodified lines
1429 hideCheckBox(CB_CONF_LINECOLORS);1442 hideCheckBox(CB_CONF_LINECOLORS);
1430 hideCheckBox(CB_CONF_CHANNUMS);1443 hideCheckBox(CB_CONF_CHANNUMS);
1431 hideCheckBox(CB_CONF_SHOW_VOLCOL);1444 hideCheckBox(CB_CONF_SHOW_VOLCOL);
1445 hideCheckBox(CB_CONF_ENABLE_CUSTOM_POINTER);
1432 hideCheckBox(CB_CONF_SOFTWARE_MOUSE);1446 hideCheckBox(CB_CONF_SOFTWARE_MOUSE);
1433 hidePushButton(PB_CONFIG_PAL_R_DOWN);1447 hidePushButton(PB_CONFIG_PAL_R_DOWN);
1434 hidePushButton(PB_CONFIG_PAL_R_UP);1448 hidePushButton(PB_CONFIG_PAL_R_UP);
@@ -1737,6 +1751,29 @@ void cbConfigShowVolCol(void) · 302 unmodified lines
1737 redrawPatternEditor();1751 redrawPatternEditor();
1738}1752}
1739 1753
1754void cbEnableCustomPointer(void)
1755{
1756 config.specialFlags2 ^= USE_OS_MOUSE_POINTER;
1757
1758 if (config.specialFlags2 & USE_OS_MOUSE_POINTER)
1759 {
1760 checkBoxes[CB_CONF_ENABLE_CUSTOM_POINTER].checked = false;
1761 drawCheckBox(CB_CONF_ENABLE_CUSTOM_POINTER);
1762 }
1763 else
1764 {
1765 checkBoxes[CB_CONF_ENABLE_CUSTOM_POINTER].checked = true;
1766 drawCheckBox(CB_CONF_ENABLE_CUSTOM_POINTER);
1767 }
1768
1769 if (config.specialFlags2 & HARDWARE_MOUSE)
1770 SDL_ShowCursor(SDL_TRUE);
1771 else
1772 SDL_ShowCursor(SDL_FALSE);
1773
1774 createMouseCursors();
1775}
1776
1740void cbSoftwareMouse(void)1777void cbSoftwareMouse(void)
1741{1778{
1742 config.specialFlags2 ^= HARDWARE_MOUSE;1779 config.specialFlags2 ^= HARDWARE_MOUSE;
@@ -1747,14 +1784,17 @@ void cbSoftwareMouse(void) · 4 unmodified lines
1747 {1784 {
1748 checkBoxes[CB_CONF_SOFTWARE_MOUSE].checked = false;1785 checkBoxes[CB_CONF_SOFTWARE_MOUSE].checked = false;
1749 drawCheckBox(CB_CONF_SOFTWARE_MOUSE);1786 drawCheckBox(CB_CONF_SOFTWARE_MOUSE);
1750 SDL_ShowCursor(SDL_TRUE);
1751 }1787 }
1752 else1788 else
1753 {1789 {
1754 checkBoxes[CB_CONF_SOFTWARE_MOUSE].checked = true;1790 checkBoxes[CB_CONF_SOFTWARE_MOUSE].checked = true;
1755 drawCheckBox(CB_CONF_SOFTWARE_MOUSE);1791 drawCheckBox(CB_CONF_SOFTWARE_MOUSE);
1756 SDL_ShowCursor(SDL_FALSE);
1757 }1792 }
1793
1794 if (config.specialFlags2 & HARDWARE_MOUSE)
1795 SDL_ShowCursor(SDL_TRUE);
1796 else
1797 SDL_ShowCursor(SDL_FALSE);
1758}1798}
1759 1799
1760void rbConfigMouseNice(void)1800void rbConfigMouseNice(void)
@@ -2081,7 +2121,7 @@ void cbPixelFilter(void) · 320 unmodified lines
2081 recreateTexture();2121 recreateTexture();
2082 if (video.fullscreen)2122 if (video.fullscreen)
2083 {2123 {
2084 leaveFullScreen();2124 leaveFullscreen();
2085 enterFullscreen();2125 enterFullscreen();
2086 }2126 }
2087}2127}
@@ -2092,7 +2132,7 @@ void cbStretchImage(void) · 4 unmodified lines
2092 2132
2093 if (video.fullscreen)2133 if (video.fullscreen)
2094 {2134 {
2095 leaveFullScreen();2135 leaveFullscreen();
2096 enterFullscreen();2136 enterFullscreen();
2097 }2137 }
2098}2138}
src/ft2_config.h+3−1
@@ -80,9 +80,10 @@ enum · 79 unmodified lines
80 LINED_SCOPES = 128,80 LINED_SCOPES = 128,
81 81
82 // specialFlags282 // specialFlags2
83 DITHERED_AUDIO = 1, /* DEPRECATED */83 DITHERED_AUDIO = 1, /* DEPRECATED (but don't use it for anything else!) */
84 HARDWARE_MOUSE = 2,84 HARDWARE_MOUSE = 2,
85 STRETCH_IMAGE = 4,85 STRETCH_IMAGE = 4,
86 USE_OS_MOUSE_POINTER = 8,
86 87
87 // windowFlags88 // windowFlags
88 WINSIZE_AUTO = 1,89 WINSIZE_AUTO = 1,
@@ -260,6 +261,7 @@ void cbConfigFramework(void); · 171 unmodified lines
260void cbConfigLineColors(void);261void cbConfigLineColors(void);
261void cbConfigChanNums(void);262void cbConfigChanNums(void);
262void cbConfigShowVolCol(void);263void cbConfigShowVolCol(void);
264void cbEnableCustomPointer(void);
263void cbSoftwareMouse(void);265void cbSoftwareMouse(void);
264void cbSampCutToBuff(void);266void cbSampCutToBuff(void);
265void cbPattCutToBuff(void);267void cbPattCutToBuff(void);
src/ft2_diskop.c+7−2
@@ -2251,13 +2251,18 @@ void showDiskOpScreen(void) · 2250 unmodified lines
2251 // first test if we can change the dir to the one stored in the config (if present)2251 // first test if we can change the dir to the one stored in the config (if present)
2252 if (FReq_ModCurPathU[0] == '\0' || UNICHAR_CHDIR(FReq_ModCurPathU) != 0)2252 if (FReq_ModCurPathU[0] == '\0' || UNICHAR_CHDIR(FReq_ModCurPathU) != 0)
2253 {2253 {
2254 // nope, couldn't do that, set Disk Op. path to user/home directory2254 // nope, couldn't do that, set Disk Op. path to the user's desktop directory
2255#ifdef _WIN322255#ifdef _WIN32
2256 SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, FReq_ModCurPathU);2256 SHGetFolderPathW(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0, FReq_ModCurPathU);
2257#else2257#else
2258 char *home = getenv("HOME");2258 char *home = getenv("HOME");
2259 if (home != NULL)2259 if (home != NULL)
2260 {
2261 UNICHAR_CHDIR(home);
2260 UNICHAR_STRCPY(FReq_ModCurPathU, home);2262 UNICHAR_STRCPY(FReq_ModCurPathU, home);
2263
2264 UNICHAR_STRCAT(FReq_ModCurPathU, "/Desktop");
2265 }
2261#endif2266#endif
2262 UNICHAR_CHDIR(FReq_ModCurPathU);2267 UNICHAR_CHDIR(FReq_ModCurPathU);
2263 }2268 }
src/ft2_edit.c+9−1
@@ -118,7 +118,15 @@ static bool testEditKeys(SDL_Scancode scancode, SDL_Keycode keycode) · 117 unmodified lines
118 }118 }
119 119
120 if (i == KEY2VOL_ENTRIES)120 if (i == KEY2VOL_ENTRIES)
121 i = -1; // invalid key for slot121 {
122 // volume column key not found, let's try a hack for '-' and '+' keys first
123 if (scancode == SDL_SCANCODE_MINUS)
124 i = 5;
125 else if (scancode == SDL_SCANCODE_EQUALS)
126 i = 6;
127 else
128 i = -1; // invalid key for slot
129 }
122 }130 }
123 else if (cursor.object == CURSOR_EFX0)131 else if (cursor.object == CURSOR_EFX0)
124 {132 {
src/ft2_events.c+18−51
@@ -38,7 +38,7 @@ · 37 unmodified lines
38 "Try to mention what you did before the crash happened.\n" \38 "Try to mention what you did before the crash happened.\n" \
39 "My email can be found at the bottom of www.16-bits.org."39 "My email can be found at the bottom of www.16-bits.org."
40 40
41static bool backupMadeAfterCrash;41static bool backupMadeAfterCrash, didDropFile;
42 42
43#ifdef _WIN3243#ifdef _WIN32
44#define SYSMSG_FILE_ARG (WM_USER+1)44#define SYSMSG_FILE_ARG (WM_USER+1)
@@ -48,52 +48,16 @@ static bool backupMadeAfterCrash; · 3 unmodified lines
48static HWND hWnd;48static HWND hWnd;
49static HANDLE oneInstHandle, hMapFile;49static HANDLE oneInstHandle, hMapFile;
50static LPCTSTR sharedMemBuf;50static LPCTSTR sharedMemBuf;
51
52// used for Windows usleep() implementation
53static NTSTATUS (__stdcall *NtDelayExecution)(BOOL Alertable, PLARGE_INTEGER DelayInterval);
54#endif51#endif
55 52
56static void handleInput(void);53static void handleSDLEvents(void);
57
58// usleep() implementation for Windows (Warning: This might not be future-safe!)
59#ifdef _WIN32
60void usleep(uint32_t usec)
61{
62 LARGE_INTEGER lpDueTime;
63
64 if (NtDelayExecution == NULL)
65 {
66 // NtDelayExecution() is not available (shouldn't happen), use regular sleep()
67 Sleep(usec / 1000);
68 }
69 else
70 {
71 // this prevents a 64-bit MUL (will not overflow with the ranges we use anyway)
72 lpDueTime.HighPart = UINT32_MAX;
73 lpDueTime.LowPart = (DWORD)(-10 * (int32_t)usec);
74
75 NtDelayExecution(false, &lpDueTime);
76 }
77}
78
79void setupWin32Usleep(void)
80{
81 NtDelayExecution = (NTSTATUS (__stdcall *)(BOOL, PLARGE_INTEGER))GetProcAddress(GetModuleHandle("ntdll.dll"), "NtDelayExecution");
82 timeBeginPeriod(0); // enter highest timer resolution
83}
84
85void freeWin32Usleep(void)
86{
87 timeEndPeriod(0); // exit highest timer resolution
88}
89#endif
90 54
91void readInput(void)55void readInput(void)
92{56{
93 readMouseXY();57 readMouseXY();
94 readKeyModifiers();58 readKeyModifiers();
95 setSyncedReplayerVars();59 setSyncedReplayerVars();
96 handleInput();60 handleSDLEvents();
97}61}
98 62
99void handleThreadEvents(void)63void handleThreadEvents(void)
@@ -402,21 +366,13 @@ void handleWaitVblQuirk(SDL_Event *event) · 302 unmodified lines
402 else if (event->window.event == SDL_WINDOWEVENT_SHOWN)366 else if (event->window.event == SDL_WINDOWEVENT_SHOWN)
403 video.windowHidden = false;367 video.windowHidden = false;
404 368
405 if (video.vsync60HzPresent)369 // reset vblank end time if we minimize window
406 {370 if (event->window.event == SDL_WINDOWEVENT_MINIMIZED || event->window.event == SDL_WINDOWEVENT_FOCUS_LOST)
407 /* If we minimize the window and vsync is present, vsync is temporarily turned off.371 hpc_ResetCounters(&video.vblankHpc);
408 ** recalc waitVBL() vars so that it can sleep properly in said mode.
409 */
410 if (event->window.event == SDL_WINDOWEVENT_MINIMIZED ||
411 event->window.event == SDL_WINDOWEVENT_FOCUS_LOST)
412 {
413 setupWaitVBL();
414 }
415 }
416 }372 }
417}373}
418 374
419static void handleInput(void)375static void handleSDLEvents(void)
420{376{
421 SDL_Event event;377 SDL_Event event;
422 378
@@ -492,6 +448,10 @@ static void handleInput(void) · 69 unmodified lines
492 editor.autoPlayOnDrop = false;448 editor.autoPlayOnDrop = false;
493 loadDroppedFile(event.drop.file, true);449 loadDroppedFile(event.drop.file, true);
494 SDL_free(event.drop.file);450 SDL_free(event.drop.file);
451
452 // kludge: allow focus-clickthrough after drag-n-drop
453 SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
454 didDropFile = true;
495 }455 }
496 else if (event.type == SDL_QUIT)456 else if (event.type == SDL_QUIT)
497 {457 {
@@ -529,6 +489,13 @@ static void handleInput(void) · 31 unmodified lines
529 else if (event.type == SDL_MOUSEBUTTONUP)489 else if (event.type == SDL_MOUSEBUTTONUP)
530 {490 {
531 mouseButtonUpHandler(event.button.button);491 mouseButtonUpHandler(event.button.button);
492
493 // kludge: we drag-n-dropped a file before this mouse click release, restore focus-clickthrough mode
494 if (didDropFile)
495 {
496 didDropFile = false;
497 SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "0");
498 }
532 }499 }
533 else if (event.type == SDL_MOUSEBUTTONDOWN)500 else if (event.type == SDL_MOUSEBUTTONDOWN)
534 {501 {
src/ft2_events.h+0−3
@@ -20,7 +20,4 @@ void handleWaitVblQuirk(SDL_Event *event); · 19 unmodified lines
20#ifdef _WIN3220#ifdef _WIN32
21bool handleSingleInstancing(int32_t argc, char **argv);21bool handleSingleInstancing(int32_t argc, char **argv);
22void closeSingleInstancing(void);22void closeSingleInstancing(void);
23void usleep(uint32_t usec);
24void setupWin32Usleep(void);
25void freeWin32Usleep(void);
26#endif23#endif
src/ft2_header.h+4−7
@@ -12,11 +12,11 @@ · 11 unmodified lines
12#endif12#endif
13#include "ft2_replayer.h"13#include "ft2_replayer.h"
14 14
15#define PROG_VER_STR "1.51"15#define PROG_VER_STR "1.63"
16 16
17// do NOT change these! It will only mess things up...17// do NOT change these! It will only mess things up...
18 18
19#define FT2_VBLANK_HZ 7019#define FT2_VBLANK_HZ 70.086302895323 /* nominal, 640x400 @ 70Hz */
20#define SCREEN_W 63220#define SCREEN_W 632
21#define SCREEN_H 40021#define SCREEN_H 400
22 22
@@ -37,8 +37,8 @@ · 14 unmodified lines
37** branchless in the inner channel mixer loop.37** branchless in the inner channel mixer loop.
38** Warning: Do not change this!38** Warning: Do not change this!
39*/39*/
40#define SMP_DAT_OFFSET 3240#define SMP_DAT_OFFSET ((SINC_LEFT_TAPS*2)+1)
41#define SAMPLE_PAD_LENGTH (SMP_DAT_OFFSET+32)41#define SAMPLE_PAD_LENGTH (SMP_DAT_OFFSET+(SINC_RIGHT_TAPS*2))
42 42
43#ifndef _WIN3243#ifndef _WIN32
44#define _stricmp strcasecmp44#define _stricmp strcasecmp
@@ -69,9 +69,6 @@ · 24 unmodified lines
69// fast 32-bit -> 16-bit clamp69// fast 32-bit -> 16-bit clamp
70#define CLAMP16(i) if ((int16_t)(i) != i) i = 0x7FFF ^ (i >> 31)70#define CLAMP16(i) if ((int16_t)(i) != i) i = 0x7FFF ^ (i >> 31)
71 71
72#define ALIGN_PTR(p, x) (((uintptr_t)(p) + ((x)-1)) & ~((x)-1))
73#define MALLOC_PAD(size, pad) (malloc((size) + (pad)))
74
75#define SWAP16(x) \72#define SWAP16(x) \
76( \73( \
77 (((uint16_t)((x) & 0x00FF)) << 8) | \74 (((uint16_t)((x) & 0x00FF)) << 8) | \
src/ft2_hpc.c+163−0
@@ -0,0 +1,163 @@
1/*
2** Hardware Performance Counter delay routines
3*/
4
5#ifdef _WIN32
6#define WIN32_MEAN_AND_LEAN
7#include <windows.h>
8#else
9#include <unistd.h>
10#endif
11#include <SDL2/SDL.h>
12#include <stdint.h>
13#include <stdbool.h>
14#include "ft2_hpc.h"
15
16#define FRAC_BITS 63
17#define FRAC_SCALE (1ULL << FRAC_BITS)
18#define FRAC_MASK (FRAC_SCALE-1)
19
20hpcFreq_t hpcFreq;
21
22#ifdef _WIN32 // Windows usleep() implementation
23
24#define STATUS_SUCCESS 0
25
26static bool canAdjustTimerResolution;
27
28static NTSTATUS (__stdcall *NtDelayExecution)(BOOL Alertable, PLARGE_INTEGER DelayInterval);
29static NTSTATUS (__stdcall *NtQueryTimerResolution)(PULONG MinimumResolution, PULONG MaximumResolution, PULONG ActualResolution);
30static NTSTATUS (__stdcall *NtSetTimerResolution)(ULONG DesiredResolution, BOOLEAN SetResolution, PULONG CurrentResolution);
31
32static void (*usleep)(int32_t usec);
33
34static void usleepGood(int32_t usec)
35{
36 LARGE_INTEGER delayInterval;
37
38 // NtDelayExecution() delays in 100ns-units, and a negative value means to delay from current time
39 usec *= -10;
40
41 delayInterval.HighPart = 0xFFFFFFFF; // negative 64-bit value, we only set the lower dword
42 delayInterval.LowPart = usec;
43 NtDelayExecution(false, &delayInterval);
44}
45
46static void usleepPoor(int32_t usec) // fallback if no NtDelayExecution()
47{
48 Sleep((usec + 500) / 1000);
49}
50
51static void windowsSetupUsleep(void)
52{
53 NtDelayExecution = (NTSTATUS (__stdcall *)(BOOL, PLARGE_INTEGER))GetProcAddress(GetModuleHandle("ntdll.dll"), "NtDelayExecution");
54 usleep = (NtDelayExecution != NULL) ? usleepGood : usleepPoor;
55
56 NtQueryTimerResolution = (NTSTATUS (__stdcall *)(PULONG, PULONG, PULONG))GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryTimerResolution");
57 NtSetTimerResolution = (NTSTATUS (__stdcall *)(ULONG, BOOLEAN, PULONG))GetProcAddress(GetModuleHandle("ntdll.dll"), "NtSetTimerResolution");
58 canAdjustTimerResolution = (NtQueryTimerResolution != NULL && NtSetTimerResolution != NULL);
59}
60#endif
61
62void hpc_Init(void)
63{
64#ifdef _WIN32
65 windowsSetupUsleep();
66#endif
67 hpcFreq.freq64 = SDL_GetPerformanceFrequency();
68
69 double dFreq = (double)hpcFreq.freq64;
70
71 hpcFreq.dFreqMulMs = 1000.0 / dFreq;
72 hpcFreq.dFreqMulMicro = (1000.0 * 1000.0) / dFreq;
73}
74
75// returns 64-bit fractional part of u64 divided by u32
76static uint64_t getFrac64FromU64DivU32(uint64_t dividend, uint32_t divisor)
77{
78 if (dividend == 0 || divisor == 0 || divisor >= dividend)
79 return 0;
80
81 dividend %= divisor;
82
83 if (dividend == 0)
84 return 0;
85
86 const uint32_t quotient = (uint32_t)((dividend << 32) / divisor);
87 const uint32_t remainder = (uint32_t)((dividend << 32) % divisor);
88
89 const uint32_t resultHi = quotient;
90 const uint32_t resultLo = (uint32_t)(((uint64_t)remainder << 32) / divisor);
91
92 return ((uint64_t)resultHi << 32) | resultLo;
93}
94
95void hpc_SetDurationInHz(hpc_t *hpc, uint32_t hz)
96{
97 // set 64:63fp value
98 hpc->durationInt = hpcFreq.freq64 / hz;
99 hpc->durationFrac = getFrac64FromU64DivU32(hpcFreq.freq64, hz) >> 1;
100
101 hpc->resetFrame = hz * 3600; // reset counters every hour
102}
103
104void hpc_ResetCounters(hpc_t *hpc)
105{
106 hpc->endTimeInt = SDL_GetPerformanceCounter() + hpc->durationInt;
107 hpc->endTimeFrac = hpc->durationFrac;
108}
109
110void hpc_Wait(hpc_t *hpc)
111{
112#ifdef _WIN32
113 /* Make sure resolution is set to 0.5ms (safest minimum) - this is confirmed to improve
114 ** NtDelayExecution() and Sleep(). This will only be changed when needed, not per frame.
115 */
116 ULONG curRes, minRes, maxRes, junk;
117 if (canAdjustTimerResolution && NtQueryTimerResolution(&minRes, &maxRes, &curRes) == STATUS_SUCCESS)
118 {
119 if (curRes != 5000 && maxRes <= 5000)
120 NtSetTimerResolution(5000, TRUE, &junk); // 0.5ms
121 }
122#endif
123
124 const uint64_t currTime64 = SDL_GetPerformanceCounter();
125 if (currTime64 < hpc->endTimeInt)
126 {
127 uint64_t timeLeft64 = hpc->endTimeInt - currTime64;
128
129 // convert to int32_t for fast SSE2 SIMD usage lateron
130 if (timeLeft64 > INT32_MAX)
131 timeLeft64 = INT32_MAX;
132
133 const int32_t timeLeft32 = (int32_t)timeLeft64;
134
135 int32_t microSecsLeft = (int32_t)((timeLeft32 * hpcFreq.dFreqMulMicro) + 0.5); // rounded
136 if (microSecsLeft > 0)
137 usleep(microSecsLeft);
138 }
139
140 // set next end time
141
142 hpc->endTimeInt += hpc->durationInt;
143
144 // handle fractional part
145 hpc->endTimeFrac += hpc->durationFrac;
146 if (hpc->endTimeFrac >= FRAC_SCALE)
147 {
148 hpc->endTimeFrac &= FRAC_MASK;
149 hpc->endTimeInt++;
150 }
151
152 /* The counter ("endTimeInt") can accumulate major errors after a couple of hours,
153 ** since each frame is not happening at perfect intervals.
154 ** To fix this, reset the counter's int & frac once every hour. We should only get
155 ** up to one frame of stutter while they are resetting, then it's back to normal.
156 */
157 hpc->frameCounter++;
158 if (hpc->frameCounter >= hpc->resetFrame)
159 {
160 hpc->frameCounter = 0;
161 hpc_ResetCounters(hpc);
162 }
163}
src/ft2_hpc.h+24−0
@@ -0,0 +1,24 @@
1#pragma once
2
3#include <stdint.h>
4#include <stdbool.h>
5
6typedef struct
7{
8 uint64_t freq64;
9 double dFreqMulMicro, dFreqMulMs;
10} hpcFreq_t;
11
12typedef struct
13{
14 uint64_t durationInt, durationFrac;
15 uint64_t endTimeInt, endTimeFrac;
16 uint64_t frameCounter, resetFrame;
17} hpc_t;
18
19extern hpcFreq_t hpcFreq;
20
21void hpc_Init(void);
22void hpc_SetDurationInHz(hpc_t *hpc, uint32_t dHz);
23void hpc_ResetCounters(hpc_t *hpc);
24void hpc_Wait(hpc_t *hpc);
src/ft2_inst_ed.c+2−1
@@ -175,9 +175,10 @@ static int32_t SDLCALL copyInstrThread(void *ptr) · 174 unmodified lines
175 pauseAudio();175 pauseAudio();
176 freeInstr(dstIns);176 freeInstr(dstIns);
177 177
178 bool error = true;178 bool error = false;
179 if (instr[srcIns] != NULL)179 if (instr[srcIns] != NULL)
180 {180 {
181 error = true;
181 if (allocateInstr(dstIns))182 if (allocateInstr(dstIns))
182 {183 {
183 int16_t i;184 int16_t i;
src/ft2_keyboard.c+2−2
@@ -703,7 +703,7 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 702 unmodified lines
703 {703 {
704 if (keyb.leftAltPressed)704 if (keyb.leftAltPressed)
705 {705 {
706 toggleFullScreen();706 toggleFullscreen();
707 707
708 // prevent fullscreen toggle from firing twice on certain SDL2 Linux ports708 // prevent fullscreen toggle from firing twice on certain SDL2 Linux ports
709#ifdef __unix__709#ifdef __unix__
@@ -896,7 +896,7 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 186 unmodified lines
896#ifdef __APPLE__896#ifdef __APPLE__
897 if (keyb.leftCommandPressed && keyb.leftCtrlPressed)897 if (keyb.leftCommandPressed && keyb.leftCtrlPressed)
898 {898 {
899 toggleFullScreen();899 toggleFullscreen();
900 return true;900 return true;
901 }901 }
902 else902 else
src/ft2_main.c+13−35
@@ -33,12 +33,12 @@ · 32 unmodified lines
33#include "ft2_events.h"33#include "ft2_events.h"
34#include "ft2_bmp.h"34#include "ft2_bmp.h"
35#include "ft2_structs.h"35#include "ft2_structs.h"
36#include "ft2_hpc.h"
36 37
37#ifdef HAS_MIDI38#ifdef HAS_MIDI
38static SDL_Thread *initMidiThread;39static SDL_Thread *initMidiThread;
39#endif40#endif
40 41
41static void setupPerfFreq(void);
42static void initializeVars(void);42static void initializeVars(void);
43static void cleanUpAndExit(void); // never call this inside the main loop43static void cleanUpAndExit(void); // never call this inside the main loop
44#ifdef __APPLE__44#ifdef __APPLE__
@@ -60,7 +60,7 @@ int main(int argc, char *argv[]) · 15 unmodified lines
60 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);60 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
61#endif61#endif
62 62
63#if SDL_PATCHLEVEL < 563#if SDL_MAJOR_VERSION == 2 && SDL_MINOR_VERSION == 0 && SDL_PATCHLEVEL < 5
64#pragma message("WARNING: The SDL2 dev lib is older than ver 2.0.5. You'll get fullscreen mode issues and no audio input sampling.")64#pragma message("WARNING: The SDL2 dev lib is older than ver 2.0.5. You'll get fullscreen mode issues and no audio input sampling.")
65#pragma message("At least version 2.0.7 is recommended.")65#pragma message("At least version 2.0.7 is recommended.")
66#endif66#endif
@@ -93,12 +93,13 @@ int main(int argc, char *argv[]) · 26 unmodified lines
93 }93 }
94#endif94#endif
95 95
96#if SDL_PATCHLEVEL >= 4 // SDL 2.0.4 or later96#ifdef _WIN32
97 SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1"); // windows only - prevent ALT+F4 from exiting (FT2 uses ALT+F4)97
98 // ALT+F4 is used in FT2, but is "close program" in Windows...
99#if SDL_MINOR_VERSION >= 24 || (SDL_MINOR_VERSION == 0 && SDL_PATCHLEVEL >= 4)
100 SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1");
98#endif101#endif
99 102
100#ifdef _WIN32
101
102#ifndef _MSC_VER103#ifndef _MSC_VER
103 SetProcessDPIAware();104 SetProcessDPIAware();
104#endif105#endif
@@ -117,7 +118,6 @@ int main(int argc, char *argv[]) · 12 unmodified lines
117 return 0;118 return 0;
118 }119 }
119 120
120 setupWin32Usleep();
121 disableWasapi(); // disable problematic WASAPI SDL2 audio driver on Windows (causes clicks/pops sometimes...)121 disableWasapi(); // disable problematic WASAPI SDL2 audio driver on Windows (causes clicks/pops sometimes...)
122 // 13.03.2020: This is still needed with SDL 2.0.12...122 // 13.03.2020: This is still needed with SDL 2.0.12...
123#endif123#endif
@@ -127,7 +127,7 @@ int main(int argc, char *argv[]) · 3 unmodified lines
127 ** reinitialized in Windows and what not.127 ** reinitialized in Windows and what not.
128 ** Ref.: https://bugzilla.libsdl.org/show_bug.cgi?id=4391128 ** Ref.: https://bugzilla.libsdl.org/show_bug.cgi?id=4391
129 */129 */
130#if defined _WIN32 && SDL_PATCHLEVEL == 9130#if defined _WIN32 && SDL_MAJOR_VERSION == 2 && SDL_MINOR_VERSION == 0 && SDL_PATCHLEVEL == 9
131 if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) != 0)131 if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) != 0)
132#else132#else
133 if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO) != 0)133 if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO) != 0)
@@ -144,6 +144,9 @@ int main(int argc, char *argv[]) · 10 unmodified lines
144 */144 */
145 SDL_StopTextInput();145 SDL_StopTextInput();
146 146
147 hpc_Init();
148 hpc_SetDurationInHz(&video.vblankHpc, VBLANK_HZ);
149
147#ifdef __APPLE__150#ifdef __APPLE__
148 osxSetDirToProgramDirFromArgs(argv);151 osxSetDirToProgramDirFromArgs(argv);
149#endif152#endif
@@ -178,8 +181,6 @@ int main(int argc, char *argv[]) · 28 unmodified lines
178 audio.currOutputDevice = getAudioOutputDeviceFromConfig();181 audio.currOutputDevice = getAudioOutputDeviceFromConfig();
179 audio.currInputDevice = getAudioInputDeviceFromConfig();182 audio.currInputDevice = getAudioInputDeviceFromConfig();
180 183
181 setupPerfFreq();
182
183 if (!setupAudio(CONFIG_HIDE_ERRORS)) // can we open the audio device?184 if (!setupAudio(CONFIG_HIDE_ERRORS)) // can we open the audio device?
184 {185 {
185 // nope, try with the default audio device186 // nope, try with the default audio device
@@ -232,11 +233,11 @@ int main(int argc, char *argv[]) · 46 unmodified lines
232 SDL_DetachThread(initMidiThread); // don't wait for this thread, let it clean up when done233 SDL_DetachThread(initMidiThread); // don't wait for this thread, let it clean up when done
233#endif234#endif
234 235
235 setupWaitVBL(); // this is needed for potential okBox() calls in handleModuleLoadFromArg()236 hpc_ResetCounters(&video.vblankHpc); // quirk: this is needed for potential okBox() calls in handleModuleLoadFromArg()
236 handleModuleLoadFromArg(argc, argv);237 handleModuleLoadFromArg(argc, argv);
237 238
238 editor.mainLoopOngoing = true;239 editor.mainLoopOngoing = true;
239 setupWaitVBL(); // this must be the very last thing done before entering the main loop240 hpc_ResetCounters(&video.vblankHpc); // this must be the last thing we do before entering the main loop
240 241
241 while (editor.programRunning)242 while (editor.programRunning)
242 {243 {
@@ -377,7 +378,6 @@ static void cleanUpAndExit(void) // never call this inside the main loop! · 134 unmodified lines
377 }378 }
378 379
379#ifdef _WIN32380#ifdef _WIN32
380 freeWin32Usleep();
381 closeSingleInstancing();381 closeSingleInstancing();
382#endif382#endif
383 383
@@ -417,28 +417,6 @@ static void osxSetDirToProgramDirFromArgs(char **argv) · 33 unmodified lines
417}417}
418#endif418#endif
419 419
420static void setupPerfFreq(void)
421{
422 double dInt;
423
424 const uint64_t perfFreq64 = SDL_GetPerformanceFrequency();
425 assert(perfFreq64 != 0);
426
427 editor.dPerfFreq = (double)perfFreq64;
428 editor.dPerfFreqMulMicro = 1000000.0 / editor.dPerfFreq;
429 editor.dPerfFreqMulMs = 1.0 / (editor.dPerfFreq / 1000.0);
430
431 // calculate vblank time for performance counters and split into int/frac
432 double dFrac = modf(editor.dPerfFreq / VBLANK_HZ, &dInt);
433
434 // integer part
435 video.vblankTimeLen = (int32_t)dInt;
436
437 // fractional part scaled to 0..2^32-1
438 dFrac *= UINT32_MAX+1.0;
439 video.vblankTimeLenFrac = (uint32_t)dFrac;
440}
441
442#ifdef _WIN32420#ifdef _WIN32
443static void disableWasapi(void)421static void disableWasapi(void)
444{422{
src/ft2_mouse.c+42−6
@@ -32,6 +32,12 @@ static SDL_Cursor *cursors[NUM_CURSORS]; · 31 unmodified lines
32 32
33static bool setSystemCursor(SDL_Cursor *cur)33static bool setSystemCursor(SDL_Cursor *cur)
34{34{
35 if (config.specialFlags2 & USE_OS_MOUSE_POINTER)
36 {
37 SDL_SetCursor(SDL_GetDefaultCursor());
38 return true;
39 }
40
35 if (cur == NULL)41 if (cur == NULL)
36 {42 {
37 SDL_SetCursor(SDL_GetDefaultCursor());43 SDL_SetCursor(SDL_GetDefaultCursor());
@@ -77,8 +83,18 @@ bool createMouseCursors(void) // creates scaled SDL surfaces for current mouse p · 39 unmodified lines
77 if (surface == NULL)83 if (surface == NULL)
78 {84 {
79 freeMouseCursors();85 freeMouseCursors();
80 config.specialFlags2 &= ~HARDWARE_MOUSE; // enable software mouse86
81 SDL_ShowCursor(SDL_FALSE);87 if (config.specialFlags2 & USE_OS_MOUSE_POINTER)
88 {
89 SDL_ShowCursor(SDL_TRUE);
90 }
91 else
92 {
93 // enable software mouse
94 config.specialFlags2 &= ~HARDWARE_MOUSE;
95 SDL_ShowCursor(SDL_FALSE);
96 }
97
82 return false;98 return false;
83 }99 }
84 100
@@ -148,8 +164,18 @@ bool createMouseCursors(void) // creates scaled SDL surfaces for current mouse p · 63 unmodified lines
148 {164 {
149 SDL_FreeSurface(surface);165 SDL_FreeSurface(surface);
150 freeMouseCursors();166 freeMouseCursors();
151 config.specialFlags2 &= ~HARDWARE_MOUSE; // enable software mouse167
152 SDL_ShowCursor(SDL_FALSE);168 if (config.specialFlags2 & USE_OS_MOUSE_POINTER)
169 {
170 SDL_ShowCursor(SDL_TRUE);
171 }
172 else
173 {
174 // enable software mouse
175 config.specialFlags2 &= ~HARDWARE_MOUSE;
176 SDL_ShowCursor(SDL_FALSE);
177 }
178
153 return false;179 return false;
154 }180 }
155 181
@@ -658,8 +684,8 @@ void mouseButtonDownHandler(uint8_t mouseButton) · 502 unmodified lines
658 return;684 return;
659 }685 }
660 686
661 // mouse 0,0 = open exit dialog687 // mouse 0,0 = open exit dialog (also make sure the test always works in fullscreen mode)
662 if (mouse.x == 0 && mouse.y == 0)688 if ((mouse.x == 0 && mouse.y == 0) || (video.fullscreen && (video.renderX > 0 || video.renderY > 0) && (mouse.rawX == 0 && mouse.rawY == 0)))
663 {689 {
664 if (quitBox(false) == 1)690 if (quitBox(false) == 1)
665 editor.throwExit = true;691 editor.throwExit = true;
@@ -808,8 +834,12 @@ void readMouseXY(void) · 142 unmodified lines
808 {834 {
809 mouse.buttonState = SDL_GetGlobalMouseState(&mx, &my);835 mouse.buttonState = SDL_GetGlobalMouseState(&mx, &my);
810 836
837 mouse.absX = mx;
838 mouse.absY = my;
839
811 // convert desktop coords to window coords840 // convert desktop coords to window coords
812 SDL_GetWindowPosition(video.window, &windowX, &windowY);841 SDL_GetWindowPosition(video.window, &windowX, &windowY);
842
813 mx -= windowX;843 mx -= windowX;
814 my -= windowY;844 my -= windowY;
815 }845 }
@@ -817,8 +847,14 @@ void readMouseXY(void) · 1 unmodified line
817 {847 {
818 // special mode for KMSDRM (XXX: Confirm that this still works...)848 // special mode for KMSDRM (XXX: Confirm that this still works...)
819 mouse.buttonState = SDL_GetMouseState(&mx, &my);849 mouse.buttonState = SDL_GetMouseState(&mx, &my);
850
851 mouse.absX = mx;
852 mouse.absY = my;
820 }853 }
821 854
855 mouse.rawX = mx;
856 mouse.rawY = my;
857
822 if (video.fullscreen)858 if (video.fullscreen)
823 {859 {
824 // centered fullscreen mode (not stretched) needs further coord translation860 // centered fullscreen mode (not stretched) needs further coord translation
src/ft2_mouse.h+1−1
@@ -20,7 +20,7 @@ typedef struct mouse_t · 19 unmodified lines
20 bool firstTimePressingButton, mouseOverTextBox;20 bool firstTimePressingButton, mouseOverTextBox;
21 int8_t buttonCounter, mode;21 int8_t buttonCounter, mode;
22 int16_t lastUsedObjectID, lastUsedObjectType, lastEditBox;22 int16_t lastUsedObjectID, lastUsedObjectType, lastEditBox;
23 int32_t x, y, lastX, lastY, xBias, yBias, setPosX, setPosY;23 int32_t absX, absY, rawX, rawY, x, y, lastX, lastY, xBias, yBias, setPosX, setPosY;
24 int32_t lastScrollX, lastScrollXTmp, lastScrollY, saveMouseX, saveMouseY;24 int32_t lastScrollX, lastScrollXTmp, lastScrollY, saveMouseX, saveMouseY;
25 uint32_t buttonState;25 uint32_t buttonState;
26} mouse_t;26} mouse_t;
src/ft2_pushbuttons.c+1−1
@@ -382,7 +382,7 @@ pushButton_t pushButtons[NUM_PUSHBUTTONS] = · 381 unmodified lines
382 382
383 // ------ WAV RENDERER PUSHBUTTONS ------383 // ------ WAV RENDERER PUSHBUTTONS ------
384 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp384 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
385 { 3, 111, 73, 43, 0, 0, "Export", NULL, NULL, pbWavRender },385 { 3, 138, 73, 16, 0, 0, "Export", NULL, NULL, pbWavRender },
386 { 3, 155, 73, 16, 0, 0, "Exit", NULL, NULL, pbWavExit },386 { 3, 155, 73, 16, 0, 0, "Exit", NULL, NULL, pbWavExit },
387 { 253, 114, 18, 13, 1, 6, ARROW_UP_STRING, NULL, pbWavFreqUp, NULL },387 { 253, 114, 18, 13, 1, 6, ARROW_UP_STRING, NULL, pbWavFreqUp, NULL },
388 { 270, 114, 18, 13, 1, 6, ARROW_DOWN_STRING, NULL, pbWavFreqDown, NULL },388 { 270, 114, 18, 13, 1, 6, ARROW_DOWN_STRING, NULL, pbWavFreqDown, NULL },
src/ft2_replayer.c+22−5
@@ -311,7 +311,7 @@ void setFrequencyTable(bool linearPeriodsFlag) · 310 unmodified lines
311 if (ui.configScreenShown && editor.currConfigScreen == CONFIG_SCREEN_IO_DEVICES)311 if (ui.configScreenShown && editor.currConfigScreen == CONFIG_SCREEN_IO_DEVICES)
312 {312 {
313 // update "frequency table" radiobutton, if it's shown313 // update "frequency table" radiobutton, if it's shown
314 setConfigIORadioButtonStates(); 314 setConfigIORadioButtonStates();
315 315
316 // update mid-C freq. in instr. editor (it can slightly differ between Amiga/linear)316 // update mid-C freq. in instr. editor (it can slightly differ between Amiga/linear)
317 if (ui.instEditorShown)317 if (ui.instEditorShown)
@@ -404,7 +404,7 @@ void calcReplayerLogTab(void) // for linear period -> hz calculation · 86 unmodified lines
404 dExp2MulTab[i] = 1.0 / exp2(i); // 1/(2^i)404 dExp2MulTab[i] = 1.0 / exp2(i); // 1/(2^i)
405 405
406 for (int32_t i = 0; i < 4*12*16; i++)406 for (int32_t i = 0; i < 4*12*16; i++)
407 dLogTab[i] = 8363.0 * exp2(i / 768.0) * 256.0;407 dLogTab[i] = (8363.0 * 256.0) * exp2(i / (4.0 * 12.0 * 16.0));
408}408}
409 409
410void calcReplayerVars(int32_t audioFreq)410void calcReplayerVars(int32_t audioFreq)
@@ -839,7 +839,7 @@ static void setEnvelopePos(channel_t *ch, uint8_t param) · 428 unmodified lines
839 }839 }
840 840
841 // *** PANNING ENVELOPE ***841 // *** PANNING ENVELOPE ***
842 if (ins->volEnvFlags & ENV_SUSTAIN) // What..? An FT2 bug!?842 if (ins->volEnvFlags & ENV_SUSTAIN) // FT2 PLAYER BUG: Should've been ins->panEnvFlags
843 {843 {
844 ch->panEnvTick = param-1;844 ch->panEnvTick = param-1;
845 845
@@ -2215,6 +2215,15 @@ static void getNextPos(void) · 1369 unmodified lines
2215 song.pattNum = song.orders[song.songPos & 0xFF];2215 song.pattNum = song.orders[song.songPos & 0xFF];
2216 song.currNumRows = patternNumRows[song.pattNum & 0xFF];2216 song.currNumRows = patternNumRows[song.pattNum & 0xFF];
2217 }2217 }
2218
2219 /*
2220 ** Because of a bug in FT2, pattern loop commands will manipulate
2221 ** the row the next pattern will begin at (should be 0).
2222 ** However, this can overflow the number of rows (length) for that
2223 ** pattern and cause out-of-bounds reads. Set to row 0 in this case.
2224 */
2225 if (song.row >= song.currNumRows)
2226 song.row = 0;
2218 }2227 }
2219}2228}
2220 2229
@@ -2229,7 +2238,6 @@ void resumeMusic(void) // starts reading pattern data · 8 unmodified lines
2229 musicPaused = false;2238 musicPaused = false;
2230}2239}
2231 2240
2232
2233void tickReplayer(void) // periodically called from audio callback2241void tickReplayer(void) // periodically called from audio callback
2234{2242{
2235 int32_t i;2243 int32_t i;
@@ -3127,11 +3135,20 @@ void resetReplayerState(void) · 891 unmodified lines
3127 song.pBreakPos = 0;3135 song.pBreakPos = 0;
3128 song.pBreakFlag = false;3136 song.pBreakFlag = false;
3129 3137
3138 // reset pattern loops (E6x)
3139 channel_t *ch = channel;
3140 for (int32_t i = 0; i < song.numChannels; i++, ch++)
3141 {
3142 ch->jumpToRow = 0;
3143 ch->patLoopCounter = 0;
3144 }
3145
3146 // reset global volume (if song was playing)
3130 if (songPlaying)3147 if (songPlaying)
3131 {3148 {
3132 song.globalVolume = 64;3149 song.globalVolume = 64;
3133 3150
3134 channel_t *ch = channel;3151 ch = channel;
3135 for (int32_t i = 0; i < song.numChannels; i++, ch++)3152 for (int32_t i = 0; i < song.numChannels; i++, ch++)
3136 ch->status |= IS_Vol;3153 ch->status |= IS_Vol;
3137 }3154 }
src/ft2_sample_ed.c+31−19
@@ -153,26 +153,34 @@ bool cloneSample(sample_t *src, sample_t *dst) · 152 unmodified lines
153 smpPtr_t sp;153 smpPtr_t sp;
154 154
155 freeSmpData(dst);155 freeSmpData(dst);
156 memcpy(dst, src, sizeof (sample_t));
157 156
158 // zero out stuff that wasn't supposed to be cloned157 if (src == NULL)
159 dst->origDataPtr = dst->dataPtr = NULL;
160 dst->isFixed = false;
161 dst->fixedPos = 0;
162
163 // if source sample isn't empty, allocate room and copy it over (and fix it)
164 if (src->length > 0 && src->dataPtr != NULL)
165 {158 {
166 bool sample16Bit = !!(src->flags & SAMPLE_16BIT);159 memset(dst, 0, sizeof (sample_t));
167 if (!allocateSmpDataPtr(&sp, src->length, sample16Bit))160 }
161 else
162 {
163 memcpy(dst, src, sizeof (sample_t));
164
165 // zero out stuff that wasn't supposed to be cloned
166 dst->origDataPtr = dst->dataPtr = NULL;
167 dst->isFixed = false;
168 dst->fixedPos = 0;
169
170 // if source sample isn't empty, allocate room and copy it over (and fix it)
171 if (src->length > 0 && src->dataPtr != NULL)
168 {172 {
169 dst->length = 0;173 bool sample16Bit = !!(src->flags & SAMPLE_16BIT);
170 return false;174 if (!allocateSmpDataPtr(&sp, src->length, sample16Bit))
171 }175 {
176 dst->length = 0;
177 return false;
178 }
172 179
173 setSmpDataPtr(dst, &sp);180 setSmpDataPtr(dst, &sp);
174 memcpy(dst->dataPtr, src->dataPtr, src->length << sample16Bit);181 memcpy(dst->dataPtr, src->dataPtr, src->length << sample16Bit);
175 fixSample(dst);182 fixSample(dst);
183 }
176 }184 }
177 185
178 return true;186 return true;
@@ -695,14 +703,18 @@ static bool getCopyBuffer(int32_t size, bool sample16Bit) · 516 unmodified lines
695 703
696static int32_t SDLCALL copySampleThread(void *ptr)704static int32_t SDLCALL copySampleThread(void *ptr)
697{705{
698 sample_t *src = &instr[editor.srcInstr]->smp[editor.srcSmp];
699 sample_t *dst = &instr[editor.curInstr]->smp[editor.curSmp];
700
701 pauseAudio();706 pauseAudio();
702 707
708 sample_t *src;
709 if (instr[editor.srcInstr] == NULL)
710 src = NULL;
711 else
712 src = &instr[editor.srcInstr]->smp[editor.srcSmp];
713
703 if (instr[editor.curInstr] == NULL && !allocateInstr(editor.curInstr))714 if (instr[editor.curInstr] == NULL && !allocateInstr(editor.curInstr))
704 goto error;715 goto error;
705 716
717 sample_t *dst = &instr[editor.curInstr]->smp[editor.curSmp];
706 if (!cloneSample(src, dst))718 if (!cloneSample(src, dst))
707 goto error;719 goto error;
708 720
src/ft2_sampling.c+1−1
@@ -325,7 +325,7 @@ void handleSamplingUpdates(void) · 324 unmodified lines
325 325
326void startSampling(void)326void startSampling(void)
327{327{
328#if SDL_PATCHLEVEL < 5328#if SDL_MAJOR_VERSION == 2 && SDL_MINOR_VERSION == 0 && SDL_PATCHLEVEL < 5
329 okBox(0, "System message", "This program needs to be compiled with SDL 2.0.5 or later to support audio sampling.");329 okBox(0, "System message", "This program needs to be compiled with SDL 2.0.5 or later to support audio sampling.");
330 return;330 return;
331#else331#else
src/ft2_sysreqs.c+2−2
@@ -637,7 +637,7 @@ int16_t okBoxThreadSafe(int16_t type, const char *headline, const char *text) · 636 unmodified lines
637 637
638 // block multiple calls before they are completed (for safety)638 // block multiple calls before they are completed (for safety)
639 while (okBoxData.active)639 while (okBoxData.active)
640 SDL_Delay(1000 / VBLANK_HZ);640 SDL_Delay(1000 / VBLANK_HZ); // accuracy is not important here
641 641
642 okBoxData.type = type;642 okBoxData.type = type;
643 okBoxData.headline = headline;643 okBoxData.headline = headline;
@@ -645,7 +645,7 @@ int16_t okBoxThreadSafe(int16_t type, const char *headline, const char *text) · 1 unmodified line
645 okBoxData.active = true;645 okBoxData.active = true;
646 646
647 while (okBoxData.active)647 while (okBoxData.active)
648 SDL_Delay(1000 / VBLANK_HZ);648 SDL_Delay(1000 / VBLANK_HZ); // accuracy is not important here
649 649
650 return okBoxData.returnData;650 return okBoxData.returnData;
651}651}
src/ft2_textboxes.c+32−29
@@ -515,45 +515,48 @@ void drawTextBox(uint16_t textBoxID) · 514 unmodified lines
515 if (t->textPtr == NULL)515 if (t->textPtr == NULL)
516 return;516 return;
517 517
518 // draw text mark background518 // draw text mark background (if this is the textbox we last interacted with)
519 if (textIsMarked())519 if (mouse.lastEditBox == textBoxID)
520 {520 {
521 hideSprite(SPRITE_TEXT_CURSOR);521 if (textIsMarked())
522 {
523 hideSprite(SPRITE_TEXT_CURSOR);
522 524
523 int32_t start = getTextMarkStart();525 int32_t start = getTextMarkStart();
524 int32_t end = getTextMarkEnd();526 int32_t end = getTextMarkEnd();
525 527
526 assert(start < t->maxChars && end <= t->maxChars);528 assert(start < t->maxChars && end <= t->maxChars);
527 529
528 // find pixel start/length from markX1 and markX2530 // find pixel start/length from markX1 and markX2
529 531
530 int32_t x1 = 0;532 int32_t x1 = 0;
531 int32_t x2 = 0;533 int32_t x2 = 0;
532 534
533 for (int32_t i = 0; i < end; i++)535 for (int32_t i = 0; i < end; i++)
534 {536 {
535 const char ch = t->textPtr[i];537 const char ch = t->textPtr[i];
536 if (ch == '\0')538 if (ch == '\0')
537 break;539 break;
538 540
539 cw = charWidth(ch);541 cw = charWidth(ch);
540 if (i < start)542 if (i < start)
541 x1 += cw;543 x1 += cw;
542 544
543 x2 += cw;545 x2 += cw;
544 }546 }
545 547
546 // render text mark background548 // render text mark background
547 if (x1 != x2)549 if (x1 != x2)
548 {550 {
549 start = x1;551 start = x1;
550 const int32_t length = x2 - x1;552 const int32_t length = x2 - x1;
551 553
552 assert(start+length <= t->renderBufW);554 assert(start+length <= t->renderBufW);
553 555
554 uint8_t *ptr32 = &t->renderBuf[start];556 uint8_t *ptr32 = &t->renderBuf[start];
555 for (uint16_t y = 0; y < t->renderBufH; y++, ptr32 += t->renderBufW)557 for (uint16_t y = 0; y < t->renderBufH; y++, ptr32 += t->renderBufW)
556 memset(ptr32, PAL_TEXTMRK, length);558 memset(ptr32, PAL_TEXTMRK, length);
559 }
557 }560 }
558 }561 }
559 562
@@ -893,7 +896,7 @@ void handleTextEditControl(SDL_Keycode keycode) · 333 unmodified lines
893 {896 {
894 // ALT+ENTER = toggle fullscreen, even while text editing897 // ALT+ENTER = toggle fullscreen, even while text editing
895 if (keyb.leftAltPressed)898 if (keyb.leftAltPressed)
896 toggleFullScreen();899 toggleFullscreen();
897 else900 else
898 exitTextEditing();901 exitTextEditing();
899 }902 }
src/ft2_video.c+125−93
@@ -48,19 +48,19 @@ video_t video; // globalized · 47 unmodified lines
48 48
49static bool songIsModified;49static bool songIsModified;
50static char wndTitle[256];50static char wndTitle[256];
51static uint64_t timeNext64, timeNext64Frac;
52static sprite_t sprites[SPRITE_NUM];51static sprite_t sprites[SPRITE_NUM];
53 52
54// for FPS counter53// for FPS counter
54#define FPS_LINES 15
55#define FPS_SCAN_FRAMES 6055#define FPS_SCAN_FRAMES 60
56#define FPS_RENDER_W 28556#define FPS_RENDER_W 285
57#define FPS_RENDER_H (((FONT1_CHAR_H + 1) * 8) + 1)57#define FPS_RENDER_H (((FONT1_CHAR_H + 1) * FPS_LINES) + 1)
58#define FPS_RENDER_X 258#define FPS_RENDER_X 2
59#define FPS_RENDER_Y 259#define FPS_RENDER_Y 2
60 60
61static char fpsTextBuf[1024];61static char fpsTextBuf[1024];
62static uint64_t frameStartTime;62static uint64_t frameStartTime;
63static double dRunningFPS, dFrameTime, dAvgFPS;63static double dRunningFrameDuration, dAvgFPS;
64// ------------------64// ------------------
65 65
66static void drawReplayerData(void);66static void drawReplayerData(void);
@@ -69,8 +69,7 @@ void resetFPSCounter(void) · 2 unmodified lines
69{69{
70 editor.framesPassed = 0;70 editor.framesPassed = 0;
71 fpsTextBuf[0] = '\0';71 fpsTextBuf[0] = '\0';
72 dRunningFPS = VBLANK_HZ;72 dRunningFrameDuration = 1000.0 / VBLANK_HZ;
73 dFrameTime = 1000.0 / VBLANK_HZ;
74}73}
75 74
76void beginFPSCounter(void)75void beginFPSCounter(void)
@@ -81,13 +80,17 @@ void beginFPSCounter(void) · 4 unmodified lines
81 80
82static void drawFPSCounter(void)81static void drawFPSCounter(void)
83{82{
83 SDL_version SDLVer;
84
85 SDL_GetVersion(&SDLVer);
86
84 if (editor.framesPassed >= FPS_SCAN_FRAMES && (editor.framesPassed % FPS_SCAN_FRAMES) == 0)87 if (editor.framesPassed >= FPS_SCAN_FRAMES && (editor.framesPassed % FPS_SCAN_FRAMES) == 0)
85 {88 {
86 dAvgFPS = dRunningFPS * (1.0 / FPS_SCAN_FRAMES);89 dAvgFPS = 1000.0 / (dRunningFrameDuration / FPS_SCAN_FRAMES);
87 if (dAvgFPS < 0.0 || dAvgFPS > 99999999.9999)90 if (dAvgFPS < 0.0 || dAvgFPS > 99999999.9999)
88 dAvgFPS = 99999999.9999; // prevent number from overflowing text box91 dAvgFPS = 99999999.9999; // prevent number from overflowing text box
89 92
90 dRunningFPS = 0.0;93 dRunningFrameDuration = 0.0;
91 }94 }
92 95
93 clearRect(FPS_RENDER_X+2, FPS_RENDER_Y+2, FPS_RENDER_W, FPS_RENDER_H);96 clearRect(FPS_RENDER_X+2, FPS_RENDER_Y+2, FPS_RENDER_W, FPS_RENDER_H);
@@ -96,10 +99,12 @@ static void drawFPSCounter(void) · 2 unmodified lines
96 hLineDouble(FPS_RENDER_X+1, FPS_RENDER_Y, FPS_RENDER_W, PAL_FORGRND);99 hLineDouble(FPS_RENDER_X+1, FPS_RENDER_Y, FPS_RENDER_W, PAL_FORGRND);
97 hLineDouble(FPS_RENDER_X+1, FPS_RENDER_Y+FPS_RENDER_H+2, FPS_RENDER_W, PAL_FORGRND);100 hLineDouble(FPS_RENDER_X+1, FPS_RENDER_Y+FPS_RENDER_H+2, FPS_RENDER_W, PAL_FORGRND);
98 101
99 // test if enough data is collected yet102 // if enough frame data isn't collected yet, show a message
100 if (editor.framesPassed < FPS_SCAN_FRAMES)103 if (editor.framesPassed < FPS_SCAN_FRAMES)
101 {104 {
102 textOut(FPS_RENDER_X+53, FPS_RENDER_Y+39, PAL_FORGRND, "Collecting frame information...");105 const char *text = "Gathering frame information...";
106 const uint16_t textW = textWidth(text);
107 textOut(FPS_RENDER_X+((FPS_RENDER_W/2)-(textW/2)), FPS_RENDER_Y+((FPS_RENDER_H/2)-(FONT1_CHAR_H/2)), PAL_FORGRND, text);
103 return;108 return;
104 }109 }
105 110
@@ -111,20 +116,36 @@ static void drawFPSCounter(void) · 5 unmodified lines
111 if (dAudLatency < 0.0 || dAudLatency > 999999999.9999)116 if (dAudLatency < 0.0 || dAudLatency > 999999999.9999)
112 dAudLatency = 999999999.9999; // prevent number from overflowing text box117 dAudLatency = 999999999.9999; // prevent number from overflowing text box
113 118
114 sprintf(fpsTextBuf, "Frames per second: %.4f\n" \119 sprintf(fpsTextBuf,
120 "SDL version: %u.%u.%u\n" \
121 "Frames per second: %.3f\n" \
115 "Monitor refresh rate: %.1fHz (+/-)\n" \122 "Monitor refresh rate: %.1fHz (+/-)\n" \
116 "59..61Hz GPU VSync used: %s\n" \123 "59..61Hz GPU VSync used: %s\n" \
117 "Audio frequency: %.1fkHz (expected %.1fkHz)\n" \124 "Audio frequency: %.1fkHz (expected %.1fkHz)\n" \
118 "Audio buffer samples: %d (expected %d)\n" \125 "Audio buffer samples: %d (expected %d)\n" \
119 "Audio channels: %d (expected %d)\n" \126 "Audio channels: %d (expected %d)\n" \
120 "Audio latency: %.1fms (expected %.1fms)\n" \127 "Audio latency: %.1fms (expected %.1fms)\n" \
128 "Render size: %dx%d (offset %d,%d)\n" \
129 "Disp. size: %dx%d (window: %dx%d)\n" \
130 "Render scaling: x=%.2f, y=%.2f\n" \
131 "Mouse to render space muls: x=%.2f, y=%.2f\n" \
132 "Relative mouse coords: %d,%d\n" \
133 "Absolute mouse coords: %d,%d\n" \
121 "Press CTRL+SHIFT+F to close this box.\n",134 "Press CTRL+SHIFT+F to close this box.\n",
122 dAvgFPS, dRefreshRate,135 SDLVer.major, SDLVer.minor, SDLVer.patch,
136 dAvgFPS,
137 dRefreshRate,
123 video.vsync60HzPresent ? "yes" : "no",138 video.vsync60HzPresent ? "yes" : "no",
124 audio.haveFreq * (1.0 / 1000.0), audio.wantFreq * (1.0 / 1000.0),139 audio.haveFreq * (1.0 / 1000.0), audio.wantFreq * (1.0 / 1000.0),
125 audio.haveSamples, audio.wantSamples,140 audio.haveSamples, audio.wantSamples,
126 audio.haveChannels, audio.wantChannels,141 audio.haveChannels, audio.wantChannels,
127 dAudLatency, ((audio.wantSamples * 1000.0) / audio.wantFreq));142 dAudLatency, ((audio.wantSamples * 1000.0) / audio.wantFreq),
143 video.renderW, video.renderH, video.renderX, video.renderY,
144 video.displayW, video.displayH, video.windowW, video.windowH,
145 video.renderW / (float)SCREEN_W, video.renderH / (float)SCREEN_H,
146 video.fMouseXMul, video.fMouseYMul,
147 mouse.x, mouse.y,
148 mouse.absX, mouse.absY);
128 149
129 // draw text150 // draw text
130 151
@@ -138,22 +159,35 @@ static void drawFPSCounter(void) · 7 unmodified lines
138 if (ch == '\n')159 if (ch == '\n')
139 {160 {
140 yPos += FONT1_CHAR_H+1;161 yPos += FONT1_CHAR_H+1;
141 xPos = FPS_RENDER_X + 3;162 xPos = FPS_RENDER_X+3;
142 continue;163 continue;
143 }164 }
144 165
145 charOut(xPos, yPos, PAL_FORGRND, ch);166 charOut(xPos, yPos, PAL_FORGRND, ch);
146 xPos += charWidth(ch);167 xPos += charWidth(ch);
147 }168 }
169
170 // draw framerate tester symbol
171
172 const uint16_t symbolEnd = 115;
173
174 // ping-pong movement
175 uint16_t x = editor.framesPassed % (symbolEnd * 2);
176 if (x >= symbolEnd)
177 x = (symbolEnd * 2) - x;
178
179 charOut(164 + x, 16, PAL_FORGRND, '*');
148}180}
149 181
150void endFPSCounter(void)182void endFPSCounter(void)
151{183{
152 if (video.showFPSCounter && frameStartTime > 0)184 if (video.showFPSCounter && frameStartTime > 0)
153 {185 {
154 const uint64_t frameTimeDiff = SDL_GetPerformanceCounter() - frameStartTime;186 uint64_t frameTimeDiff64 = SDL_GetPerformanceCounter() - frameStartTime;
155 const double dHz = 1000.0 / (frameTimeDiff * editor.dPerfFreqMulMs);187 if (frameTimeDiff64 > INT32_MAX)
156 dRunningFPS += dHz;188 frameTimeDiff64 = INT32_MAX;
189
190 dRunningFrameDuration += (int32_t)frameTimeDiff64 * hpcFreq.dFreqMulMs;
157 }191 }
158}192}
159 193
@@ -180,7 +214,8 @@ void flipFrame(void) · 20 unmodified lines
180 214
181 if (!video.vsync60HzPresent)215 if (!video.vsync60HzPresent)
182 {216 {
183 waitVBL(); // we have no VSync, do crude thread sleeping to sync to ~60Hz217 // we have no VSync, do crude thread sleeping to sync to ~60Hz
218 hpc_Wait(&video.vblankHpc);
184 }219 }
185 else220 else
186 {221 {
@@ -190,14 +225,14 @@ void flipFrame(void) · 3 unmodified lines
190#ifdef __APPLE__225#ifdef __APPLE__
191 // macOS: VSync gets disabled if the window is 100% covered by another window. Let's add a (crude) fix:226 // macOS: VSync gets disabled if the window is 100% covered by another window. Let's add a (crude) fix:
192 if (minimized || !(windowFlags & SDL_WINDOW_INPUT_FOCUS))227 if (minimized || !(windowFlags & SDL_WINDOW_INPUT_FOCUS))
193 waitVBL();228 hpc_Wait(&video.vblankHpc);
194#elif __unix__229#elif __unix__
195 // *NIX: VSync gets disabled in fullscreen mode (at least on some distros/systems). Let's add a fix:230 // *NIX: VSync gets disabled in fullscreen mode (at least on some distros/systems). Let's add a fix:
196 if (minimized || video.fullscreen)231 if (minimized || video.fullscreen)
197 waitVBL();232 hpc_Wait(&video.vblankHpc);
198#else233#else
199 if (minimized)234 if (minimized)
200 waitVBL();235 hpc_Wait(&video.vblankHpc);
201#endif236#endif
202 }237 }
203 238
@@ -238,6 +273,8 @@ static void updateRenderSizeVars(void) · 34 unmodified lines
238 SDL_GetWindowSize(video.window, &video.displayW, &video.displayH);273 SDL_GetWindowSize(video.window, &video.displayW, &video.displayH);
239 }274 }
240 275
276 SDL_GetWindowSize(video.window, &video.windowW, &video.windowH);
277
241 if (video.fullscreen)278 if (video.fullscreen)
242 {279 {
243 if (config.specialFlags2 & STRETCH_IMAGE)280 if (config.specialFlags2 & STRETCH_IMAGE)
@@ -271,8 +308,8 @@ static void updateRenderSizeVars(void) · 27 unmodified lines
271 if (dXUpscale != 0.0) video.renderW = (int32_t)(video.renderW / dXUpscale);308 if (dXUpscale != 0.0) video.renderW = (int32_t)(video.renderW / dXUpscale);
272 if (dYUpscale != 0.0) video.renderH = (int32_t)(video.renderH / dYUpscale);309 if (dYUpscale != 0.0) video.renderH = (int32_t)(video.renderH / dYUpscale);
273 310
274 video.renderX = (video.displayW - video.renderW) >> 1;311 video.renderX = (video.displayW - video.renderW) / 2;
275 video.renderY = (video.displayH - video.renderH) >> 1;312 video.renderY = (video.displayH - video.renderH) / 2;
276 }313 }
277 }314 }
278 else315 else
@@ -284,19 +321,26 @@ static void updateRenderSizeVars(void) · 5 unmodified lines
284 }321 }
285 322
286 // for mouse cursor creation323 // for mouse cursor creation
287 video.xScale = (uint32_t)round(video.renderW * (1.0 / SCREEN_W));324 video.xScale = (uint32_t)round(video.renderW / (double)SCREEN_W);
288 video.yScale = (uint32_t)round(video.renderH * (1.0 / SCREEN_H));325 video.yScale = (uint32_t)round(video.renderH / (double)SCREEN_H);
289 326
290 createMouseCursors();327 createMouseCursors();
291}328}
292 329
293void enterFullscreen(void)330void enterFullscreen(void)
294{331{
295 SDL_DisplayMode dm;332 SDL_SetWindowFullscreen(video.window, SDL_WINDOW_FULLSCREEN_DESKTOP);
296 333
297 if (config.specialFlags2 & STRETCH_IMAGE)334 if (config.specialFlags2 & STRETCH_IMAGE)
298 {335 {
299 SDL_GetDesktopDisplayMode(0, &dm);336 SDL_DisplayMode dm;
337
338 int32_t di = SDL_GetWindowDisplayIndex(video.window);
339 if (di < 0)
340 di = 0; // return display index 0 (default) on error
341
342 SDL_GetDesktopDisplayMode(di, &dm);
343
300 SDL_RenderSetLogicalSize(video.renderer, dm.w, dm.h);344 SDL_RenderSetLogicalSize(video.renderer, dm.w, dm.h);
301 }345 }
302 else346 else
@@ -305,15 +349,17 @@ void enterFullscreen(void) · 2 unmodified lines
305 }349 }
306 350
307 SDL_SetWindowSize(video.window, SCREEN_W, SCREEN_H);351 SDL_SetWindowSize(video.window, SCREEN_W, SCREEN_H);
308 SDL_SetWindowFullscreen(video.window, SDL_WINDOW_FULLSCREEN_DESKTOP);352
353#ifndef __unix__ // can be severely buggy on Linux... (at least when used like this)
309 SDL_SetWindowGrab(video.window, SDL_TRUE);354 SDL_SetWindowGrab(video.window, SDL_TRUE);
355#endif
310 356
311 updateRenderSizeVars();357 updateRenderSizeVars();
312 updateMouseScaling();358 updateMouseScaling();
313 setMousePosToCenter();359 setMousePosToCenter();
314}360}
315 361
316void leaveFullScreen(void)362void leaveFullscreen(void)
317{363{
318 SDL_SetWindowFullscreen(video.window, 0);364 SDL_SetWindowFullscreen(video.window, 0);
319 SDL_RenderSetLogicalSize(video.renderer, SCREEN_W, SCREEN_H);365 SDL_RenderSetLogicalSize(video.renderer, SCREEN_W, SCREEN_H);
@@ -321,21 +367,28 @@ void leaveFullScreen(void) · 1 unmodified line
321 setWindowSizeFromConfig(false);367 setWindowSizeFromConfig(false);
322 368
323 SDL_SetWindowSize(video.window, SCREEN_W * video.upscaleFactor, SCREEN_H * video.upscaleFactor);369 SDL_SetWindowSize(video.window, SCREEN_W * video.upscaleFactor, SCREEN_H * video.upscaleFactor);
370
371#ifndef __unix__
324 SDL_SetWindowGrab(video.window, SDL_FALSE);372 SDL_SetWindowGrab(video.window, SDL_FALSE);
373#endif
325 374
326 updateRenderSizeVars();375 updateRenderSizeVars();
327 updateMouseScaling();376 updateMouseScaling();
328 setMousePosToCenter();377 setMousePosToCenter();
378
379#ifdef __unix__ // can be required on Linux... (or else the window keeps moving down every time you leave fullscreen)
380 SDL_SetWindowPosition(video.window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
381#endif
329}382}
330 383
331void toggleFullScreen(void)384void toggleFullscreen(void)
332{385{
333 video.fullscreen ^= 1;386 video.fullscreen ^= 1;
334 387
335 if (video.fullscreen)388 if (video.fullscreen)
336 enterFullscreen();389 enterFullscreen();
337 else390 else
338 leaveFullScreen();391 leaveFullscreen();
339}392}
340 393
341bool setupSprites(void)394bool setupSprites(void)
@@ -722,44 +775,6 @@ void renderLoopPins(void) · 380 unmodified lines
722 }775 }
723}776}
724 777
725void setupWaitVBL(void)
726{
727 // set next frame time
728 timeNext64 = SDL_GetPerformanceCounter() + video.vblankTimeLen;
729 timeNext64Frac = video.vblankTimeLenFrac;
730}
731
732void waitVBL(void)
733{
734 // this routine almost never delays if we have 60Hz vsync, but it's still needed in some occasions
735
736 uint64_t time64 = SDL_GetPerformanceCounter();
737 if (time64 < timeNext64)
738 {
739 time64 = timeNext64 - time64;
740 if (time64 > INT32_MAX)
741 time64 = INT32_MAX;
742
743 const int32_t diff32 = (int32_t)time64;
744
745 // convert and round to microseconds
746 const int32_t time32 = (int32_t)((diff32 * editor.dPerfFreqMulMicro) + 0.5);
747
748 // delay until we have reached the next frame
749 if (time32 > 0)
750 usleep(time32);
751 }
752
753 // update next frame time
754 timeNext64 += video.vblankTimeLen;
755 timeNext64Frac += video.vblankTimeLenFrac;
756 if (timeNext64Frac > UINT32_MAX)
757 {
758 timeNext64Frac &= UINT32_MAX;
759 timeNext64++;
760 }
761}
762
763void closeVideo(void)778void closeVideo(void)
764{779{
765 if (video.texture != NULL)780 if (video.texture != NULL)
@@ -780,13 +795,11 @@ void closeVideo(void) · 14 unmodified lines
780 video.window = NULL;795 video.window = NULL;
781 }796 }
782 797
783 if (video.frameBufferUnaligned != NULL)798 if (video.frameBuffer != NULL)
784 {799 {
785 free(video.frameBufferUnaligned);800 free(video.frameBuffer);
786 video.frameBufferUnaligned = NULL;801 video.frameBuffer = NULL;
787 }802 }
788
789 video.frameBuffer = NULL;
790}803}
791 804
792void setWindowSizeFromConfig(bool updateRenderer)805void setWindowSizeFromConfig(bool updateRenderer)
@@ -811,8 +824,12 @@ void setWindowSizeFromConfig(bool updateRenderer) · 18 unmodified lines
811 uint8_t oldUpscaleFactor = video.upscaleFactor;824 uint8_t oldUpscaleFactor = video.upscaleFactor;
812 if (config.windowFlags & WINSIZE_AUTO)825 if (config.windowFlags & WINSIZE_AUTO)
813 {826 {
827 int32_t di = SDL_GetWindowDisplayIndex(video.window);
828 if (di < 0)
829 di = 0; // return display index 0 (default) on error
830
814 // find out which upscaling factor is the biggest to fit on screen831 // find out which upscaling factor is the biggest to fit on screen
815 if (SDL_GetDesktopDisplayMode(0, &dm) == 0)832 if (SDL_GetDesktopDisplayMode(di, &dm) == 0)
816 {833 {
817 for (i = MAX_UPSCALE_FACTOR; i >= 1; i--)834 for (i = MAX_UPSCALE_FACTOR; i >= 1; i--)
818 {835 {
@@ -869,17 +886,31 @@ void updateWindowTitle(bool forceUpdate) · 50 unmodified lines
869 strncpy(songTitleTrunc, songTitle, sizeof (songTitleTrunc)-1);886 strncpy(songTitleTrunc, songTitle, sizeof (songTitleTrunc)-1);
870 songTitleTrunc[sizeof (songTitleTrunc)-1] = '\0';887 songTitleTrunc[sizeof (songTitleTrunc)-1] = '\0';
871 888
872 if (song.isModified)889#if CPU_BITS==32
873 sprintf(wndTitle, "Fasttracker II clone v%s (%d-bit) - \"%s\" (unsaved)", PROG_VER_STR, CPU_BITS, songTitleTrunc);890 if (song.isModified)
874 else891 sprintf(wndTitle, "Fasttracker II clone v%s (32-bit) - \"%s\" (unsaved)", PROG_VER_STR, songTitleTrunc);
875 sprintf(wndTitle, "Fasttracker II clone v%s (%d-bit) - \"%s\"", PROG_VER_STR, CPU_BITS, songTitleTrunc);892 else
893 sprintf(wndTitle, "Fasttracker II clone v%s (32-bit) - \"%s\"", PROG_VER_STR, songTitleTrunc);
894#else
895 if (song.isModified)
896 sprintf(wndTitle, "Fasttracker II clone v%s - \"%s\" (unsaved)", PROG_VER_STR, songTitleTrunc);
897 else
898 sprintf(wndTitle, "Fasttracker II clone v%s - \"%s\"", PROG_VER_STR, songTitleTrunc);
899#endif
876 }900 }
877 else901 else
878 {902 {
903#if CPU_BITS==32
879 if (song.isModified)904 if (song.isModified)
880 sprintf(wndTitle, "Fasttracker II clone v%s (%d-bit) - \"untitled\" (unsaved)", PROG_VER_STR, CPU_BITS);905 sprintf(wndTitle, "Fasttracker II clone v%s (32-bit) - \"untitled\" (unsaved)", PROG_VER_STR);
881 else906 else
882 sprintf(wndTitle, "Fasttracker II clone v%s (%d-bit) - \"untitled\"", PROG_VER_STR, CPU_BITS);907 sprintf(wndTitle, "Fasttracker II clone v%s (32-bit) - \"untitled\"", PROG_VER_STR);
908#else
909 if (song.isModified)
910 sprintf(wndTitle, "Fasttracker II clone v%s - \"untitled\" (unsaved)", PROG_VER_STR);
911 else
912 sprintf(wndTitle, "Fasttracker II clone v%s - \"untitled\"", PROG_VER_STR);
913#endif
883 }914 }
884 915
885 SDL_SetWindowTitle(video.window, wndTitle);916 SDL_SetWindowTitle(video.window, wndTitle);
@@ -923,7 +954,11 @@ bool setupWindow(void) · 37 unmodified lines
923 954
924 setWindowSizeFromConfig(false);955 setWindowSizeFromConfig(false);
925 956
926 SDL_GetDesktopDisplayMode(0, &dm);957 int32_t di = SDL_GetWindowDisplayIndex(video.window);
958 if (di < 0)
959 di = 0; // return display index 0 (default) on error
960
961 SDL_GetDesktopDisplayMode(di, &dm);
927 video.dMonitorRefreshRate = (double)dm.refresh_rate;962 video.dMonitorRefreshRate = (double)dm.refresh_rate;
928 963
929 if (dm.refresh_rate >= 59 && dm.refresh_rate <= 61)964 if (dm.refresh_rate >= 59 && dm.refresh_rate <= 61)
@@ -979,7 +1014,7 @@ bool setupRenderer(void) · 49 unmodified lines
979 1014
980 SDL_RenderSetLogicalSize(video.renderer, SCREEN_W, SCREEN_H);1015 SDL_RenderSetLogicalSize(video.renderer, SCREEN_W, SCREEN_H);
981 1016
982#if SDL_PATCHLEVEL >= 51017#if SDL_MINOR_VERSION >= 24 || (SDL_MINOR_VERSION == 0 && SDL_PATCHLEVEL >= 5)
983 SDL_RenderSetIntegerScale(video.renderer, SDL_TRUE);1018 SDL_RenderSetIntegerScale(video.renderer, SDL_TRUE);
984#endif1019#endif
985 1020
@@ -993,19 +1028,22 @@ bool setupRenderer(void) · 7 unmodified lines
993 }1028 }
994 1029
995 // framebuffer used by SDL (for texture)1030 // framebuffer used by SDL (for texture)
996 video.frameBufferUnaligned = (uint32_t *)MALLOC_PAD(SCREEN_W * SCREEN_H * sizeof (int32_t), 256);1031 video.frameBuffer = (uint32_t *)malloc(SCREEN_W * SCREEN_H * sizeof (int32_t));
997 if (video.frameBufferUnaligned == NULL)1032 if (video.frameBuffer == NULL)
998 {1033 {
999 showErrorMsgBox("Not enough memory!");1034 showErrorMsgBox("Not enough memory!");
1000 return false;1035 return false;
1001 }1036 }
1002 1037
1003 // we want an aligned pointer
1004 video.frameBuffer = (uint32_t *)ALIGN_PTR(video.frameBufferUnaligned, 256);
1005
1006 if (!setupSprites())1038 if (!setupSprites())
1007 return false;1039 return false;
1008 1040
1041 // Workaround: SDL_GetGlobalMouseState() doesn't work with KMSDRM/Wayland
1042 video.useDesktopMouseCoords = true;
1043 const char *videoDriver = SDL_GetCurrentVideoDriver();
1044 if (videoDriver != NULL && (strcmp("KMSDRM", videoDriver) == 0 || strcmp("wayland", videoDriver) == 0))
1045 video.useDesktopMouseCoords = false;
1046
1009 updateRenderSizeVars();1047 updateRenderSizeVars();
1010 updateMouseScaling();1048 updateMouseScaling();
1011 1049
@@ -1014,12 +1052,6 @@ bool setupRenderer(void) · 2 unmodified lines
1014 else1052 else
1015 SDL_ShowCursor(SDL_FALSE);1053 SDL_ShowCursor(SDL_FALSE);
1016 1054
1017 // Workaround: SDL_GetGlobalMouseState() doesn't work with KMSDRM/Wayland
1018 video.useDesktopMouseCoords = true;
1019 const char *videoDriver = SDL_GetCurrentVideoDriver();
1020 if (videoDriver != NULL && (strcmp("KMSDRM", videoDriver) == 0 || strcmp("wayland", videoDriver) == 0))
1021 video.useDesktopMouseCoords = false;
1022
1023 SDL_SetRenderDrawColor(video.renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);1055 SDL_SetRenderDrawColor(video.renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
1024 return true;1056 return true;
1025}1057}
src/ft2_video.h+6−7
@@ -5,6 +5,7 @@ · 4 unmodified lines
5#include "ft2_header.h"5#include "ft2_header.h"
6#include "ft2_palette.h"6#include "ft2_palette.h"
7#include "ft2_audio.h"7#include "ft2_audio.h"
8#include "ft2_hpc.h"
8 9
9enum10enum
10{11{
@@ -20,17 +21,17 @@ typedef struct video_t · 9 unmodified lines
20{21{
21 bool fullscreen, showFPSCounter, useDesktopMouseCoords;22 bool fullscreen, showFPSCounter, useDesktopMouseCoords;
22 uint32_t xScale, yScale;23 uint32_t xScale, yScale;
23 uint32_t *frameBuffer, palette[PAL_NUM], vblankTimeLen, vblankTimeLenFrac;24 uint32_t *frameBuffer, palette[PAL_NUM];
24#ifdef _WIN3225#ifdef _WIN32
25 HWND hWnd;26 HWND hWnd;
26#endif27#endif
28 hpc_t vblankHpc;
27 SDL_Window *window;29 SDL_Window *window;
28 double dMonitorRefreshRate;30 double dMonitorRefreshRate;
29 float fMouseXMul, fMouseYMul;31 float fMouseXMul, fMouseYMul;
30 uint8_t upscaleFactor;32 uint8_t upscaleFactor;
31 bool vsync60HzPresent, windowHidden;33 bool vsync60HzPresent, windowHidden;
32 int32_t renderX, renderY, renderW, renderH, displayW, displayH;34 int32_t renderX, renderY, renderW, renderH, displayW, displayH, windowW, windowH;
33 uint32_t *frameBufferUnaligned;
34 SDL_Renderer *renderer;35 SDL_Renderer *renderer;
35 SDL_Texture *texture;36 SDL_Texture *texture;
36 SDL_Surface *iconSurface;37 SDL_Surface *iconSurface;
@@ -70,9 +71,7 @@ void changeSpriteData(int32_t sprite, const uint8_t *data); · 33 unmodified lines
70void hideSprite(int32_t sprite);71void hideSprite(int32_t sprite);
71void handleRedrawing(void);72void handleRedrawing(void);
72void enterFullscreen(void);73void enterFullscreen(void);
73void leaveFullScreen(void);74void leaveFullscreen(void);
74void setWindowSizeFromConfig(bool updateRenderer);75void setWindowSizeFromConfig(bool updateRenderer);
75bool recreateTexture(void);76bool recreateTexture(void);
76void toggleFullScreen(void);77void toggleFullscreen(void);
77void setupWaitVBL(void);
78void waitVBL(void);
src/ft2_wav_renderer.c+37−30
@@ -20,6 +20,7 @@ · 19 unmodified lines
20#include "ft2_wav_renderer.h"20#include "ft2_wav_renderer.h"
21#include "ft2_structs.h"21#include "ft2_structs.h"
22 22
23#define UPDATE_VISUALS_AT_TICK 4
23#define TICKS_PER_RENDER_CHUNK 6424#define TICKS_PER_RENDER_CHUNK 64
24 25
25enum26enum
@@ -37,9 +38,10 @@ typedef struct wavHeader_t · 11 unmodified lines
37 uint32_t subchunk2ID, subchunk2Size;38 uint32_t subchunk2ID, subchunk2Size;
38} wavHeader_t;39} wavHeader_t;
39 40
41static bool useLegacyBPM = false;
40static uint8_t WDBitDepth = 16, WDStartPos, WDStopPos, *wavRenderBuffer;42static uint8_t WDBitDepth = 16, WDStartPos, WDStopPos, *wavRenderBuffer;
41static int16_t WDAmp;43static int16_t WDAmp;
42static uint32_t WDFrequency = DEFAULT_AUDIO_FREQ;44static uint32_t WDFrequency = 44100;
43static SDL_Thread *thread;45static SDL_Thread *thread;
44 46
45static void updateWavRenderer(void)47static void updateWavRenderer(void)
@@ -58,22 +60,9 @@ static void updateWavRenderer(void) · 12 unmodified lines
58 hexOut(237, 158, PAL_FORGRND, WDStopPos, 2);60 hexOut(237, 158, PAL_FORGRND, WDStopPos, 2);
59}61}
60 62
61void setWavRenderFrequency(int32_t freq)63void cbToggleWavRenderBPMMode(void)
62{64{
63 WDFrequency = CLAMP(freq, MIN_WAV_RENDER_FREQ, MAX_WAV_RENDER_FREQ);65 useLegacyBPM ^= 1;
64 if (ui.wavRendererShown)
65 updateWavRenderer();
66}
67
68void setWavRenderBitDepth(uint8_t bitDepth)
69{
70 if (bitDepth == 16)
71 WDBitDepth = 16;
72 else if (bitDepth == 32)
73 WDBitDepth = 32;
74
75 if (ui.wavRendererShown)
76 updateWavRenderer();
77}66}
78 67
79void updateWavRendererSettings(void) // called when changing config.boostLevel68void updateWavRendererSettings(void) // called when changing config.boostLevel
@@ -91,6 +80,9 @@ void drawWavRenderer(void) · 11 unmodified lines
91 textOutShadow(156, 96, PAL_FORGRND, PAL_DSKTOP2, "16-bit");80 textOutShadow(156, 96, PAL_FORGRND, PAL_DSKTOP2, "16-bit");
92 textOutShadow(221, 96, PAL_FORGRND, PAL_DSKTOP2, "32-bit float");81 textOutShadow(221, 96, PAL_FORGRND, PAL_DSKTOP2, "32-bit float");
93 82
83 textOutShadow(19, 114, PAL_FORGRND, PAL_DSKTOP2, "Imprecise");
84 textOutShadow(4, 127, PAL_FORGRND, PAL_DSKTOP2, "BPM (FT2)");
85
94 textOutShadow(85, 116, PAL_FORGRND, PAL_DSKTOP2, "Frequency");86 textOutShadow(85, 116, PAL_FORGRND, PAL_DSKTOP2, "Frequency");
95 textOutShadow(85, 130, PAL_FORGRND, PAL_DSKTOP2, "Amplification");87 textOutShadow(85, 130, PAL_FORGRND, PAL_DSKTOP2, "Amplification");
96 textOutShadow(85, 144, PAL_FORGRND, PAL_DSKTOP2, "Start song position");88 textOutShadow(85, 144, PAL_FORGRND, PAL_DSKTOP2, "Start song position");
@@ -107,6 +99,8 @@ void drawWavRenderer(void) · 10 unmodified lines
107 showPushButton(PB_WAV_END_UP);99 showPushButton(PB_WAV_END_UP);
108 showPushButton(PB_WAV_END_DOWN);100 showPushButton(PB_WAV_END_DOWN);
109 101
102 showCheckBox(CB_WAV_BPM_MODE);
103
110 // bitdepth radiobuttons104 // bitdepth radiobuttons
111 105
112 radioButtons[RB_WAV_RENDER_BITDEPTH16].state = RADIOBUTTON_UNCHECKED;106 radioButtons[RB_WAV_RENDER_BITDEPTH16].state = RADIOBUTTON_UNCHECKED;
@@ -162,6 +156,7 @@ void hideWavRenderer(void) · 49 unmodified lines
162 hidePushButton(PB_WAV_START_DOWN);156 hidePushButton(PB_WAV_START_DOWN);
163 hidePushButton(PB_WAV_END_UP);157 hidePushButton(PB_WAV_END_UP);
164 hidePushButton(PB_WAV_END_DOWN);158 hidePushButton(PB_WAV_END_DOWN);
159 hideCheckBox(CB_WAV_BPM_MODE);
165 hideRadioButtonGroup(RB_GROUP_WAV_RENDER_BITDEPTH);160 hideRadioButtonGroup(RB_GROUP_WAV_RENDER_BITDEPTH);
166 161
167 ui.scopesShown = true;162 ui.scopesShown = true;
@@ -325,7 +320,7 @@ static int32_t SDLCALL renderWavThread(void *ptr) · 157 unmodified lines
325 320
326 uint32_t sampleCounter = 0;321 uint32_t sampleCounter = 0;
327 bool overflow = false, renderDone = false;322 bool overflow = false, renderDone = false;
328 uint8_t tickCounter = 4;323 uint8_t tickCounter = UPDATE_VISUALS_AT_TICK;
329 int64_t tickSampleCounter64 = 0;324 int64_t tickSampleCounter64 = 0;
330 325
331 uint64_t bytesInFile = sizeof (wavHeader_t);326 uint64_t bytesInFile = sizeof (wavHeader_t);
@@ -345,31 +340,43 @@ static int32_t SDLCALL renderWavThread(void *ptr) · 13 unmodified lines
345 break;340 break;
346 }341 }
347 342
348 if (tickSampleCounter64 <= 0) // new replayer tick343 int32_t tickSamples;
344
345 if (useLegacyBPM)
349 {346 {
350 dump_TickReplayer();347 dump_TickReplayer();
351 tickSampleCounter64 += audio.samplesPerTick64;348 tickSamples = audio.samplesPerTick64 >> 32; // truncate
349 }
350 else
351 {
352 if (tickSampleCounter64 <= 0) // new replayer tick
353 {
354 dump_TickReplayer();
355 tickSampleCounter64 += audio.samplesPerTick64;
356 }
357
358 tickSamples = (tickSampleCounter64 + UINT32_MAX) >> 32; // ceil (rounded upwards)
352 }359 }
353 360
354 int32_t remainingTick = (tickSampleCounter64 + UINT32_MAX) >> 32; // ceil (rounded upwards)361 mixReplayerTickToBuffer(tickSamples, ptr8, WDBitDepth);
355 362
356 mixReplayerTickToBuffer(remainingTick, ptr8, WDBitDepth);363 if (!useLegacyBPM)
357 tickSampleCounter64 -= (int64_t)remainingTick << 32;364 tickSampleCounter64 -= (int64_t)tickSamples << 32;
358 365
359 remainingTick *= 2; // stereo366 tickSamples *= 2; // stereo
360 samplesInChunk += remainingTick;367 samplesInChunk += tickSamples;
361 sampleCounter += remainingTick;368 sampleCounter += tickSamples;
362 369
363 // increase buffer pointer370 // increase buffer pointer
364 if (WDBitDepth == 16)371 if (WDBitDepth == 16)
365 {372 {
366 ptr8 += remainingTick * sizeof (int16_t);373 ptr8 += tickSamples * sizeof (int16_t);
367 bytesInFile += remainingTick * sizeof (int16_t);374 bytesInFile += tickSamples * sizeof (int16_t);
368 }375 }
369 else376 else
370 {377 {
371 ptr8 += remainingTick * sizeof (float);378 ptr8 += tickSamples * sizeof (float);
372 bytesInFile += remainingTick * sizeof (float);379 bytesInFile += tickSamples * sizeof (float);
373 }380 }
374 381
375 if (bytesInFile >= INT32_MAX)382 if (bytesInFile >= INT32_MAX)
@@ -379,7 +386,7 @@ static int32_t SDLCALL renderWavThread(void *ptr) · 3 unmodified lines
379 break;386 break;
380 }387 }
381 388
382 if (++tickCounter >= 4)389 if (++tickCounter >= UPDATE_VISUALS_AT_TICK)
383 {390 {
384 tickCounter = 0;391 tickCounter = 0;
385 updateVisuals();392 updateVisuals();
src/ft2_wav_renderer.h+1−2
@@ -14,8 +14,7 @@ · 13 unmodified lines
14 14
15#define MAX_WAV_RENDER_SAMPLES_PER_TICK (((MAX_WAV_RENDER_FREQ * 5) / 2) / MIN_BPM)15#define MAX_WAV_RENDER_SAMPLES_PER_TICK (((MAX_WAV_RENDER_FREQ * 5) / 2) / MIN_BPM)
16 16
17void setWavRenderFrequency(int32_t freq);17void cbToggleWavRenderBPMMode(void);
18void setWavRenderBitDepth(uint8_t bitDepth);
19void updateWavRendererSettings(void);18void updateWavRendererSettings(void);
20void drawWavRenderer(void);19void drawWavRenderer(void);
21void showWavRenderer(void);20void showWavRenderer(void);
src/helpdata/FT2.HLP+11−7
@@ -782,6 +782,15 @@ changed with respect to the resampling rate. · 781 unmodified lines
782By pressing the right mouse button in the sample window, you can782By pressing the right mouse button in the sample window, you can
783draw your waveforms manually.783draw your waveforms manually.
784 784
785@X020@C001WAV export:
786>
787>@X040@C001Imprecise BPM (FT2):
788>@X060@C002
789The BPM precision in original FT2 is not exact. Tick this box to use
790the same (poor) BPM precision that original FT2 uses. It will be
791a fraction off, but the WAV output will be the same length as from FT2.
792This settings only affects WAV export, and not tracker playback.
793
785@X020@C001Configuration:794@X020@C001Configuration:
786>795>
787>@X040@C001Auto save:796>@X040@C001Auto save:
@@ -922,11 +931,6 @@ END · 134 unmodified lines
922;***************************************************************************931;***************************************************************************
923@LKnown bugs932@LKnown bugs
924>933>
925>@X010@C001Sample recording on Mac:
926>
927>@X010@C002- Sample recording doesn't work on macOS Mojave and later, because of an
928>@X021issue in SDL2 where it doesn't ask for permission to use the audio input device.
929>
930>@X010@C001WAV exporting (rendering song to WAV):934>@X010@C001WAV exporting (rendering song to WAV):
931>935>
932>@X010@C002- Songs that jump back to a previous pattern will render forever and ever,936>@X010@C002- Songs that jump back to a previous pattern will render forever and ever,
@@ -936,7 +940,7 @@ END · 3 unmodified lines
936>@X010@C001Video:940>@X010@C001Video:
937>@C002941>@C002
938>@X010- Fullscreen mode can be unbearably slow on a Raspberry Pi (even on RPi 4)942>@X010- Fullscreen mode can be unbearably slow on a Raspberry Pi (even on RPi 4)
939>@X010- Not a bug, but if your monitor's refresh rate is not set to 60Hz (or 59Hz)943>@X010- Fullscreen mode can have several problems on multi-monitor systems
940>@X021you may experience visual stuttering because VSync will not be used.944>@X010- Fullscreen mode can have several problems on some Linux systems
941 945
942END946END
src/helpdata/ft2_help_data.h+542−532
@@ -3,9 +3,9 @@ · 2 unmodified lines
3 3
4#include <stdint.h>4#include <stdint.h>
5 5
6#define HELP_DATA_LEN 277666#define HELP_DATA_LEN 27884
7 7
8const uint8_t helpData[27766] =8const uint8_t helpData[27884] =
9{9{
10 0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,10 0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
11 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,11 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
@@ -1789,538 +1789,548 @@ const uint8_t helpData[27766] = · 1777 unmodified lines
1789 0x2C,0x20,0x79,0x6F,0x75,0x20,0x63,0x61,0x6E,0x1D,0x64,0x72,1789 0x2C,0x20,0x79,0x6F,0x75,0x20,0x63,0x61,0x6E,0x1D,0x64,0x72,
1790 0x61,0x77,0x20,0x79,0x6F,0x75,0x72,0x20,0x77,0x61,0x76,0x65,1790 0x61,0x77,0x20,0x79,0x6F,0x75,0x72,0x20,0x77,0x61,0x76,0x65,
1791 0x66,0x6F,0x72,0x6D,0x73,0x20,0x6D,0x61,0x6E,0x75,0x61,0x6C,1791 0x66,0x6F,0x72,0x6D,0x73,0x20,0x6D,0x61,0x6E,0x75,0x61,0x6C,
1792 0x6C,0x79,0x2E,0x00,0x18,0x40,0x58,0x30,0x32,0x30,0x40,0x43,1792 0x6C,0x79,0x2E,0x00,0x15,0x40,0x58,0x30,0x32,0x30,0x40,0x43,
1793 0x30,0x30,0x31,0x43,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,1793 0x30,0x30,0x31,0x57,0x41,0x56,0x20,0x65,0x78,0x70,0x6F,0x72,
1794 0x74,0x69,0x6F,0x6E,0x3A,0x01,0x3E,0x15,0x3E,0x40,0x58,0x30,1794 0x74,0x3A,0x01,0x3E,0x1F,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,
1795 0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x41,0x75,0x74,0x6F,0x20,1795 0x43,0x30,0x30,0x31,0x49,0x6D,0x70,0x72,0x65,0x63,0x69,0x73,
1796 0x73,0x61,0x76,0x65,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,1796 0x65,0x20,0x42,0x50,0x4D,0x20,0x28,0x46,0x54,0x32,0x29,0x3A,
1797 0x40,0x43,0x30,0x30,0x32,0x43,0x49,0x66,0x20,0x74,0x68,0x65,
1798 0x20,0x61,0x75,0x74,0x6F,0x20,0x73,0x61,0x76,0x65,0x20,0x69,
1799 0x73,0x20,0x6F,0x6E,0x2C,0x20,0x46,0x54,0x32,0x20,0x77,0x69,
1800 0x6C,0x6C,0x20,0x75,0x70,0x64,0x61,0x74,0x65,0x20,0x74,0x68,
1801 0x65,0x20,0x63,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,0x74,
1802 0x69,0x6F,0x6E,0x20,0x66,0x69,0x6C,0x65,0x20,0x77,0x68,0x65,
1803 0x6E,0x15,0x79,0x6F,0x75,0x20,0x65,0x78,0x69,0x74,0x20,0x74,
1804 0x68,0x65,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x2E,0x00,
1805 0x25,0x40,0x58,0x30,0x32,0x30,0x40,0x43,0x30,0x30,0x31,0x43,
1806 0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,
1807 0x2C,0x20,0x49,0x2F,0x4F,0x20,0x64,0x65,0x76,0x69,0x63,0x65,
1808 0x73,0x3A,0x01,0x3E,0x19,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,
1809 0x43,0x30,0x30,0x31,0x49,0x6E,0x74,0x65,0x72,0x70,0x6F,0x6C,
1810 0x61,0x74,0x69,0x6F,0x6E,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,
1811 0x30,0x40,0x43,0x30,0x30,0x32,0x35,0x53,0x65,0x6C,0x65,0x63,
1812 0x74,0x73,0x20,0x77,0x68,0x61,0x74,0x20,0x74,0x79,0x70,0x65,
1813 0x20,0x6F,0x66,0x20,0x72,0x65,0x73,0x61,0x6D,0x70,0x6C,0x69,
1814 0x6E,0x67,0x20,0x69,0x6E,0x74,0x65,0x72,0x70,0x6F,0x6C,0x61,
1815 0x74,0x69,0x6F,0x6E,0x20,0x74,0x6F,0x20,0x75,0x73,0x65,0x2E,
1816 0x45,0x22,0x4E,0x6F,0x6E,0x65,0x22,0x20,0x75,0x73,0x65,0x73,
1817 0x20,0x6E,0x6F,0x20,0x69,0x6E,0x74,0x65,0x72,0x70,0x6F,0x6C,
1818 0x61,0x74,0x69,0x6F,0x6E,0x20,0x28,0x6E,0x65,0x61,0x72,0x65,
1819 0x73,0x74,0x20,0x6E,0x65,0x69,0x67,0x68,0x62,0x6F,0x72,0x29,
1820 0x2C,0x20,0x77,0x68,0x69,0x63,0x68,0x20,0x77,0x69,0x6C,0x6C,
1821 0x20,0x72,0x65,0x73,0x75,0x6C,0x74,0x20,0x69,0x6E,0x49,0x61,
1822 0x6C,0x69,0x61,0x73,0x69,0x6E,0x67,0x20,0x28,0x6E,0x6F,0x69,
1823 0x73,0x65,0x29,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x73,
1824 0x6F,0x75,0x6E,0x64,0x2E,0x20,0x22,0x4C,0x69,0x6E,0x65,0x61,
1825 0x72,0x22,0x20,0x69,0x73,0x20,0x77,0x68,0x61,0x74,0x20,0x72,
1826 0x65,0x61,0x6C,0x20,0x46,0x54,0x32,0x20,0x75,0x73,0x65,0x73,
1827 0x2C,0x20,0x77,0x68,0x69,0x63,0x68,0x20,0x69,0x73,0x20,0x61,
1828 0x47,0x6D,0x65,0x64,0x69,0x6F,0x63,0x72,0x65,0x20,0x69,0x6E,
1829 0x74,0x65,0x72,0x70,0x6F,0x6C,0x61,0x74,0x69,0x6F,0x6E,0x20,
1830 0x74,0x79,0x70,0x65,0x2E,0x20,0x22,0x57,0x69,0x6E,0x64,0x6F,
1831 0x77,0x65,0x64,0x2D,0x73,0x69,0x6E,0x63,0x22,0x20,0x69,0x73,
1832 0x20,0x74,0x68,0x65,0x20,0x72,0x65,0x63,0x6F,0x6D,0x6D,0x65,
1833 0x6E,0x64,0x65,0x64,0x20,0x73,0x65,0x74,0x74,0x69,0x6E,0x67,
1834 0x48,0x66,0x6F,0x72,0x20,0x74,0x68,0x65,0x20,0x62,0x65,0x73,
1835 0x74,0x20,0x61,0x75,0x64,0x69,0x6F,0x20,0x71,0x75,0x61,0x6C,
1836 0x69,0x74,0x79,0x2C,0x20,0x61,0x6C,0x74,0x68,0x6F,0x75,0x67,
1837 0x68,0x20,0x69,0x74,0x20,0x6D,0x61,0x79,0x20,0x73,0x6F,0x6D,
1838 0x65,0x74,0x69,0x6D,0x65,0x73,0x20,0x73,0x6F,0x75,0x6E,0x64,
1839 0x20,0x74,0x6F,0x6F,0x20,0x66,0x69,0x6C,0x74,0x65,0x72,0x65,
1840 0x64,0x2A,0x6F,0x6E,0x20,0x6C,0x6F,0x77,0x2D,0x71,0x75,0x61,
1841 0x6C,0x69,0x74,0x79,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65,0x73,
1842 0x20,0x28,0x66,0x2E,0x65,0x78,0x2E,0x20,0x41,0x6D,0x69,0x67,
1843 0x61,0x20,0x4D,0x4F,0x44,0x73,0x29,0x2E,0x00,0x1A,0x3E,0x40,
1844 0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x56,0x6F,0x6C,
1845 0x75,0x6D,0x65,0x20,0x72,0x61,0x6D,0x70,0x69,0x6E,0x67,0x3A,
1846 0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,1797 0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,
1847 0x3B,0x45,0x6E,0x61,0x62,0x6C,0x65,0x73,0x20,0x74,0x68,0x65,1798 0x44,0x54,0x68,0x65,0x20,0x42,0x50,0x4D,0x20,0x70,0x72,0x65,
1848 0x20,0x61,0x6E,0x74,0x69,0x2D,0x63,0x6C,0x69,0x63,0x6B,0x20,1799 0x63,0x69,0x73,0x69,0x6F,0x6E,0x20,0x69,0x6E,0x20,0x6F,0x72,
1849 0x73,0x79,0x73,0x74,0x65,0x6D,0x20,0x69,0x6E,0x20,0x74,0x68,1800 0x69,0x67,0x69,0x6E,0x61,0x6C,0x20,0x46,0x54,0x32,0x20,0x69,
1850 0x65,0x20,0x61,0x75,0x64,0x69,0x6F,0x20,0x6D,0x69,0x78,0x65,1801 0x73,0x20,0x6E,0x6F,0x74,0x20,0x65,0x78,0x61,0x63,0x74,0x2E,
1851 0x72,0x20,0x28,0x46,0x54,0x32,0x2E,0x30,0x38,0x2B,0x29,0x2E,1802 0x20,0x54,0x69,0x63,0x6B,0x20,0x74,0x68,0x69,0x73,0x20,0x62,
1852 0x3B,0x50,0x6C,0x65,0x61,0x73,0x65,0x20,0x6E,0x6F,0x74,0x65,1803 0x6F,0x78,0x20,0x74,0x6F,0x20,0x75,0x73,0x65,0x40,0x74,0x68,
1853 0x20,0x74,0x68,0x61,0x74,0x20,0x6F,0x72,0x69,0x67,0x69,0x6E,1804 0x65,0x20,0x73,0x61,0x6D,0x65,0x20,0x28,0x70,0x6F,0x6F,0x72,
1854 0x61,0x6C,0x20,0x46,0x54,0x32,0x20,0x63,0x61,0x6E,0x27,0x74,1805 0x29,0x20,0x42,0x50,0x4D,0x20,0x70,0x72,0x65,0x63,0x69,0x73,
1855 0x20,0x6C,0x6F,0x61,0x64,0x20,0x74,0x68,0x69,0x73,0x20,0x63,1806 0x69,0x6F,0x6E,0x20,0x74,0x68,0x61,0x74,0x20,0x6F,0x72,0x69,
1856 0x6F,0x6E,0x66,0x69,0x67,0x20,0x65,0x6E,0x74,0x72,0x79,0x2C,1807 0x67,0x69,0x6E,0x61,0x6C,0x20,0x46,0x54,0x32,0x20,0x75,0x73,
1857 0x0B,0x63,0x6C,0x6F,0x6E,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x2E,1808 0x65,0x73,0x2E,0x20,0x49,0x74,0x20,0x77,0x69,0x6C,0x6C,0x20,
1858 0x00,0x19,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,1809 0x62,0x65,0x47,0x61,0x20,0x66,0x72,0x61,0x63,0x74,0x69,0x6F,
1859 0x31,0x41,0x6D,0x70,0x6C,0x69,0x66,0x69,0x63,0x61,0x74,0x69,1810 0x6E,0x20,0x6F,0x66,0x66,0x2C,0x20,0x62,0x75,0x74,0x20,0x74,
1860 0x6F,0x6E,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43,1811 0x68,0x65,0x20,0x57,0x41,0x56,0x20,0x6F,0x75,0x74,0x70,0x75,
1861 0x30,0x30,0x32,0x46,0x41,0x6D,0x70,0x6C,0x69,0x66,0x69,0x65,1812 0x74,0x20,0x77,0x69,0x6C,0x6C,0x20,0x62,0x65,0x20,0x74,0x68,
1862 0x73,0x20,0x74,0x68,0x65,0x20,0x76,0x6F,0x6C,0x75,0x6D,0x65,1813 0x65,0x20,0x73,0x61,0x6D,0x65,0x20,0x6C,0x65,0x6E,0x67,0x74,
1863 0x20,0x77,0x68,0x65,0x6E,0x20,0x6D,0x69,0x78,0x69,0x6E,0x67,1814 0x68,0x20,0x61,0x73,0x20,0x66,0x72,0x6F,0x6D,0x20,0x46,0x54,
1864 0x2E,0x20,0x49,0x66,0x20,0x79,0x6F,0x75,0x20,0x73,0x65,0x74,1815 0x32,0x2E,0x40,0x54,0x68,0x69,0x73,0x20,0x73,0x65,0x74,0x74,
1865 0x20,0x74,0x68,0x69,0x73,0x20,0x6F,0x6E,0x65,0x20,0x74,0x6F,1816 0x69,0x6E,0x67,0x73,0x20,0x6F,0x6E,0x6C,0x79,0x20,0x61,0x66,
1866 0x6F,0x20,0x68,0x69,0x67,0x68,0x2C,0x20,0x79,0x6F,0x75,0x27,1817 0x66,0x65,0x63,0x74,0x73,0x20,0x57,0x41,0x56,0x20,0x65,0x78,
1867 0x6C,0x6C,0x3A,0x67,0x65,0x74,0x20,0x64,0x69,0x73,0x74,0x6F,1818 0x70,0x6F,0x72,0x74,0x2C,0x20,0x61,0x6E,0x64,0x20,0x6E,0x6F,
1868 0x72,0x74,0x69,0x6F,0x6E,0x2E,0x20,0x33,0x32,0x58,0x20,0x65,1819 0x74,0x20,0x74,0x72,0x61,0x63,0x6B,0x65,0x72,0x20,0x70,0x6C,
1869 0x71,0x75,0x61,0x6C,0x73,0x20,0x66,0x75,0x6C,0x6C,0x20,0x61,1820 0x61,0x79,0x62,0x61,0x63,0x6B,0x2E,0x00,0x18,0x40,0x58,0x30,
1870 0x6D,0x70,0x6C,0x69,0x74,0x75,0x64,0x65,0x20,0x66,0x6F,0x72,1821 0x32,0x30,0x40,0x43,0x30,0x30,0x31,0x43,0x6F,0x6E,0x66,0x69,
1871 0x20,0x6F,0x6E,0x65,0x20,0x63,0x68,0x61,0x6E,0x6E,0x65,0x6C,1822 0x67,0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,0x3A,0x01,0x3E,0x15,
1872 0x2E,0x00,0x1B,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,1823 0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x41,
1873 0x30,0x31,0x46,0x72,0x65,0x71,0x75,0x65,0x6E,0x63,0x79,0x20,1824 0x75,0x74,0x6F,0x20,0x73,0x61,0x76,0x65,0x3A,0x0B,0x3E,0x40,
1874 0x74,0x61,0x62,0x6C,0x65,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,1825 0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x43,0x49,0x66,
1875 0x30,0x40,0x43,0x30,0x30,0x32,0x40,0x54,0x68,0x65,0x20,0x6C,1826 0x20,0x74,0x68,0x65,0x20,0x61,0x75,0x74,0x6F,0x20,0x73,0x61,
1876 0x69,0x6E,0x65,0x61,0x72,0x20,0x66,0x72,0x65,0x71,0x75,0x65,1827 0x76,0x65,0x20,0x69,0x73,0x20,0x6F,0x6E,0x2C,0x20,0x46,0x54,
1877 0x6E,0x63,0x79,0x20,0x74,0x61,0x62,0x6C,0x65,0x20,0x6D,0x61,1828 0x32,0x20,0x77,0x69,0x6C,0x6C,0x20,0x75,0x70,0x64,0x61,0x74,
1878 0x6B,0x65,0x73,0x20,0x61,0x6C,0x6C,0x20,0x70,0x69,0x74,0x63,1829 0x65,0x20,0x74,0x68,0x65,0x20,0x63,0x6F,0x6E,0x66,0x69,0x67,
1879 0x68,0x20,0x62,0x65,0x6E,0x64,0x73,0x20,0x72,0x75,0x6E,0x20,1830 0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,0x20,0x66,0x69,0x6C,0x65,
1880 0x69,0x6E,0x20,0x63,0x6F,0x6E,0x73,0x74,0x61,0x6E,0x74,0x3F,1831 0x20,0x77,0x68,0x65,0x6E,0x15,0x79,0x6F,0x75,0x20,0x65,0x78,
1881 0x73,0x70,0x65,0x65,0x64,0x2C,0x20,0x69,0x6E,0x64,0x65,0x70,1832 0x69,0x74,0x20,0x74,0x68,0x65,0x20,0x70,0x72,0x6F,0x67,0x72,
1882 0x65,0x6E,0x64,0x65,0x6E,0x74,0x20,0x6F,0x66,0x20,0x74,0x68,1833 0x61,0x6D,0x2E,0x00,0x25,0x40,0x58,0x30,0x32,0x30,0x40,0x43,
1883 0x65,0x20,0x63,0x75,0x72,0x72,0x65,0x6E,0x74,0x20,0x66,0x72,
1884 0x65,0x71,0x75,0x65,0x6E,0x63,0x79,0x2E,0x20,0x49,0x66,0x20,
1885 0x79,0x6F,0x75,0x20,0x73,0x77,0x69,0x74,0x63,0x68,0x20,0x74,
1886 0x68,0x69,0x73,0x41,0x6F,0x6E,0x65,0x2C,0x20,0x6F,0x6E,0x20,
1887 0x61,0x20,0x66,0x69,0x6E,0x69,0x73,0x68,0x65,0x64,0x20,0x73,
1888 0x6F,0x6E,0x67,0x2C,0x20,0x69,0x74,0x20,0x6D,0x69,0x67,0x68,
1889 0x74,0x20,0x73,0x6F,0x75,0x6E,0x64,0x20,0x73,0x74,0x72,0x61,
1890 0x6E,0x67,0x65,0x20,0x69,0x66,0x20,0x74,0x68,0x65,0x20,0x73,
1891 0x6F,0x75,0x6E,0x64,0x20,0x75,0x73,0x65,0x73,0x0D,0x70,0x6F,
1892 0x72,0x74,0x61,0x6D,0x65,0x6E,0x74,0x6F,0x65,0x73,0x2E,0x00,
1893 0x20,0x40,0x58,0x30,0x32,0x30,0x40,0x43,0x30,0x30,0x31,0x43,
1894 0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,
1895 0x2C,0x20,0x4C,0x61,0x79,0x6F,0x75,0x74,0x3A,0x01,0x3E,0x29,
1896 0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x50,
1897 0x61,0x74,0x74,0x65,0x72,0x6E,0x20,0x6C,0x61,0x79,0x6F,0x75,
1898 0x74,0x2C,0x20,0x68,0x65,0x78,0x20,0x6E,0x75,0x6D,0x62,0x65,
1899 0x72,0x69,0x6E,0x67,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,
1900 0x40,0x43,0x30,0x30,0x32,0x41,0x49,0x66,0x20,0x79,0x6F,0x75,
1901 0x20,0x75,0x73,0x65,0x20,0x70,0x61,0x74,0x74,0x65,0x72,0x6E,
1902 0x73,0x20,0x74,0x68,0x61,0x74,0x20,0x61,0x72,0x65,0x20,0x6C,
1903 0x6F,0x6E,0x67,0x65,0x72,0x20,0x74,0x68,0x61,0x6E,0x20,0x39,
1904 0x39,0x20,0x6C,0x69,0x6E,0x65,0x73,0x2C,0x20,0x79,0x6F,0x75,
1905 0x20,0x73,0x68,0x6F,0x75,0x6C,0x64,0x20,0x75,0x73,0x65,0x45,
1906 0x68,0x65,0x78,0x20,0x63,0x6F,0x75,0x6E,0x74,0x69,0x6E,0x67,
1907 0x20,0x73,0x69,0x6E,0x63,0x65,0x20,0x74,0x68,0x65,0x72,0x65,
1908 0x20,0x61,0x72,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x20,0x32,0x20,
1909 0x64,0x69,0x67,0x69,0x74,0x73,0x20,0x69,0x6E,0x20,0x74,0x68,
1910 0x65,0x20,0x6C,0x69,0x6E,0x65,0x20,0x6E,0x75,0x6D,0x62,0x65,
1911 0x72,0x20,0x63,0x6F,0x6C,0x75,0x6D,0x6E,0x2E,0x00,0x12,0x3E,
1912 0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x53,0x63,
1913 0x6F,0x70,0x65,0x73,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,
1914 0x40,0x43,0x30,0x30,0x32,0x43,0x22,0x53,0x74,0x64,0x2E,0x22,
1915 0x20,0x28,0x73,0x74,0x61,0x6E,0x64,0x61,0x72,0x64,0x29,0x20,
1916 0x77,0x69,0x6C,0x6C,0x20,0x73,0x68,0x6F,0x77,0x20,0x74,0x68,
1917 0x65,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65,0x20,0x70,0x6F,0x69,
1918 0x6E,0x74,0x73,0x20,0x61,0x73,0x20,0x70,0x69,0x78,0x65,0x6C,
1919 0x73,0x20,0x28,0x6C,0x69,0x6B,0x65,0x20,0x46,0x54,0x32,0x29,
1920 0x2E,0x3D,0x22,0x4C,0x69,0x6E,0x65,0x64,0x22,0x20,0x77,0x69,
1921 0x6C,0x6C,0x20,0x64,0x72,0x61,0x77,0x20,0x69,0x6E,0x74,0x65,
1922 0x72,0x70,0x6F,0x6C,0x61,0x74,0x65,0x64,0x20,0x73,0x61,0x6D,
1923 0x70,0x6C,0x65,0x73,0x20,0x28,0x6C,0x69,0x6E,0x65,0x61,0x72,
1924 0x20,0x69,0x6E,0x74,0x65,0x72,0x70,0x6F,0x6C,0x61,0x74,0x69,
1925 0x6F,0x6E,0x2E,0x00,0x27,0x40,0x58,0x30,0x32,0x30,0x40,0x43,
1926 0x30,0x30,0x31,0x43,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,1834 0x30,0x30,0x31,0x43,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,
1927 0x74,0x69,0x6F,0x6E,0x2C,0x20,0x4D,0x69,0x73,0x63,0x65,0x6C,1835 0x74,0x69,0x6F,0x6E,0x2C,0x20,0x49,0x2F,0x4F,0x20,0x64,0x65,
1928 0x6C,0x61,0x6E,0x65,0x6F,0x75,0x73,0x3A,0x01,0x3E,0x15,0x3E,1836 0x76,0x69,0x63,0x65,0x73,0x3A,0x01,0x3E,0x19,0x3E,0x40,0x58,
1929 0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x56,0x53,1837 0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x49,0x6E,0x74,0x65,
1930 0x79,0x6E,0x63,0x20,0x6F,0x66,0x66,0x3A,0x0B,0x3E,0x40,0x58,1838 0x72,0x70,0x6F,0x6C,0x61,0x74,0x69,0x6F,0x6E,0x3A,0x0B,0x3E,
1931 0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x3F,0x54,0x65,0x6C,1839 0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x35,0x53,
1932 0x6C,0x73,0x20,0x74,0x68,0x65,0x20,0x70,0x72,0x6F,0x67,0x72,1840 0x65,0x6C,0x65,0x63,0x74,0x73,0x20,0x77,0x68,0x61,0x74,0x20,
1933 0x61,0x6D,0x20,0x74,0x6F,0x20,0x6E,0x6F,0x74,0x20,0x75,0x73,1841 0x74,0x79,0x70,0x65,0x20,0x6F,0x66,0x20,0x72,0x65,0x73,0x61,
1934 0x65,0x20,0x56,0x53,0x79,0x6E,0x63,0x20,0x66,0x6F,0x72,0x20,1842 0x6D,0x70,0x6C,0x69,0x6E,0x67,0x20,0x69,0x6E,0x74,0x65,0x72,
1935 0x76,0x69,0x64,0x65,0x6F,0x2E,0x20,0x49,0x66,0x20,0x79,0x6F,1843 0x70,0x6F,0x6C,0x61,0x74,0x69,0x6F,0x6E,0x20,0x74,0x6F,0x20,
1936 0x75,0x72,0x20,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x27,0x73,1844 0x75,0x73,0x65,0x2E,0x45,0x22,0x4E,0x6F,0x6E,0x65,0x22,0x20,
1937 0x40,0x72,0x65,0x66,0x72,0x65,0x73,0x68,0x20,0x72,0x61,0x74,1845 0x75,0x73,0x65,0x73,0x20,0x6E,0x6F,0x20,0x69,0x6E,0x74,0x65,
1938 0x65,0x20,0x69,0x73,0x20,0x6E,0x6F,0x74,0x20,0x36,0x30,0x48,1846 0x72,0x70,0x6F,0x6C,0x61,0x74,0x69,0x6F,0x6E,0x20,0x28,0x6E,
1939 0x7A,0x20,0x28,0x6F,0x72,0x20,0x35,0x39,0x48,0x7A,0x29,0x2C,1847 0x65,0x61,0x72,0x65,0x73,0x74,0x20,0x6E,0x65,0x69,0x67,0x68,
1940 0x20,0x74,0x68,0x65,0x6E,0x20,0x56,0x53,0x79,0x6E,0x63,0x20,1848 0x62,0x6F,0x72,0x29,0x2C,0x20,0x77,0x68,0x69,0x63,0x68,0x20,
1941 0x69,0x73,0x20,0x61,0x6C,0x77,0x61,0x79,0x73,0x20,0x6F,0x66,1849 0x77,0x69,0x6C,0x6C,0x20,0x72,0x65,0x73,0x75,0x6C,0x74,0x20,
1942 0x66,0x20,0x66,0x6F,0x72,0x45,0x74,0x68,0x69,0x73,0x20,0x70,1850 0x69,0x6E,0x49,0x61,0x6C,0x69,0x61,0x73,0x69,0x6E,0x67,0x20,
1943 0x72,0x6F,0x67,0x72,0x61,0x6D,0x2E,0x20,0x4E,0x6F,0x74,0x20,1851 0x28,0x6E,0x6F,0x69,0x73,0x65,0x29,0x20,0x69,0x6E,0x20,0x74,
1944 0x68,0x61,0x76,0x69,0x6E,0x67,0x20,0x56,0x53,0x79,0x6E,0x63,1852 0x68,0x65,0x20,0x73,0x6F,0x75,0x6E,0x64,0x2E,0x20,0x22,0x4C,
1945 0x20,0x77,0x69,0x6C,0x6C,0x20,0x72,0x65,0x73,0x75,0x6C,0x74,1853 0x69,0x6E,0x65,0x61,0x72,0x22,0x20,0x69,0x73,0x20,0x77,0x68,
1946 0x20,0x69,0x6E,0x20,0x6C,0x65,0x73,0x73,0x20,0x69,0x6E,0x70,1854 0x61,0x74,0x20,0x72,0x65,0x61,0x6C,0x20,0x46,0x54,0x32,0x20,
1947 0x75,0x74,0x2F,0x76,0x69,0x64,0x65,0x6F,0x20,0x64,0x65,0x6C,1855 0x75,0x73,0x65,0x73,0x2C,0x20,0x77,0x68,0x69,0x63,0x68,0x20,
1948 0x61,0x79,0x2C,0x1E,0x62,0x75,0x74,0x20,0x61,0x6C,0x73,0x6F,1856 0x69,0x73,0x20,0x61,0x47,0x6D,0x65,0x64,0x69,0x6F,0x63,0x72,
1949 0x20,0x70,0x6F,0x74,0x65,0x6E,0x74,0x69,0x61,0x6C,0x20,0x73,1857 0x65,0x20,0x69,0x6E,0x74,0x65,0x72,0x70,0x6F,0x6C,0x61,0x74,
1950 0x74,0x75,0x74,0x74,0x65,0x72,0x69,0x6E,0x67,0x2E,0x00,0x15,1858 0x69,0x6F,0x6E,0x20,0x74,0x79,0x70,0x65,0x2E,0x20,0x22,0x57,
1951 0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x53,1859 0x69,0x6E,0x64,0x6F,0x77,0x65,0x64,0x2D,0x73,0x69,0x6E,0x63,
1952 0x74,0x72,0x65,0x74,0x63,0x68,0x65,0x64,0x3A,0x0B,0x3E,0x40,1860 0x22,0x20,0x69,0x73,0x20,0x74,0x68,0x65,0x20,0x72,0x65,0x63,
1953 0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x4A,0x4D,0x61,1861 0x6F,0x6D,0x6D,0x65,0x6E,0x64,0x65,0x64,0x20,0x73,0x65,0x74,
1954 0x6B,0x65,0x73,0x20,0x66,0x75,0x6C,0x6C,0x73,0x63,0x72,0x65,1862 0x74,0x69,0x6E,0x67,0x48,0x66,0x6F,0x72,0x20,0x74,0x68,0x65,
1955 0x65,0x6E,0x20,0x6D,0x6F,0x64,0x65,0x20,0x63,0x6F,0x6D,0x70,1863 0x20,0x62,0x65,0x73,0x74,0x20,0x61,0x75,0x64,0x69,0x6F,0x20,
1956 0x6C,0x65,0x74,0x65,0x6C,0x79,0x20,0x73,0x74,0x72,0x65,0x74,1864 0x71,0x75,0x61,0x6C,0x69,0x74,0x79,0x2C,0x20,0x61,0x6C,0x74,
1957 0x63,0x68,0x20,0x6F,0x75,0x74,0x20,0x74,0x68,0x65,0x20,0x69,1865 0x68,0x6F,0x75,0x67,0x68,0x20,0x69,0x74,0x20,0x6D,0x61,0x79,
1958 0x6D,0x61,0x67,0x65,0x2E,0x20,0x54,0x68,0x69,0x73,0x20,0x63,1866 0x20,0x73,0x6F,0x6D,0x65,0x74,0x69,0x6D,0x65,0x73,0x20,0x73,
1959 0x61,0x6E,0x20,0x72,0x65,0x73,0x75,0x6C,0x74,0x20,0x69,0x6E,1867 0x6F,0x75,0x6E,0x64,0x20,0x74,0x6F,0x6F,0x20,0x66,0x69,0x6C,
1960 0x4E,0x61,0x6C,0x69,0x61,0x73,0x69,0x6E,0x67,0x20,0x28,0x75,1868 0x74,0x65,0x72,0x65,0x64,0x2A,0x6F,0x6E,0x20,0x6C,0x6F,0x77,
1961 0x6E,0x65,0x76,0x65,0x6E,0x20,0x70,0x69,0x78,0x65,0x6C,0x20,1869 0x2D,0x71,0x75,0x61,0x6C,0x69,0x74,0x79,0x20,0x73,0x61,0x6D,
1962 0x77,0x69,0x64,0x74,0x68,0x73,0x29,0x20,0x69,0x66,0x20,0x74,1870 0x70,0x6C,0x65,0x73,0x20,0x28,0x66,0x2E,0x65,0x78,0x2E,0x20,
1963 0x68,0x65,0x20,0x61,0x73,0x70,0x65,0x63,0x74,0x20,0x72,0x61,1871 0x41,0x6D,0x69,0x67,0x61,0x20,0x4D,0x4F,0x44,0x73,0x29,0x2E,
1964 0x74,0x69,0x6F,0x20,0x6F,0x66,0x20,0x74,0x68,0x65,0x20,0x73,1872 0x00,0x1A,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,
1965 0x63,0x72,0x65,0x65,0x6E,0x20,0x69,0x73,0x20,0x6E,0x6F,0x74,1873 0x31,0x56,0x6F,0x6C,0x75,0x6D,0x65,0x20,0x72,0x61,0x6D,0x70,
1966 0x20,0x31,0x36,0x3A,0x31,0x30,0x2E,0x52,0x54,0x68,0x65,0x20,1874 0x69,0x6E,0x67,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,
1967 0x22,0x50,0x69,0x78,0x65,0x6C,0x20,0x66,0x69,0x6C,0x74,0x65,1875 0x43,0x30,0x30,0x32,0x3B,0x45,0x6E,0x61,0x62,0x6C,0x65,0x73,
1968 0x72,0x22,0x20,0x73,0x65,0x74,0x74,0x69,0x6E,0x67,0x20,0x63,1876 0x20,0x74,0x68,0x65,0x20,0x61,0x6E,0x74,0x69,0x2D,0x63,0x6C,
1969 0x61,0x6E,0x20,0x68,0x65,0x6C,0x70,0x20,0x77,0x69,0x74,0x68,1877 0x69,0x63,0x6B,0x20,0x73,0x79,0x73,0x74,0x65,0x6D,0x20,0x69,
1970 0x20,0x74,0x68,0x69,0x73,0x2C,0x20,0x62,0x75,0x74,0x20,0x69,1878 0x6E,0x20,0x74,0x68,0x65,0x20,0x61,0x75,0x64,0x69,0x6F,0x20,
1971 0x74,0x20,0x6D,0x61,0x6B,0x65,0x73,0x20,0x74,0x68,0x65,0x20,1879 0x6D,0x69,0x78,0x65,0x72,0x20,0x28,0x46,0x54,0x32,0x2E,0x30,
1972 0x69,0x6D,0x61,0x67,0x65,0x20,0x6C,0x6F,0x6F,0x6B,0x20,0x62,1880 0x38,0x2B,0x29,0x2E,0x3B,0x50,0x6C,0x65,0x61,0x73,0x65,0x20,
1973 0x6C,0x75,0x72,0x72,0x79,0x2E,0x01,0x20,0x18,0x3E,0x40,0x58,1881 0x6E,0x6F,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x6F,0x72,
1974 0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x50,0x69,0x78,0x65,1882 0x69,0x67,0x69,0x6E,0x61,0x6C,0x20,0x46,0x54,0x32,0x20,0x63,
1975 0x6C,0x20,0x66,0x69,0x6C,0x74,0x65,0x72,0x3A,0x0B,0x3E,0x40,1883 0x61,0x6E,0x27,0x74,0x20,0x6C,0x6F,0x61,0x64,0x20,0x74,0x68,
1976 0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x52,0x41,0x70,1884 0x69,0x73,0x20,0x63,0x6F,0x6E,0x66,0x69,0x67,0x20,0x65,0x6E,
1977 0x70,0x6C,0x69,0x65,0x73,0x20,0x61,0x6E,0x20,0x61,0x6E,0x74,1885 0x74,0x72,0x79,0x2C,0x0B,0x63,0x6C,0x6F,0x6E,0x65,0x20,0x6F,
1978 0x69,0x2D,0x61,0x6C,0x69,0x61,0x73,0x69,0x6E,0x67,0x20,0x73,1886 0x6E,0x6C,0x79,0x2E,0x00,0x19,0x3E,0x40,0x58,0x30,0x34,0x30,
1979 0x75,0x62,0x70,0x69,0x78,0x65,0x6C,0x20,0x66,0x69,0x6C,0x74,1887 0x40,0x43,0x30,0x30,0x31,0x41,0x6D,0x70,0x6C,0x69,0x66,0x69,
1980 0x65,0x72,0x20,0x74,0x68,0x61,0x74,0x20,0x69,0x73,0x20,0x75,1888 0x63,0x61,0x74,0x69,0x6F,0x6E,0x3A,0x0B,0x3E,0x40,0x58,0x30,
1981 0x73,0x65,0x64,0x20,0x77,0x68,0x65,0x6E,0x20,0x74,0x68,0x65,1889 0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x46,0x41,0x6D,0x70,0x6C,
1982 0x20,0x77,0x69,0x6E,0x64,0x6F,0x77,0x20,0x69,0x73,0x20,0x75,1890 0x69,0x66,0x69,0x65,0x73,0x20,0x74,0x68,0x65,0x20,0x76,0x6F,
1983 0x70,0x73,0x63,0x61,0x6C,0x65,0x64,0x2E,0x3B,0x50,0x6C,0x65,1891 0x6C,0x75,0x6D,0x65,0x20,0x77,0x68,0x65,0x6E,0x20,0x6D,0x69,
1984 0x61,0x73,0x65,0x20,0x6B,0x65,0x65,0x70,0x20,0x69,0x6E,0x20,1892 0x78,0x69,0x6E,0x67,0x2E,0x20,0x49,0x66,0x20,0x79,0x6F,0x75,
1985 0x6D,0x69,0x6E,0x64,0x20,0x74,0x68,0x61,0x74,0x20,0x74,0x68,1893 0x20,0x73,0x65,0x74,0x20,0x74,0x68,0x69,0x73,0x20,0x6F,0x6E,
1986 0x69,0x73,0x20,0x77,0x69,0x6C,0x6C,0x20,0x6D,0x61,0x6B,0x65,1894 0x65,0x20,0x74,0x6F,0x6F,0x20,0x68,0x69,0x67,0x68,0x2C,0x20,
1987 0x20,0x70,0x69,0x78,0x65,0x6C,0x73,0x20,0x6C,0x6F,0x6F,0x6B,1895 0x79,0x6F,0x75,0x27,0x6C,0x6C,0x3A,0x67,0x65,0x74,0x20,0x64,
1988 0x20,0x62,0x6C,0x75,0x72,0x72,0x79,0x2E,0x00,0x23,0x40,0x58,1896 0x69,0x73,0x74,0x6F,0x72,0x74,0x69,0x6F,0x6E,0x2E,0x20,0x33,
1989 0x30,0x32,0x30,0x40,0x43,0x30,0x30,0x31,0x41,0x64,0x76,0x61,1897 0x32,0x58,0x20,0x65,0x71,0x75,0x61,0x6C,0x73,0x20,0x66,0x75,
1990 0x6E,0x63,0x65,0x64,0x20,0x65,0x64,0x69,0x74,0x20,0x66,0x75,1898 0x6C,0x6C,0x20,0x61,0x6D,0x70,0x6C,0x69,0x74,0x75,0x64,0x65,
1991 0x6E,0x63,0x74,0x69,0x6F,0x6E,0x73,0x3A,0x20,0x01,0x3E,0x1E,1899 0x20,0x66,0x6F,0x72,0x20,0x6F,0x6E,0x65,0x20,0x63,0x68,0x61,
1992 0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x43,1900 0x6E,0x6E,0x65,0x6C,0x2E,0x00,0x1B,0x3E,0x40,0x58,0x30,0x34,
1993 0x6F,0x70,0x79,0x2F,0x50,0x61,0x73,0x74,0x65,0x20,0x6D,0x61,1901 0x30,0x40,0x43,0x30,0x30,0x31,0x46,0x72,0x65,0x71,0x75,0x65,
1994 0x73,0x6B,0x69,0x6E,0x67,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,1902 0x6E,0x63,0x79,0x20,0x74,0x61,0x62,0x6C,0x65,0x3A,0x0B,0x3E,
1995 0x30,0x40,0x43,0x30,0x30,0x32,0x37,0x54,0x68,0x65,0x20,0x6D,1903 0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x40,0x54,
1996 0x61,0x73,0x6B,0x69,0x6E,0x67,0x20,0x69,0x73,0x20,0x75,0x73,1904 0x68,0x65,0x20,0x6C,0x69,0x6E,0x65,0x61,0x72,0x20,0x66,0x72,
1997 0x65,0x64,0x20,0x66,0x6F,0x72,0x20,0x63,0x6F,0x70,0x79,0x69,1905 0x65,0x71,0x75,0x65,0x6E,0x63,0x79,0x20,0x74,0x61,0x62,0x6C,
1998 0x6E,0x67,0x2F,0x70,0x61,0x73,0x74,0x69,0x6E,0x67,0x20,0x6F,1906 0x65,0x20,0x6D,0x61,0x6B,0x65,0x73,0x20,0x61,0x6C,0x6C,0x20,
1999 0x6E,0x6C,0x79,0x20,0x70,0x61,0x72,0x74,0x73,0x20,0x6F,0x66,1907 0x70,0x69,0x74,0x63,0x68,0x20,0x62,0x65,0x6E,0x64,0x73,0x20,
2000 0x20,0x61,0x46,0x22,0x6E,0x6F,0x74,0x65,0x2D,0x63,0x65,0x6C,1908 0x72,0x75,0x6E,0x20,0x69,0x6E,0x20,0x63,0x6F,0x6E,0x73,0x74,
2001 0x6C,0x22,0x2E,0x20,0x54,0x68,0x65,0x20,0x64,0x69,0x66,0x66,1909 0x61,0x6E,0x74,0x3F,0x73,0x70,0x65,0x65,0x64,0x2C,0x20,0x69,
2002 0x65,0x72,0x65,0x6E,0x74,0x20,0x70,0x61,0x72,0x74,0x73,0x20,1910 0x6E,0x64,0x65,0x70,0x65,0x6E,0x64,0x65,0x6E,0x74,0x20,0x6F,
2003 0x6F,0x66,0x20,0x61,0x20,0x22,0x6E,0x6F,0x74,0x65,0x2D,0x63,1911 0x66,0x20,0x74,0x68,0x65,0x20,0x63,0x75,0x72,0x72,0x65,0x6E,
2004 0x65,0x6C,0x6C,0x22,0x20,0x69,0x73,0x20,0x4E,0x6F,0x74,0x65,1912 0x74,0x20,0x66,0x72,0x65,0x71,0x75,0x65,0x6E,0x63,0x79,0x2E,
2005 0x2C,0x20,0x49,0x6E,0x73,0x74,0x72,0x2E,0x20,0x6E,0x72,0x2E,1913 0x20,0x49,0x66,0x20,0x79,0x6F,0x75,0x20,0x73,0x77,0x69,0x74,
2006 0x2C,0x20,0x56,0x6F,0x6C,0x75,0x6D,0x65,0x2C,0x20,0x45,0x66,1914 0x63,0x68,0x20,0x74,0x68,0x69,0x73,0x41,0x6F,0x6E,0x65,0x2C,
2007 0x66,0x65,0x63,0x74,0x20,0x6E,0x72,0x20,0x26,0x20,0x45,0x66,1915 0x20,0x6F,0x6E,0x20,0x61,0x20,0x66,0x69,0x6E,0x69,0x73,0x68,
2008 0x66,0x65,0x63,0x74,0x20,0x64,0x61,0x74,0x61,0x2E,0x34,0x3E,1916 0x65,0x64,0x20,0x73,0x6F,0x6E,0x67,0x2C,0x20,0x69,0x74,0x20,
2009 0x41,0x73,0x20,0x79,0x6F,0x75,0x20,0x63,0x61,0x6E,0x20,0x73,1917 0x6D,0x69,0x67,0x68,0x74,0x20,0x73,0x6F,0x75,0x6E,0x64,0x20,
2010 0x65,0x65,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x77,0x69,1918 0x73,0x74,0x72,0x61,0x6E,0x67,0x65,0x20,0x69,0x66,0x20,0x74,
2011 0x6E,0x64,0x6F,0x77,0x20,0x74,0x68,0x65,0x72,0x65,0x20,0x61,1919 0x68,0x65,0x20,0x73,0x6F,0x75,0x6E,0x64,0x20,0x75,0x73,0x65,
2012 0x72,0x65,0x20,0x33,0x20,0x63,0x6F,0x6C,0x75,0x6D,0x6E,0x73,1920 0x73,0x0D,0x70,0x6F,0x72,0x74,0x61,0x6D,0x65,0x6E,0x74,0x6F,
2013 0x20,0x6F,0x66,0x3D,0x22,0x65,0x6E,0x61,0x62,0x6C,0x65,0x2F,1921 0x65,0x73,0x2E,0x00,0x20,0x40,0x58,0x30,0x32,0x30,0x40,0x43,
2014 0x64,0x69,0x73,0x61,0x62,0x6C,0x65,0x20,0x62,0x75,0x74,0x74,1922 0x30,0x30,0x31,0x43,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,
2015 0x6F,0x6E,0x73,0x22,0x20,0x77,0x68,0x69,0x63,0x68,0x20,0x68,1923 0x74,0x69,0x6F,0x6E,0x2C,0x20,0x4C,0x61,0x79,0x6F,0x75,0x74,
2016 0x61,0x73,0x20,0x74,0x68,0x65,0x20,0x6C,0x65,0x74,0x74,0x65,1924 0x3A,0x01,0x3E,0x29,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,
2017 0x72,0x73,0x20,0x43,0x2C,0x50,0x20,0x26,0x20,0x54,0x20,0x61,1925 0x30,0x30,0x31,0x50,0x61,0x74,0x74,0x65,0x72,0x6E,0x20,0x6C,
2018 0x62,0x6F,0x76,0x65,0x2E,0x45,0x3E,0x43,0x20,0x6D,0x65,0x61,1926 0x61,0x79,0x6F,0x75,0x74,0x2C,0x20,0x68,0x65,0x78,0x20,0x6E,
2019 0x6E,0x73,0x20,0x63,0x6F,0x70,0x79,0x2C,0x20,0x69,0x74,0x20,1927 0x75,0x6D,0x62,0x65,0x72,0x69,0x6E,0x67,0x3A,0x0B,0x3E,0x40,
2020 0x63,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x73,0x20,0x77,0x68,0x69,1928 0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x41,0x49,0x66,
2021 0x63,0x68,0x20,0x70,0x61,0x72,0x74,0x73,0x20,0x74,0x68,0x61,1929 0x20,0x79,0x6F,0x75,0x20,0x75,0x73,0x65,0x20,0x70,0x61,0x74,
2022 0x74,0x20,0x67,0x6F,0x65,0x73,0x20,0x69,0x6E,0x74,0x6F,0x20,1930 0x74,0x65,0x72,0x6E,0x73,0x20,0x74,0x68,0x61,0x74,0x20,0x61,
2023 0x74,0x68,0x65,0x20,0x63,0x6F,0x70,0x79,0x62,0x75,0x66,0x66,1931 0x72,0x65,0x20,0x6C,0x6F,0x6E,0x67,0x65,0x72,0x20,0x74,0x68,
2024 0x65,0x72,0x2E,0x3E,0x3E,0x50,0x20,0x6D,0x65,0x61,0x6E,0x73,1932 0x61,0x6E,0x20,0x39,0x39,0x20,0x6C,0x69,0x6E,0x65,0x73,0x2C,
2025 0x20,0x70,0x61,0x73,0x74,0x65,0x20,0x61,0x6E,0x64,0x20,0x63,1933 0x20,0x79,0x6F,0x75,0x20,0x73,0x68,0x6F,0x75,0x6C,0x64,0x20,
2026 0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x73,0x20,0x77,0x68,0x69,0x63,1934 0x75,0x73,0x65,0x45,0x68,0x65,0x78,0x20,0x63,0x6F,0x75,0x6E,
2027 0x68,0x20,0x70,0x61,0x72,0x74,0x73,0x20,0x74,0x68,0x61,0x74,1935 0x74,0x69,0x6E,0x67,0x20,0x73,0x69,0x6E,0x63,0x65,0x20,0x74,
2028 0x20,0x67,0x6F,0x65,0x73,0x20,0x6F,0x75,0x74,0x20,0x66,0x72,1936 0x68,0x65,0x72,0x65,0x20,0x61,0x72,0x65,0x20,0x6F,0x6E,0x6C,
2029 0x6F,0x6D,0x20,0x74,0x68,0x65,0x0B,0x63,0x6F,0x70,0x79,0x62,1937 0x79,0x20,0x32,0x20,0x64,0x69,0x67,0x69,0x74,0x73,0x20,0x69,
2030 0x75,0x66,0x66,0x65,0x72,0x2E,0x45,0x3E,0x54,0x20,0x6D,0x65,1938 0x6E,0x20,0x74,0x68,0x65,0x20,0x6C,0x69,0x6E,0x65,0x20,0x6E,
2031 0x61,0x6E,0x73,0x20,0x74,0x72,0x61,0x6E,0x73,0x70,0x61,0x72,1939 0x75,0x6D,0x62,0x65,0x72,0x20,0x63,0x6F,0x6C,0x75,0x6D,0x6E,
2032 0x65,0x6E,0x63,0x79,0x2E,0x20,0x49,0x66,0x20,0x69,0x74,0x27,1940 0x2E,0x00,0x12,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,
2033 0x73,0x20,0x65,0x6E,0x61,0x62,0x6C,0x65,0x64,0x2C,0x20,0x74,1941 0x30,0x31,0x53,0x63,0x6F,0x70,0x65,0x73,0x3A,0x0B,0x3E,0x40,
2034 0x68,0x65,0x20,0x70,0x61,0x73,0x74,0x69,0x6E,0x67,0x20,0x64,1942 0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x43,0x22,0x53,
2035 0x6F,0x65,0x73,0x6E,0x27,0x74,0x20,0x6F,0x76,0x65,0x72,0x77,1943 0x74,0x64,0x2E,0x22,0x20,0x28,0x73,0x74,0x61,0x6E,0x64,0x61,
2036 0x72,0x69,0x74,0x65,0x3D,0x64,0x61,0x74,0x61,0x20,0x77,0x69,1944 0x72,0x64,0x29,0x20,0x77,0x69,0x6C,0x6C,0x20,0x73,0x68,0x6F,
2037 0x74,0x68,0x20,0x6E,0x69,0x6C,0x2D,0x69,0x6E,0x66,0x6F,0x72,1945 0x77,0x20,0x74,0x68,0x65,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65,
2038 0x6D,0x61,0x74,0x69,0x6F,0x6E,0x2C,0x20,0x6F,0x6E,0x6C,0x79,1946 0x20,0x70,0x6F,0x69,0x6E,0x74,0x73,0x20,0x61,0x73,0x20,0x70,
2039 0x20,0x77,0x69,0x74,0x68,0x20,0x61,0x20,0x6E,0x6F,0x74,0x65,1947 0x69,0x78,0x65,0x6C,0x73,0x20,0x28,0x6C,0x69,0x6B,0x65,0x20,
2040 0x20,0x6F,0x72,0x20,0x61,0x20,0x6E,0x75,0x6D,0x62,0x65,0x72,1948 0x46,0x54,0x32,0x29,0x2E,0x3D,0x22,0x4C,0x69,0x6E,0x65,0x64,
2041 0x20,0x3C,0x3E,0x20,0x30,0x2E,0x01,0x3E,0x40,0x3E,0x54,0x68,1949 0x22,0x20,0x77,0x69,0x6C,0x6C,0x20,0x64,0x72,0x61,0x77,0x20,
2042 0x65,0x20,0x63,0x75,0x74,0x20,0x66,0x75,0x6E,0x63,0x74,0x69,1950 0x69,0x6E,0x74,0x65,0x72,0x70,0x6F,0x6C,0x61,0x74,0x65,0x64,
2043 0x6F,0x6E,0x73,0x20,0x77,0x6F,0x72,0x6B,0x73,0x20,0x6C,0x69,1951 0x20,0x73,0x61,0x6D,0x70,0x6C,0x65,0x73,0x20,0x28,0x6C,0x69,
2044 0x6B,0x65,0x20,0x70,0x61,0x73,0x74,0x69,0x6E,0x67,0x20,0x77,1952 0x6E,0x65,0x61,0x72,0x20,0x69,0x6E,0x74,0x65,0x72,0x70,0x6F,
2045 0x69,0x74,0x68,0x20,0x7A,0x65,0x72,0x6F,0x2D,0x64,0x61,0x74,1953 0x6C,0x61,0x74,0x69,0x6F,0x6E,0x2E,0x00,0x27,0x40,0x58,0x30,
2046 0x61,0x2E,0x20,0x54,0x68,0x69,0x73,0x20,0x6D,0x65,0x61,0x6E,1954 0x32,0x30,0x40,0x43,0x30,0x30,0x31,0x43,0x6F,0x6E,0x66,0x69,
2047 0x73,0x3B,0x74,0x68,0x61,0x74,0x20,0x74,0x68,0x65,0x20,0x63,1955 0x67,0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,0x2C,0x20,0x4D,0x69,
2048 0x75,0x74,0x74,0x69,0x6E,0x67,0x20,0x69,0x73,0x20,0x63,0x6F,1956 0x73,0x63,0x65,0x6C,0x6C,0x61,0x6E,0x65,0x6F,0x75,0x73,0x3A,
2049 0x6E,0x74,0x72,0x6F,0x6C,0x6C,0x65,0x64,0x20,0x77,0x69,0x74,1957 0x01,0x3E,0x15,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,
2050 0x68,0x20,0x50,0x2D,0x63,0x6F,0x6C,0x75,0x6D,0x6E,0x20,0x28,1958 0x30,0x31,0x56,0x53,0x79,0x6E,0x63,0x20,0x6F,0x66,0x66,0x3A,
2051 0x6F,0x72,0x20,0x54,0x2D,0x63,0x6F,0x6C,0x75,0x6D,0x6E,0x29,1959 0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,
2052 0x2E,0x3C,0x3E,0x57,0x68,0x65,0x6E,0x20,0x79,0x6F,0x75,0x20,1960 0x3F,0x54,0x65,0x6C,0x6C,0x73,0x20,0x74,0x68,0x65,0x20,0x70,
2053 0x63,0x6F,0x70,0x79,0x20,0x64,0x61,0x74,0x61,0x20,0x77,0x69,1961 0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x74,0x6F,0x20,0x6E,0x6F,
2054 0x74,0x68,0x20,0x6D,0x61,0x73,0x6B,0x69,0x6E,0x67,0x2C,0x20,1962 0x74,0x20,0x75,0x73,0x65,0x20,0x56,0x53,0x79,0x6E,0x63,0x20,
2055 0x74,0x68,0x65,0x20,0x64,0x69,0x73,0x61,0x62,0x6C,0x65,0x64,1963 0x66,0x6F,0x72,0x20,0x76,0x69,0x64,0x65,0x6F,0x2E,0x20,0x49,
2056 0x20,0x70,0x61,0x72,0x74,0x73,0x20,0x61,0x72,0x65,0x20,0x6E,1964 0x66,0x20,0x79,0x6F,0x75,0x72,0x20,0x6D,0x6F,0x6E,0x69,0x74,
2057 0x6F,0x74,0x43,0x63,0x6C,0x65,0x61,0x72,0x65,0x64,0x20,0x69,1965 0x6F,0x72,0x27,0x73,0x40,0x72,0x65,0x66,0x72,0x65,0x73,0x68,
2058 0x6E,0x20,0x74,0x68,0x65,0x20,0x63,0x6F,0x70,0x79,0x62,0x75,1966 0x20,0x72,0x61,0x74,0x65,0x20,0x69,0x73,0x20,0x6E,0x6F,0x74,
2059 0x66,0x66,0x65,0x72,0x2E,0x20,0x28,0x4D,0x61,0x6B,0x69,0x6E,1967 0x20,0x36,0x30,0x48,0x7A,0x20,0x28,0x6F,0x72,0x20,0x35,0x39,
2060 0x67,0x20,0x69,0x74,0x20,0x70,0x6F,0x73,0x73,0x69,0x62,0x6C,1968 0x48,0x7A,0x29,0x2C,0x20,0x74,0x68,0x65,0x6E,0x20,0x56,0x53,
2061 0x65,0x20,0x74,0x6F,0x20,0x63,0x6F,0x6C,0x6C,0x65,0x63,0x74,1969 0x79,0x6E,0x63,0x20,0x69,0x73,0x20,0x61,0x6C,0x77,0x61,0x79,
2062 0x20,0x64,0x61,0x74,0x61,0x20,0x66,0x72,0x6F,0x6D,0x27,0x73,1970 0x73,0x20,0x6F,0x66,0x66,0x20,0x66,0x6F,0x72,0x45,0x74,0x68,
2063 0x65,0x76,0x65,0x72,0x61,0x6C,0x20,0x6C,0x6F,0x63,0x61,0x74,1971 0x69,0x73,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x2E,0x20,
2064 0x69,0x6F,0x6E,0x73,0x20,0x69,0x6E,0x74,0x6F,0x20,0x74,0x68,1972 0x4E,0x6F,0x74,0x20,0x68,0x61,0x76,0x69,0x6E,0x67,0x20,0x56,
2065 0x65,0x20,0x63,0x6F,0x70,0x79,0x62,0x75,0x66,0x66,0x65,0x72,1973 0x53,0x79,0x6E,0x63,0x20,0x77,0x69,0x6C,0x6C,0x20,0x72,0x65,
2066 0x2E,0x29,0x00,0x03,0x45,0x4E,0x44,0x4C,0x3B,0x2A,0x2A,0x2A,1974 0x73,0x75,0x6C,0x74,0x20,0x69,0x6E,0x20,0x6C,0x65,0x73,0x73,
2067 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,1975 0x20,0x69,0x6E,0x70,0x75,0x74,0x2F,0x76,0x69,0x64,0x65,0x6F,
2068 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,1976 0x20,0x64,0x65,0x6C,0x61,0x79,0x2C,0x1E,0x62,0x75,0x74,0x20,
2069 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,1977 0x61,0x6C,0x73,0x6F,0x20,0x70,0x6F,0x74,0x65,0x6E,0x74,0x69,
2070 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,1978 0x61,0x6C,0x20,0x73,0x74,0x75,0x74,0x74,0x65,0x72,0x69,0x6E,
2071 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,1979 0x67,0x2E,0x00,0x15,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,
2072 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,1980 0x30,0x30,0x31,0x53,0x74,0x72,0x65,0x74,0x63,0x68,0x65,0x64,
2073 0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,1981 0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,
2074 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,1982 0x32,0x4A,0x4D,0x61,0x6B,0x65,0x73,0x20,0x66,0x75,0x6C,0x6C,
2075 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,1983 0x73,0x63,0x72,0x65,0x65,0x6E,0x20,0x6D,0x6F,0x64,0x65,0x20,
2076 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,1984 0x63,0x6F,0x6D,0x70,0x6C,0x65,0x74,0x65,0x6C,0x79,0x20,0x73,
2077 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,1985 0x74,0x72,0x65,0x74,0x63,0x68,0x20,0x6F,0x75,0x74,0x20,0x74,
2078 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,1986 0x68,0x65,0x20,0x69,0x6D,0x61,0x67,0x65,0x2E,0x20,0x54,0x68,
2079 0x2A,0x2A,0x2A,0x2A,0x2A,0x0E,0x40,0x4C,0x50,0x72,0x6F,0x62,1987 0x69,0x73,0x20,0x63,0x61,0x6E,0x20,0x72,0x65,0x73,0x75,0x6C,
2080 0x6C,0x65,0x6D,0x73,0x2F,0x46,0x41,0x51,0x06,0x3E,0x40,0x58,1988 0x74,0x20,0x69,0x6E,0x4E,0x61,0x6C,0x69,0x61,0x73,0x69,0x6E,
2081 0x30,0x32,0x30,0x2A,0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,1989 0x67,0x20,0x28,0x75,0x6E,0x65,0x76,0x65,0x6E,0x20,0x70,0x69,
2082 0x20,0x48,0x6F,0x77,0x20,0x63,0x61,0x6E,0x20,0x49,0x20,0x74,1990 0x78,0x65,0x6C,0x20,0x77,0x69,0x64,0x74,0x68,0x73,0x29,0x20,
2083 0x6F,0x67,0x67,0x6C,0x65,0x20,0x66,0x75,0x6C,0x6C,0x73,0x63,1991 0x69,0x66,0x20,0x74,0x68,0x65,0x20,0x61,0x73,0x70,0x65,0x63,
2084 0x72,0x65,0x65,0x6E,0x20,0x6D,0x6F,0x64,0x65,0x3F,0x37,0x3E,1992 0x74,0x20,0x72,0x61,0x74,0x69,0x6F,0x20,0x6F,0x66,0x20,0x74,
2085 0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x50,0x72,0x65,0x73,1993 0x68,0x65,0x20,0x73,0x63,0x72,0x65,0x65,0x6E,0x20,0x69,0x73,
2086 0x73,0x20,0x41,0x6C,0x74,0x2B,0x45,0x6E,0x74,0x65,0x72,0x20,1994 0x20,0x6E,0x6F,0x74,0x20,0x31,0x36,0x3A,0x31,0x30,0x2E,0x52,
2087 0x28,0x43,0x74,0x72,0x6C,0x2B,0x43,0x6D,0x64,0x2B,0x46,0x20,1995 0x54,0x68,0x65,0x20,0x22,0x50,0x69,0x78,0x65,0x6C,0x20,0x66,
2088 0x61,0x6C,0x73,0x6F,0x20,0x77,0x6F,0x72,0x6B,0x73,0x20,0x6F,1996 0x69,0x6C,0x74,0x65,0x72,0x22,0x20,0x73,0x65,0x74,0x74,0x69,
2089 0x6E,0x20,0x4D,0x61,0x63,0x29,0x06,0x3E,0x40,0x58,0x30,0x32,1997 0x6E,0x67,0x20,0x63,0x61,0x6E,0x20,0x68,0x65,0x6C,0x70,0x20,
2090 0x30,0x45,0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x48,1998 0x77,0x69,0x74,0x68,0x20,0x74,0x68,0x69,0x73,0x2C,0x20,0x62,
2091 0x6F,0x77,0x20,0x63,0x61,0x6E,0x20,0x49,0x20,0x6D,0x61,0x6B,1999 0x75,0x74,0x20,0x69,0x74,0x20,0x6D,0x61,0x6B,0x65,0x73,0x20,
2092 0x65,0x20,0x66,0x75,0x6C,0x6C,0x73,0x63,0x72,0x65,0x65,0x6E,2000 0x74,0x68,0x65,0x20,0x69,0x6D,0x61,0x67,0x65,0x20,0x6C,0x6F,
2093 0x20,0x6D,0x6F,0x64,0x65,0x20,0x73,0x74,0x72,0x65,0x74,0x63,2001 0x6F,0x6B,0x20,0x62,0x6C,0x75,0x72,0x72,0x79,0x2E,0x01,0x20,
2094 0x68,0x20,0x6F,0x75,0x74,0x20,0x74,0x68,0x65,0x20,0x77,0x68,2002 0x18,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,
2095 0x6F,0x6C,0x65,0x20,0x73,0x63,0x72,0x65,0x65,0x6E,0x3F,0x37,2003 0x50,0x69,0x78,0x65,0x6C,0x20,0x66,0x69,0x6C,0x74,0x65,0x72,
2096 0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x45,0x6E,0x61,2004 0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,
2097 0x62,0x6C,0x65,0x20,0x22,0x53,0x74,0x72,0x65,0x74,0x63,0x68,2005 0x32,0x52,0x41,0x70,0x70,0x6C,0x69,0x65,0x73,0x20,0x61,0x6E,
2098 0x65,0x64,0x22,0x20,0x69,0x6E,0x20,0x43,0x6F,0x6E,0x66,0x69,2006 0x20,0x61,0x6E,0x74,0x69,0x2D,0x61,0x6C,0x69,0x61,0x73,0x69,
2099 0x67,0x20,0x2D,0x3E,0x20,0x4D,0x69,0x73,0x63,0x65,0x6C,0x6C,2007 0x6E,0x67,0x20,0x73,0x75,0x62,0x70,0x69,0x78,0x65,0x6C,0x20,
2100 0x61,0x6E,0x65,0x6F,0x75,0x73,0x2E,0x4E,0x3E,0x40,0x58,0x30,2008 0x66,0x69,0x6C,0x74,0x65,0x72,0x20,0x74,0x68,0x61,0x74,0x20,
2101 0x33,0x35,0x54,0x68,0x69,0x73,0x20,0x77,0x69,0x6C,0x6C,0x20,2009 0x69,0x73,0x20,0x75,0x73,0x65,0x64,0x20,0x77,0x68,0x65,0x6E,
2102 0x72,0x65,0x73,0x75,0x6C,0x74,0x20,0x69,0x6E,0x20,0x75,0x6E,2010 0x20,0x74,0x68,0x65,0x20,0x77,0x69,0x6E,0x64,0x6F,0x77,0x20,
2103 0x65,0x76,0x65,0x6E,0x20,0x70,0x69,0x78,0x65,0x6C,0x20,0x77,2011 0x69,0x73,0x20,0x75,0x70,0x73,0x63,0x61,0x6C,0x65,0x64,0x2E,
2104 0x69,0x64,0x74,0x68,0x73,0x2E,0x20,0x49,0x66,0x20,0x79,0x6F,2012 0x3B,0x50,0x6C,0x65,0x61,0x73,0x65,0x20,0x6B,0x65,0x65,0x70,
2105 0x75,0x20,0x77,0x61,0x6E,0x74,0x20,0x74,0x6F,0x20,0x66,0x69,2013 0x20,0x69,0x6E,0x20,0x6D,0x69,0x6E,0x64,0x20,0x74,0x68,0x61,
2106 0x78,0x20,0x74,0x68,0x69,0x73,0x2C,0x20,0x65,0x6E,0x61,0x62,2014 0x74,0x20,0x74,0x68,0x69,0x73,0x20,0x77,0x69,0x6C,0x6C,0x20,
2107 0x6C,0x65,0x3D,0x22,0x50,0x69,0x78,0x65,0x6C,0x20,0x66,0x69,2015 0x6D,0x61,0x6B,0x65,0x20,0x70,0x69,0x78,0x65,0x6C,0x73,0x20,
2108 0x6C,0x74,0x65,0x72,0x22,0x20,0x28,0x74,0x68,0x6F,0x75,0x67,2016 0x6C,0x6F,0x6F,0x6B,0x20,0x62,0x6C,0x75,0x72,0x72,0x79,0x2E,
2109 0x68,0x20,0x74,0x68,0x69,0x73,0x20,0x77,0x69,0x6C,0x6C,0x20,2017 0x00,0x23,0x40,0x58,0x30,0x32,0x30,0x40,0x43,0x30,0x30,0x31,
2110 0x6D,0x61,0x6B,0x65,0x20,0x74,0x68,0x65,0x20,0x69,0x6D,0x61,2018 0x41,0x64,0x76,0x61,0x6E,0x63,0x65,0x64,0x20,0x65,0x64,0x69,
2111 0x67,0x65,0x20,0x6C,0x6F,0x6F,0x6B,0x20,0x62,0x6C,0x75,0x72,2019 0x74,0x20,0x66,0x75,0x6E,0x63,0x74,0x69,0x6F,0x6E,0x73,0x3A,
2112 0x72,0x79,0x29,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x27,2020 0x20,0x01,0x3E,0x1E,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,
2113 0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x49,0x20,0x63,2021 0x30,0x30,0x31,0x43,0x6F,0x70,0x79,0x2F,0x50,0x61,0x73,0x74,
2114 0x61,0x6E,0x27,0x74,0x20,0x75,0x73,0x65,0x20,0x41,0x6C,0x74,2022 0x65,0x20,0x6D,0x61,0x73,0x6B,0x69,0x6E,0x67,0x3A,0x0B,0x3E,
2115 0x2B,0x46,0x34,0x20,0x61,0x6E,0x64,0x20,0x41,0x6C,0x74,0x2B,2023 0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x37,0x54,
2116 0x46,0x35,0x21,0x4E,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,2024 0x68,0x65,0x20,0x6D,0x61,0x73,0x6B,0x69,0x6E,0x67,0x20,0x69,
2117 0x20,0x57,0x69,0x6E,0x64,0x6F,0x77,0x73,0x3A,0x20,0x49,0x66,2025 0x73,0x20,0x75,0x73,0x65,0x64,0x20,0x66,0x6F,0x72,0x20,0x63,
2118 0x20,0x79,0x6F,0x75,0x20,0x68,0x61,0x76,0x65,0x20,0x47,0x65,2026 0x6F,0x70,0x79,0x69,0x6E,0x67,0x2F,0x70,0x61,0x73,0x74,0x69,
2119 0x46,0x6F,0x72,0x63,0x65,0x20,0x45,0x78,0x70,0x65,0x72,0x69,2027 0x6E,0x67,0x20,0x6F,0x6E,0x6C,0x79,0x20,0x70,0x61,0x72,0x74,
2120 0x65,0x6E,0x63,0x65,0x20,0x69,0x6E,0x73,0x74,0x61,0x6C,0x6C,2028 0x73,0x20,0x6F,0x66,0x20,0x61,0x46,0x22,0x6E,0x6F,0x74,0x65,
2121 0x65,0x64,0x2C,0x20,0x79,0x6F,0x75,0x20,0x6E,0x65,0x65,0x64,2029 0x2D,0x63,0x65,0x6C,0x6C,0x22,0x2E,0x20,0x54,0x68,0x65,0x20,
2122 0x20,0x74,0x6F,0x20,0x63,0x68,0x61,0x6E,0x67,0x65,0x2B,0x3E,2030 0x64,0x69,0x66,0x66,0x65,0x72,0x65,0x6E,0x74,0x20,0x70,0x61,
2123 0x40,0x58,0x30,0x33,0x35,0x74,0x68,0x65,0x20,0x6B,0x65,0x79,2031 0x72,0x74,0x73,0x20,0x6F,0x66,0x20,0x61,0x20,0x22,0x6E,0x6F,
2124 0x62,0x69,0x6E,0x64,0x69,0x6E,0x67,0x73,0x20,0x69,0x6E,0x20,2032 0x74,0x65,0x2D,0x63,0x65,0x6C,0x6C,0x22,0x20,0x69,0x73,0x20,
2125 0x69,0x74,0x73,0x20,0x73,0x65,0x74,0x74,0x69,0x6E,0x67,0x73,2033 0x4E,0x6F,0x74,0x65,0x2C,0x20,0x49,0x6E,0x73,0x74,0x72,0x2E,
2126 0x20,0x70,0x61,0x67,0x65,0x2E,0x57,0x3E,0x6D,0x61,0x63,0x4F,2034 0x20,0x6E,0x72,0x2E,0x2C,0x20,0x56,0x6F,0x6C,0x75,0x6D,0x65,
2127 0x53,0x2F,0x4F,0x53,0x20,0x58,0x3A,0x20,0x43,0x68,0x61,0x6E,2035 0x2C,0x20,0x45,0x66,0x66,0x65,0x63,0x74,0x20,0x6E,0x72,0x20,
2128 0x67,0x65,0x20,0x41,0x6C,0x74,0x2B,0x46,0x34,0x2F,0x41,0x6C,2036 0x26,0x20,0x45,0x66,0x66,0x65,0x63,0x74,0x20,0x64,0x61,0x74,
2129 0x74,0x2B,0x46,0x35,0x20,0x6B,0x65,0x79,0x73,0x20,0x69,0x6E,2037 0x61,0x2E,0x34,0x3E,0x41,0x73,0x20,0x79,0x6F,0x75,0x20,0x63,
2130 0x20,0x74,0x68,0x65,0x20,0x4F,0x53,0x20,0x74,0x6F,0x20,0x73,2038 0x61,0x6E,0x20,0x73,0x65,0x65,0x20,0x69,0x6E,0x20,0x74,0x68,
2131 0x6F,0x6D,0x65,0x74,0x68,0x69,0x6E,0x67,0x20,0x65,0x6C,0x73,2039 0x65,0x20,0x77,0x69,0x6E,0x64,0x6F,0x77,0x20,0x74,0x68,0x65,
2132 0x65,0x2E,0x20,0x41,0x6C,0x73,0x6F,0x20,0x66,0x6F,0x72,0x20,2040 0x72,0x65,0x20,0x61,0x72,0x65,0x20,0x33,0x20,0x63,0x6F,0x6C,
2133 0x47,0x4E,0x55,0x2F,0x4C,0x69,0x6E,0x75,0x78,0x2E,0x06,0x3E,2041 0x75,0x6D,0x6E,0x73,0x20,0x6F,0x66,0x3D,0x22,0x65,0x6E,0x61,
2134 0x40,0x58,0x30,0x32,0x30,0x2B,0x3E,0x40,0x43,0x30,0x30,0x31,2042 0x62,0x6C,0x65,0x2F,0x64,0x69,0x73,0x61,0x62,0x6C,0x65,0x20,
2135 0x51,0x3A,0x20,0x54,0x68,0x65,0x20,0x6D,0x6F,0x75,0x73,0x65,2043 0x62,0x75,0x74,0x74,0x6F,0x6E,0x73,0x22,0x20,0x77,0x68,0x69,
2136 0x20,0x63,0x75,0x72,0x73,0x6F,0x72,0x20,0x69,0x73,0x20,0x64,2044 0x63,0x68,0x20,0x68,0x61,0x73,0x20,0x74,0x68,0x65,0x20,0x6C,
2137 0x65,0x6C,0x61,0x79,0x65,0x64,0x2F,0x6C,0x61,0x67,0x67,0x79,2045 0x65,0x74,0x74,0x65,0x72,0x73,0x20,0x43,0x2C,0x50,0x20,0x26,
2138 0x21,0x44,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x4D,2046 0x20,0x54,0x20,0x61,0x62,0x6F,0x76,0x65,0x2E,0x45,0x3E,0x43,
2139 0x61,0x6B,0x65,0x20,0x73,0x75,0x72,0x65,0x20,0x22,0x53,0x6F,2047 0x20,0x6D,0x65,0x61,0x6E,0x73,0x20,0x63,0x6F,0x70,0x79,0x2C,
2140 0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x6D,0x6F,0x75,0x73,0x65,2048 0x20,0x69,0x74,0x20,0x63,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x73,
2141 0x22,0x20,0x69,0x73,0x20,0x64,0x69,0x73,0x61,0x62,0x6C,0x65,2049 0x20,0x77,0x68,0x69,0x63,0x68,0x20,0x70,0x61,0x72,0x74,0x73,
2142 0x64,0x20,0x69,0x6E,0x20,0x43,0x6F,0x6E,0x66,0x69,0x67,0x20,2050 0x20,0x74,0x68,0x61,0x74,0x20,0x67,0x6F,0x65,0x73,0x20,0x69,
2143 0x2D,0x3E,0x20,0x4C,0x61,0x79,0x6F,0x75,0x74,0x2E,0x4B,0x3E,2051 0x6E,0x74,0x6F,0x20,0x74,0x68,0x65,0x20,0x63,0x6F,0x70,0x79,
2144 0x40,0x58,0x30,0x33,0x35,0x41,0x6C,0x74,0x65,0x72,0x6E,0x61,2052 0x62,0x75,0x66,0x66,0x65,0x72,0x2E,0x3E,0x3E,0x50,0x20,0x6D,
2145 0x74,0x69,0x76,0x65,0x6C,0x79,0x2C,0x20,0x79,0x6F,0x75,0x20,2053 0x65,0x61,0x6E,0x73,0x20,0x70,0x61,0x73,0x74,0x65,0x20,0x61,
2146 0x63,0x61,0x6E,0x20,0x65,0x6E,0x61,0x62,0x6C,0x65,0x20,0x22,2054 0x6E,0x64,0x20,0x63,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x73,0x20,
2147 0x56,0x53,0x79,0x6E,0x63,0x20,0x6F,0x66,0x66,0x22,0x20,0x69,2055 0x77,0x68,0x69,0x63,0x68,0x20,0x70,0x61,0x72,0x74,0x73,0x20,
2148 0x6E,0x20,0x43,0x6F,0x6E,0x66,0x69,0x67,0x20,0x2D,0x3E,0x20,2056 0x74,0x68,0x61,0x74,0x20,0x67,0x6F,0x65,0x73,0x20,0x6F,0x75,
2149 0x4D,0x69,0x73,0x63,0x65,0x6C,0x6C,0x61,0x6E,0x65,0x6F,0x75,2057 0x74,0x20,0x66,0x72,0x6F,0x6D,0x20,0x74,0x68,0x65,0x0B,0x63,
2150 0x73,0x2E,0x46,0x3E,0x54,0x68,0x69,0x73,0x20,0x68,0x6F,0x77,2058 0x6F,0x70,0x79,0x62,0x75,0x66,0x66,0x65,0x72,0x2E,0x45,0x3E,
2151 0x65,0x76,0x65,0x72,0x2C,0x20,0x77,0x69,0x6C,0x6C,0x20,0x69,2059 0x54,0x20,0x6D,0x65,0x61,0x6E,0x73,0x20,0x74,0x72,0x61,0x6E,
2152 0x6E,0x74,0x72,0x6F,0x64,0x75,0x63,0x65,0x20,0x73,0x74,0x75,2060 0x73,0x70,0x61,0x72,0x65,0x6E,0x63,0x79,0x2E,0x20,0x49,0x66,
2153 0x74,0x74,0x65,0x72,0x69,0x6E,0x67,0x20,0x62,0x65,0x63,0x61,2061 0x20,0x69,0x74,0x27,0x73,0x20,0x65,0x6E,0x61,0x62,0x6C,0x65,
2154 0x75,0x73,0x65,0x20,0x74,0x68,0x65,0x20,0x72,0x65,0x6E,0x64,2062 0x64,0x2C,0x20,0x74,0x68,0x65,0x20,0x70,0x61,0x73,0x74,0x69,
2155 0x65,0x72,0x69,0x6E,0x67,0x20,0x72,0x61,0x74,0x65,0x20,0x69,2063 0x6E,0x67,0x20,0x64,0x6F,0x65,0x73,0x6E,0x27,0x74,0x20,0x6F,
2156 0x73,0x22,0x3E,0x6E,0x6F,0x74,0x20,0x65,0x78,0x61,0x63,0x74,2064 0x76,0x65,0x72,0x77,0x72,0x69,0x74,0x65,0x3D,0x64,0x61,0x74,
2157 0x20,0x74,0x6F,0x20,0x79,0x6F,0x75,0x72,0x20,0x6D,0x6F,0x6E,2065 0x61,0x20,0x77,0x69,0x74,0x68,0x20,0x6E,0x69,0x6C,0x2D,0x69,
2158 0x69,0x74,0x6F,0x72,0x27,0x73,0x20,0x72,0x61,0x74,0x65,0x2E,2066 0x6E,0x66,0x6F,0x72,0x6D,0x61,0x74,0x69,0x6F,0x6E,0x2C,0x20,
2159 0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x33,0x3E,0x40,0x43,0x30,2067 0x6F,0x6E,0x6C,0x79,0x20,0x77,0x69,0x74,0x68,0x20,0x61,0x20,
2160 0x30,0x31,0x51,0x3A,0x20,0x57,0x69,0x6C,0x6C,0x20,0x79,0x6F,2068 0x6E,0x6F,0x74,0x65,0x20,0x6F,0x72,0x20,0x61,0x20,0x6E,0x75,
2161 0x75,0x20,0x69,0x6D,0x70,0x6C,0x65,0x6D,0x65,0x6E,0x74,0x20,2069 0x6D,0x62,0x65,0x72,0x20,0x3C,0x3E,0x20,0x30,0x2E,0x01,0x3E,
2162 0x4D,0x49,0x44,0x49,0x20,0x6F,0x75,0x74,0x20,0x66,0x75,0x6E,2070 0x40,0x3E,0x54,0x68,0x65,0x20,0x63,0x75,0x74,0x20,0x66,0x75,
2163 0x63,0x74,0x69,0x6F,0x6E,0x61,0x6C,0x69,0x74,0x79,0x3F,0x4D,2071 0x6E,0x63,0x74,0x69,0x6F,0x6E,0x73,0x20,0x77,0x6F,0x72,0x6B,
2164 0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x4E,0x6F,0x2C,2072 0x73,0x20,0x6C,0x69,0x6B,0x65,0x20,0x70,0x61,0x73,0x74,0x69,
2165 0x20,0x73,0x6F,0x72,0x72,0x79,0x2E,0x20,0x54,0x68,0x69,0x73,2073 0x6E,0x67,0x20,0x77,0x69,0x74,0x68,0x20,0x7A,0x65,0x72,0x6F,
2166 0x20,0x69,0x73,0x20,0x76,0x65,0x72,0x79,0x20,0x64,0x69,0x66,2074 0x2D,0x64,0x61,0x74,0x61,0x2E,0x20,0x54,0x68,0x69,0x73,0x20,
2167 0x66,0x69,0x63,0x75,0x6C,0x74,0x20,0x74,0x6F,0x20,0x69,0x6D,2075 0x6D,0x65,0x61,0x6E,0x73,0x3B,0x74,0x68,0x61,0x74,0x20,0x74,
2168 0x70,0x6C,0x65,0x6D,0x65,0x6E,0x74,0x20,0x63,0x6F,0x72,0x72,2076 0x68,0x65,0x20,0x63,0x75,0x74,0x74,0x69,0x6E,0x67,0x20,0x69,
2169 0x65,0x63,0x74,0x6C,0x79,0x20,0x77,0x68,0x65,0x6E,0x20,0x68,2077 0x73,0x20,0x63,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x6C,0x65,0x64,
2170 0x61,0x76,0x69,0x6E,0x67,0x3C,0x3E,0x40,0x58,0x30,0x33,0x35,2078 0x20,0x77,0x69,0x74,0x68,0x20,0x50,0x2D,0x63,0x6F,0x6C,0x75,
2171 0x68,0x69,0x67,0x68,0x65,0x72,0x20,0x61,0x75,0x64,0x69,0x6F,2079 0x6D,0x6E,0x20,0x28,0x6F,0x72,0x20,0x54,0x2D,0x63,0x6F,0x6C,
2172 0x20,0x62,0x75,0x66,0x66,0x65,0x72,0x20,0x73,0x69,0x7A,0x65,2080 0x75,0x6D,0x6E,0x29,0x2E,0x3C,0x3E,0x57,0x68,0x65,0x6E,0x20,
2173 0x73,0x20,0x28,0x62,0x75,0x66,0x66,0x65,0x72,0x65,0x64,0x20,2081 0x79,0x6F,0x75,0x20,0x63,0x6F,0x70,0x79,0x20,0x64,0x61,0x74,
2174 0x72,0x65,0x70,0x6C,0x61,0x79,0x65,0x72,0x20,0x74,0x69,0x63,2082 0x61,0x20,0x77,0x69,0x74,0x68,0x20,0x6D,0x61,0x73,0x6B,0x69,
2175 0x6B,0x73,0x29,0x2E,0x2E,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32,2083 0x6E,0x67,0x2C,0x20,0x74,0x68,0x65,0x20,0x64,0x69,0x73,0x61,
2176 0x30,0x30,0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x57,2084 0x62,0x6C,0x65,0x64,0x20,0x70,0x61,0x72,0x74,0x73,0x20,0x61,
2177 0x68,0x65,0x72,0x65,0x20,0x69,0x73,0x20,0x74,0x68,0x65,0x20,2085 0x72,0x65,0x20,0x6E,0x6F,0x74,0x43,0x63,0x6C,0x65,0x61,0x72,
2178 0x63,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F,2086 0x65,0x64,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x63,0x6F,
2179 0x6E,0x20,0x66,0x69,0x6C,0x65,0x20,0x73,0x74,0x6F,0x72,0x65,2087 0x70,0x79,0x62,0x75,0x66,0x66,0x65,0x72,0x2E,0x20,0x28,0x4D,
2180 0x64,0x3F,0x3F,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,2088 0x61,0x6B,0x69,0x6E,0x67,0x20,0x69,0x74,0x20,0x70,0x6F,0x73,
2181 0x57,0x69,0x6E,0x64,0x6F,0x77,0x73,0x3A,0x20,0x5C,0x55,0x73,2089 0x73,0x69,0x62,0x6C,0x65,0x20,0x74,0x6F,0x20,0x63,0x6F,0x6C,
2182 0x65,0x72,0x73,0x5C,0x55,0x53,0x45,0x52,0x5C,0x41,0x70,0x70,2090 0x6C,0x65,0x63,0x74,0x20,0x64,0x61,0x74,0x61,0x20,0x66,0x72,
2183 0x44,0x61,0x74,0x61,0x5C,0x52,0x6F,0x61,0x6D,0x69,0x6E,0x67,2091 0x6F,0x6D,0x27,0x73,0x65,0x76,0x65,0x72,0x61,0x6C,0x20,0x6C,
2184 0x5C,0x46,0x54,0x32,0x20,0x63,0x6C,0x6F,0x6E,0x65,0x5C,0x46,2092 0x6F,0x63,0x61,0x74,0x69,0x6F,0x6E,0x73,0x20,0x69,0x6E,0x74,
2185 0x54,0x32,0x2E,0x43,0x46,0x47,0x45,0x3E,0x40,0x58,0x30,0x33,2093 0x6F,0x20,0x74,0x68,0x65,0x20,0x63,0x6F,0x70,0x79,0x62,0x75,
2186 0x35,0x4F,0x53,0x20,0x58,0x3A,0x20,0x2F,0x55,0x73,0x65,0x72,2094 0x66,0x66,0x65,0x72,0x2E,0x29,0x00,0x03,0x45,0x4E,0x44,0x4C,
2187 0x73,0x2F,0x55,0x53,0x45,0x52,0x2F,0x4C,0x69,0x62,0x72,0x61,2095 0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2188 0x72,0x79,0x2F,0x41,0x70,0x70,0x6C,0x69,0x63,0x61,0x74,0x69,2096 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2189 0x6F,0x6E,0x20,0x53,0x75,0x70,0x70,0x6F,0x72,0x74,0x2F,0x46,2097 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2190 0x54,0x32,0x20,0x63,0x6C,0x6F,0x6E,0x65,0x2F,0x46,0x54,0x32,2098 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2191 0x2E,0x43,0x46,0x47,0x2F,0x47,0x4E,0x55,0x2F,0x4C,0x69,0x6E,2099 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2192 0x75,0x78,0x3A,0x20,0x2F,0x68,0x6F,0x6D,0x65,0x2F,0x55,0x53,2100 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2193 0x45,0x52,0x2F,0x2E,0x63,0x6F,0x6E,0x66,0x69,0x67,0x2F,0x46,2101 0x2A,0x2A,0x2A,0x2A,0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2194 0x54,0x32,0x20,0x63,0x6C,0x6F,0x6E,0x65,0x2F,0x46,0x54,0x32,2102 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2195 0x2E,0x43,0x46,0x47,0x01,0x3E,0x48,0x49,0x74,0x20,0x77,0x69,2103 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2196 0x6C,0x6C,0x20,0x62,0x65,0x20,0x73,0x74,0x6F,0x72,0x65,0x64,2104 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2197 0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x70,0x72,0x6F,0x67,2105 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2198 0x72,0x61,0x6D,0x20,0x64,0x69,0x72,0x65,0x63,0x74,0x6F,0x72,2106 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2199 0x79,0x20,0x69,0x66,0x20,0x74,0x68,0x65,0x20,0x70,0x61,0x74,2107 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x0E,0x40,0x4C,
2200 0x68,0x20,0x63,0x6F,0x75,0x6C,0x64,0x6E,0x27,0x74,0x20,0x62,2108 0x50,0x72,0x6F,0x62,0x6C,0x65,0x6D,0x73,0x2F,0x46,0x41,0x51,
2201 0x65,0x20,0x75,0x73,0x65,0x64,0x2E,0x4D,0x49,0x66,0x20,0x79,2109 0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x2A,0x3E,0x40,0x43,0x30,
2202 0x6F,0x75,0x20,0x70,0x75,0x74,0x20,0x74,0x68,0x65,0x20,0x63,2110 0x30,0x31,0x51,0x3A,0x20,0x48,0x6F,0x77,0x20,0x63,0x61,0x6E,
2203 0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,2111 0x20,0x49,0x20,0x74,0x6F,0x67,0x67,0x6C,0x65,0x20,0x66,0x75,
2204 0x20,0x66,0x69,0x6C,0x65,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,2112 0x6C,0x6C,0x73,0x63,0x72,0x65,0x65,0x6E,0x20,0x6D,0x6F,0x64,
2205 0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x64,0x69,0x72,2113 0x65,0x3F,0x37,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,
2206 0x65,0x63,0x74,0x6F,0x72,0x79,0x2C,0x20,0x69,0x74,0x20,0x77,2114 0x50,0x72,0x65,0x73,0x73,0x20,0x41,0x6C,0x74,0x2B,0x45,0x6E,
2207 0x69,0x6C,0x6C,0x20,0x72,0x65,0x61,0x64,0x20,0x74,0x68,0x61,2115 0x74,0x65,0x72,0x20,0x28,0x43,0x74,0x72,0x6C,0x2B,0x43,0x6D,
2208 0x74,0x4A,0x6F,0x6E,0x65,0x20,0x61,0x6E,0x64,0x20,0x6E,0x6F,2116 0x64,0x2B,0x46,0x20,0x61,0x6C,0x73,0x6F,0x20,0x77,0x6F,0x72,
2209 0x74,0x20,0x61,0x74,0x74,0x65,0x6D,0x70,0x74,0x20,0x74,0x6F,2117 0x6B,0x73,0x20,0x6F,0x6E,0x20,0x4D,0x61,0x63,0x29,0x06,0x3E,
2210 0x20,0x63,0x72,0x65,0x61,0x74,0x65,0x20,0x63,0x6F,0x6E,0x66,2118 0x40,0x58,0x30,0x32,0x30,0x45,0x3E,0x40,0x43,0x30,0x30,0x31,
2211 0x69,0x67,0x20,0x64,0x69,0x72,0x73,0x20,0x66,0x6F,0x72,0x20,2119 0x51,0x3A,0x20,0x48,0x6F,0x77,0x20,0x63,0x61,0x6E,0x20,0x49,
2212 0x74,0x68,0x65,0x20,0x4F,0x53,0x20,0x75,0x73,0x65,0x72,0x2E,2120 0x20,0x6D,0x61,0x6B,0x65,0x20,0x66,0x75,0x6C,0x6C,0x73,0x63,
2213 0x20,0x28,0x70,0x6F,0x72,0x74,0x61,0x62,0x6C,0x65,0x20,0x6D,2121 0x72,0x65,0x65,0x6E,0x20,0x6D,0x6F,0x64,0x65,0x20,0x73,0x74,
2214 0x6F,0x64,0x65,0x29,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x42,2122 0x72,0x65,0x74,0x63,0x68,0x20,0x6F,0x75,0x74,0x20,0x74,0x68,
2215 0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x43,0x61,0x6E,2123 0x65,0x20,0x77,0x68,0x6F,0x6C,0x65,0x20,0x73,0x63,0x72,0x65,
2216 0x20,0x74,0x68,0x65,0x20,0x63,0x6C,0x6F,0x6E,0x65,0x20,0x72,2124 0x65,0x6E,0x3F,0x37,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,
2217 0x65,0x61,0x64,0x20,0x46,0x54,0x32,0x2E,0x43,0x46,0x47,0x20,2125 0x20,0x45,0x6E,0x61,0x62,0x6C,0x65,0x20,0x22,0x53,0x74,0x72,
2218 0x66,0x72,0x6F,0x6D,0x20,0x72,0x65,0x61,0x6C,0x20,0x46,0x54,2126 0x65,0x74,0x63,0x68,0x65,0x64,0x22,0x20,0x69,0x6E,0x20,0x43,
2219 0x32,0x2C,0x20,0x61,0x6E,0x64,0x20,0x76,0x69,0x63,0x65,0x20,2127 0x6F,0x6E,0x66,0x69,0x67,0x20,0x2D,0x3E,0x20,0x4D,0x69,0x73,
2220 0x76,0x65,0x72,0x73,0x61,0x3F,0x4C,0x3E,0x40,0x43,0x30,0x30,2128 0x63,0x65,0x6C,0x6C,0x61,0x6E,0x65,0x6F,0x75,0x73,0x2E,0x4E,
2221 0x32,0x41,0x3A,0x20,0x59,0x65,0x73,0x2C,0x20,0x69,0x74,0x20,2129 0x3E,0x40,0x58,0x30,0x33,0x35,0x54,0x68,0x69,0x73,0x20,0x77,
2222 0x73,0x68,0x6F,0x75,0x6C,0x64,0x20,0x77,0x6F,0x72,0x6B,0x20,2130 0x69,0x6C,0x6C,0x20,0x72,0x65,0x73,0x75,0x6C,0x74,0x20,0x69,
2223 0x6A,0x75,0x73,0x74,0x20,0x66,0x69,0x6E,0x65,0x2E,0x20,0x50,2131 0x6E,0x20,0x75,0x6E,0x65,0x76,0x65,0x6E,0x20,0x70,0x69,0x78,
2224 0x75,0x74,0x20,0x69,0x74,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,2132 0x65,0x6C,0x20,0x77,0x69,0x64,0x74,0x68,0x73,0x2E,0x20,0x49,
2225 0x20,0x64,0x69,0x72,0x65,0x63,0x74,0x6F,0x72,0x79,0x20,0x73,2133 0x66,0x20,0x79,0x6F,0x75,0x20,0x77,0x61,0x6E,0x74,0x20,0x74,
2226 0x68,0x6F,0x77,0x6E,0x20,0x61,0x62,0x6F,0x76,0x65,0x2E,0x06,2134 0x6F,0x20,0x66,0x69,0x78,0x20,0x74,0x68,0x69,0x73,0x2C,0x20,
2227 0x3E,0x40,0x58,0x30,0x32,0x30,0x51,0x3E,0x40,0x43,0x30,0x30,2135 0x65,0x6E,0x61,0x62,0x6C,0x65,0x3D,0x22,0x50,0x69,0x78,0x65,
2228 0x31,0x51,0x3A,0x20,0x53,0x6D,0x70,0x2E,0x20,0x45,0x64,0x2E,2136 0x6C,0x20,0x66,0x69,0x6C,0x74,0x65,0x72,0x22,0x20,0x28,0x74,
2229 0x3A,0x20,0x57,0x68,0x69,0x6C,0x65,0x20,0x7A,0x6F,0x6F,0x6D,2137 0x68,0x6F,0x75,0x67,0x68,0x20,0x74,0x68,0x69,0x73,0x20,0x77,
2230 0x65,0x64,0x20,0x69,0x6E,0x2C,0x20,0x49,0x20,0x73,0x6F,0x6D,2138 0x69,0x6C,0x6C,0x20,0x6D,0x61,0x6B,0x65,0x20,0x74,0x68,0x65,
2231 0x65,0x74,0x69,0x6D,0x65,0x73,0x20,0x63,0x61,0x6E,0x27,0x74,2139 0x20,0x69,0x6D,0x61,0x67,0x65,0x20,0x6C,0x6F,0x6F,0x6B,0x20,
2232 0x20,0x6D,0x61,0x72,0x6B,0x20,0x74,0x68,0x65,0x20,0x6C,0x61,2140 0x62,0x6C,0x75,0x72,0x72,0x79,0x29,0x2E,0x06,0x3E,0x40,0x58,
2233 0x73,0x74,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65,0x20,0x70,0x6F,2141 0x30,0x32,0x30,0x27,0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,
2234 0x69,0x6E,0x74,0x21,0x47,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,2142 0x20,0x49,0x20,0x63,0x61,0x6E,0x27,0x74,0x20,0x75,0x73,0x65,
2235 0x3A,0x20,0x54,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x6E,0x6F,2143 0x20,0x41,0x6C,0x74,0x2B,0x46,0x34,0x20,0x61,0x6E,0x64,0x20,
2236 0x72,0x6D,0x61,0x6C,0x2E,0x20,0x54,0x68,0x69,0x73,0x20,0x69,2144 0x41,0x6C,0x74,0x2B,0x46,0x35,0x21,0x4E,0x3E,0x40,0x43,0x30,
2237 0x73,0x20,0x61,0x20,0x6C,0x69,0x6D,0x69,0x74,0x61,0x74,0x69,2145 0x30,0x32,0x41,0x3A,0x20,0x57,0x69,0x6E,0x64,0x6F,0x77,0x73,
2238 0x6F,0x6E,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x6E,0x61,2146 0x3A,0x20,0x49,0x66,0x20,0x79,0x6F,0x75,0x20,0x68,0x61,0x76,
2239 0x74,0x75,0x72,0x65,0x20,0x6F,0x66,0x20,0x73,0x63,0x61,0x6C,2147 0x65,0x20,0x47,0x65,0x46,0x6F,0x72,0x63,0x65,0x20,0x45,0x78,
2240 0x69,0x6E,0x67,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x17,2148 0x70,0x65,0x72,0x69,0x65,0x6E,0x63,0x65,0x20,0x69,0x6E,0x73,
2241 0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x49,0x20,0x66,2149 0x74,0x61,0x6C,0x6C,0x65,0x64,0x2C,0x20,0x79,0x6F,0x75,0x20,
2242 0x6F,0x75,0x6E,0x64,0x20,0x61,0x20,0x62,0x75,0x67,0x21,0x4C,2150 0x6E,0x65,0x65,0x64,0x20,0x74,0x6F,0x20,0x63,0x68,0x61,0x6E,
2243 0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x50,0x6C,0x65,2151 0x67,0x65,0x2B,0x3E,0x40,0x58,0x30,0x33,0x35,0x74,0x68,0x65,
2244 0x61,0x73,0x65,0x20,0x73,0x65,0x6E,0x64,0x20,0x6D,0x65,0x20,2152 0x20,0x6B,0x65,0x79,0x62,0x69,0x6E,0x64,0x69,0x6E,0x67,0x73,
2245 0x61,0x20,0x6D,0x61,0x69,0x6C,0x20,0x28,0x66,0x6F,0x75,0x6E,2153 0x20,0x69,0x6E,0x20,0x69,0x74,0x73,0x20,0x73,0x65,0x74,0x74,
2246 0x64,0x20,0x61,0x74,0x20,0x31,0x36,0x2D,0x62,0x69,0x74,0x73,2154 0x69,0x6E,0x67,0x73,0x20,0x70,0x61,0x67,0x65,0x2E,0x57,0x3E,
2247 0x2E,0x6F,0x72,0x67,0x29,0x20,0x61,0x6E,0x64,0x20,0x74,0x72,2155 0x6D,0x61,0x63,0x4F,0x53,0x2F,0x4F,0x53,0x20,0x58,0x3A,0x20,
2248 0x79,0x20,0x74,0x6F,0x20,0x65,0x78,0x70,0x6C,0x61,0x69,0x6E,2156 0x43,0x68,0x61,0x6E,0x67,0x65,0x20,0x41,0x6C,0x74,0x2B,0x46,
2249 0x20,0x69,0x74,0x2E,0x00,0x03,0x45,0x4E,0x44,0x4C,0x3B,0x2A,2157 0x34,0x2F,0x41,0x6C,0x74,0x2B,0x46,0x35,0x20,0x6B,0x65,0x79,
2250 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,2158 0x73,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x4F,0x53,0x20,
2251 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,2159 0x74,0x6F,0x20,0x73,0x6F,0x6D,0x65,0x74,0x68,0x69,0x6E,0x67,
2252 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,2160 0x20,0x65,0x6C,0x73,0x65,0x2E,0x20,0x41,0x6C,0x73,0x6F,0x20,
2253 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,2161 0x66,0x6F,0x72,0x20,0x47,0x4E,0x55,0x2F,0x4C,0x69,0x6E,0x75,
2254 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,2162 0x78,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x2B,0x3E,0x40,
2255 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,2163 0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x54,0x68,0x65,0x20,0x6D,
2256 0x2A,0x2A,0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,2164 0x6F,0x75,0x73,0x65,0x20,0x63,0x75,0x72,0x73,0x6F,0x72,0x20,
2257 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,2165 0x69,0x73,0x20,0x64,0x65,0x6C,0x61,0x79,0x65,0x64,0x2F,0x6C,
2258 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,2166 0x61,0x67,0x67,0x79,0x21,0x44,0x3E,0x40,0x43,0x30,0x30,0x32,
2259 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,2167 0x41,0x3A,0x20,0x4D,0x61,0x6B,0x65,0x20,0x73,0x75,0x72,0x65,
2260 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,2168 0x20,0x22,0x53,0x6F,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x6D,
2261 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,2169 0x6F,0x75,0x73,0x65,0x22,0x20,0x69,0x73,0x20,0x64,0x69,0x73,
2262 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x0C,0x40,0x4C,0x4B,0x6E,2170 0x61,0x62,0x6C,0x65,0x64,0x20,0x69,0x6E,0x20,0x43,0x6F,0x6E,
2263 0x6F,0x77,0x6E,0x20,0x62,0x75,0x67,0x73,0x01,0x3E,0x23,0x3E,2171 0x66,0x69,0x67,0x20,0x2D,0x3E,0x20,0x4C,0x61,0x79,0x6F,0x75,
2264 0x40,0x58,0x30,0x31,0x30,0x40,0x43,0x30,0x30,0x31,0x53,0x61,2172 0x74,0x2E,0x4B,0x3E,0x40,0x58,0x30,0x33,0x35,0x41,0x6C,0x74,
2265 0x6D,0x70,0x6C,0x65,0x20,0x72,0x65,0x63,0x6F,0x72,0x64,0x69,2173 0x65,0x72,0x6E,0x61,0x74,0x69,0x76,0x65,0x6C,0x79,0x2C,0x20,
2266 0x6E,0x67,0x20,0x6F,0x6E,0x20,0x4D,0x61,0x63,0x3A,0x01,0x3E,2174 0x79,0x6F,0x75,0x20,0x63,0x61,0x6E,0x20,0x65,0x6E,0x61,0x62,
2267 0x53,0x3E,0x40,0x58,0x30,0x31,0x30,0x40,0x43,0x30,0x30,0x32,2175 0x6C,0x65,0x20,0x22,0x56,0x53,0x79,0x6E,0x63,0x20,0x6F,0x66,
2268 0x2D,0x20,0x53,0x61,0x6D,0x70,0x6C,0x65,0x20,0x72,0x65,0x63,2176 0x66,0x22,0x20,0x69,0x6E,0x20,0x43,0x6F,0x6E,0x66,0x69,0x67,
2269 0x6F,0x72,0x64,0x69,0x6E,0x67,0x20,0x64,0x6F,0x65,0x73,0x6E,2177 0x20,0x2D,0x3E,0x20,0x4D,0x69,0x73,0x63,0x65,0x6C,0x6C,0x61,
2270 0x27,0x74,0x20,0x77,0x6F,0x72,0x6B,0x20,0x6F,0x6E,0x20,0x6D,2178 0x6E,0x65,0x6F,0x75,0x73,0x2E,0x46,0x3E,0x54,0x68,0x69,0x73,
2271 0x61,0x63,0x4F,0x53,0x20,0x4D,0x6F,0x6A,0x61,0x76,0x65,0x20,2179 0x20,0x68,0x6F,0x77,0x65,0x76,0x65,0x72,0x2C,0x20,0x77,0x69,
2272 0x61,0x6E,0x64,0x20,0x6C,0x61,0x74,0x65,0x72,0x2C,0x20,0x62,2180 0x6C,0x6C,0x20,0x69,0x6E,0x74,0x72,0x6F,0x64,0x75,0x63,0x65,
2273 0x65,0x63,0x61,0x75,0x73,0x65,0x20,0x6F,0x66,0x20,0x61,0x6E,2181 0x20,0x73,0x74,0x75,0x74,0x74,0x65,0x72,0x69,0x6E,0x67,0x20,
2274 0x56,0x3E,0x40,0x58,0x30,0x32,0x31,0x69,0x73,0x73,0x75,0x65,2182 0x62,0x65,0x63,0x61,0x75,0x73,0x65,0x20,0x74,0x68,0x65,0x20,
2275 0x20,0x69,0x6E,0x20,0x53,0x44,0x4C,0x32,0x20,0x77,0x68,0x65,2183 0x72,0x65,0x6E,0x64,0x65,0x72,0x69,0x6E,0x67,0x20,0x72,0x61,
2276 0x72,0x65,0x20,0x69,0x74,0x20,0x64,0x6F,0x65,0x73,0x6E,0x27,2184 0x74,0x65,0x20,0x69,0x73,0x22,0x3E,0x6E,0x6F,0x74,0x20,0x65,
2277 0x74,0x20,0x61,0x73,0x6B,0x20,0x66,0x6F,0x72,0x20,0x70,0x65,2185 0x78,0x61,0x63,0x74,0x20,0x74,0x6F,0x20,0x79,0x6F,0x75,0x72,
2278 0x72,0x6D,0x69,0x73,0x73,0x69,0x6F,0x6E,0x20,0x74,0x6F,0x20,2186 0x20,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x27,0x73,0x20,0x72,
2279 0x75,0x73,0x65,0x20,0x74,0x68,0x65,0x20,0x61,0x75,0x64,0x69,2187 0x61,0x74,0x65,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x33,
2280 0x6F,0x20,0x69,0x6E,0x70,0x75,0x74,0x20,0x64,0x65,0x76,0x69,2188 0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x57,0x69,0x6C,
2281 0x63,0x65,0x2E,0x01,0x3E,0x31,0x3E,0x40,0x58,0x30,0x31,0x30,2189 0x6C,0x20,0x79,0x6F,0x75,0x20,0x69,0x6D,0x70,0x6C,0x65,0x6D,
2282 0x40,0x43,0x30,0x30,0x31,0x57,0x41,0x56,0x20,0x65,0x78,0x70,2190 0x65,0x6E,0x74,0x20,0x4D,0x49,0x44,0x49,0x20,0x6F,0x75,0x74,
2283 0x6F,0x72,0x74,0x69,0x6E,0x67,0x20,0x28,0x72,0x65,0x6E,0x64,2191 0x20,0x66,0x75,0x6E,0x63,0x74,0x69,0x6F,0x6E,0x61,0x6C,0x69,
2284 0x65,0x72,0x69,0x6E,0x67,0x20,0x73,0x6F,0x6E,0x67,0x20,0x74,2192 0x74,0x79,0x3F,0x4D,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,
2285 0x6F,0x20,0x57,0x41,0x56,0x29,0x3A,0x01,0x3E,0x55,0x3E,0x40,2193 0x20,0x4E,0x6F,0x2C,0x20,0x73,0x6F,0x72,0x72,0x79,0x2E,0x20,
2286 0x58,0x30,0x31,0x30,0x40,0x43,0x30,0x30,0x32,0x2D,0x20,0x53,2194 0x54,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x76,0x65,0x72,0x79,
2287 0x6F,0x6E,0x67,0x73,0x20,0x74,0x68,0x61,0x74,0x20,0x6A,0x75,2195 0x20,0x64,0x69,0x66,0x66,0x69,0x63,0x75,0x6C,0x74,0x20,0x74,
2288 0x6D,0x70,0x20,0x62,0x61,0x63,0x6B,0x20,0x74,0x6F,0x20,0x61,2196 0x6F,0x20,0x69,0x6D,0x70,0x6C,0x65,0x6D,0x65,0x6E,0x74,0x20,
2289 0x20,0x70,0x72,0x65,0x76,0x69,0x6F,0x75,0x73,0x20,0x70,0x61,2197 0x63,0x6F,0x72,0x72,0x65,0x63,0x74,0x6C,0x79,0x20,0x77,0x68,
2290 0x74,0x74,0x65,0x72,0x6E,0x20,0x77,0x69,0x6C,0x6C,0x20,0x72,2198 0x65,0x6E,0x20,0x68,0x61,0x76,0x69,0x6E,0x67,0x3C,0x3E,0x40,
2291 0x65,0x6E,0x64,0x65,0x72,0x20,0x66,0x6F,0x72,0x65,0x76,0x65,2199 0x58,0x30,0x33,0x35,0x68,0x69,0x67,0x68,0x65,0x72,0x20,0x61,
2292 0x72,0x20,0x61,0x6E,0x64,0x20,0x65,0x76,0x65,0x72,0x2C,0x4D,2200 0x75,0x64,0x69,0x6F,0x20,0x62,0x75,0x66,0x66,0x65,0x72,0x20,
2293 0x3E,0x40,0x58,0x30,0x32,0x31,0x61,0x6E,0x64,0x20,0x79,0x6F,2201 0x73,0x69,0x7A,0x65,0x73,0x20,0x28,0x62,0x75,0x66,0x66,0x65,
2294 0x75,0x20,0x6E,0x65,0x65,0x64,0x20,0x74,0x6F,0x20,0x70,0x72,2202 0x72,0x65,0x64,0x20,0x72,0x65,0x70,0x6C,0x61,0x79,0x65,0x72,
2295 0x65,0x73,0x73,0x20,0x61,0x20,0x6B,0x65,0x79,0x20,0x6F,0x72,2203 0x20,0x74,0x69,0x63,0x6B,0x73,0x29,0x2E,0x2E,0x2E,0x06,0x3E,
2296 0x20,0x63,0x6C,0x69,0x63,0x6B,0x20,0x74,0x68,0x65,0x20,0x6D,2204 0x40,0x58,0x30,0x32,0x30,0x30,0x3E,0x40,0x43,0x30,0x30,0x31,
2297 0x6F,0x75,0x73,0x65,0x20,0x74,0x6F,0x20,0x61,0x62,0x6F,0x72,2205 0x51,0x3A,0x20,0x57,0x68,0x65,0x72,0x65,0x20,0x69,0x73,0x20,
2298 0x74,0x20,0x74,0x68,0x65,0x20,0x72,0x65,0x6E,0x64,0x65,0x72,2206 0x74,0x68,0x65,0x20,0x63,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,
2299 0x20,0x77,0x68,0x65,0x6E,0x15,0x3E,0x40,0x58,0x30,0x32,0x31,2207 0x61,0x74,0x69,0x6F,0x6E,0x20,0x66,0x69,0x6C,0x65,0x20,0x73,
2300 0x79,0x6F,0x75,0x20,0x77,0x61,0x6E,0x74,0x20,0x69,0x74,0x20,2208 0x74,0x6F,0x72,0x65,0x64,0x3F,0x3F,0x3E,0x40,0x43,0x30,0x30,
2301 0x74,0x6F,0x2E,0x01,0x3E,0x11,0x3E,0x40,0x58,0x30,0x31,0x30,2209 0x32,0x41,0x3A,0x20,0x57,0x69,0x6E,0x64,0x6F,0x77,0x73,0x3A,
2302 0x40,0x43,0x30,0x30,0x31,0x56,0x69,0x64,0x65,0x6F,0x3A,0x06,2210 0x20,0x5C,0x55,0x73,0x65,0x72,0x73,0x5C,0x55,0x53,0x45,0x52,
2303 0x3E,0x40,0x43,0x30,0x30,0x32,0x50,0x3E,0x40,0x58,0x30,0x31,2211 0x5C,0x41,0x70,0x70,0x44,0x61,0x74,0x61,0x5C,0x52,0x6F,0x61,
2304 0x30,0x2D,0x20,0x46,0x75,0x6C,0x6C,0x73,0x63,0x72,0x65,0x65,2212 0x6D,0x69,0x6E,0x67,0x5C,0x46,0x54,0x32,0x20,0x63,0x6C,0x6F,
2305 0x6E,0x20,0x6D,0x6F,0x64,0x65,0x20,0x63,0x61,0x6E,0x20,0x62,2213 0x6E,0x65,0x5C,0x46,0x54,0x32,0x2E,0x43,0x46,0x47,0x45,0x3E,
2306 0x65,0x20,0x75,0x6E,0x62,0x65,0x61,0x72,0x61,0x62,0x6C,0x79,2214 0x40,0x58,0x30,0x33,0x35,0x4F,0x53,0x20,0x58,0x3A,0x20,0x2F,
2307 0x20,0x73,0x6C,0x6F,0x77,0x20,0x6F,0x6E,0x20,0x61,0x20,0x52,2215 0x55,0x73,0x65,0x72,0x73,0x2F,0x55,0x53,0x45,0x52,0x2F,0x4C,
2308 0x61,0x73,0x70,0x62,0x65,0x72,0x72,0x79,0x20,0x50,0x69,0x20,2216 0x69,0x62,0x72,0x61,0x72,0x79,0x2F,0x41,0x70,0x70,0x6C,0x69,
2309 0x28,0x65,0x76,0x65,0x6E,0x20,0x6F,0x6E,0x20,0x52,0x50,0x69,2217 0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x75,0x70,0x70,0x6F,
2310 0x20,0x34,0x29,0x52,0x3E,0x40,0x58,0x30,0x31,0x30,0x2D,0x20,2218 0x72,0x74,0x2F,0x46,0x54,0x32,0x20,0x63,0x6C,0x6F,0x6E,0x65,
2311 0x4E,0x6F,0x74,0x20,0x61,0x20,0x62,0x75,0x67,0x2C,0x20,0x62,2219 0x2F,0x46,0x54,0x32,0x2E,0x43,0x46,0x47,0x2F,0x47,0x4E,0x55,
2312 0x75,0x74,0x20,0x69,0x66,0x20,0x79,0x6F,0x75,0x72,0x20,0x6D,2220 0x2F,0x4C,0x69,0x6E,0x75,0x78,0x3A,0x20,0x2F,0x68,0x6F,0x6D,
2313 0x6F,0x6E,0x69,0x74,0x6F,0x72,0x27,0x73,0x20,0x72,0x65,0x66,2221 0x65,0x2F,0x55,0x53,0x45,0x52,0x2F,0x2E,0x63,0x6F,0x6E,0x66,
2314 0x72,0x65,0x73,0x68,0x20,0x72,0x61,0x74,0x65,0x20,0x69,0x73,2222 0x69,0x67,0x2F,0x46,0x54,0x32,0x20,0x63,0x6C,0x6F,0x6E,0x65,
2315 0x20,0x6E,0x6F,0x74,0x20,0x73,0x65,0x74,0x20,0x74,0x6F,0x20,2223 0x2F,0x46,0x54,0x32,0x2E,0x43,0x46,0x47,0x01,0x3E,0x48,0x49,
2316 0x36,0x30,0x48,0x7A,0x20,0x28,0x6F,0x72,0x20,0x35,0x39,0x48,2224 0x74,0x20,0x77,0x69,0x6C,0x6C,0x20,0x62,0x65,0x20,0x73,0x74,
2317 0x7A,0x29,0x4A,0x3E,0x40,0x58,0x30,0x32,0x31,0x79,0x6F,0x75,2225 0x6F,0x72,0x65,0x64,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,
2318 0x20,0x6D,0x61,0x79,0x20,0x65,0x78,0x70,0x65,0x72,0x69,0x65,2226 0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x64,0x69,0x72,0x65,
2319 0x6E,0x63,0x65,0x20,0x76,0x69,0x73,0x75,0x61,0x6C,0x20,0x73,2227 0x63,0x74,0x6F,0x72,0x79,0x20,0x69,0x66,0x20,0x74,0x68,0x65,
2320 0x74,0x75,0x74,0x74,0x65,0x72,0x69,0x6E,0x67,0x20,0x62,0x65,2228 0x20,0x70,0x61,0x74,0x68,0x20,0x63,0x6F,0x75,0x6C,0x64,0x6E,
2321 0x63,0x61,0x75,0x73,0x65,0x20,0x56,0x53,0x79,0x6E,0x63,0x20,2229 0x27,0x74,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x2E,0x4D,
2322 0x77,0x69,0x6C,0x6C,0x20,0x6E,0x6F,0x74,0x20,0x62,0x65,0x20,2230 0x49,0x66,0x20,0x79,0x6F,0x75,0x20,0x70,0x75,0x74,0x20,0x74,
2323 0x75,0x73,0x65,0x64,0x2E,0x00,0x03,0x45,0x4E,0x442231 0x68,0x65,0x20,0x63,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,
2232 0x74,0x69,0x6F,0x6E,0x20,0x66,0x69,0x6C,0x65,0x20,0x69,0x6E,
2233 0x20,0x74,0x68,0x65,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,
2234 0x20,0x64,0x69,0x72,0x65,0x63,0x74,0x6F,0x72,0x79,0x2C,0x20,
2235 0x69,0x74,0x20,0x77,0x69,0x6C,0x6C,0x20,0x72,0x65,0x61,0x64,
2236 0x20,0x74,0x68,0x61,0x74,0x4A,0x6F,0x6E,0x65,0x20,0x61,0x6E,
2237 0x64,0x20,0x6E,0x6F,0x74,0x20,0x61,0x74,0x74,0x65,0x6D,0x70,
2238 0x74,0x20,0x74,0x6F,0x20,0x63,0x72,0x65,0x61,0x74,0x65,0x20,
2239 0x63,0x6F,0x6E,0x66,0x69,0x67,0x20,0x64,0x69,0x72,0x73,0x20,
2240 0x66,0x6F,0x72,0x20,0x74,0x68,0x65,0x20,0x4F,0x53,0x20,0x75,
2241 0x73,0x65,0x72,0x2E,0x20,0x28,0x70,0x6F,0x72,0x74,0x61,0x62,
2242 0x6C,0x65,0x20,0x6D,0x6F,0x64,0x65,0x29,0x06,0x3E,0x40,0x58,
2243 0x30,0x32,0x30,0x42,0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,
2244 0x20,0x43,0x61,0x6E,0x20,0x74,0x68,0x65,0x20,0x63,0x6C,0x6F,
2245 0x6E,0x65,0x20,0x72,0x65,0x61,0x64,0x20,0x46,0x54,0x32,0x2E,
2246 0x43,0x46,0x47,0x20,0x66,0x72,0x6F,0x6D,0x20,0x72,0x65,0x61,
2247 0x6C,0x20,0x46,0x54,0x32,0x2C,0x20,0x61,0x6E,0x64,0x20,0x76,
2248 0x69,0x63,0x65,0x20,0x76,0x65,0x72,0x73,0x61,0x3F,0x4C,0x3E,
2249 0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x59,0x65,0x73,0x2C,
2250 0x20,0x69,0x74,0x20,0x73,0x68,0x6F,0x75,0x6C,0x64,0x20,0x77,
2251 0x6F,0x72,0x6B,0x20,0x6A,0x75,0x73,0x74,0x20,0x66,0x69,0x6E,
2252 0x65,0x2E,0x20,0x50,0x75,0x74,0x20,0x69,0x74,0x20,0x69,0x6E,
2253 0x20,0x74,0x68,0x65,0x20,0x64,0x69,0x72,0x65,0x63,0x74,0x6F,
2254 0x72,0x79,0x20,0x73,0x68,0x6F,0x77,0x6E,0x20,0x61,0x62,0x6F,
2255 0x76,0x65,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x51,0x3E,
2256 0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x53,0x6D,0x70,0x2E,
2257 0x20,0x45,0x64,0x2E,0x3A,0x20,0x57,0x68,0x69,0x6C,0x65,0x20,
2258 0x7A,0x6F,0x6F,0x6D,0x65,0x64,0x20,0x69,0x6E,0x2C,0x20,0x49,
2259 0x20,0x73,0x6F,0x6D,0x65,0x74,0x69,0x6D,0x65,0x73,0x20,0x63,
2260 0x61,0x6E,0x27,0x74,0x20,0x6D,0x61,0x72,0x6B,0x20,0x74,0x68,
2261 0x65,0x20,0x6C,0x61,0x73,0x74,0x20,0x73,0x61,0x6D,0x70,0x6C,
2262 0x65,0x20,0x70,0x6F,0x69,0x6E,0x74,0x21,0x47,0x3E,0x40,0x43,
2263 0x30,0x30,0x32,0x41,0x3A,0x20,0x54,0x68,0x69,0x73,0x20,0x69,
2264 0x73,0x20,0x6E,0x6F,0x72,0x6D,0x61,0x6C,0x2E,0x20,0x54,0x68,
2265 0x69,0x73,0x20,0x69,0x73,0x20,0x61,0x20,0x6C,0x69,0x6D,0x69,
2266 0x74,0x61,0x74,0x69,0x6F,0x6E,0x20,0x69,0x6E,0x20,0x74,0x68,
2267 0x65,0x20,0x6E,0x61,0x74,0x75,0x72,0x65,0x20,0x6F,0x66,0x20,
2268 0x73,0x63,0x61,0x6C,0x69,0x6E,0x67,0x2E,0x06,0x3E,0x40,0x58,
2269 0x30,0x32,0x30,0x17,0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,
2270 0x20,0x49,0x20,0x66,0x6F,0x75,0x6E,0x64,0x20,0x61,0x20,0x62,
2271 0x75,0x67,0x21,0x4C,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,
2272 0x20,0x50,0x6C,0x65,0x61,0x73,0x65,0x20,0x73,0x65,0x6E,0x64,
2273 0x20,0x6D,0x65,0x20,0x61,0x20,0x6D,0x61,0x69,0x6C,0x20,0x28,
2274 0x66,0x6F,0x75,0x6E,0x64,0x20,0x61,0x74,0x20,0x31,0x36,0x2D,
2275 0x62,0x69,0x74,0x73,0x2E,0x6F,0x72,0x67,0x29,0x20,0x61,0x6E,
2276 0x64,0x20,0x74,0x72,0x79,0x20,0x74,0x6F,0x20,0x65,0x78,0x70,
2277 0x6C,0x61,0x69,0x6E,0x20,0x69,0x74,0x2E,0x00,0x03,0x45,0x4E,
2278 0x44,0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2279 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2280 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2281 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2282 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2283 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2284 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,
2285 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2286 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2287 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2288 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2289 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
2290 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x0C,
2291 0x40,0x4C,0x4B,0x6E,0x6F,0x77,0x6E,0x20,0x62,0x75,0x67,0x73,
2292 0x01,0x3E,0x31,0x3E,0x40,0x58,0x30,0x31,0x30,0x40,0x43,0x30,
2293 0x30,0x31,0x57,0x41,0x56,0x20,0x65,0x78,0x70,0x6F,0x72,0x74,
2294 0x69,0x6E,0x67,0x20,0x28,0x72,0x65,0x6E,0x64,0x65,0x72,0x69,
2295 0x6E,0x67,0x20,0x73,0x6F,0x6E,0x67,0x20,0x74,0x6F,0x20,0x57,
2296 0x41,0x56,0x29,0x3A,0x01,0x3E,0x55,0x3E,0x40,0x58,0x30,0x31,
2297 0x30,0x40,0x43,0x30,0x30,0x32,0x2D,0x20,0x53,0x6F,0x6E,0x67,
2298 0x73,0x20,0x74,0x68,0x61,0x74,0x20,0x6A,0x75,0x6D,0x70,0x20,
2299 0x62,0x61,0x63,0x6B,0x20,0x74,0x6F,0x20,0x61,0x20,0x70,0x72,
2300 0x65,0x76,0x69,0x6F,0x75,0x73,0x20,0x70,0x61,0x74,0x74,0x65,
2301 0x72,0x6E,0x20,0x77,0x69,0x6C,0x6C,0x20,0x72,0x65,0x6E,0x64,
2302 0x65,0x72,0x20,0x66,0x6F,0x72,0x65,0x76,0x65,0x72,0x20,0x61,
2303 0x6E,0x64,0x20,0x65,0x76,0x65,0x72,0x2C,0x4D,0x3E,0x40,0x58,
2304 0x30,0x32,0x31,0x61,0x6E,0x64,0x20,0x79,0x6F,0x75,0x20,0x6E,
2305 0x65,0x65,0x64,0x20,0x74,0x6F,0x20,0x70,0x72,0x65,0x73,0x73,
2306 0x20,0x61,0x20,0x6B,0x65,0x79,0x20,0x6F,0x72,0x20,0x63,0x6C,
2307 0x69,0x63,0x6B,0x20,0x74,0x68,0x65,0x20,0x6D,0x6F,0x75,0x73,
2308 0x65,0x20,0x74,0x6F,0x20,0x61,0x62,0x6F,0x72,0x74,0x20,0x74,
2309 0x68,0x65,0x20,0x72,0x65,0x6E,0x64,0x65,0x72,0x20,0x77,0x68,
2310 0x65,0x6E,0x15,0x3E,0x40,0x58,0x30,0x32,0x31,0x79,0x6F,0x75,
2311 0x20,0x77,0x61,0x6E,0x74,0x20,0x69,0x74,0x20,0x74,0x6F,0x2E,
2312 0x01,0x3E,0x11,0x3E,0x40,0x58,0x30,0x31,0x30,0x40,0x43,0x30,
2313 0x30,0x31,0x56,0x69,0x64,0x65,0x6F,0x3A,0x06,0x3E,0x40,0x43,
2314 0x30,0x30,0x32,0x50,0x3E,0x40,0x58,0x30,0x31,0x30,0x2D,0x20,
2315 0x46,0x75,0x6C,0x6C,0x73,0x63,0x72,0x65,0x65,0x6E,0x20,0x6D,
2316 0x6F,0x64,0x65,0x20,0x63,0x61,0x6E,0x20,0x62,0x65,0x20,0x75,
2317 0x6E,0x62,0x65,0x61,0x72,0x61,0x62,0x6C,0x79,0x20,0x73,0x6C,
2318 0x6F,0x77,0x20,0x6F,0x6E,0x20,0x61,0x20,0x52,0x61,0x73,0x70,
2319 0x62,0x65,0x72,0x72,0x79,0x20,0x50,0x69,0x20,0x28,0x65,0x76,
2320 0x65,0x6E,0x20,0x6F,0x6E,0x20,0x52,0x50,0x69,0x20,0x34,0x29,
2321 0x4A,0x3E,0x40,0x58,0x30,0x31,0x30,0x2D,0x20,0x46,0x75,0x6C,
2322 0x6C,0x73,0x63,0x72,0x65,0x65,0x6E,0x20,0x6D,0x6F,0x64,0x65,
2323 0x20,0x63,0x61,0x6E,0x20,0x68,0x61,0x76,0x65,0x20,0x73,0x65,
2324 0x76,0x65,0x72,0x61,0x6C,0x20,0x70,0x72,0x6F,0x62,0x6C,0x65,
2325 0x6D,0x73,0x20,0x6F,0x6E,0x20,0x6D,0x75,0x6C,0x74,0x69,0x2D,
2326 0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x20,0x73,0x79,0x73,0x74,
2327 0x65,0x6D,0x73,0x47,0x3E,0x40,0x58,0x30,0x31,0x30,0x2D,0x20,
2328 0x46,0x75,0x6C,0x6C,0x73,0x63,0x72,0x65,0x65,0x6E,0x20,0x6D,
2329 0x6F,0x64,0x65,0x20,0x63,0x61,0x6E,0x20,0x68,0x61,0x76,0x65,
2330 0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6C,0x20,0x70,0x72,0x6F,
2331 0x62,0x6C,0x65,0x6D,0x73,0x20,0x6F,0x6E,0x20,0x73,0x6F,0x6D,
2332 0x65,0x20,0x4C,0x69,0x6E,0x75,0x78,0x20,0x73,0x79,0x73,0x74,
2333 0x65,0x6D,0x73,0x00,0x03,0x45,0x4E,0x44
2324};2334};
2325 2335
2326#endif2336#endif
src/mixer/ft2_mix_macros.h+69−0
@@ -168,6 +168,9 @@ · 167 unmodified lines
168**168**
169*/169*/
170 170
171#if SINC_TAPS==8
172
173#if SINC_FSHIFT>=0
171#define WINDOWED_SINC_INTERPOLATION(s, f, scale) \174#define WINDOWED_SINC_INTERPOLATION(s, f, scale) \
172{ \175{ \
173 const float *t = v->fSincLUT + (((uint32_t)(f) >> SINC_FSHIFT) & SINC_FMASK); \176 const float *t = v->fSincLUT + (((uint32_t)(f) >> SINC_FSHIFT) & SINC_FMASK); \
@@ -180,6 +183,72 @@ · 6 unmodified lines
180 ( s[3] * t[6]) + \183 ( s[3] * t[6]) + \
181 ( s[4] * t[7])) * (1.0f / scale); \184 ( s[4] * t[7])) * (1.0f / scale); \
182}185}
186#else
187#define WINDOWED_SINC_INTERPOLATION(s, f, scale) \
188{ \
189 const float *t = v->fSincLUT + (((uint32_t)(f) << -SINC_FSHIFT) & SINC_FMASK); \
190 fSample = ((s[-3] * t[0]) + \
191 (s[-2] * t[1]) + \
192 (s[-1] * t[2]) + \
193 ( s[0] * t[3]) + \
194 ( s[1] * t[4]) + \
195 ( s[2] * t[5]) + \
196 ( s[3] * t[6]) + \
197 ( s[4] * t[7])) * (1.0f / scale); \
198}
199#endif
200
201#elif SINC_TAPS==16
202
203#if SINC_FSHIFT>=0
204#define WINDOWED_SINC_INTERPOLATION(s, f, scale) \
205{ \
206 const float *t = v->fSincLUT + (((uint32_t)(f) >> SINC_FSHIFT) & SINC_FMASK); \
207 fSample = ((s[-7] * t[0]) + \
208 (s[-6] * t[1]) + \
209 (s[-5] * t[2]) + \
210 (s[-4] * t[3]) + \
211 (s[-3] * t[4]) + \
212 (s[-2] * t[5]) + \
213 (s[-1] * t[6]) + \
214 ( s[0] * t[7]) + \
215 ( s[1] * t[8]) + \
216 ( s[2] * t[9]) + \
217 ( s[3] * t[10]) + \
218 ( s[4] * t[11]) + \
219 ( s[5] * t[12]) + \
220 ( s[6] * t[13]) + \
221 ( s[7] * t[14]) + \
222 ( s[8] * t[15])) * (1.0f / scale); \
223}
224#else
225#define WINDOWED_SINC_INTERPOLATION(s, f, scale) \
226{ \
227 const float *t = v->fSincLUT + (((uint32_t)(f) << -SINC_FSHIFT) & SINC_FMASK); \
228 fSample = ((s[-7] * t[0]) + \
229 (s[-6] * t[1]) + \
230 (s[-5] * t[2]) + \
231 (s[-4] * t[3]) + \
232 (s[-3] * t[4]) + \
233 (s[-2] * t[5]) + \
234 (s[-1] * t[6]) + \
235 ( s[0] * t[7]) + \
236 ( s[1] * t[8]) + \
237 ( s[2] * t[9]) + \
238 ( s[3] * t[10]) + \
239 ( s[4] * t[11]) + \
240 ( s[5] * t[12]) + \
241 ( s[6] * t[13]) + \
242 ( s[7] * t[14]) + \
243 ( s[8] * t[15])) * (1.0f / scale); \
244}
245#endif
246
247#else
248
249#error mixer/ft2_mix_macros.h: The SINC_TAPS definition is invalid! Valid values: 8 or 16
250
251#endif
183 252
184#define RENDER_8BIT_SMP_SINTRP \253#define RENDER_8BIT_SMP_SINTRP \
185 WINDOWED_SINC_INTERPOLATION(smpPtr, positionFrac, 128) \254 WINDOWED_SINC_INTERPOLATION(smpPtr, positionFrac, 128) \
src/mixer/ft2_windowed_sinc.c+4−7
@@ -1,5 +1,5 @@
1/* Code taken from the OpenMPT project, which has a BSD1/* Code taken from the OpenMPT project, which has a BSD license which is
2** license which is compatible with this project.2** compatible with this project.
3**3**
4** The code has been slightly modified.4** The code has been slightly modified.
5*/5*/
@@ -10,10 +10,7 @@ · 4 unmodified lines
10#include <math.h>10#include <math.h>
11#include "ft2_windowed_sinc.h"11#include "ft2_windowed_sinc.h"
12 12
13// globalized13float *fKaiserSinc = NULL, *fDownSample1 = NULL, *fDownSample2 = NULL; // globalized
14float *fKaiserSinc = NULL;
15float *fDownSample1 = NULL;
16float *fDownSample2 = NULL;
17 14
18static double Izero(double y) // Compute Bessel function Izero(y) using a series approximation15static double Izero(double y) // Compute Bessel function Izero(y) using a series approximation
19{16{
@@ -71,7 +68,7 @@ bool calcWindowedSincTables(void) · 51 unmodified lines
71 68
72 getSinc(fKaiserSinc, 9.6377, 0.97);69 getSinc(fKaiserSinc, 9.6377, 0.97);
73 getSinc(fDownSample1, 8.5, 0.5);70 getSinc(fDownSample1, 8.5, 0.5);
74 getSinc(fDownSample2, 2.7625, 0.425);71 getSinc(fDownSample2, 7.3, 0.425);
75 72
76 return true;73 return true;
77}74}
src/mixer/ft2_windowed_sinc.h+9−8
@@ -4,14 +4,17 @@ · 3 unmodified lines
4#include <stdbool.h>4#include <stdbool.h>
5#include "ft2_mix.h"5#include "ft2_mix.h"
6 6
7// if you change this, also change SINC_PHASES_BITS (>8192 gives very little improvement)7// 8 or 16. 8 allows more unwanted frequencies, which may be preferred for lo-fi samples
8#define SINC_TAPS 8
9
10// log2(SINC_TAPS)
11#define SINC_TAPS_BITS 3
12
8#define SINC_PHASES 819213#define SINC_PHASES 8192
9#define SINC_PHASES_BITS 13 /* log2(SINC_PHASES) */
10 14
11// don't change these!15// log2(SINC_PHASES)
16#define SINC_PHASES_BITS 13
12 17
13#define SINC_TAPS 8
14#define SINC_TAPS_BITS 3
15#define SINC_LUT_LEN (SINC_TAPS * SINC_PHASES)18#define SINC_LUT_LEN (SINC_TAPS * SINC_PHASES)
16#define SINC_FSHIFT (MIXER_FRAC_BITS-(SINC_PHASES_BITS+SINC_TAPS_BITS))19#define SINC_FSHIFT (MIXER_FRAC_BITS-(SINC_PHASES_BITS+SINC_TAPS_BITS))
17#define SINC_FMASK ((SINC_TAPS*SINC_PHASES)-SINC_TAPS)20#define SINC_FMASK ((SINC_TAPS*SINC_PHASES)-SINC_TAPS)
@@ -23,9 +26,7 @@ · 5 unmodified lines
23// for LUT calculation26// for LUT calculation
24#define SINC_MID_TAP ((SINC_TAPS/2)*SINC_PHASES)27#define SINC_MID_TAP ((SINC_TAPS/2)*SINC_PHASES)
25 28
26extern float *fKaiserSinc;29extern float *fKaiserSinc, *fDownSample1, *fDownSample2;
27extern float *fDownSample1;
28extern float *fDownSample2;
29 30
30bool calcWindowedSincTables(void);31bool calcWindowedSincTables(void);
31void freeWindowedSincTables(void);32void freeWindowedSincTables(void);
src/modloaders/ft2_load_digi.c+1−1
@@ -83,7 +83,7 @@ bool loadDIGI(FILE *f, uint32_t filesize) · 82 unmodified lines
83 }83 }
84 84
85 memcpy(songTmp.orders, hdr.orders, 128);85 memcpy(songTmp.orders, hdr.orders, 128);
86 86 memcpy(songTmp.name, hdr.name, 20);
87 songTmp.numChannels = hdr.numChannels;87 songTmp.numChannels = hdr.numChannels;
88 songTmp.songLength = hdr.numOrders;88 songTmp.songLength = hdr.numOrders;
89 songTmp.BPM = 125;89 songTmp.BPM = 125;
src/modloaders/ft2_load_mod.c+0−3
@@ -314,9 +314,6 @@ bool loadMOD(FILE *f, uint32_t filesize) · 313 unmodified lines
314 s->loopStart = 2 * SWAP16(hdr.smp[a].loopStart);314 s->loopStart = 2 * SWAP16(hdr.smp[a].loopStart);
315 s->loopLength = 2 * SWAP16(hdr.smp[a].loopLength);315 s->loopLength = 2 * SWAP16(hdr.smp[a].loopLength);
316 316
317 if (s->loopLength < 2)
318 s->loopLength = 2;
319
320 // fix for poorly converted STK (< v2.5) -> PT/NT modules317 // fix for poorly converted STK (< v2.5) -> PT/NT modules
321 if (s->loopLength > 2 && s->loopStart+s->loopLength > s->length)318 if (s->loopLength > 2 && s->loopStart+s->loopLength > s->length)
322 {319 {
src/scopes/ft2_scopes.c+5−42
@@ -20,12 +20,12 @@ · 19 unmodified lines
20#include "../ft2_video.h"20#include "../ft2_video.h"
21#include "../ft2_tables.h"21#include "../ft2_tables.h"
22#include "../ft2_structs.h"22#include "../ft2_structs.h"
23#include "../ft2_hpc.h"
23#include "ft2_scopes.h"24#include "ft2_scopes.h"
24#include "ft2_scopedraw.h"25#include "ft2_scopedraw.h"
25 26
26static volatile bool scopesUpdatingFlag, scopesDisplayingFlag;27static volatile bool scopesUpdatingFlag, scopesDisplayingFlag;
27static uint32_t scopeTimeLen, scopeTimeLenFrac;28static hpc_t scopeHpc;
28static uint64_t timeNext64, timeNext64Frac;
29static volatile scope_t scope[MAX_CHANNELS];29static volatile scope_t scope[MAX_CHANNELS];
30static SDL_Thread *scopeThread;30static SDL_Thread *scopeThread;
31 31
@@ -520,9 +520,8 @@ static int32_t SDLCALL scopeThreadFunc(void *ptr) · 488 unmodified lines
520 // this is needed for scope stability (confirmed)520 // this is needed for scope stability (confirmed)
521 SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);521 SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
522 522
523 // set next frame time523 hpc_SetDurationInHz(&scopeHpc, SCOPE_HZ);
524 timeNext64 = SDL_GetPerformanceCounter() + scopeTimeLen;524 hpc_ResetCounters(&scopeHpc);
525 timeNext64Frac = scopeTimeLenFrac;
526 525
527 while (editor.programRunning)526 while (editor.programRunning)
528 {527 {
@@ -530,31 +529,7 @@ static int32_t SDLCALL scopeThreadFunc(void *ptr) · 1 unmodified line
530 updateScopes();529 updateScopes();
531 editor.scopeThreadBusy = false;530 editor.scopeThreadBusy = false;
532 531
533 uint64_t time64 = SDL_GetPerformanceCounter();532 hpc_Wait(&scopeHpc);
534 if (time64 < timeNext64)
535 {
536 time64 = timeNext64 - time64;
537 if (time64 > INT32_MAX)
538 time64 = INT32_MAX;
539
540 const int32_t diff32 = (int32_t)time64;
541
542 // convert and round to microseconds
543 const int32_t time32 = (int32_t)((diff32 * editor.dPerfFreqMulMicro) + 0.5);
544
545 // delay until we have reached the next frame
546 if (time32 > 0)
547 usleep(time32);
548 }
549
550 // update next tick time
551 timeNext64 += scopeTimeLen;
552 timeNext64Frac += scopeTimeLenFrac;
553 if (timeNext64Frac > UINT32_MAX)
554 {
555 timeNext64Frac &= UINT32_MAX;
556 timeNext64++;
557 }
558 }533 }
559 534
560 (void)ptr;535 (void)ptr;
@@ -563,18 +538,6 @@ static int32_t SDLCALL scopeThreadFunc(void *ptr) · 2 unmodified lines
563 538
564bool initScopes(void)539bool initScopes(void)
565{540{
566 double dInt;
567
568 // calculate scope time for performance counters and split into int/frac
569 double dFrac = modf(editor.dPerfFreq / SCOPE_HZ, &dInt);
570
571 // integer part
572 scopeTimeLen = (int32_t)dInt;
573
574 // fractional part (scaled to 0..2^32-1)
575 dFrac *= UINT32_MAX+1.0;
576 scopeTimeLenFrac = (uint32_t)dFrac;
577
578 scopeThread = SDL_CreateThread(scopeThreadFunc, NULL, NULL);541 scopeThread = SDL_CreateThread(scopeThreadFunc, NULL, NULL);
579 if (scopeThread == NULL)542 if (scopeThread == NULL)
580 {543 {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t