diff --git a/.gitignore b/.gitignore index 24274dc3..a9982931 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,5 @@ assets/icon.ico .vscode out/ +/fmod/ +.gdb_history \ No newline at end of file diff --git a/Dockerfile-linux b/Dockerfile-linux deleted file mode 100644 index 45f6f0ee..00000000 --- a/Dockerfile-linux +++ /dev/null @@ -1,37 +0,0 @@ -# gcc10 doesn't like me, and it seems the official appimage is build using gcc 5.4.0-6ubuntu1~16.04.12 -FROM conanio/gcc5 -RUN conan remote add eliza "https://rkevin.jfrog.io/artifactory/api/conan/eliza" && \ -conan remote add bincrafters "https://bincrafters.jfrog.io/artifactory/api/conan/public-conan" && \ -conan remote add astrabit "https://rkevin.jfrog.io/artifactory/api/conan/astrabit" && \ -conan config set general.revisions_enabled=1 - -RUN sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y \ -xorg-dev libx11-xcb-dev libxcb-render0-dev libxcb-render-util0-dev libgtk2.0-dev libxfconf-0-dev vim libwmf0.2-7-gtk librsvg2-common rsync patchelf dos2unix && \ -sudo rm -rf /var/lib/apt/lists/* -RUN sudo python -m pip install mako pyqt5 pyinstaller - -# install all dependencies for the conanfile in commit -COPY --chown=conan:root conanfile.py /tmp/install_deps/conanfile.py -RUN conan install --build=missing /tmp/install_deps && sudo rm -r /tmp/install_deps - -ADD https://github.com/AppImage/AppImageKit/releases/download/12/appimagetool-x86_64.AppImage /tmp -# can't find a stable release for linuxdeploy, oh well -ADD https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage /tmp -# avoid having to run appimages by itself -# we don't want to force CAP_SYS_ADMIN into the container if possible, but running appimages require FUSE -# instead, we extract it and pray it works (it actually does!) -RUN cd /tmp && sudo chmod 755 appimagetool-x86_64.AppImage linuxdeploy-x86_64.AppImage && \ -./appimagetool-x86_64.AppImage --appimage-extract && sudo mv squashfs-root /usr/local/bin/appimagetool && \ -./linuxdeploy-x86_64.AppImage --appimage-extract && sudo mv squashfs-root /usr/local/bin/linuxdeploy && \ -sudo ln -s /usr/local/bin/appimagetool/AppRun /usr/local/bin/appimagetool-x86_64.AppImage && \ -sudo ln -s /usr/local/bin/linuxdeploy/AppRun /usr/local/bin/linuxdeploy-x86_64.AppImage - -ENTRYPOINT ["bash", "-c", "dos2unix /work/src/build-entrypoint-linux.sh && chmod +x /work/src/build-entrypoint-linux.sh && /work/src/build-entrypoint-linux.sh"] - -# build this docker image as follows: -# docker build -t oneshot-build-linux . - -# run this docker image as follows: -# docker run -i -v /path/to/modshot-core:/work/src -v /path/to/gamefiles:/work/data -v /path/to/distrubution/folder:/work/dist oneshot-build-linux -# example that worked for me: -# docker run -i -v ~/o/Modshot-Core:/work/src -v ~/o/OneShotBkup:/work/data -v ~/o/conanbuildtest:/work/dist oneshot-build-linux diff --git a/Dockerfile-windows b/Dockerfile-windows deleted file mode 100644 index ffb67e3c..00000000 --- a/Dockerfile-windows +++ /dev/null @@ -1,29 +0,0 @@ -# escape=` -# fine, windows, have your backslashes - -FROM mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-ltsc2019 - -# install vs community (not vs buildtools because we need devenv to upgrade vs solutions -ADD https://aka.ms/vs/16/release/vs_community.exe /vs_community.exe -RUN C:\vs_community.exe --quiet --wait --norestart --nocache --add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended --add Microsoft.VisualStudio.Workload.C++ - -# install chocolatey and use it to install cmake, git, conan, vim (vim for xxd only, since installing cygwin breaks docker) -RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; ` -iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')); ` -choco install -y cmake git conan vim; - -# configure path (add xxd and cmake), conan remotes, and fix windows path size limits for conan -RUN [Environment]::SetEnvironmentVariable('Path', $env:Path + ';C:\Program Files\CMake\bin;C:\tools\vim\vim82', 'Machine'); ` -conan remote add eliza https://rkevin.jfrog.io/artifactory/api/conan/eliza; ` -conan remote add bincrafters https://bincrafters.jfrog.io/artifactory/api/conan/public-conan; ` -conan remote add astrabit https://rkevin.jfrog.io/artifactory/api/conan/astrabit; ` -conan config set general.revisions_enabled=1; ` -conan profile new default --detect; ` -setx CONAN_USE_ALWAYS_SHORT_PATHS 1; - -# prebuild all dependencies using the conanfile in this commit -COPY conanfile.py C:/Temp/install_deps/ -RUN conan install --build=missing C:\Temp\install_deps -s compiler.cppstd=20 -s compiler.runtime=static - -# finally, we build oneshot when we run the container -ENTRYPOINT ["C:\\work\\src\\build-entrypoint-windows.bat"] diff --git a/README.md b/README.md index bd060caa..e47d4be7 100644 --- a/README.md +++ b/README.md @@ -32,9 +32,59 @@ The main upshot of this, of course, is remaining on par with ruby in terms of ge Previously, C extensions were very jank with ModShot, **however** now you can use a C extension right from your own Ruby install! (Provided the version is the same, and the msys2 evironment is the same. I'll get back to this later.) -### Build options +## Using clang -Unfortunately because of the way ModShot is set up, you will need to pass build options to Make **and** Meson, if it pertains to dependencies. (ruby ver, opt level, etc.) +//TODO + +# FMOD + +FMOD support is very... interesting. It involves a lot of licensing, legalese, etc. +If you want to enable FMOD support, download FMOD and extract the zip into a folder named `fmod`. +You will then need to pass `-Dfmod=true` as an option. + +ModShot should handle everything from there, it's up to you to follow the FMOD license. + +FMOD bindings also do not supply the `Audio` module. You may create wrapper functions for that if you wish. +AL Effect bndings are not supplied as well for obvious reasons. + +Functions will always return an array of values (usually two) in the order of `[result, values...]`. +This means you can do `result, value = FMOD.some_func()`, which is pretty neat, right? If a result is not `FMOD_OK` (0) there will be no return value. Keep that in mind! + +The FMOD bindings won't hold your hands either- You will need to clean up after yourself. +Because of the way the bindings work as well calling the same function twice will **NOT** return the "same" object. Fundamentally, it is the same object, as the C++ side object is the same, but it is a brand new object as far as ruby is concerned. + +Because of this behavior, you can quite easily cause a memory leak by repeatedly storing an object returned in an array somewhere constantly loaded such that ruby will not garbage collect it. +i.e +```rb +array = [] +100000.times do + array << bank.get_event_list # Bad will memory leak! +end +``` +So, be mindful of what you write! Luckily instances of objects from these bindings are very small so it's not a big deal if your code isn't perfect, but **PLEASE** do be mindful of this! RMXP already has a similar problem with Bitmaps, so if you've dealt with them you should know what to do. +There is an `==` operator provided that will check if an object is the same for you as well. You can usually assign a value `nil` to get it garbage collected. + +A feature is provided to automatically release **some** FMOD objects (Like System, Bank, etc) but it is disabled by default. +This is because some FMOD functions will allow you to "get back" an object after it has been garbage collected from ruby, and this feature messes with that. +I would not suggest using it because if you are, you're likely doing something wrong and are relying on a bandaid fix to avoid it being an issue. + +The bindings should generally line up with what's documented in the latest FMOD docs- although things like `FMOD_Studio_System_Create` are hidden away under `FMOD::Studio::System.new` instead. The bindings are closest to the `C#` bindings for FMOD. + +Plugins are potentially supported via C extensions but if you really want to add support for one you may hardcode it in. +Something like ResonanceAudio would be simple enough, since all you would need to do is wrap a struct like mkxp wraps classes, and the FMOD bindings here should do the rest. It'll pull a void pointer to your wrapped data by using `getPrivateData`. Getting data back like this will either convert it to a string, or the user will pass in a class that the bindings will set the data of. I still haven't decided on how to do this just yet, though, but I am leaning towards the string method. + +One other thing to note is that with structs you need to be mindful of method chaining. +You can chain methods on the struct (like `struct.position.y = 15`) but if chained on the return vaue from a method it won't work. +```rb +# will not work! +eventinstance.get_3d_attributes[1].up.x = 15 +# will work! +struct = eventinstance.get_3d_attributes[1] +struct.up.x = 15 +eventinstance.set_3d_attributes(struct) +``` + +I hope that's enough info to get you started! There will be some direct conversions of FMOD examples in the `scripts` folder when I get to it. (TODO) ### Options @@ -43,11 +93,13 @@ RUBY_VER && -Dmri_version (default 3.1) sets the ruby version. -Dsteam (default false) sets the build to use steam. --build-type (default Release) sets the build type. -Dbuild_static (default true) sets the build to be static. (True is faster, but with longer startup times.) +-Dfmod (default false) toggles FMOD instead of OpenAL. +-Dauto_clean_fmod (default false) toggles auto releasing SOME FMOD objects when garbage collected. ``` ## Building on Windows -First, you'll need to download [msys2](https://www.msys2.org/) and install it. +First, you'll need to download [msys2](https://www.msys2.org/) and install it. Then, you'll want to determine what Ruby version you're using, as this will determine what build environment you'll be using. As is, ModShot is set up to use Ruby 3.1, so keep that in mind. Please refer to this table to determine the environment. (You *can* use the wrong environment and it will work fine, just not with C extensions.) @@ -96,7 +148,7 @@ This should create a folder called `out` with your build of ModShot all ready to ## Configuration -*ModShot* reads configuration data from the file "oneshot.conf". The format is ini-style. Do *not* use quotes around file paths (spaces won't break). Lines starting with '#' are comments. See 'oneshot.conf.sample' for a list of accepted entries. Note that this feature appears to be brpken for the moment until we get around to fixing it. Using command line options does work, however. +*ModShot* reads configuration data from the file "oneshot.conf". The format is ini-style. Do *not* use quotes around file paths (spaces won't break). Lines starting with '#' are comments. See 'oneshot.conf.sample' for a list of accepted entries. All option entries can alternatively be specified as command line options. Any options that are not arrays (eg. preloaded scripts) specified as command line options will override entries in oneshot.conf. Note that you will have to wrap values containing spaces in quotes (unlike in oneshot.conf). @@ -108,4 +160,4 @@ Example: `./oneshot --gameFolder="oneshot" --vsync=true` Modshot builds come pre-packaged with the ruby standard library in `/lib/ruby/`. You can require gems from this folder at any point by using `require ''`. -You can ship your own gems by finding the gem install location (Typically `C:\Ruby27-x64\lib\ruby\gems\2.7.0\gems`), going inside the gem, and copying over all the files inside lib. +You can ship your own gems by finding the gem install location (Typically `C:\Ruby27-x64\lib\ruby\gems\2.7.0\gems`), going inside the gem, and copying over all the files inside lib. diff --git a/binding-mri/aleffect-binding.cpp b/binding-mri/al-binding/aleffect-binding.cpp similarity index 100% rename from binding-mri/aleffect-binding.cpp rename to binding-mri/al-binding/aleffect-binding.cpp diff --git a/binding-mri/audio-binding.cpp b/binding-mri/al-binding/audio-binding.cpp similarity index 100% rename from binding-mri/audio-binding.cpp rename to binding-mri/al-binding/audio-binding.cpp diff --git a/binding-mri/binding-mri.cpp b/binding-mri/binding-mri.cpp index 6c89fca4..91d86ac3 100644 --- a/binding-mri/binding-mri.cpp +++ b/binding-mri/binding-mri.cpp @@ -28,7 +28,9 @@ #include "sdl-util.h" #include "debugwriter.h" #include "graphics.h" +#ifndef USE_FMOD #include "audio.h" +#endif #include "boost-hash.h" #include "version.h" #include "oneshot.h" @@ -48,6 +50,9 @@ #include extern const char module_rpg1[]; +#ifdef USE_FMOD +extern const char fmod_enums[]; +#endif static void mriBindingExecute(); static void mriBindingTerminate(); @@ -75,7 +80,6 @@ void windowVXBindingInit(); void tilemapVXBindingInit(); void inputBindingInit(); -void audioBindingInit(); void graphicsBindingInit(); void fileIntBindingInit(); @@ -89,7 +93,13 @@ void nikoBindingInit(); void oneshotBindingInit(); void modshotBindingInit(); void steamBindingInit(); +#ifndef USE_FMOD +void audioBindingInit(); void aleffectBindingInit(); +#else +void fmodCoreBindingInit(); +void fmodStudioBindingInit(); +#endif void screenBindingInit(); RB_METHOD(mriPrint); RB_METHOD(mriP); @@ -117,7 +127,6 @@ static void mriBindingInit() tilemapBindingInit(); inputBindingInit(); - audioBindingInit(); graphicsBindingInit(); fileIntBindingInit(); @@ -127,7 +136,13 @@ static void mriBindingInit() oneshotBindingInit(); modshotBindingInit(); steamBindingInit(); + #ifndef USE_FMOD + audioBindingInit(); aleffectBindingInit(); + #else + fmodCoreBindingInit(); + fmodStudioBindingInit(); + #endif screenBindingInit(); rb_define_global_const("MODSHOT_VERSION", rb_str_new_cstr(MODSHOT_VERSION)); if (rgssVer >= 3) @@ -151,6 +166,10 @@ static void mriBindingInit() rb_eval_string(module_rpg1); + #ifdef USE_FMOD + rb_eval_string(fmod_enums); + #endif + VALUE mod = rb_define_module("MKXP"); _rb_define_module_function(mod, "data_directory", mkxpDataDirectory); _rb_define_module_function(mod, "puts", mkxpPuts); @@ -296,7 +315,9 @@ static VALUE rgssMainRescue(VALUE arg, VALUE exc) static void processReset() { shState->graphics().reset(); + #ifndef USE_FMOD shState->audio().reset(); + #endif shState->rtData().rqReset.clear(); shState->graphics().repaintWait(shState->rtData().rqResetFinish, @@ -665,16 +686,6 @@ static void mriBindingExecute() rubyArgsC.push_back(greedyVersioning.c_str()); } - if (conf.jitEnabled) { - std::string verboseLevel("-jit-verbose="); verboseLevel += std::to_string(conf.jitVerbosity); - std::string maxCache("--jit-max-cache="); maxCache += std::to_string(conf.jitMaxCache); - std::string minCalls("--jit-min-calls="); minCalls += std::to_string(conf.jitMinCalls); - rubyArgsC.push_back("--jit"); - rubyArgsC.push_back(verboseLevel.c_str()); - rubyArgsC.push_back(maxCache.c_str()); - rubyArgsC.push_back(minCalls.c_str()); - } - node = ruby_options(rubyArgsC.size(), const_cast(rubyArgsC.data())); int state; diff --git a/binding-mri/binding-util.cpp b/binding-mri/binding-util.cpp index 9af79252..2936c9b4 100644 --- a/binding-mri/binding-util.cpp +++ b/binding-mri/binding-util.cpp @@ -99,220 +99,320 @@ raiseDisposedAccess(VALUE self) rb_raise(getRbData()->exc[RGSS], "disposed %s", buf); } -int -rb_get_args(int argc, VALUE *argv, const char *format, ...) -{ - char c; - VALUE *arg = argv; - va_list ap; - bool opt = false; - int argI = 0; - - va_start(ap, format); - - while ((c = *format++)) - { - switch (c) - { - case '|' : +int rb_get_args(int argc, VALUE *argv, const char *format, ...) { + int arg_count = 0; + int opt_count = 0; + bool optional = false; + char arg; + while (true) { + arg = format[arg_count + opt_count]; + if (arg == '|') + optional = true; + if (arg == '\0') break; - default: - // FIXME print num of needed args vs provided - if (argc <= argI && !opt) - rb_raise(rb_eArgError, "wrong number of arguments"); - break; - } - - if (argI >= argc) - break; + if (optional) + opt_count++; + else + arg_count++; + } - switch (c) - { - case 'o' : - { - if (argI >= argc) - break; + //! If argc is less than the required arguments or more than the optional arguments + the required arguments, raise an error. + if (argc < arg_count || argc > arg_count + opt_count) + if (optional) + rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected %d..%d)", argc, arg_count, arg_count + opt_count); + else + rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected %d)", argc, arg_count); - VALUE *obj = va_arg(ap, VALUE*); + va_list ap; + va_start(ap, format); - *obj = *arg++; - ++argI; + optional = false; + for (int i = 0; i < argc + optional; i++) { //? We add optional so we can skip over the '|' + arg = format[i]; - break; + if (arg == '|') { //? Skip over the '|' + optional = true; + continue; } - case 'S' : - { - if (argI >= argc) + switch (arg) { + case 'o': { + VALUE *obj = va_arg(ap, VALUE*); + (*obj) = *argv; break; + } - VALUE *str = va_arg(ap, VALUE*); - VALUE tmp = *arg; - - tmp = rb_str_to_str(tmp); - - *str = tmp; - ++argI; - - break; - } - - case 's' : - { - if (argI >= argc) + case 'S': { + VALUE *str = va_arg(ap, VALUE*); + (*str) = rb_str_to_str(*argv); break; + } - const char **s = va_arg(ap, const char**); - int *len = va_arg(ap, int*); - - VALUE tmp = *arg; - - tmp = rb_str_to_str(tmp); + case 's': { + char **str = va_arg(ap, char**); + int *len = va_arg(ap, int*); - *s = RSTRING_PTR(tmp); - *len = RSTRING_LEN(tmp); - ++argI; - - break; - } - - case 'z' : - { - if (argI >= argc) + (*str) = StringValuePtr(*argv); //! Does not ensure that the string is null-terminated + (*len) = RSTRING_LEN(*argv); break; + } - const char **s = va_arg(ap, const char**); - - VALUE tmp = *arg++; - - tmp = rb_str_to_str(tmp); + case 'z': { + char **str = va_arg(ap, char**); - *s = RSTRING_PTR(tmp); - ++argI; - - break; - } - - case 'f' : - { - if (argI >= argc) + (*str) = StringValueCStr(*argv); //! Ensures that the string is null-terminated break; + } - double *f = va_arg(ap, double*); - VALUE fVal = *arg++; - - rb_float_arg(fVal, f, argI); + case 'f': { + double *vfloat = va_arg(ap, double*); - ++argI; - break; - } - - case 'i' : - { - if (argI >= argc) + rb_float_arg(*argv, vfloat, i - optional); break; + } - int *i = va_arg(ap, int*); - VALUE iVal = *arg++; - - rb_int_arg(iVal, i, argI); + case 'i': { + int *vint = va_arg(ap, int*); - ++argI; - break; - } - - case 'b' : - { - if (argI >= argc) + rb_int_arg(*argv, vint, i - optional); break; + } - bool *b = va_arg(ap, bool*); - VALUE bVal = *arg++; + case 'b': { + bool *vbool = va_arg(ap, bool*); - rb_bool_arg(bVal, b, argI); - - ++argI; - break; - } - - case 'n' : - { - if (argI >= argc) + rb_bool_arg(*argv, vbool, i - optional); break; + } + //! 'n' isn't added since it's not used in the code - ID *sym = va_arg(ap, ID*); - - VALUE symVal = *arg++; - - if (!SYMBOL_P(symVal)) - rb_raise(rb_eTypeError, "Argument %d: Expected symbol", argI); - - *sym = SYM2ID(symVal); - ++argI; - - break; - } - - case '|' : - opt = true; - break; - - default: - rb_raise(rb_eFatal, "invalid argument specifier %c", c); - } - } - -#ifndef NDEBUG - - /* Pop remaining arg pointers off - * the stack to check for RB_ARG_END */ - format--; - - while ((c = *format++)) - { - switch (c) - { - case 'o' : - case 'S' : - va_arg(ap, VALUE*); - break; - - case 's' : - va_arg(ap, const char**); - va_arg(ap, int*); - break; - - case 'z' : - va_arg(ap, const char**); - break; - - case 'f' : - va_arg(ap, double*); - break; - - case 'i' : - va_arg(ap, int*); - break; - - case 'b' : - va_arg(ap, bool*); - break; + default: { + rb_raise(rb_eFatal, "Invalid argument specifier: %c", arg); + } } + argv++; //! Move to the next argument } - // FIXME print num of needed args vs provided - if (!c && argc > argI) - rb_raise(rb_eArgError, "wrong number of arguments"); - - /* Verify correct termination */ - void *argEnd = va_arg(ap, void*); - (void) argEnd; - assert(argEnd == RB_ARG_END_VAL); - -#endif - va_end(ap); - return argI; + return arg_count; } + +//int +//rb_get_args(int argc, VALUE *argv, const char *format, ...) +//{ +// char c; +// VALUE *arg = argv; +// va_list ap; +// bool opt = false; +// int argI = 0; +// +// va_start(ap, format); +// +// while ((c = *format++)) +// { +// switch (c) +// { +// case '|' : +// break; +// default: +// // FIXME print num of needed args vs provided +// if (argc <= argI && !opt) +// rb_raise(rb_eArgError, "wrong number of arguments"); +// +// break; +// } +// +// if (argI >= argc) +// break; +// +// switch (c) +// { +// case 'o' : +// { +// if (argI >= argc) +// break; +// +// VALUE *obj = va_arg(ap, VALUE*); +// +// *obj = *arg++; +// ++argI; +// +// break; +// } +// +// case 'S' : +// { +// if (argI >= argc) +// break; +// +// VALUE *str = va_arg(ap, VALUE*); +// VALUE tmp = *arg; +// +// tmp = rb_str_to_str(tmp); +// +// *str = tmp; +// ++argI; +// +// break; +// } +// +// case 's' : +// { +// if (argI >= argc) +// break; +// +// const char **s = va_arg(ap, const char**); +// int *len = va_arg(ap, int*); +// +// VALUE tmp = *arg; +// +// tmp = rb_str_to_str(tmp); +// +// *s = RSTRING_PTR(tmp); +// *len = RSTRING_LEN(tmp); +// ++argI; +// +// break; +// } +// +// case 'z' : +// { +// if (argI >= argc) +// break; +// +// const char **s = va_arg(ap, const char**); +// +// VALUE tmp = *arg++; +// +// tmp = rb_str_to_str(tmp); +// +// *s = RSTRING_PTR(tmp); +// ++argI; +// +// break; +// } +// +// case 'f' : +// { +// if (argI >= argc) +// break; +// +// double *f = va_arg(ap, double*); +// VALUE fVal = *arg++; +// +// rb_float_arg(fVal, f, argI); +// +// ++argI; +// break; +// } +// +// case 'i' : +// { +// if (argI >= argc) +// break; +// +// int *i = va_arg(ap, int*); +// VALUE iVal = *arg++; +// +// rb_int_arg(iVal, i, argI); +// +// ++argI; +// break; +// } +// +// case 'b' : +// { +// if (argI >= argc) +// break; +// +// bool *b = va_arg(ap, bool*); +// VALUE bVal = *arg++; +// +// rb_bool_arg(bVal, b, argI); +// +// ++argI; +// break; +// } +// +// case 'n' : +// { +// if (argI >= argc) +// break; +// +// ID *sym = va_arg(ap, ID*); +// +// VALUE symVal = *arg++; +// +// if (!SYMBOL_P(symVal)) +// rb_raise(rb_eTypeError, "Argument %d: Expected symbol", argI); +// +// *sym = SYM2ID(symVal); +// ++argI; +// +// break; +// } +// +// case '|' : +// opt = true; +// break; +// +// default: +// rb_raise(rb_eFatal, "invalid argument specifier %c", c); +// } +// } +// +//#ifndef NDEBUG +// +// /* Pop remaining arg pointers off +// * the stack to check for RB_ARG_END */ +// format--; +// +// while ((c = *format++)) +// { +// switch (c) +// { +// case 'o' : +// case 'S' : +// va_arg(ap, VALUE*); +// break; +// +// case 's' : +// va_arg(ap, const char**); +// va_arg(ap, int*); +// break; +// +// case 'z' : +// va_arg(ap, const char**); +// break; +// +// case 'f' : +// va_arg(ap, double*); +// break; +// +// case 'i' : +// va_arg(ap, int*); +// break; +// +// case 'b' : +// va_arg(ap, bool*); +// break; +// } +// } +// +// // FIXME print num of needed args vs provided +// if (!c && argc > argI) +// rb_raise(rb_eArgError, "wrong number of arguments"); +// +// /* Verify correct termination */ +// void *argEnd = va_arg(ap, void*); +// (void) argEnd; +// assert(argEnd == RB_ARG_END_VAL); +// +//#endif +// +// va_end(ap); +// +// return argI; +//} diff --git a/binding-mri/binding-util.h b/binding-mri/binding-util.h index a441bb61..fa980fa8 100644 --- a/binding-mri/binding-util.h +++ b/binding-mri/binding-util.h @@ -48,23 +48,23 @@ enum RbException { PHYSFS, SDL, MKXP, - + ErrnoENOENT, - + IOError, - + TypeError, ArgumentError, - + RbExceptionsMax }; struct RbData { VALUE exc[RbExceptionsMax]; - + /* Input module (RGSS3) */ VALUE buttoncodeHash; - + RbData(); ~RbData(); }; @@ -202,7 +202,8 @@ template inline C *getPrivateData(VALUE self) { C *c = static_cast(DATA_PTR(self)); #endif if (!c) { - raiseRbExc(Exception(Exception::MKXPError, "No instance data for variable (missing call to super?)")); + VALUE to_string = rb_any_to_s(self); + raiseRbExc(Exception(Exception::MKXPError, "Private data for object %s missing (incorrect initialization?)", RSTRING_PTR(to_string))); } return c; } @@ -230,7 +231,7 @@ getPrivateDataCheck(VALUE self, const char *type) if (!rb_typeddata_is_kind_of(self, &type)) rb_raise(rb_eTypeError, "Can't convert %s into %s", ownname, type.wrap_struct_name); - + void *obj = RTYPEDDATA_DATA(self); #endif return static_cast(obj); @@ -257,9 +258,9 @@ wrapObject(void *p, const char *type, VALUE underKlass = rb_cObject) VALUE klass = rb_const_get(underKlass, rb_intern(type)); #endif VALUE obj = rb_obj_alloc(klass); - + setPrivateData(obj, p); - + return obj; } @@ -271,9 +272,9 @@ inline VALUE wrapProperty(VALUE self, void *prop, const char *iv, #endif VALUE underKlass = rb_cObject) { VALUE propObj = wrapObject(prop, type, underKlass); - + rb_iv_set(self, iv, propObj); - + return propObj; } @@ -332,15 +333,15 @@ static inline VALUE objectLoad(int argc, VALUE *argv, VALUE self) { const char *data; int dataLen; rb_get_args(argc, argv, "s", &data, &dataLen RB_ARG_END); - + VALUE obj = rb_obj_alloc(self); - + C *c = 0; - + GUARD_EXC(c = C::deserialize(data, dataLen);); - + setPrivateData(obj, c); - + return obj; } @@ -351,11 +352,11 @@ inline void rb_float_arg(VALUE arg, double *out, int argPos = 0) { case RUBY_T_FLOAT: *out = RFLOAT_VALUE(arg); break; - + case RUBY_T_FIXNUM: *out = FIX2INT(arg); break; - + default: rb_raise(rb_eTypeError, "Argument %d: Expected float", argPos); } @@ -367,11 +368,11 @@ inline void rb_int_arg(VALUE arg, int *out, int argPos = 0) { // FIXME check int range? *out = NUM2LONG(arg); break; - + case RUBY_T_FIXNUM: *out = FIX2INT(arg); break; - + default: rb_raise(rb_eTypeError, "Argument %d: Expected fixnum", argPos); } @@ -382,12 +383,12 @@ inline void rb_bool_arg(VALUE arg, bool *out, int argPos = 0) { case RUBY_T_TRUE: *out = true; break; - + case RUBY_T_FALSE: case RUBY_T_NIL: *out = false; break; - + default: rb_raise(rb_eTypeError, "Argument %d: Expected bool", argPos); } diff --git a/binding-mri/fmod-binding/common_structs.h b/binding-mri/fmod-binding/common_structs.h new file mode 100644 index 00000000..d0a31099 --- /dev/null +++ b/binding-mri/fmod-binding/common_structs.h @@ -0,0 +1,58 @@ +#ifndef COMMON_STRUCTS_H +#define COMMON_STRUCTS_H + +#include "binding-util.h" + +#define DEFINE_CONVERT_FUNC(type) \ + VALUE fmod##type##2rb(type p); \ + type rb2##type(VALUE self); + +#define DECLARE_FMOD2RB(type, klass) \ + VALUE fmod##type##2rb(type p) \ + { \ + VALUE self = rb_obj_alloc(klass); + +#define FMOD2RB(path, convert) \ + rb_iv_set(self, "@" #path, convert(p.path)); + +#define FMOD2RB_NAME(name, path, convert) \ + rb_iv_set(self, "@" #name, convert(p.path)); + +#define FMOD2RB_CAST(name, path, cast, convert) \ + rb_iv_set(self, "@" #name, convert((cast)p.path)); + +#define FMOD2RB_STRUCT(path, type) \ + rb_iv_set(self, "@" #path, fmod##type##2rb(p.path)); + +#define FMOD2RB_STRUCT_NAME(name, path, type) \ + rb_iv_set(self, "@" #name, fmod##type##2rb(p.path)); + +#define FMOD2RB_END \ + return self; \ + } + +#define DECLARE_RB2FMOD(type, klass) \ + type rb2##type(VALUE self) \ + { \ + type p = type(); + +#define RB2FMOD(path, convert) \ + p.path = convert(rb_iv_get(self, "@" #path)); + +#define RB2FMOD_NAME(name, path, convert) \ + p.path = convert(rb_iv_get(self, "@" #name)); + +#define RB2FMOD_CAST(name, path, cast, convert) \ + p.path = (cast)convert(rb_iv_get(self, "@" #name)); + +#define RB2FMOD_STRUCT(path, type) \ + p.path = rb2##type(rb_iv_get(self, "@" #path)); + +#define RB2FMOD_END \ + return p; \ + } + +#define ATTR(klass, name) \ + rb_define_attr(klass, #name, 1, 1); + +#endif diff --git a/binding-mri/fmod-binding/core/channelgroup.cpp b/binding-mri/fmod-binding/core/channelgroup.cpp new file mode 100644 index 00000000..e69de29b diff --git a/binding-mri/fmod-binding/core/common_structs.cpp b/binding-mri/fmod-binding/core/common_structs.cpp new file mode 100644 index 00000000..cc5f872f --- /dev/null +++ b/binding-mri/fmod-binding/core/common_structs.cpp @@ -0,0 +1,175 @@ +#include "common_structs.h" +#include "fmod_bindings.h" +#include + +VALUE rb_cGUID = Qnil; + +DECLARE_FMOD2RB(FMOD_GUID, rb_cGUID); +FMOD2RB_NAME(data1, Data1, UINT2NUM); +FMOD2RB_NAME(data2, Data2, UINT2NUM); +FMOD2RB_NAME(data3, Data3, UINT2NUM); +FMOD2RB_CAST(data4, Data4, char*, rb_str_new_cstr); +FMOD2RB_END; + +DECLARE_RB2FMOD(FMOD_GUID, rb_cGUID); +RB2FMOD_NAME(data1, Data1, NUM2UINT); +RB2FMOD_NAME(data2, Data2, NUM2UINT); +RB2FMOD_NAME(data3, Data3, NUM2UINT); +if (RSTRING_LEN(rb_iv_get(self, "@data4")) != 8) +{ + rb_raise(rb_eArgError, "data4 must be 8 bytes long"); +} +strcpy((char*) p.Data4, RSTRING_PTR(rb_iv_get(self, "@data4"))); //! BAD UNSAFE BAD +RB2FMOD_END; + +VALUE rb_c3D_Attributes = Qnil; +DECLARE_FMOD2RB(FMOD_3D_ATTRIBUTES, rb_c3D_Attributes); +FMOD2RB_STRUCT(position, FMOD_VECTOR); +FMOD2RB_STRUCT(velocity, FMOD_VECTOR); +FMOD2RB_STRUCT(forward, FMOD_VECTOR); +FMOD2RB_STRUCT(up, FMOD_VECTOR); +FMOD2RB_END; + +DECLARE_RB2FMOD(FMOD_3D_ATTRIBUTES, rb_c3D_Attributes); +RB2FMOD_STRUCT(position, FMOD_VECTOR); +RB2FMOD_STRUCT(velocity, FMOD_VECTOR); +RB2FMOD_STRUCT(forward, FMOD_VECTOR); +RB2FMOD_STRUCT(up, FMOD_VECTOR); +RB2FMOD_END; + +VALUE rb_cVector = Qnil; +DECLARE_FMOD2RB(FMOD_VECTOR, rb_cVector); +FMOD2RB(x, DBL2NUM); +FMOD2RB(y, DBL2NUM); +FMOD2RB(z, DBL2NUM); +FMOD2RB_END; + +DECLARE_RB2FMOD(FMOD_VECTOR, rb_cVector); +RB2FMOD(x, NUM2DBL); +RB2FMOD(y, NUM2DBL); +RB2FMOD(z, NUM2DBL); +RB2FMOD_END; + +//! Holy fuck +VALUE rb_cCreateSoundExInfo = Qnil; +DECLARE_FMOD2RB(FMOD_CREATESOUNDEXINFO, rb_cCreateSoundExInfo); +FMOD2RB_NAME(cb_size, cbsize, INT2NUM); +FMOD2RB(length, UINT2NUM); +FMOD2RB_NAME(file_offset, fileoffset, UINT2NUM); +FMOD2RB_NAME(num_channels, numchannels, INT2NUM); +FMOD2RB_NAME(default_frequency, defaultfrequency, INT2NUM); +FMOD2RB(format, INT2NUM); +FMOD2RB_NAME(decode_buffer_size, decodebuffersize, UINT2NUM); +FMOD2RB_NAME(initial_subsound, initialsubsound, INT2NUM); +FMOD2RB_NAME(num_subsounds, numsubsounds, INT2NUM); +VALUE inclusion_list = rb_ary_new(); +for (int i = 0; i < p.numsubsounds; i++) +{ + rb_ary_push(inclusion_list, INT2NUM(p.inclusionlist[i])); +} +rb_iv_set(self, "@inclusion_list", inclusion_list); +FMOD2RB_NAME(inclusion_list_num, inclusionlistnum, INT2NUM); +rb_iv_set(self, "@pcm_read_callback", Qnil); // TODO +rb_iv_set(self, "@pcm_set_pos_callback", Qnil); // TODO +rb_iv_set(self, "@nonblock_callback", Qnil); // TODO +FMOD2RB_NAME(dls_name, dlsname, rb_str_new_cstr); +FMOD2RB_NAME(encryption_key, encryptionkey, rb_str_new_cstr); +FMOD2RB_NAME(max_poly_phony, maxpolyphony, INT2NUM); +rb_iv_set(self, "@userdata", Qnil); // TODO +FMOD2RB_NAME(suggested_sound_type, suggestedsoundtype, INT2NUM); +rb_iv_set(self, "@file_user_open", Qnil); // TODO +rb_iv_set(self, "@file_user_close", Qnil); // TODO +rb_iv_set(self, "@file_user_read", Qnil); // TODO +rb_iv_set(self, "@file_user_seek", Qnil); // TODO +rb_iv_set(self, "@file_user_async_read", Qnil); // TODO +rb_iv_set(self, "@file_user_async_cancel", Qnil); // TODO +rb_iv_set(self, "@file_user_data", Qnil); // TODO +FMOD2RB_NAME(file_buffer_size, filebuffersize, INT2NUM); +FMOD2RB_NAME(channel_order, channelorder, INT2NUM); +rb_iv_set(self, "@channel_group", Qnil); // TODO +FMOD2RB_NAME(initial_seek_position, initialseekposition, UINT2NUM); +FMOD2RB_NAME(initial_seek_pos_type, initialseekpostype, UINT2NUM); +FMOD2RB_NAME(ignore_set_filesystem, ignoresetfilesystem, INT2NUM); +FMOD2RB_NAME(audio_queue_policy, audioqueuepolicy, UINT2NUM); +FMOD2RB_NAME(min_midi_granularity, minmidigranularity, UINT2NUM); +FMOD2RB_NAME(nonblock_thread_id, nonblockthreadid, INT2NUM); +if (p.fsbguid) { + rb_iv_set(self, "@fsb_guid", fmodFMOD_GUID2rb(*p.fsbguid)); // FIXME: Probably not right +} +FMOD2RB_END; + +VALUE rb_cCPUUsage = Qnil; +DECLARE_FMOD2RB(FMOD_CPU_USAGE, rb_cCPUUsage); +FMOD2RB(dsp, DBL2NUM); +FMOD2RB(stream, DBL2NUM); +FMOD2RB(geometry, DBL2NUM); +FMOD2RB(update, DBL2NUM); +FMOD2RB(convolution1, DBL2NUM); +FMOD2RB(convolution2, DBL2NUM); +FMOD2RB_END; + +void bindFmodCoreStructs() +{ + rb_cGUID = rb_define_class_under(rb_mFMOD_Core, "GUID", rb_cObject); + ATTR(rb_cGUID, data1); + ATTR(rb_cGUID, data2); + ATTR(rb_cGUID, data3); + ATTR(rb_cGUID, data4); + + rb_c3D_Attributes = rb_define_class_under(rb_mFMOD_Core, "_3DAttributes", rb_cObject); + ATTR(rb_c3D_Attributes, position); + ATTR(rb_c3D_Attributes, velocity); + ATTR(rb_c3D_Attributes, forward); + ATTR(rb_c3D_Attributes, up); + + rb_cVector = rb_define_class_under(rb_mFMOD_Core, "Vector", rb_cObject); + ATTR(rb_cVector, x); + ATTR(rb_cVector, y); + ATTR(rb_cVector, z); + + rb_cCreateSoundExInfo = rb_define_class_under(rb_mFMOD_Core, "CreateSoundExInfo", rb_cObject); + ATTR(rb_cCreateSoundExInfo, cb_size); + ATTR(rb_cCreateSoundExInfo, length); + ATTR(rb_cCreateSoundExInfo, file_offset); + ATTR(rb_cCreateSoundExInfo, num_channels); + ATTR(rb_cCreateSoundExInfo, default_frequency); + ATTR(rb_cCreateSoundExInfo, format); + ATTR(rb_cCreateSoundExInfo, decode_buffer_size); + ATTR(rb_cCreateSoundExInfo, initial_subsound); + ATTR(rb_cCreateSoundExInfo, num_subsounds); + ATTR(rb_cCreateSoundExInfo, inclusion_list); + ATTR(rb_cCreateSoundExInfo, inclusion_list_num); + ATTR(rb_cCreateSoundExInfo, pcm_read_callback); + ATTR(rb_cCreateSoundExInfo, pcm_set_pos_callback); + ATTR(rb_cCreateSoundExInfo, nonblock_callback); + ATTR(rb_cCreateSoundExInfo, dls_name); + ATTR(rb_cCreateSoundExInfo, encryption_key); + ATTR(rb_cCreateSoundExInfo, max_poly_phony); + ATTR(rb_cCreateSoundExInfo, userdata); + ATTR(rb_cCreateSoundExInfo, suggested_sound_type); + ATTR(rb_cCreateSoundExInfo, file_user_open); + ATTR(rb_cCreateSoundExInfo, file_user_close); + ATTR(rb_cCreateSoundExInfo, file_user_read); + ATTR(rb_cCreateSoundExInfo, file_user_seek); + ATTR(rb_cCreateSoundExInfo, file_user_async_read); + ATTR(rb_cCreateSoundExInfo, file_user_async_cancel); + ATTR(rb_cCreateSoundExInfo, file_user_data); + ATTR(rb_cCreateSoundExInfo, file_buffer_size); + ATTR(rb_cCreateSoundExInfo, channel_order); + ATTR(rb_cCreateSoundExInfo, channel_group); + ATTR(rb_cCreateSoundExInfo, initial_seek_position); + ATTR(rb_cCreateSoundExInfo, initial_seek_pos_type); + ATTR(rb_cCreateSoundExInfo, ignore_set_filesystem); + ATTR(rb_cCreateSoundExInfo, audio_queue_policy); + ATTR(rb_cCreateSoundExInfo, min_midi_granularity); + ATTR(rb_cCreateSoundExInfo, nonblock_thread_id); + ATTR(rb_cCreateSoundExInfo, fsb); + + rb_cCPUUsage = rb_define_class_under(rb_mFMOD_Core, "CPUUsage", rb_cObject); + ATTR(rb_cCPUUsage, dsp); + ATTR(rb_cCPUUsage, stream); + ATTR(rb_cCPUUsage, geometry); + ATTR(rb_cCPUUsage, update); + ATTR(rb_cCPUUsage, convolution1); + ATTR(rb_cCPUUsage, convolution2); +} diff --git a/binding-mri/fmod-binding/core/fmod-core-binding.cpp b/binding-mri/fmod-binding/core/fmod-core-binding.cpp new file mode 100644 index 00000000..fe1ca067 --- /dev/null +++ b/binding-mri/fmod-binding/core/fmod-core-binding.cpp @@ -0,0 +1,13 @@ +#include "binding-util.h" +#include "fmod_bindings.h" + +VALUE rb_mFMOD = Qnil; +VALUE rb_mFMOD_Core = Qnil; + +void fmodCoreBindingInit() { + rb_mFMOD = rb_define_module("FMOD"); + rb_mFMOD_Core = rb_define_module_under(rb_mFMOD, "Core"); + + bindFmodCoreStructs(); + bindFmodSystem(); +} diff --git a/binding-mri/fmod-binding/core/system.cpp b/binding-mri/fmod-binding/core/system.cpp new file mode 100644 index 00000000..203e6cc7 --- /dev/null +++ b/binding-mri/fmod-binding/core/system.cpp @@ -0,0 +1,21 @@ +#include "binding-util.h" +#include "fmod_bindings.h" +#ifdef AUTO_CLEAN_FMOD +#include "debugwriter.h" +#include +#endif + +DEF_TYPE(System); +System::~System() { + #ifdef AUTO_CLEAN_FMOD + Debug() << "Warning: auto releasing system (garbage collected?)"; + Debug() << "System release result: " << FMOD_ErrorString(FMOD_System_Release(p)); + #endif +} + +VALUE rb_cSystem = Qnil; + +void bindFmodSystem() { + rb_cSystem = rb_define_class_under(rb_mFMOD_Core, "System", rb_cObject); + rb_define_alloc_func(rb_cSystem, classAllocate<&SystemType>); +} diff --git a/binding-mri/fmod-binding/fmod_bindings.h b/binding-mri/fmod-binding/fmod_bindings.h new file mode 100644 index 00000000..d602d19a --- /dev/null +++ b/binding-mri/fmod-binding/fmod_bindings.h @@ -0,0 +1,351 @@ +#ifndef FMOD_BINDINGS_H +#define FMOD_BINDINGS_H + +#include "binding-util.h" +#include "common_structs.h" +#include + +//* Bool to ruby converter +#define BOOL2RB(val) ((val) ? Qtrue : Qfalse) +#define RB2BOOL(val) (val == Qtrue) + +/* + * We use wrapper classes since we can't set the private data + * of the ruby object using setPrivateData(klass, self) + * with most FMOD types (Like FMOD_STUDIO_BANK, etc) since + * their members are not defined anywhere + */ + +#define DEF_FMOD_WRAPPER(Klass, wrap_type) \ + class Klass \ + { \ + public: \ + wrap_type *p; \ + \ + Klass(wrap_type *p) \ + : p(p) {} \ + \ + ~Klass(); \ + }; + +/* +* Return result macros +* These macros cover returning results of function calls in fmod +* Most functions have 2 (or should have 2) return values, +* ordered by an FMOD_RESULT and then the actual return value. +* +* FMOD_RESULT_WRAP is for when we need to wrap an FMOD struct pointer +! but the struct has no defined members (I.e FMOD_STUDIO_BANK) +* +* FMOD_RESULT_CONVERT is for when we need to convert the return value +* using a standard ruby conversion macro (like INT2NUM) +* +* FMOD_RESULT_VALUE is for when we want to add a VALUE to the +* return array. +* +* FMOD_RESULT_NO_CHECK is for when we are almost always returning a value +* and the value could be 0, it also acts like FMOD_RESULT_CONVERT +* +* FMOD_RESULT_NO_WRAP is for when we need to wrap an FMOD struct pointer, +! but the struct has defined members (I.e. FMOD_GUID) +* +* FMOD_RESULT_SIMPLE just returns the result. That's it. +*/ +#define FMOD_RESULT_BASE \ + VALUE return_ary = rb_ary_new(); \ + rb_ary_push(return_ary, INT2NUM(result)); + +#define FMOD_RESULT_RET return return_ary; + +//! We use alloc since it skirts around initializing the object +#define FMOD_RESULT_WRAP(val, wrap) \ + FMOD_RESULT_BASE \ + if (result == FMOD_OK) \ + { \ + VALUE return_val = rb_obj_alloc(rb_c##wrap); \ + setPrivateData(return_val, new wrap(val)); \ + rb_ary_push(return_ary, return_val); \ + } \ + FMOD_RESULT_RET + +#define FMOD_RESULT_CONVERT(val, convert) \ + FMOD_RESULT_BASE \ + if (result == FMOD_OK) \ + { \ + rb_ary_push(return_ary, convert(val)); \ + } \ + FMOD_RESULT_RET + +#define FMOD_RESULT_NO_CHECK(val, convert) \ + FMOD_RESULT_BASE \ + rb_ary_push(return_ary, convert(val)); \ + FMOD_RESULT_RET + +#define FMOD_RESULT_VALUE(val) \ + FMOD_RESULT_BASE \ + if (result == FMOD_OK) \ + { \ + rb_ary_push(return_ary, val); \ + } \ + FMOD_RESULT_RET + +//! We can delete the val (and want to) since it's always a newly +//! allocated struct that this is used for +//! If we don't, and the function did not return ok, we risk a +//! memory leak +#define FMOD_RESULT_NO_WRAP(val, klass) \ + FMOD_RESULT_BASE \ + if (result == FMOD_OK) \ + { \ + VALUE return_val = fmod##klass##2rb(val); \ + rb_ary_push(return_ary, return_val); \ + } \ + \ + FMOD_RESULT_RET + +#define FMOD_RESULT_SIMPLE \ + FMOD_RESULT_BASE \ + FMOD_RESULT_RET + +DEF_FMOD_WRAPPER(System, FMOD_SYSTEM) +DECL_TYPE(System); + +DEF_FMOD_WRAPPER(StudioSystem, FMOD_STUDIO_SYSTEM); +DECL_TYPE(StudioSystem); + +//? Define wrapper for Bank +DEF_FMOD_WRAPPER(Bank, FMOD_STUDIO_BANK); +//? Define ruby data type for Bank +DECL_TYPE(Bank); + +DEF_FMOD_WRAPPER(VCA, FMOD_STUDIO_VCA); +DECL_TYPE(VCA); + +DEF_FMOD_WRAPPER(Bus, FMOD_STUDIO_BUS); +DECL_TYPE(Bus); + +DEF_FMOD_WRAPPER(EventDescription, FMOD_STUDIO_EVENTDESCRIPTION); +DECL_TYPE(EventDescription); + +DEF_FMOD_WRAPPER(EventInstance, FMOD_STUDIO_EVENTINSTANCE); +DECL_TYPE(EventInstance); + +DEF_FMOD_WRAPPER(CommandReplay, FMOD_STUDIO_COMMANDREPLAY); +DECL_TYPE(CommandReplay); + +// * Modules and classes to be defined under +extern VALUE rb_mFMOD; +extern VALUE rb_mFMOD_Core; +extern VALUE rb_mFMOD_Studio; +extern VALUE rb_cSystem; +extern VALUE rb_cGUID; +DEFINE_CONVERT_FUNC(FMOD_GUID); +extern VALUE rb_c3D_Attributes; +DEFINE_CONVERT_FUNC(FMOD_3D_ATTRIBUTES); +extern VALUE rb_cVector; +DEFINE_CONVERT_FUNC(FMOD_VECTOR); +extern VALUE rb_cCreateSoundExInfo; +DEFINE_CONVERT_FUNC(FMOD_CREATESOUNDEXINFO); +extern VALUE rb_cCPUUsage; +DEFINE_CONVERT_FUNC(FMOD_CPU_USAGE); + +extern VALUE rb_cStudioSystem; +extern VALUE rb_cBank; +extern VALUE rb_cVCA; +extern VALUE rb_cBus; +extern VALUE rb_cMemoryUsage; +DEFINE_CONVERT_FUNC(FMOD_STUDIO_MEMORY_USAGE); +extern VALUE rb_cEventDescription; +extern VALUE rb_cParameterID; +DEFINE_CONVERT_FUNC(FMOD_STUDIO_PARAMETER_ID); +extern VALUE rb_cParameterDescription; +DEFINE_CONVERT_FUNC(FMOD_STUDIO_PARAMETER_DESCRIPTION); +extern VALUE rb_cUserProperty; +DEFINE_CONVERT_FUNC(FMOD_STUDIO_USER_PROPERTY); +extern VALUE rb_cEventInstance; +extern VALUE rb_cCommandReplay; +extern VALUE rb_cCommandInfo; +DEFINE_CONVERT_FUNC(FMOD_STUDIO_COMMAND_INFO); +extern VALUE rb_cAdvancedSettings; +DEFINE_CONVERT_FUNC(FMOD_STUDIO_ADVANCEDSETTINGS); +extern VALUE rb_cSoundInfo; +DEFINE_CONVERT_FUNC(FMOD_STUDIO_SOUND_INFO); +extern VALUE rb_cStudioCPUUsage; +DEFINE_CONVERT_FUNC(FMOD_STUDIO_CPU_USAGE); +extern VALUE rb_cBufferUsage; +DEFINE_CONVERT_FUNC(FMOD_STUDIO_BUFFER_USAGE); +extern VALUE rb_cBufferInfo; +DEFINE_CONVERT_FUNC(FMOD_STUDIO_BUFFER_INFO); + +void bindFmodStudioBank(); +void bindFmodStudioSystem(); +void bindFmodStudioStructs(); +void bindFmodStudioVCA(); +void bindFmodStudioBus(); +void bindFmodStudioEventDescription(); +void bindFmodStudioEventInstance(); +void bindFmodStudioCommandReplay(); + +void bindFmodSystem(); +void bindFmodCoreStructs(); + +inline RB_METHOD(fmodErrorInit) +{ + rb_raise(rb_eException, "You cannot instantiate this class directly."); + + return Qnil; +} + +//? These functions are common, so we share them +//? in the header +#define FMOD_USERDATA_FUNC(func_base, type) \ + RB_METHOD(fmodGetUserData) \ + { \ + RB_UNUSED_PARAM; \ + \ + type *b = getPrivateData(self); \ + VALUE data; \ + \ + FMOD_RESULT result = func_base##_GetUserData( \ + b->p, (void **)&data); \ + \ + FMOD_RESULT_BASE; \ + if (data) \ + { \ + rb_ary_push(return_ary, data); \ + } \ + FMOD_RESULT_RET; \ + } \ + RB_METHOD(fmodSetUserData) \ + { \ + VALUE arg; \ + rb_get_args(argc, argv, "o", &arg RB_ARG_END); \ + \ + rb_iv_set(self, "userdata_dont_touch_please", arg); \ + \ + type *b = getPrivateData(self); \ + \ + FMOD_RESULT result = func_base##_SetUserData( \ + b->p, (void *)arg); \ + \ + FMOD_RESULT_SIMPLE; \ + } + +#define FMOD_VALID_FUNC(func_base, type) \ + RB_METHOD(fmodIsValid) \ + { \ + RB_UNUSED_PARAM; \ + type *b = getPrivateData(self); \ + return BOOL2RB(func_base##_IsValid(b->p)); \ + } + +#define FMOD_ID_FUNC(func_base, type) \ + RB_METHOD(fmodGetID) \ + { \ + RB_UNUSED_PARAM; \ + type *b = getPrivateData(self); \ + FMOD_GUID guid = FMOD_GUID(); \ + FMOD_RESULT result = func_base##_GetID(b->p, &guid); \ + FMOD_RESULT_NO_WRAP(guid, FMOD_GUID); \ + } + +#define FMOD_PATH_FUNC(func_base, type) \ + RB_METHOD(fmodGetPath) \ + { \ + RB_UNUSED_PARAM; \ + type *b = getPrivateData(self); \ + int retrieved; \ + char *path = NULL; \ + FMOD_RESULT result = func_base##_GetPath(b->p, NULL, 0, &retrieved); \ + if (result == FMOD_OK) \ + { \ + path = new char[retrieved]; \ + result = func_base##_GetPath(b->p, path, retrieved, &retrieved); \ + } \ + \ + FMOD_RESULT_CONVERT(path, rb_str_new_cstr); \ + } + +#define FMOD_VOLUME_FUNC(func_base, type) \ + RB_METHOD(fmodGetVolume) \ + { \ + RB_UNUSED_PARAM; \ + type *b = getPrivateData(self); \ + float volume; \ + float finalvolume; \ + FMOD_RESULT result = func_base##_GetVolume(b->p, &volume, &finalvolume); \ + FMOD_RESULT_BASE; \ + if (result == FMOD_OK) \ + { \ + rb_ary_push(return_ary, DBL2NUM(volume)); \ + rb_ary_push(return_ary, DBL2NUM(finalvolume)); \ + } \ + FMOD_RESULT_RET; \ + } \ + RB_METHOD(fmodSetVolume) \ + { \ + float volume; \ + rb_get_args(argc, argv, "f", &volume RB_ARG_END); \ + type *b = getPrivateData(self); \ + FMOD_RESULT result = func_base##_SetVolume(b->p, volume); \ + FMOD_RESULT_SIMPLE; \ + } + +#define FMOD_PAUSED_FUNC(func_base, type) \ + RB_METHOD(fmodGetPaused) \ + { \ + RB_UNUSED_PARAM; \ + type *b = getPrivateData(self); \ + int paused; \ + FMOD_RESULT result = func_base##_GetPaused(b->p, &paused); \ + FMOD_RESULT_CONVERT(paused, BOOL2RB); \ + } \ + RB_METHOD(fmodSetPaused) \ + { \ + bool paused; \ + rb_get_args(argc, argv, "b", &paused RB_ARG_END); \ + type *b = getPrivateData(self); \ + FMOD_RESULT result = func_base##_SetPaused(b->p, paused); \ + FMOD_RESULT_SIMPLE; \ + } + +#define FMOD_CPU_USAGE_FUNC(func_base, type) \ + RB_METHOD(fmodGetCPUUsage) \ + { \ + RB_UNUSED_PARAM; \ + type *b = getPrivateData(self); \ + unsigned int exclusive, inclusive; \ + FMOD_RESULT result = func_base##_GetCPUUsage( \ + b->p, &exclusive, &inclusive); \ + FMOD_RESULT_BASE; \ + if (result == FMOD_OK) \ + { \ + rb_ary_push(return_ary, UINT2NUM(exclusive)); \ + rb_ary_push(return_ary, UINT2NUM(inclusive)); \ + } \ + FMOD_RESULT_RET; \ + } + +#define FMOD_MEMORY_USAGE_FUNC(func_base, type) \ + RB_METHOD(fmodGetMemoryUsage) \ + { \ + RB_UNUSED_PARAM; \ + type *b = getPrivateData(self); \ + FMOD_STUDIO_MEMORY_USAGE usage = FMOD_STUDIO_MEMORY_USAGE(); \ + FMOD_RESULT result = func_base##_GetMemoryUsage(b->p, &usage); \ + FMOD_RESULT_NO_WRAP(usage, FMOD_STUDIO_MEMORY_USAGE); \ + } + +#define FMOD_EQUAL_FUNC(type) \ + RB_METHOD(fmodEqual) \ + { \ + VALUE otherObj; \ + rb_get_args(argc, argv, "o", &otherObj RB_ARG_END); \ + if (!rb_typeddata_is_kind_of(otherObj, &type##Type)) \ + return Qfalse; \ + type *p = getPrivateData(self); \ + type *b = getPrivateDataCheck(otherObj, type##Type); \ + return rb_bool_new(p->p == b->p); \ + } + +#endif diff --git a/binding-mri/fmod-binding/fmod_enums.cpp b/binding-mri/fmod-binding/fmod_enums.cpp new file mode 100644 index 00000000..b7fea589 --- /dev/null +++ b/binding-mri/fmod-binding/fmod_enums.cpp @@ -0,0 +1 @@ +#include "fmod_enums.rb.xxd" diff --git a/binding-mri/fmod-binding/fmod_enums.rb b/binding-mri/fmod-binding/fmod_enums.rb new file mode 100644 index 00000000..9f85050a --- /dev/null +++ b/binding-mri/fmod-binding/fmod_enums.rb @@ -0,0 +1,749 @@ +module FMOD + module Core + module DebugFlags + LEVEL_NONE = 0x00000000 + LEVEL_ERROR = 0x00000001 + LEVEL_WARNING = 0x00000002 + LEVEL_LOG = 0x00000004 + TYPE_MEMORY = 0x00000100 + TYPE_FILE = 0x00000200 + TYPE_CODEC = 0x00000400 + TYPE_TRACE = 0x00000800 + DISPLAY_TIMESTAMPS = 0x00010000 + DISPLAY_LINENUMBERS = 0x00020000 + DISPLAY_THREAD = 0x00040000 + end + + module MemoryType + NORMAL = 0x00000000 + STREAM_FILE = 0x00000001 + STREAM_DECODE = 0x00000002 + SAMPLEDATA = 0x00000004 + DSP_BUFFER = 0x00000008 + PLUGIN = 0x00000010 + PERSISTENT = 0x00200000 + ALL = 0xFFFFFFFF + end + + module InitFlags + NORMAL = 0x00000000 + STREAM_FROM_UPDATE = 0x00000001 + MIX_FROM_UPDATE = 0x00000002 + _3D_RIGHTHANDED = 0x00000004 + CHANNEL_LOWPASS = 0x00000100 + CHANNEL_DISTANCEFILTER = 0x00000200 + PROFILE_ENABLE = 0x00010000 + VOL0_BECOMES_VIRTUAL = 0x00020000 + GEOMETRY_USECLOSEST = 0x00040000 + PREFER_DOLBY_DOWNMIX = 0x00080000 + THREAD_UNSAFE = 0x00100000 + PROFILE_METER_ALL = 0x00200000 + MEMORY_TRACKING = 0x00400000 + end + + module DriverState + CONNECTED = 0x00000001 + DEFAULT = 0x00000002 + end + + module TimeUnit + MS = 0x00000001 + PCM = 0x00000002 + PCMBYTES = 0x00000004 + RAWBYTES = 0x00000008 + PCMFRACTION = 0x00000010 + MODORDER = 0x00000100 + MODROW = 0x00000200 + MODPATTERN = 0x00000400 + end + + module SystemCallbackType + DEVICELISTCHANGED = 0x00000001 + DEVICELOST = 0x00000002 + MEMORYALLOCATIONFAILED = 0x00000004 + THREADCREATED = 0x00000008 + BADDSPCONNECTION = 0x00000010 + PREMIX = 0x00000020 + POSTMIX = 0x00000040 + ERROR = 0x00000080 + MIDMIX = 0x00000100 + THREADDESTROYED = 0x00000200 + PREUPDATE = 0x00000400 + POSTUPDATE = 0x00000800 + RECORDLISTCHANGED = 0x00001000 + BUFFEREDNOMIX = 0x00002000 + DEVICEREINITIALIZE = 0x00004000 + OUTPUTUNDERRUN = 0x00008000 + ALL = 0xFFFFFFFF + end + + module Mode + DEFAULT = 0x00000000 + LOOP_OFF = 0x00000001 + LOOP_NORMAL = 0x00000002 + LOOP_BIDI = 0x00000004 + _2D = 0x00000008 + _3D = 0x00000010 + CREATESTREAM = 0x00000080 + CREATESAMPLE = 0x00000100 + CREATECOMPRESSEDSAMPLE = 0x00000200 + OPENUSER = 0x00000400 + OPENMEMORY = 0x00000800 + OPENMEMORY_POINT = 0x10000000 + OPENRAW = 0x00001000 + OPENONLY = 0x00002000 + ACCURATETIME = 0x00004000 + MPEGSEARCH = 0x00008000 + NONBLOCKING = 0x00010000 + UNIQUE = 0x00020000 + _3D_HEADRELATIVE = 0x00040000 + _3D_WORLDRELATIVE = 0x00080000 + _3D_INVERSEROLLOFF = 0x00100000 + _3D_LINEARROLLOFF = 0x00200000 + _3D_LINEARSQUAREROLLOFF = 0x00400000 + _3D_INVERSETAPEREDROLLOFF = 0x00800000 + _3D_CUSTOMROLLOFF = 0x04000000 + _3D_IGNOREGEOMETRY = 0x40000000 + IGNORETAGS = 0x02000000 + LOWMEM = 0x08000000 + VIRTUAL_PLAYFROMSTART = 0x80000000 + end + + module ChannelMask + FRONT_LEFT = 0x00000001 + FRONT_RIGHT = 0x00000002 + FRONT_CENTER = 0x00000004 + LOW_FREQUENCY = 0x00000008 + SURROUND_LEFT = 0x00000010 + SURROUND_RIGHT = 0x00000020 + BACK_LEFT = 0x00000040 + BACK_RIGHT = 0x00000080 + BACK_CENTER = 0x00000100 + + MONO = (FRONT_LEFT) + STEREO = (FRONT_LEFT | FRONT_RIGHT) + LRC = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER) + QUAD = (FRONT_LEFT | FRONT_RIGHT | SURROUND_LEFT | SURROUND_RIGHT) + SURROUND = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | SURROUND_LEFT | SURROUND_RIGHT) + _5POINT1 = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | SURROUND_LEFT | SURROUND_RIGHT) + _5POINT1_REARS = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | BACK_LEFT | BACK_RIGHT) + _7POINT0 = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | SURROUND_LEFT | SURROUND_RIGHT | BACK_LEFT | BACK_RIGHT) + _7POINT1 = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | SURROUND_LEFT | SURROUND_RIGHT | BACK_LEFT | BACK_RIGHT) + end + + module ThreadPriority + PLATFORM_MIN = (-32 * 1024) + PLATFORM_MAX = (32 * 1024) + + DEFAULT = (PLATFORM_MIN - 1) + LOW = (PLATFORM_MIN - 2) + MEDIUM = (PLATFORM_MIN - 3) + HIGH = (PLATFORM_MIN - 4) + VERY_HIGH = (PLATFORM_MIN - 5) + EXTREME = (PLATFORM_MIN - 6) + CRITICAL = (PLATFORM_MIN - 7) + + MIXER = EXTREME + FEEDER = CRITICAL + STREAM = VERY_HIGH + FILE = HIGH + NONBLOCKING = HIGH + RECORD = HIGH + GEOMETRY = LOW + PROFILER = MEDIUM + STUDIO_UPDATE = MEDIUM + STUDIO_LOAD_BANK = MEDIUM + STUDIO_LOAD_SAMPLE = MEDIUM + CONVOLUTION1 = VERY_HIGH + CONVOLUTION2 = VERY_HIGH + end + + module ThreadStackSize + DEFAULT = 0 + MIXER = (80 * 1024) + FEEDER = (16 * 1024) + STREAM = (96 * 1024) + FILE = (64 * 1024) + NONBLOCKING = (112 * 1024) + RECORD = (16 * 1024) + GEOMETRY = (48 * 1024) + PROFILER = (128 * 1024) + STUDIO_UPDATE = (96 * 1024) + STUDIO_LOAD_BANK = (96 * 1024) + STUDIO_LOAD_SAMPLE = (96 * 1024) + CONVOLUTION1 = (16 * 1024) + CONVOLUTION2 = (16 * 1024) + end + + module ThreadAffinity + GROUP_DEFAULT = 0x4000000000000000 + GROUP_A = 0x4000000000000001 + GROUP_B = 0x4000000000000002 + GROUP_C = 0x4000000000000003 + + MIXER = GROUP_A + FEEDER = GROUP_C + STREAM = GROUP_C + FILE = GROUP_C + NONBLOCKING = GROUP_C + RECORD = GROUP_C + GEOMETRY = GROUP_C + PROFILER = GROUP_C + STUDIO_UPDATE = GROUP_B + STUDIO_LOAD_BANK = GROUP_C + STUDIO_LOAD_SAMPLE = GROUP_C + CONVOLUTION1 = GROUP_C + CONVOLUTION2 = GROUP_C + + CORE_ALL = 0 + CORE_0 = (1 << 0) + CORE_1 = (1 << 1) + CORE_2 = (1 << 2) + CORE_3 = (1 << 3) + CORE_4 = (1 << 4) + CORE_5 = (1 << 5) + CORE_6 = (1 << 6) + CORE_7 = (1 << 7) + CORE_8 = (1 << 8) + CORE_9 = (1 << 9) + CORE_10 = (1 << 10) + CORE_11 = (1 << 11) + CORE_12 = (1 << 12) + CORE_13 = (1 << 13) + CORE_14 = (1 << 14) + CORE_15 = (1 << 15) + end + + module Preset + OFF = [1000, 7, 11, 5000, 100, 100, 100, 250, 0, 20, 96, -80.0] + GENERIC = [1500, 7, 11, 5000, 83, 100, 100, 250, 0, 14500, 96, -8.0] + PADDEDCELL = [170, 1, 2, 5000, 10, 100, 100, 250, 0, 160, 84, -7.8] + ROOM = [400, 2, 3, 5000, 83, 100, 100, 250, 0, 6050, 88, -9.4] + BATHROOM = [1500, 7, 11, 5000, 54, 100, 60, 250, 0, 2900, 83, 0.5] + LIVINGROOM = [500, 3, 4, 5000, 10, 100, 100, 250, 0, 160, 58, -19.0] + STONEROOM = [2300, 12, 17, 5000, 64, 100, 100, 250, 0, 7800, 71, -8.5] + AUDITORIUM = [4300, 20, 30, 5000, 59, 100, 100, 250, 0, 5850, 64, -11.7] + CONCERTHALL = [3900, 20, 29, 5000, 70, 100, 100, 250, 0, 5650, 80, -9.8] + CAVE = [2900, 15, 22, 5000, 100, 100, 100, 250, 0, 20000, 59, -11.3] + ARENA = [7200, 20, 30, 5000, 33, 100, 100, 250, 0, 4500, 80, -9.6] + HANGAR = [10000, 20, 30, 5000, 23, 100, 100, 250, 0, 3400, 72, -7.4] + CARPETTEDHALLWAY = [300, 2, 30, 5000, 10, 100, 100, 250, 0, 500, 56, -24.0] + HALLWAY = [1500, 7, 11, 5000, 59, 100, 100, 250, 0, 7800, 87, -5.5] + STONECORRIDOR = [270, 13, 20, 5000, 79, 100, 100, 250, 0, 9000, 86, -6.0] + ALLEY = [1500, 7, 11, 5000, 86, 100, 100, 250, 0, 8300, 80, -9.8] + FOREST = [1500, 162, 88, 5000, 54, 79, 100, 250, 0, 760, 94, -12.3] + CITY = [1500, 7, 11, 5000, 67, 50, 100, 250, 0, 4050, 66, -26.0] + MOUNTAINS = [1500, 300, 100, 5000, 21, 27, 100, 250, 0, 1220, 82, -24.0] + QUARRY = [1500, 61, 25, 5000, 83, 100, 100, 250, 0, 3400, 100, -5.0] + PLAIN = [1500, 179, 100, 5000, 50, 21, 100, 250, 0, 1670, 65, -28.0] + PARKINGLOT = [1700, 8, 12, 5000, 100, 100, 100, 250, 0, 20000, 56, -19.5] + SEWERPIPE = [2800, 14, 21, 5000, 14, 80, 60, 250, 0, 3400, 66, 1.2] + UNDERWATER = [1500, 7, 11, 5000, 10, 100, 100, 250, 0, 500, 92, 7.0] + end + + MAX_CHANNEL_WIDTH = 32 + MAX_SYSTEMS = 8 + MAX_LISTENERS = 8 + REVERB_MAXINSTANCES = 4 + PORT_INDEX_NONE = 0xFFFFFFFFFFFFFFFF + + FORCEINT = 65536 + + module ThreadType + %w[ + MIXER + FEEDER + STREAM + FILE + NONBLOCKING + RECORD + GEOMETRY + PROFILER + STUDIO_UPDATE + STUDIO_LOAD_BANK + STUDIO_LOAD_SAMPLE + CONVOLUTION1 + CONVOLUTION2 + ].each_with_index do |const, i| + self.const_set(const, i) + end + end + + module Result + %w[ + OK + ERR_BADCOMMAND + ERR_CHANNEL_ALLOC + ERR_CHANNEL_STOLEN + ERR_DMA + ERR_DSP_CONNECTION + ERR_DSP_DONTPROCESS + ERR_DSP_FORMAT + ERR_DSP_INUSE + ERR_DSP_NOTFOUND + ERR_DSP_RESERVED + ERR_DSP_SILENCE + ERR_DSP_TYPE + ERR_FILE_BAD + ERR_FILE_COULDNOTSEEK + ERR_FILE_DISKEJECTED + ERR_FILE_EOF + ERR_FILE_ENDOFDATA + ERR_FILE_NOTFOUND + ERR_FORMAT + ERR_HEADER_MISMATCH + ERR_HTTP + ERR_HTTP_ACCESS + ERR_HTTP_PROXY_AUTH + ERR_HTTP_SERVER_ERROR + ERR_HTTP_TIMEOUT + ERR_INITIALIZATION + ERR_INITIALIZED + ERR_INTERNAL + ERR_INVALID_FLOAT + ERR_INVALID_HANDLE + ERR_INVALID_PARAM + ERR_INVALID_POSITION + ERR_INVALID_SPEAKER + ERR_INVALID_SYNCPOINT + ERR_INVALID_THREAD + ERR_INVALID_VECTOR + ERR_MAXAUDIBLE + ERR_MEMORY + ERR_MEMORY_CANTPOINT + ERR_NEEDS3D + ERR_NEEDSHARDWARE + ERR_NET_CONNECT + ERR_NET_SOCKET_ERROR + ERR_NET_URL + ERR_NET_WOULD_BLOCK + ERR_NOTREADY + ERR_OUTPUT_ALLOCATED + ERR_OUTPUT_CREATEBUFFER + ERR_OUTPUT_DRIVERCALL + ERR_OUTPUT_FORMAT + ERR_OUTPUT_INIT + ERR_OUTPUT_NODRIVERS + ERR_PLUGIN + ERR_PLUGIN_MISSING + ERR_PLUGIN_RESOURCE + ERR_PLUGIN_VERSION + ERR_RECORD + ERR_REVERB_CHANNELGROUP + ERR_REVERB_INSTANCE + ERR_SUBSOUNDS + ERR_SUBSOUND_ALLOCATED + ERR_SUBSOUND_CANTMOVE + ERR_TAGNOTFOUND + ERR_TOOMANYCHANNELS + ERR_TRUNCATED + ERR_UNIMPLEMENTED + ERR_UNINITIALIZED + ERR_UNSUPPORTED + ERR_VERSION + ERR_EVENT_ALREADY_LOADED + ERR_EVENT_LIVEUPDATE_BUSY + ERR_EVENT_LIVEUPDATE_MISMA + ERR_EVENT_LIVEUPDATE_TIMEO + ERR_EVENT_NOTFOUND + ERR_STUDIO_UNINITIALIZED + ERR_STUDIO_NOT_LOADED + ERR_INVALID_STRING + ERR_ALREADY_LOCKED + ERR_NOT_LOCKED + ERR_RECORD_DISCONNECTED + ERR_TOOMANYSAMPLES + ].each_with_index do |const, i| + self.const_set(const, i) + end + end + + module ChannelControlType + CHANNEL = 0 + CHANNELGROUP = 1 + MAX = 2 + end + + module OutputType + %w[ + AUTODETECT + UNKNOWN + NOSOUND + WAVWRITER + NOSOUND_NRT + WAVWRITER_NRT + WASAPI + ASIO + PULSEAUDIO + ALSA + COREAUDIO + AUDIOTRACK + OPENSL + AUDIOOUT + AUDIO3D + WEBAUDIO + NNAUDIO + WINSONIC + AAUDIO + AUDIOWORKLET + MAX + ].each_with_index do |const, i| + self.const_set(const, i) + end + end + + module DebugMode + TTY = 0 + FILE = 1 + CALLBACK = 2 + end + + module SpeakerMode + DEFAULT = 0 + RAW = 1 + MONO = 2 + STEREO = 3 + QUAD = 4 + SURROUND = 5 + _5POINT1 = 6 + _7POINT1 = 7 + _7POINT1POINT4 = 8 + MAX = 9 + end + + module Speaker + %w[ + NONE + FRONT_LEFT + FRONT_RIGHT + FRONT_CENTER + LOW_FREQUENCY + SURROUND_LEFT + SURROUND_RIGHT + BACK_LEFT + BACK_RIGHT + TOP_FRONT_LEFT + TOP_FRONT_RIGHT + TOP_BACK_LEFT + TOP_BACK_RIGHT + MAX + ].each_with_index do |const, i| + self.const_set(const, i - 1) + end + end + + module ChannelOrder + %w[ + DEFAULT + WAVEFORMAT + PROTOOLS + ALLMONO + ALLSTEREO + ALSA + MAX + ].each_with_index do |const, i| + self.const_set(const, i) + end + end + + module PluginType + OUTPUT = 0 + CODEC = 1 + DSP = 2 + MAX = 3 + end + + module SoundType + %w[ + UNKNOWN + AIFF + ASF + DLS + FLAC + FSB + IT + MIDI + MOD + MPEG + OGGVORBIS + PLAYLIST + RAW + S3M + USER + WAV + XM + XMA + AUDIOQUEUE + AT9 + VORBIS + MEDIA_FOUND + MEDIACODEC + FADPCM + OPUS + MAX + ].each_with_index do |const, i| + self.const_set(const, i) + end + end + + module SoundFormat + NONE = 0 + PCM8 = 1 + PCM16 = 2 + PCM24 = 3 + PCM32 = 4 + PCMFLOAT = 5 + BITSTREAM = 6 + MAX = 7 + end + + module SoundGroupBehavior + NORMAL = 0 + MUTE = 1 + STEALLOWEST = 2 + MAX = 3 + end + + module ChannelControlCallbackType + _END = 0 + VIRTUALVOICE = 1 + SYNCPOINT = 2 + OCCLUSION = 3 + MAX = 4 + end + + module ChannelControlDSPIndex + HEAD = -1 + FADER = -2 + TAIL = -3 + end + + module ErrorCallbackInstanceType + %w[ + NONE + SYSTEM + CHANNEL + CHANNELGROUP + CHANNELCONTROL + SOUND + SOUNDGROUP + DSP + DSPCONNECTION + GEOMETRY + REVERB3D + STUDIO_SYSTEM + STUDIO_EVENTDESCRIPTION + STUDIO_EVENTINSTANCE + STUDIO_PARAMETERINSTANCE + STUDIO_BUS + STUDIO_VCA + STUDIO_BANK + STUDIO_COMMANDREPLAY + ].each_with_index do |const, i| + self.const_set(const, i) + end + end + + module DSPResampler + DEFAULT = 0 + NOINTERP = 1 + LINEAR = 2 + CUBIC = 3 + SPLINE = 4 + MAX = 5 + end + + module DSPConnectionType + STANDARD = 0 + SIDECHAIN = 1 + SEND = 2 + SEND_SIDECHAIN = 3 + MAX = 4 + end + + module TagType + %w[ + UNKNOWN + ID3V1 + ID3V2 + VORBISCOMMENT + SHOUTCAST + ICECAST + ASF + MIDI + PLAYLIST + FMOD + USER + MAX + ].each_with_index do |const, i| + self.const_set(const, i) + end + end + + module TagDataType + BINARY = 0 + INT = 1 + FLOAT = 2 + STRING = 3 + STRING_UTF16 = 4 + STRING_UTF16BE = 5 + STRING_UTF8 = 6 + MAX = 7 + end + + module PortType + MUSIC = 0 + COPYRIGHT_MUSIC = 1 + VOICE = 2 + CONTROLLER = 3 + PERSONA = 4 + VIBRATION = 5 + AUX = 6 + MAX = 7 + end + end + + module Studio + LOAD_MEMORY_ALIGNMENT = 32 + + module InitFlags + NORMAL = 0x00000000 + LIVEUPDATE = 0x00000001 + ALLOW_MISSING_PLUGINS = 0x00000002 + SYNCHRONOUS_UPDATE = 0x00000004 + DEFERRED_CALLBACKS = 0x00000008 + LOAD_FROM_UPDATE = 0x00000010 + MEMORY_TRACKING = 0x00000020 + end + + module ParameterFlags + READONLY = 0x00000001 + AUTOMATIC = 0x00000002 + GLOBAL = 0x00000004 + DISCRETE = 0x00000008 + LABELED = 0x00000010 + end + + module SystemCallbackType + CALLBACK_PREUPDATE = 0x00000001 + CALLBACK_POSTUPDATE = 0x00000002 + CALLBACK_BANK_UNLOAD = 0x00000004 + CALLBACK_LIVEUPDATE_CONNECTED = 0x00000008 + CALLBACK_LIVEUPDATE_DISCONNECTED = 0x00000010 + CALLBACK_ALL = 0xFFFFFFFF + end + + module EventCallbackType + CREATED = 0x00000001 + DESTROYED = 0x00000002 + STARTING = 0x00000004 + STARTED = 0x00000008 + RESTARTED = 0x00000010 + STOPPED = 0x00000020 + START_FAILED = 0x00000040 + CREATE_PROGRAMMER_SOUND = 0x00000080 + DESTROY_PROGRAMMER_SOUND = 0x00000100 + PLUGIN_CREATED = 0x00000200 + PLUGIN_DESTROYED = 0x00000400 + TIMELINE_MARKER = 0x00000800 + TIMELINE_BEAT = 0x00001000 + SOUND_PLAYED = 0x00002000 + SOUND_STOPPED = 0x00004000 + REAL_TO_VIRTUAL = 0x00008000 + VIRTUAL_TO_REAL = 0x00010000 + START_EVENT_COMMAND = 0x00020000 + NESTED_TIMELINE_BEAT = 0x00040000 + ALL = 0xFFFFFFFF + end + + module LoadBankFlags + NORMAL = 0x00000000 + NONBLOCKING = 0x00000001 + DECOMPRESS_SAMPLES = 0x00000002 + UNENCRYPTED = 0x00000004 + end + + module CommandCaptureFlags + NORMAL = 0x00000000 + FILEFLUSH = 0x00000001 + SKIP_INITIAL_STATE = 0x00000002 + end + + module CommandReplayFlags + NORMAL = 0x00000000 + SKIP_CLEANUP = 0x00000001 + FAST_FORWARD = 0x00000002 + SKIP_BANK_LOAD = 0x00000004 + end + + FORCEINT = 65536 + + module LoadingState + UNLOADING = 0 + UNLOADED = 1 + LOADING = 2 + LOADED = 3 + ERROR = 4 + end + + module LoadMemoryMode + MEMORY = 0 + MEMORY_POINT = 1 + end + + module ParameterType + GAME_CONTROLLED = 0 + AUTOMATIC_DISTANCE = 1 + AUTOMATIC_EVENT_CONE_ANGLE = 2 + AUTOMATIC_EVENT_ORIENTATION = 3 + AUTOMATIC_DIRECTION = 4 + AUTOMATIC_ELEVATION = 5 + AUTOMATIC_LISTENER_ORIENTATION = 6 + AUTOMATIC_SPEED = 7 + AUTOMATIC_SPEED_ABSOLUTE = 8 + AUTOMATIC_DISTANCE_NORMALIZED = 9 + end + + module UserPropertyType + INTEGER = 0 + BOOLEAN = 1 + FLOAT = 2 + STRING = 3 + end + + module EventProperty + CHANNELPRIORITY = 0 + SCHEDULE_DELAY = 1 + SCHEDULE_LOOKAHEAD = 2 + MINIMUM_DISTANCE = 3 + MAXIMUM_DISTANCE = 4 + COOLDOWN = 5 + MAX = 6 + end + + module PlaybackState + PLAYING = 0 + SUSTAINING = 1 + STOPPED = 2 + STARTING = 3 + STOPPING = 4 + end + + module StopMode + ALLOWFADEOUT = 0 + IMMEDIATE = 1 + end + + module InstanceType + NONE = 0 + SYSTEM = 1 + EVENTDESCRIPTION = 2 + EVENTINSTANCE = 3 + PARAMETERINSTANCE = 4 + BUS = 5 + VCA = 6 + BANK = 7 + COMMANDREPLAY = 8 + end + end +end diff --git a/binding-mri/fmod-binding/fmod_enums.rb.xxd b/binding-mri/fmod-binding/fmod_enums.rb.xxd new file mode 100644 index 00000000..cda3cab7 --- /dev/null +++ b/binding-mri/fmod-binding/fmod_enums.rb.xxd @@ -0,0 +1,1571 @@ +extern const char fmod_enums[] = { + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x46, 0x4d, 0x4f, 0x44, 0x0d, + 0x0a, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x43, 0x6f, + 0x72, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x20, 0x44, 0x65, 0x62, 0x75, 0x67, 0x46, 0x6c, 0x61, 0x67, + 0x73, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x45, 0x56, + 0x45, 0x4c, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x20, 0x3d, 0x20, 0x30, 0x78, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, + 0x47, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x45, + 0x56, 0x45, 0x4c, 0x5f, 0x4c, 0x4f, 0x47, 0x20, 0x3d, 0x20, 0x30, 0x78, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x4d, + 0x4f, 0x52, 0x59, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x31, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x30, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, + 0x4f, 0x44, 0x45, 0x43, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x34, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, 0x52, 0x41, 0x43, 0x45, 0x20, + 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x30, 0x30, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x49, 0x53, 0x50, + 0x4c, 0x41, 0x59, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, + 0x50, 0x53, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x31, 0x30, + 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, + 0x49, 0x53, 0x50, 0x4c, 0x41, 0x59, 0x5f, 0x4c, 0x49, 0x4e, 0x45, 0x4e, + 0x55, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, + 0x30, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x44, 0x49, 0x53, 0x50, 0x4c, 0x41, 0x59, 0x5f, 0x54, + 0x48, 0x52, 0x45, 0x41, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, + 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, + 0x54, 0x79, 0x70, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x46, 0x49, + 0x4c, 0x45, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, + 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x44, 0x45, 0x43, 0x4f, 0x44, 0x45, + 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x41, 0x4d, + 0x50, 0x4c, 0x45, 0x44, 0x41, 0x54, 0x41, 0x20, 0x3d, 0x20, 0x30, 0x78, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x44, 0x53, 0x50, 0x5f, 0x42, 0x55, 0x46, 0x46, + 0x45, 0x52, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x38, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, + 0x4c, 0x55, 0x47, 0x49, 0x4e, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x50, 0x45, 0x52, 0x53, 0x49, 0x53, 0x54, 0x45, 0x4e, 0x54, + 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x4c, 0x4c, + 0x20, 0x3d, 0x20, 0x30, 0x78, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, + 0x46, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x20, 0x49, 0x6e, 0x69, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, + 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x52, + 0x45, 0x41, 0x4d, 0x5f, 0x46, 0x52, 0x4f, 0x4d, 0x5f, 0x55, 0x50, 0x44, + 0x41, 0x54, 0x45, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x4d, 0x49, 0x58, 0x5f, 0x46, 0x52, 0x4f, 0x4d, 0x5f, 0x55, 0x50, 0x44, + 0x41, 0x54, 0x45, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x5f, 0x33, 0x44, 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x48, 0x41, 0x4e, + 0x44, 0x45, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x34, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x5f, 0x4c, 0x4f, 0x57, 0x50, + 0x41, 0x53, 0x53, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x31, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x5f, 0x44, 0x49, 0x53, 0x54, + 0x41, 0x4e, 0x43, 0x45, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x20, 0x3d, + 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x30, 0x30, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x52, 0x4f, 0x46, 0x49, + 0x4c, 0x45, 0x5f, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x56, 0x4f, 0x4c, 0x30, 0x5f, 0x42, + 0x45, 0x43, 0x4f, 0x4d, 0x45, 0x53, 0x5f, 0x56, 0x49, 0x52, 0x54, 0x55, + 0x41, 0x4c, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x32, 0x30, + 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x47, + 0x45, 0x4f, 0x4d, 0x45, 0x54, 0x52, 0x59, 0x5f, 0x55, 0x53, 0x45, 0x43, + 0x4c, 0x4f, 0x53, 0x45, 0x53, 0x54, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, + 0x30, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x50, 0x52, 0x45, 0x46, 0x45, 0x52, 0x5f, 0x44, 0x4f, + 0x4c, 0x42, 0x59, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x4d, 0x49, 0x58, 0x20, + 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x38, 0x30, 0x30, 0x30, 0x30, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x48, 0x52, 0x45, + 0x41, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x41, 0x46, 0x45, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x52, 0x4f, 0x46, 0x49, 0x4c, + 0x45, 0x5f, 0x4d, 0x45, 0x54, 0x45, 0x52, 0x5f, 0x41, 0x4c, 0x4c, 0x20, + 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x45, 0x4d, 0x4f, + 0x52, 0x59, 0x5f, 0x54, 0x52, 0x41, 0x43, 0x4b, 0x49, 0x4e, 0x47, 0x20, + 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, + 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x4f, 0x4e, 0x4e, 0x45, + 0x43, 0x54, 0x45, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x3d, 0x20, 0x30, + 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x54, 0x69, 0x6d, + 0x65, 0x55, 0x6e, 0x69, 0x74, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x4d, 0x53, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x50, 0x43, 0x4d, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x50, 0x43, 0x4d, 0x42, 0x59, 0x54, 0x45, 0x53, 0x20, 0x3d, 0x20, 0x30, + 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x41, 0x57, 0x42, 0x59, 0x54, 0x45, + 0x53, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x38, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x43, + 0x4d, 0x46, 0x52, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x4f, 0x44, 0x4f, 0x52, 0x44, + 0x45, 0x52, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x31, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, + 0x4f, 0x44, 0x52, 0x4f, 0x57, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x32, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x4d, 0x4f, 0x44, 0x50, 0x41, 0x54, 0x54, 0x45, 0x52, 0x4e, + 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x30, + 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x61, 0x6c, 0x6c, 0x62, + 0x61, 0x63, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x4c, 0x49, 0x53, + 0x54, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, 0x20, 0x3d, 0x20, 0x30, + 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x4c, + 0x4f, 0x53, 0x54, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x59, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x20, 0x3d, + 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x48, 0x52, 0x45, 0x41, + 0x44, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x20, 0x3d, 0x20, 0x30, + 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x42, 0x41, 0x44, 0x44, 0x53, 0x50, 0x43, + 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x58, + 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, + 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x4f, 0x53, + 0x54, 0x4d, 0x49, 0x58, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x34, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x4d, 0x49, 0x44, 0x4d, 0x49, 0x58, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x48, 0x52, 0x45, 0x41, 0x44, + 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f, 0x59, 0x45, 0x44, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x30, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x52, 0x45, 0x55, 0x50, 0x44, + 0x41, 0x54, 0x45, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x34, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x50, 0x4f, 0x53, 0x54, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x20, 0x3d, + 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x30, 0x30, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x45, 0x43, 0x4f, 0x52, + 0x44, 0x4c, 0x49, 0x53, 0x54, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, + 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, + 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x42, 0x55, 0x46, + 0x46, 0x45, 0x52, 0x45, 0x44, 0x4e, 0x4f, 0x4d, 0x49, 0x58, 0x20, 0x3d, + 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x32, 0x30, 0x30, 0x30, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x45, 0x56, 0x49, 0x43, + 0x45, 0x52, 0x45, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, + 0x45, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x34, 0x30, + 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4f, 0x55, + 0x54, 0x50, 0x55, 0x54, 0x55, 0x4e, 0x44, 0x45, 0x52, 0x52, 0x55, 0x4e, + 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x38, 0x30, 0x30, + 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x4c, 0x4c, + 0x20, 0x3d, 0x20, 0x30, 0x78, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, + 0x46, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x3d, 0x20, 0x30, + 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x4f, 0x46, + 0x46, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x4f, + 0x4f, 0x50, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x42, + 0x49, 0x44, 0x49, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x34, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x5f, 0x32, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x38, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x5f, 0x33, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x31, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, + 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, + 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x52, 0x45, + 0x41, 0x54, 0x45, 0x53, 0x41, 0x4d, 0x50, 0x4c, 0x45, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, + 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x45, 0x44, 0x53, 0x41, + 0x4d, 0x50, 0x4c, 0x45, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x32, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x4f, 0x50, 0x45, 0x4e, 0x55, 0x53, 0x45, 0x52, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x30, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4f, 0x50, 0x45, 0x4e, 0x4d, 0x45, + 0x4d, 0x4f, 0x52, 0x59, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x38, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x4f, 0x50, 0x45, 0x4e, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x59, 0x5f, + 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x31, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x4f, 0x50, 0x45, 0x4e, 0x52, 0x41, 0x57, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4f, 0x50, 0x45, 0x4e, 0x4f, 0x4e, + 0x4c, 0x59, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x32, + 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, + 0x43, 0x43, 0x55, 0x52, 0x41, 0x54, 0x45, 0x54, 0x49, 0x4d, 0x45, 0x20, + 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x34, 0x30, 0x30, 0x30, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x50, 0x45, 0x47, + 0x53, 0x45, 0x41, 0x52, 0x43, 0x48, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, + 0x30, 0x30, 0x30, 0x38, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x4e, 0x4f, 0x4e, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x49, + 0x4e, 0x47, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x31, 0x30, + 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x55, + 0x4e, 0x49, 0x51, 0x55, 0x45, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, + 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x5f, 0x33, 0x44, 0x5f, 0x48, 0x45, 0x41, 0x44, 0x52, 0x45, + 0x4c, 0x41, 0x54, 0x49, 0x56, 0x45, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, + 0x30, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x5f, 0x33, 0x44, 0x5f, 0x57, 0x4f, 0x52, 0x4c, 0x44, + 0x52, 0x45, 0x4c, 0x41, 0x54, 0x49, 0x56, 0x45, 0x20, 0x3d, 0x20, 0x30, + 0x78, 0x30, 0x30, 0x30, 0x38, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x33, 0x44, 0x5f, 0x49, 0x4e, 0x56, + 0x45, 0x52, 0x53, 0x45, 0x52, 0x4f, 0x4c, 0x4c, 0x4f, 0x46, 0x46, 0x20, + 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x33, 0x44, 0x5f, + 0x4c, 0x49, 0x4e, 0x45, 0x41, 0x52, 0x52, 0x4f, 0x4c, 0x4c, 0x4f, 0x46, + 0x46, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x32, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x33, + 0x44, 0x5f, 0x4c, 0x49, 0x4e, 0x45, 0x41, 0x52, 0x53, 0x51, 0x55, 0x41, + 0x52, 0x45, 0x52, 0x4f, 0x4c, 0x4c, 0x4f, 0x46, 0x46, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x33, 0x44, 0x5f, 0x49, 0x4e, + 0x56, 0x45, 0x52, 0x53, 0x45, 0x54, 0x41, 0x50, 0x45, 0x52, 0x45, 0x44, + 0x52, 0x4f, 0x4c, 0x4c, 0x4f, 0x46, 0x46, 0x20, 0x3d, 0x20, 0x30, 0x78, + 0x30, 0x30, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x5f, 0x33, 0x44, 0x5f, 0x43, 0x55, 0x53, 0x54, + 0x4f, 0x4d, 0x52, 0x4f, 0x4c, 0x4c, 0x4f, 0x46, 0x46, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x33, 0x44, 0x5f, 0x49, 0x47, + 0x4e, 0x4f, 0x52, 0x45, 0x47, 0x45, 0x4f, 0x4d, 0x45, 0x54, 0x52, 0x59, + 0x20, 0x3d, 0x20, 0x30, 0x78, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x47, 0x4e, + 0x4f, 0x52, 0x45, 0x54, 0x41, 0x47, 0x53, 0x20, 0x3d, 0x20, 0x30, 0x78, + 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x4c, 0x4f, 0x57, 0x4d, 0x45, 0x4d, 0x20, 0x3d, + 0x20, 0x30, 0x78, 0x30, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x56, 0x49, 0x52, 0x54, 0x55, + 0x41, 0x4c, 0x5f, 0x50, 0x4c, 0x41, 0x59, 0x46, 0x52, 0x4f, 0x4d, 0x53, + 0x54, 0x41, 0x52, 0x54, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x38, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x20, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, + 0x4d, 0x61, 0x73, 0x6b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x20, 0x3d, + 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x52, 0x4f, 0x4e, 0x54, + 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x43, 0x45, 0x4e, + 0x54, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x34, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x4c, 0x4f, 0x57, 0x5f, 0x46, 0x52, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, + 0x59, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x38, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x55, + 0x52, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x20, + 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x55, 0x52, 0x52, + 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x20, 0x3d, + 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x30, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x42, 0x41, 0x43, 0x4b, 0x5f, + 0x4c, 0x45, 0x46, 0x54, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x34, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x20, + 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x30, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x42, 0x41, 0x43, 0x4b, + 0x5f, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x30, 0x78, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x0d, 0x0a, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x4f, 0x4e, 0x4f, 0x20, 0x3d, + 0x20, 0x28, 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x4c, 0x45, 0x46, 0x54, + 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x45, + 0x52, 0x45, 0x4f, 0x20, 0x3d, 0x20, 0x28, 0x46, 0x52, 0x4f, 0x4e, 0x54, + 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x20, 0x7c, 0x20, 0x46, 0x52, 0x4f, 0x4e, + 0x54, 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x29, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x4c, 0x52, 0x43, 0x20, 0x3d, 0x20, 0x28, 0x46, + 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x20, 0x7c, 0x20, + 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x20, + 0x7c, 0x20, 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x43, 0x45, 0x4e, 0x54, + 0x45, 0x52, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x51, + 0x55, 0x41, 0x44, 0x20, 0x3d, 0x20, 0x28, 0x46, 0x52, 0x4f, 0x4e, 0x54, + 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x20, 0x7c, 0x20, 0x46, 0x52, 0x4f, 0x4e, + 0x54, 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x20, 0x7c, 0x20, 0x53, 0x55, + 0x52, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x20, + 0x7c, 0x20, 0x53, 0x55, 0x52, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x52, + 0x49, 0x47, 0x48, 0x54, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x53, 0x55, 0x52, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x20, 0x3d, 0x20, + 0x28, 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x20, + 0x7c, 0x20, 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x52, 0x49, 0x47, 0x48, + 0x54, 0x20, 0x7c, 0x20, 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x43, 0x45, + 0x4e, 0x54, 0x45, 0x52, 0x20, 0x7c, 0x20, 0x53, 0x55, 0x52, 0x52, 0x4f, + 0x55, 0x4e, 0x44, 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x20, 0x7c, 0x20, 0x53, + 0x55, 0x52, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x52, 0x49, 0x47, 0x48, + 0x54, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x35, + 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x31, 0x20, 0x3d, 0x20, 0x28, 0x46, 0x52, + 0x4f, 0x4e, 0x54, 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x20, 0x7c, 0x20, 0x46, + 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x20, 0x7c, + 0x20, 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x43, 0x45, 0x4e, 0x54, 0x45, + 0x52, 0x20, 0x7c, 0x20, 0x4c, 0x4f, 0x57, 0x5f, 0x46, 0x52, 0x45, 0x51, + 0x55, 0x45, 0x4e, 0x43, 0x59, 0x20, 0x7c, 0x20, 0x53, 0x55, 0x52, 0x52, + 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x20, 0x7c, 0x20, + 0x53, 0x55, 0x52, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x52, 0x49, 0x47, + 0x48, 0x54, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, + 0x35, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x31, 0x5f, 0x52, 0x45, 0x41, 0x52, + 0x53, 0x20, 0x3d, 0x20, 0x28, 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x4c, + 0x45, 0x46, 0x54, 0x20, 0x7c, 0x20, 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, + 0x52, 0x49, 0x47, 0x48, 0x54, 0x20, 0x7c, 0x20, 0x46, 0x52, 0x4f, 0x4e, + 0x54, 0x5f, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x20, 0x7c, 0x20, 0x4c, + 0x4f, 0x57, 0x5f, 0x46, 0x52, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x59, + 0x20, 0x7c, 0x20, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x45, 0x46, 0x54, + 0x20, 0x7c, 0x20, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x52, 0x49, 0x47, 0x48, + 0x54, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x37, + 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x30, 0x20, 0x3d, 0x20, 0x28, 0x46, 0x52, + 0x4f, 0x4e, 0x54, 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x20, 0x7c, 0x20, 0x46, + 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x20, 0x7c, + 0x20, 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x43, 0x45, 0x4e, 0x54, 0x45, + 0x52, 0x20, 0x7c, 0x20, 0x53, 0x55, 0x52, 0x52, 0x4f, 0x55, 0x4e, 0x44, + 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x20, 0x7c, 0x20, 0x53, 0x55, 0x52, 0x52, + 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x20, 0x7c, + 0x20, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x20, 0x7c, + 0x20, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x29, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x37, 0x50, 0x4f, + 0x49, 0x4e, 0x54, 0x31, 0x20, 0x3d, 0x20, 0x28, 0x46, 0x52, 0x4f, 0x4e, + 0x54, 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x20, 0x7c, 0x20, 0x46, 0x52, 0x4f, + 0x4e, 0x54, 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x20, 0x7c, 0x20, 0x46, + 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x20, + 0x7c, 0x20, 0x4c, 0x4f, 0x57, 0x5f, 0x46, 0x52, 0x45, 0x51, 0x55, 0x45, + 0x4e, 0x43, 0x59, 0x20, 0x7c, 0x20, 0x53, 0x55, 0x52, 0x52, 0x4f, 0x55, + 0x4e, 0x44, 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x20, 0x7c, 0x20, 0x53, 0x55, + 0x52, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x20, 0x7c, 0x20, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x45, 0x46, 0x54, + 0x20, 0x7c, 0x20, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x52, 0x49, 0x47, 0x48, + 0x54, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, + 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x20, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x50, 0x72, 0x69, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x50, 0x4c, 0x41, 0x54, 0x46, 0x4f, 0x52, 0x4d, 0x5f, 0x4d, 0x49, 0x4e, + 0x20, 0x3d, 0x20, 0x28, 0x2d, 0x33, 0x32, 0x20, 0x2a, 0x20, 0x31, 0x30, + 0x32, 0x34, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, + 0x4c, 0x41, 0x54, 0x46, 0x4f, 0x52, 0x4d, 0x5f, 0x4d, 0x41, 0x58, 0x20, + 0x3d, 0x20, 0x28, 0x33, 0x32, 0x20, 0x2a, 0x20, 0x31, 0x30, 0x32, 0x34, + 0x29, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, + 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x3d, 0x20, 0x28, 0x50, 0x4c, + 0x41, 0x54, 0x46, 0x4f, 0x52, 0x4d, 0x5f, 0x4d, 0x49, 0x4e, 0x20, 0x2d, + 0x20, 0x31, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, + 0x4f, 0x57, 0x20, 0x3d, 0x20, 0x28, 0x50, 0x4c, 0x41, 0x54, 0x46, 0x4f, + 0x52, 0x4d, 0x5f, 0x4d, 0x49, 0x4e, 0x20, 0x2d, 0x20, 0x32, 0x29, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x45, 0x44, 0x49, 0x55, + 0x4d, 0x20, 0x3d, 0x20, 0x28, 0x50, 0x4c, 0x41, 0x54, 0x46, 0x4f, 0x52, + 0x4d, 0x5f, 0x4d, 0x49, 0x4e, 0x20, 0x2d, 0x20, 0x33, 0x29, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x48, 0x49, 0x47, 0x48, 0x20, 0x3d, + 0x20, 0x28, 0x50, 0x4c, 0x41, 0x54, 0x46, 0x4f, 0x52, 0x4d, 0x5f, 0x4d, + 0x49, 0x4e, 0x20, 0x2d, 0x20, 0x34, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x48, 0x49, 0x47, 0x48, + 0x20, 0x3d, 0x20, 0x28, 0x50, 0x4c, 0x41, 0x54, 0x46, 0x4f, 0x52, 0x4d, + 0x5f, 0x4d, 0x49, 0x4e, 0x20, 0x2d, 0x20, 0x35, 0x29, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x58, 0x54, 0x52, 0x45, 0x4d, 0x45, + 0x20, 0x3d, 0x20, 0x28, 0x50, 0x4c, 0x41, 0x54, 0x46, 0x4f, 0x52, 0x4d, + 0x5f, 0x4d, 0x49, 0x4e, 0x20, 0x2d, 0x20, 0x36, 0x29, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x52, 0x49, 0x54, 0x49, 0x43, 0x41, + 0x4c, 0x20, 0x3d, 0x20, 0x28, 0x50, 0x4c, 0x41, 0x54, 0x46, 0x4f, 0x52, + 0x4d, 0x5f, 0x4d, 0x49, 0x4e, 0x20, 0x2d, 0x20, 0x37, 0x29, 0x0d, 0x0a, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x49, 0x58, 0x45, + 0x52, 0x20, 0x3d, 0x20, 0x45, 0x58, 0x54, 0x52, 0x45, 0x4d, 0x45, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x45, 0x45, 0x44, 0x45, + 0x52, 0x20, 0x3d, 0x20, 0x43, 0x52, 0x49, 0x54, 0x49, 0x43, 0x41, 0x4c, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x52, 0x45, + 0x41, 0x4d, 0x20, 0x3d, 0x20, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x48, 0x49, + 0x47, 0x48, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x49, + 0x4c, 0x45, 0x20, 0x3d, 0x20, 0x48, 0x49, 0x47, 0x48, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x4f, 0x4e, 0x42, 0x4c, 0x4f, 0x43, + 0x4b, 0x49, 0x4e, 0x47, 0x20, 0x3d, 0x20, 0x48, 0x49, 0x47, 0x48, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x45, 0x43, 0x4f, 0x52, + 0x44, 0x20, 0x3d, 0x20, 0x48, 0x49, 0x47, 0x48, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x47, 0x45, 0x4f, 0x4d, 0x45, 0x54, 0x52, 0x59, + 0x20, 0x3d, 0x20, 0x4c, 0x4f, 0x57, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x50, 0x52, 0x4f, 0x46, 0x49, 0x4c, 0x45, 0x52, 0x20, 0x3d, + 0x20, 0x4d, 0x45, 0x44, 0x49, 0x55, 0x4d, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x53, 0x54, 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x55, 0x50, + 0x44, 0x41, 0x54, 0x45, 0x20, 0x3d, 0x20, 0x4d, 0x45, 0x44, 0x49, 0x55, + 0x4d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x55, + 0x44, 0x49, 0x4f, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x41, 0x4e, + 0x4b, 0x20, 0x3d, 0x20, 0x4d, 0x45, 0x44, 0x49, 0x55, 0x4d, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x55, 0x44, 0x49, 0x4f, + 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x53, 0x41, 0x4d, 0x50, 0x4c, 0x45, + 0x20, 0x3d, 0x20, 0x4d, 0x45, 0x44, 0x49, 0x55, 0x4d, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x4f, 0x4e, 0x56, 0x4f, 0x4c, 0x55, + 0x54, 0x49, 0x4f, 0x4e, 0x31, 0x20, 0x3d, 0x20, 0x56, 0x45, 0x52, 0x59, + 0x5f, 0x48, 0x49, 0x47, 0x48, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x43, 0x4f, 0x4e, 0x56, 0x4f, 0x4c, 0x55, 0x54, 0x49, 0x4f, 0x4e, + 0x32, 0x20, 0x3d, 0x20, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x48, 0x49, 0x47, + 0x48, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x20, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x53, 0x74, 0x61, 0x63, 0x6b, + 0x53, 0x69, 0x7a, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x3d, 0x20, 0x30, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x49, 0x58, 0x45, 0x52, + 0x20, 0x3d, 0x20, 0x28, 0x38, 0x30, 0x20, 0x2a, 0x20, 0x31, 0x30, 0x32, + 0x34, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x45, + 0x45, 0x44, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x28, 0x31, 0x36, 0x20, 0x2a, + 0x20, 0x31, 0x30, 0x32, 0x34, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x20, 0x3d, 0x20, 0x28, + 0x39, 0x36, 0x20, 0x2a, 0x20, 0x31, 0x30, 0x32, 0x34, 0x29, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x49, 0x4c, 0x45, 0x20, 0x3d, + 0x20, 0x28, 0x36, 0x34, 0x20, 0x2a, 0x20, 0x31, 0x30, 0x32, 0x34, 0x29, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x4f, 0x4e, 0x42, + 0x4c, 0x4f, 0x43, 0x4b, 0x49, 0x4e, 0x47, 0x20, 0x3d, 0x20, 0x28, 0x31, + 0x31, 0x32, 0x20, 0x2a, 0x20, 0x31, 0x30, 0x32, 0x34, 0x29, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, + 0x20, 0x3d, 0x20, 0x28, 0x31, 0x36, 0x20, 0x2a, 0x20, 0x31, 0x30, 0x32, + 0x34, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x47, 0x45, + 0x4f, 0x4d, 0x45, 0x54, 0x52, 0x59, 0x20, 0x3d, 0x20, 0x28, 0x34, 0x38, + 0x20, 0x2a, 0x20, 0x31, 0x30, 0x32, 0x34, 0x29, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x50, 0x52, 0x4f, 0x46, 0x49, 0x4c, 0x45, 0x52, + 0x20, 0x3d, 0x20, 0x28, 0x31, 0x32, 0x38, 0x20, 0x2a, 0x20, 0x31, 0x30, + 0x32, 0x34, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, + 0x54, 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, + 0x20, 0x3d, 0x20, 0x28, 0x39, 0x36, 0x20, 0x2a, 0x20, 0x31, 0x30, 0x32, + 0x34, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, + 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x41, + 0x4e, 0x4b, 0x20, 0x3d, 0x20, 0x28, 0x39, 0x36, 0x20, 0x2a, 0x20, 0x31, + 0x30, 0x32, 0x34, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x53, 0x54, 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x5f, + 0x53, 0x41, 0x4d, 0x50, 0x4c, 0x45, 0x20, 0x3d, 0x20, 0x28, 0x39, 0x36, + 0x20, 0x2a, 0x20, 0x31, 0x30, 0x32, 0x34, 0x29, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x43, 0x4f, 0x4e, 0x56, 0x4f, 0x4c, 0x55, 0x54, + 0x49, 0x4f, 0x4e, 0x31, 0x20, 0x3d, 0x20, 0x28, 0x31, 0x36, 0x20, 0x2a, + 0x20, 0x31, 0x30, 0x32, 0x34, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x43, 0x4f, 0x4e, 0x56, 0x4f, 0x4c, 0x55, 0x54, 0x49, 0x4f, + 0x4e, 0x32, 0x20, 0x3d, 0x20, 0x28, 0x31, 0x36, 0x20, 0x2a, 0x20, 0x31, + 0x30, 0x32, 0x34, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x20, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x41, 0x66, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x79, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x44, 0x45, 0x46, 0x41, + 0x55, 0x4c, 0x54, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x34, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x47, 0x52, 0x4f, 0x55, + 0x50, 0x5f, 0x41, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x34, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x47, 0x52, 0x4f, 0x55, + 0x50, 0x5f, 0x42, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x34, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x47, 0x52, 0x4f, 0x55, + 0x50, 0x5f, 0x43, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x34, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, + 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x49, + 0x58, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, + 0x41, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x45, 0x45, + 0x44, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, + 0x43, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x52, + 0x45, 0x41, 0x4d, 0x20, 0x3d, 0x20, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, + 0x43, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x49, 0x4c, + 0x45, 0x20, 0x3d, 0x20, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x43, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x4f, 0x4e, 0x42, 0x4c, + 0x4f, 0x43, 0x4b, 0x49, 0x4e, 0x47, 0x20, 0x3d, 0x20, 0x47, 0x52, 0x4f, + 0x55, 0x50, 0x5f, 0x43, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x20, 0x3d, 0x20, 0x47, 0x52, 0x4f, + 0x55, 0x50, 0x5f, 0x43, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x47, 0x45, 0x4f, 0x4d, 0x45, 0x54, 0x52, 0x59, 0x20, 0x3d, 0x20, 0x47, + 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x43, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x50, 0x52, 0x4f, 0x46, 0x49, 0x4c, 0x45, 0x52, 0x20, 0x3d, + 0x20, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x43, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x55, + 0x50, 0x44, 0x41, 0x54, 0x45, 0x20, 0x3d, 0x20, 0x47, 0x52, 0x4f, 0x55, + 0x50, 0x5f, 0x42, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, + 0x54, 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, + 0x41, 0x4e, 0x4b, 0x20, 0x3d, 0x20, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, + 0x43, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x55, + 0x44, 0x49, 0x4f, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x53, 0x41, 0x4d, + 0x50, 0x4c, 0x45, 0x20, 0x3d, 0x20, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, + 0x43, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x4f, 0x4e, + 0x56, 0x4f, 0x4c, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x31, 0x20, 0x3d, 0x20, + 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x43, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x43, 0x4f, 0x4e, 0x56, 0x4f, 0x4c, 0x55, 0x54, 0x49, + 0x4f, 0x4e, 0x32, 0x20, 0x3d, 0x20, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, + 0x43, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, + 0x4f, 0x52, 0x45, 0x5f, 0x41, 0x4c, 0x4c, 0x20, 0x3d, 0x20, 0x30, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x4f, 0x52, 0x45, 0x5f, + 0x30, 0x20, 0x3d, 0x20, 0x28, 0x31, 0x20, 0x3c, 0x3c, 0x20, 0x30, 0x29, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x4f, 0x52, 0x45, + 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x28, 0x31, 0x20, 0x3c, 0x3c, 0x20, 0x31, + 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x4f, 0x52, + 0x45, 0x5f, 0x32, 0x20, 0x3d, 0x20, 0x28, 0x31, 0x20, 0x3c, 0x3c, 0x20, + 0x32, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x4f, + 0x52, 0x45, 0x5f, 0x33, 0x20, 0x3d, 0x20, 0x28, 0x31, 0x20, 0x3c, 0x3c, + 0x20, 0x33, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, + 0x4f, 0x52, 0x45, 0x5f, 0x34, 0x20, 0x3d, 0x20, 0x28, 0x31, 0x20, 0x3c, + 0x3c, 0x20, 0x34, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x43, 0x4f, 0x52, 0x45, 0x5f, 0x35, 0x20, 0x3d, 0x20, 0x28, 0x31, 0x20, + 0x3c, 0x3c, 0x20, 0x35, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x43, 0x4f, 0x52, 0x45, 0x5f, 0x36, 0x20, 0x3d, 0x20, 0x28, 0x31, + 0x20, 0x3c, 0x3c, 0x20, 0x36, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x43, 0x4f, 0x52, 0x45, 0x5f, 0x37, 0x20, 0x3d, 0x20, 0x28, + 0x31, 0x20, 0x3c, 0x3c, 0x20, 0x37, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x43, 0x4f, 0x52, 0x45, 0x5f, 0x38, 0x20, 0x3d, 0x20, + 0x28, 0x31, 0x20, 0x3c, 0x3c, 0x20, 0x38, 0x29, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x43, 0x4f, 0x52, 0x45, 0x5f, 0x39, 0x20, 0x3d, + 0x20, 0x28, 0x31, 0x20, 0x3c, 0x3c, 0x20, 0x39, 0x29, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x4f, 0x52, 0x45, 0x5f, 0x31, 0x30, + 0x20, 0x3d, 0x20, 0x28, 0x31, 0x20, 0x3c, 0x3c, 0x20, 0x31, 0x30, 0x29, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x4f, 0x52, 0x45, + 0x5f, 0x31, 0x31, 0x20, 0x3d, 0x20, 0x28, 0x31, 0x20, 0x3c, 0x3c, 0x20, + 0x31, 0x31, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, + 0x4f, 0x52, 0x45, 0x5f, 0x31, 0x32, 0x20, 0x3d, 0x20, 0x28, 0x31, 0x20, + 0x3c, 0x3c, 0x20, 0x31, 0x32, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x43, 0x4f, 0x52, 0x45, 0x5f, 0x31, 0x33, 0x20, 0x3d, 0x20, + 0x28, 0x31, 0x20, 0x3c, 0x3c, 0x20, 0x31, 0x33, 0x29, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x4f, 0x52, 0x45, 0x5f, 0x31, 0x34, + 0x20, 0x3d, 0x20, 0x28, 0x31, 0x20, 0x3c, 0x3c, 0x20, 0x31, 0x34, 0x29, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x4f, 0x52, 0x45, + 0x5f, 0x31, 0x35, 0x20, 0x3d, 0x20, 0x28, 0x31, 0x20, 0x3c, 0x3c, 0x20, + 0x31, 0x35, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x20, 0x50, 0x72, 0x65, 0x73, 0x65, 0x74, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x4f, 0x46, 0x46, 0x20, 0x3d, 0x20, 0x5b, + 0x31, 0x30, 0x30, 0x30, 0x2c, 0x20, 0x37, 0x2c, 0x20, 0x31, 0x31, 0x2c, + 0x20, 0x35, 0x30, 0x30, 0x30, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, + 0x31, 0x30, 0x30, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, + 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x32, 0x30, 0x2c, 0x20, 0x39, 0x36, + 0x2c, 0x20, 0x2d, 0x38, 0x30, 0x2e, 0x30, 0x5d, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x49, 0x43, 0x20, + 0x3d, 0x20, 0x5b, 0x31, 0x35, 0x30, 0x30, 0x2c, 0x20, 0x37, 0x2c, 0x20, + 0x31, 0x31, 0x2c, 0x20, 0x35, 0x30, 0x30, 0x30, 0x2c, 0x20, 0x38, 0x33, + 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, + 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x31, 0x34, 0x35, 0x30, + 0x30, 0x2c, 0x20, 0x39, 0x36, 0x2c, 0x20, 0x2d, 0x38, 0x2e, 0x30, 0x5d, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x41, 0x44, 0x44, + 0x45, 0x44, 0x43, 0x45, 0x4c, 0x4c, 0x20, 0x3d, 0x20, 0x5b, 0x31, 0x37, + 0x30, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x32, 0x2c, 0x20, 0x35, 0x30, 0x30, + 0x30, 0x2c, 0x20, 0x31, 0x30, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, + 0x31, 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, 0x2c, + 0x20, 0x31, 0x36, 0x30, 0x2c, 0x20, 0x38, 0x34, 0x2c, 0x20, 0x2d, 0x37, + 0x2e, 0x38, 0x5d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, + 0x4f, 0x4f, 0x4d, 0x20, 0x3d, 0x20, 0x5b, 0x34, 0x30, 0x30, 0x2c, 0x20, + 0x32, 0x2c, 0x20, 0x33, 0x2c, 0x20, 0x35, 0x30, 0x30, 0x30, 0x2c, 0x20, + 0x38, 0x33, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x31, 0x30, 0x30, + 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x36, 0x30, + 0x35, 0x30, 0x2c, 0x20, 0x38, 0x38, 0x2c, 0x20, 0x2d, 0x39, 0x2e, 0x34, + 0x5d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x42, 0x41, 0x54, + 0x48, 0x52, 0x4f, 0x4f, 0x4d, 0x20, 0x3d, 0x20, 0x5b, 0x31, 0x35, 0x30, + 0x30, 0x2c, 0x20, 0x37, 0x2c, 0x20, 0x31, 0x31, 0x2c, 0x20, 0x35, 0x30, + 0x30, 0x30, 0x2c, 0x20, 0x35, 0x34, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, + 0x20, 0x36, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, 0x2c, + 0x20, 0x32, 0x39, 0x30, 0x30, 0x2c, 0x20, 0x38, 0x33, 0x2c, 0x20, 0x30, + 0x2e, 0x35, 0x5d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, + 0x49, 0x56, 0x49, 0x4e, 0x47, 0x52, 0x4f, 0x4f, 0x4d, 0x20, 0x3d, 0x20, + 0x5b, 0x35, 0x30, 0x30, 0x2c, 0x20, 0x33, 0x2c, 0x20, 0x34, 0x2c, 0x20, + 0x35, 0x30, 0x30, 0x30, 0x2c, 0x20, 0x31, 0x30, 0x2c, 0x20, 0x31, 0x30, + 0x30, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, + 0x20, 0x30, 0x2c, 0x20, 0x31, 0x36, 0x30, 0x2c, 0x20, 0x35, 0x38, 0x2c, + 0x20, 0x2d, 0x31, 0x39, 0x2e, 0x30, 0x5d, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x53, 0x54, 0x4f, 0x4e, 0x45, 0x52, 0x4f, 0x4f, 0x4d, + 0x20, 0x3d, 0x20, 0x5b, 0x32, 0x33, 0x30, 0x30, 0x2c, 0x20, 0x31, 0x32, + 0x2c, 0x20, 0x31, 0x37, 0x2c, 0x20, 0x35, 0x30, 0x30, 0x30, 0x2c, 0x20, + 0x36, 0x34, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x31, 0x30, 0x30, + 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x37, 0x38, + 0x30, 0x30, 0x2c, 0x20, 0x37, 0x31, 0x2c, 0x20, 0x2d, 0x38, 0x2e, 0x35, + 0x5d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x55, 0x44, + 0x49, 0x54, 0x4f, 0x52, 0x49, 0x55, 0x4d, 0x20, 0x3d, 0x20, 0x5b, 0x34, + 0x33, 0x30, 0x30, 0x2c, 0x20, 0x32, 0x30, 0x2c, 0x20, 0x33, 0x30, 0x2c, + 0x20, 0x35, 0x30, 0x30, 0x30, 0x2c, 0x20, 0x35, 0x39, 0x2c, 0x20, 0x31, + 0x30, 0x30, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x30, + 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x35, 0x38, 0x35, 0x30, 0x2c, 0x20, 0x36, + 0x34, 0x2c, 0x20, 0x2d, 0x31, 0x31, 0x2e, 0x37, 0x5d, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x4f, 0x4e, 0x43, 0x45, 0x52, 0x54, + 0x48, 0x41, 0x4c, 0x4c, 0x20, 0x3d, 0x20, 0x5b, 0x33, 0x39, 0x30, 0x30, + 0x2c, 0x20, 0x32, 0x30, 0x2c, 0x20, 0x32, 0x39, 0x2c, 0x20, 0x35, 0x30, + 0x30, 0x30, 0x2c, 0x20, 0x37, 0x30, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, + 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, + 0x2c, 0x20, 0x35, 0x36, 0x35, 0x30, 0x2c, 0x20, 0x38, 0x30, 0x2c, 0x20, + 0x2d, 0x39, 0x2e, 0x38, 0x5d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x43, 0x41, 0x56, 0x45, 0x20, 0x3d, 0x20, 0x5b, 0x32, 0x39, 0x30, + 0x30, 0x2c, 0x20, 0x31, 0x35, 0x2c, 0x20, 0x32, 0x32, 0x2c, 0x20, 0x35, + 0x30, 0x30, 0x30, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x31, 0x30, + 0x30, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, + 0x20, 0x30, 0x2c, 0x20, 0x32, 0x30, 0x30, 0x30, 0x30, 0x2c, 0x20, 0x35, + 0x39, 0x2c, 0x20, 0x2d, 0x31, 0x31, 0x2e, 0x33, 0x5d, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x52, 0x45, 0x4e, 0x41, 0x20, 0x3d, + 0x20, 0x5b, 0x37, 0x32, 0x30, 0x30, 0x2c, 0x20, 0x32, 0x30, 0x2c, 0x20, + 0x33, 0x30, 0x2c, 0x20, 0x35, 0x30, 0x30, 0x30, 0x2c, 0x20, 0x33, 0x33, + 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, + 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x34, 0x35, 0x30, 0x30, + 0x2c, 0x20, 0x38, 0x30, 0x2c, 0x20, 0x2d, 0x39, 0x2e, 0x36, 0x5d, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x48, 0x41, 0x4e, 0x47, 0x41, + 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x31, 0x30, 0x30, 0x30, 0x30, 0x2c, 0x20, + 0x32, 0x30, 0x2c, 0x20, 0x33, 0x30, 0x2c, 0x20, 0x35, 0x30, 0x30, 0x30, + 0x2c, 0x20, 0x32, 0x33, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x31, + 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, + 0x33, 0x34, 0x30, 0x30, 0x2c, 0x20, 0x37, 0x32, 0x2c, 0x20, 0x2d, 0x37, + 0x2e, 0x34, 0x5d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, + 0x41, 0x52, 0x50, 0x45, 0x54, 0x54, 0x45, 0x44, 0x48, 0x41, 0x4c, 0x4c, + 0x57, 0x41, 0x59, 0x20, 0x3d, 0x20, 0x5b, 0x33, 0x30, 0x30, 0x2c, 0x20, + 0x32, 0x2c, 0x20, 0x33, 0x30, 0x2c, 0x20, 0x35, 0x30, 0x30, 0x30, 0x2c, + 0x20, 0x31, 0x30, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x31, 0x30, + 0x30, 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x35, + 0x30, 0x30, 0x2c, 0x20, 0x35, 0x36, 0x2c, 0x20, 0x2d, 0x32, 0x34, 0x2e, + 0x30, 0x5d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x48, 0x41, + 0x4c, 0x4c, 0x57, 0x41, 0x59, 0x20, 0x3d, 0x20, 0x5b, 0x31, 0x35, 0x30, + 0x30, 0x2c, 0x20, 0x37, 0x2c, 0x20, 0x31, 0x31, 0x2c, 0x20, 0x35, 0x30, + 0x30, 0x30, 0x2c, 0x20, 0x35, 0x39, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, + 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, + 0x2c, 0x20, 0x37, 0x38, 0x30, 0x30, 0x2c, 0x20, 0x38, 0x37, 0x2c, 0x20, + 0x2d, 0x35, 0x2e, 0x35, 0x5d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x53, 0x54, 0x4f, 0x4e, 0x45, 0x43, 0x4f, 0x52, 0x52, 0x49, 0x44, + 0x4f, 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x32, 0x37, 0x30, 0x2c, 0x20, 0x31, + 0x33, 0x2c, 0x20, 0x32, 0x30, 0x2c, 0x20, 0x35, 0x30, 0x30, 0x30, 0x2c, + 0x20, 0x37, 0x39, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x31, 0x30, + 0x30, 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x39, + 0x30, 0x30, 0x30, 0x2c, 0x20, 0x38, 0x36, 0x2c, 0x20, 0x2d, 0x36, 0x2e, + 0x30, 0x5d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x4c, + 0x4c, 0x45, 0x59, 0x20, 0x3d, 0x20, 0x5b, 0x31, 0x35, 0x30, 0x30, 0x2c, + 0x20, 0x37, 0x2c, 0x20, 0x31, 0x31, 0x2c, 0x20, 0x35, 0x30, 0x30, 0x30, + 0x2c, 0x20, 0x38, 0x36, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x31, + 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, + 0x38, 0x33, 0x30, 0x30, 0x2c, 0x20, 0x38, 0x30, 0x2c, 0x20, 0x2d, 0x39, + 0x2e, 0x38, 0x5d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, + 0x4f, 0x52, 0x45, 0x53, 0x54, 0x20, 0x3d, 0x20, 0x5b, 0x31, 0x35, 0x30, + 0x30, 0x2c, 0x20, 0x31, 0x36, 0x32, 0x2c, 0x20, 0x38, 0x38, 0x2c, 0x20, + 0x35, 0x30, 0x30, 0x30, 0x2c, 0x20, 0x35, 0x34, 0x2c, 0x20, 0x37, 0x39, + 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x20, + 0x30, 0x2c, 0x20, 0x37, 0x36, 0x30, 0x2c, 0x20, 0x39, 0x34, 0x2c, 0x20, + 0x2d, 0x31, 0x32, 0x2e, 0x33, 0x5d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x43, 0x49, 0x54, 0x59, 0x20, 0x3d, 0x20, 0x5b, 0x31, 0x35, + 0x30, 0x30, 0x2c, 0x20, 0x37, 0x2c, 0x20, 0x31, 0x31, 0x2c, 0x20, 0x35, + 0x30, 0x30, 0x30, 0x2c, 0x20, 0x36, 0x37, 0x2c, 0x20, 0x35, 0x30, 0x2c, + 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, + 0x2c, 0x20, 0x34, 0x30, 0x35, 0x30, 0x2c, 0x20, 0x36, 0x36, 0x2c, 0x20, + 0x2d, 0x32, 0x36, 0x2e, 0x30, 0x5d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x4d, 0x4f, 0x55, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x53, 0x20, + 0x3d, 0x20, 0x5b, 0x31, 0x35, 0x30, 0x30, 0x2c, 0x20, 0x33, 0x30, 0x30, + 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x35, 0x30, 0x30, 0x30, 0x2c, + 0x20, 0x32, 0x31, 0x2c, 0x20, 0x32, 0x37, 0x2c, 0x20, 0x31, 0x30, 0x30, + 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x31, 0x32, + 0x32, 0x30, 0x2c, 0x20, 0x38, 0x32, 0x2c, 0x20, 0x2d, 0x32, 0x34, 0x2e, + 0x30, 0x5d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x51, 0x55, + 0x41, 0x52, 0x52, 0x59, 0x20, 0x3d, 0x20, 0x5b, 0x31, 0x35, 0x30, 0x30, + 0x2c, 0x20, 0x36, 0x31, 0x2c, 0x20, 0x32, 0x35, 0x2c, 0x20, 0x35, 0x30, + 0x30, 0x30, 0x2c, 0x20, 0x38, 0x33, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, + 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, + 0x2c, 0x20, 0x33, 0x34, 0x30, 0x30, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, + 0x20, 0x2d, 0x35, 0x2e, 0x30, 0x5d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x20, 0x3d, 0x20, 0x5b, 0x31, + 0x35, 0x30, 0x30, 0x2c, 0x20, 0x31, 0x37, 0x39, 0x2c, 0x20, 0x31, 0x30, + 0x30, 0x2c, 0x20, 0x35, 0x30, 0x30, 0x30, 0x2c, 0x20, 0x35, 0x30, 0x2c, + 0x20, 0x32, 0x31, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, + 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x31, 0x36, 0x37, 0x30, 0x2c, 0x20, + 0x36, 0x35, 0x2c, 0x20, 0x2d, 0x32, 0x38, 0x2e, 0x30, 0x5d, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x41, 0x52, 0x4b, 0x49, 0x4e, + 0x47, 0x4c, 0x4f, 0x54, 0x20, 0x3d, 0x20, 0x5b, 0x31, 0x37, 0x30, 0x30, + 0x2c, 0x20, 0x38, 0x2c, 0x20, 0x31, 0x32, 0x2c, 0x20, 0x35, 0x30, 0x30, + 0x30, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, + 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, + 0x2c, 0x20, 0x32, 0x30, 0x30, 0x30, 0x30, 0x2c, 0x20, 0x35, 0x36, 0x2c, + 0x20, 0x2d, 0x31, 0x39, 0x2e, 0x35, 0x5d, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x53, 0x45, 0x57, 0x45, 0x52, 0x50, 0x49, 0x50, 0x45, + 0x20, 0x3d, 0x20, 0x5b, 0x32, 0x38, 0x30, 0x30, 0x2c, 0x20, 0x31, 0x34, + 0x2c, 0x20, 0x32, 0x31, 0x2c, 0x20, 0x35, 0x30, 0x30, 0x30, 0x2c, 0x20, + 0x31, 0x34, 0x2c, 0x20, 0x38, 0x30, 0x2c, 0x20, 0x36, 0x30, 0x2c, 0x20, + 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x33, 0x34, 0x30, 0x30, + 0x2c, 0x20, 0x36, 0x36, 0x2c, 0x20, 0x31, 0x2e, 0x32, 0x5d, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x55, 0x4e, 0x44, 0x45, 0x52, 0x57, + 0x41, 0x54, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x31, 0x35, 0x30, 0x30, + 0x2c, 0x20, 0x37, 0x2c, 0x20, 0x31, 0x31, 0x2c, 0x20, 0x35, 0x30, 0x30, + 0x30, 0x2c, 0x20, 0x31, 0x30, 0x2c, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x20, + 0x31, 0x30, 0x30, 0x2c, 0x20, 0x32, 0x35, 0x30, 0x2c, 0x20, 0x30, 0x2c, + 0x20, 0x35, 0x30, 0x30, 0x2c, 0x20, 0x39, 0x32, 0x2c, 0x20, 0x37, 0x2e, + 0x30, 0x5d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, + 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x41, 0x58, 0x5f, 0x43, + 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x5f, 0x57, 0x49, 0x44, 0x54, 0x48, + 0x20, 0x3d, 0x20, 0x33, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, + 0x41, 0x58, 0x5f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x53, 0x20, 0x3d, + 0x20, 0x38, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x41, 0x58, 0x5f, + 0x4c, 0x49, 0x53, 0x54, 0x45, 0x4e, 0x45, 0x52, 0x53, 0x20, 0x3d, 0x20, + 0x38, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x45, 0x56, 0x45, 0x52, + 0x42, 0x5f, 0x4d, 0x41, 0x58, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, 0x43, + 0x45, 0x53, 0x20, 0x3d, 0x20, 0x34, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x50, 0x4f, 0x52, 0x54, 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x5f, 0x4e, + 0x4f, 0x4e, 0x45, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x46, 0x46, 0x46, 0x46, + 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, + 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x46, 0x4f, 0x52, 0x43, + 0x45, 0x49, 0x4e, 0x54, 0x20, 0x3d, 0x20, 0x36, 0x35, 0x35, 0x33, 0x36, + 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x20, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x54, 0x79, 0x70, + 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x25, 0x77, 0x5b, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x49, + 0x58, 0x45, 0x52, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x46, 0x45, 0x45, 0x44, 0x45, 0x52, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x49, 0x4c, + 0x45, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, + 0x4f, 0x4e, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x49, 0x4e, 0x47, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x45, 0x43, 0x4f, + 0x52, 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x47, 0x45, 0x4f, 0x4d, 0x45, 0x54, 0x52, 0x59, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x52, 0x4f, 0x46, 0x49, 0x4c, + 0x45, 0x52, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x53, 0x54, 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, + 0x45, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, + 0x54, 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, + 0x41, 0x4e, 0x4b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x53, 0x54, 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x4c, 0x4f, 0x41, 0x44, + 0x5f, 0x53, 0x41, 0x4d, 0x50, 0x4c, 0x45, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x4f, 0x4e, 0x56, 0x4f, 0x4c, 0x55, + 0x54, 0x49, 0x4f, 0x4e, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x43, 0x4f, 0x4e, 0x56, 0x4f, 0x4c, 0x55, 0x54, 0x49, + 0x4f, 0x4e, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, + 0x2e, 0x65, 0x61, 0x63, 0x68, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x20, 0x64, 0x6f, 0x20, 0x7c, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x2c, 0x20, 0x69, 0x7c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x5f, 0x73, 0x65, 0x74, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x2c, 0x20, 0x69, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x20, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x25, 0x77, 0x5b, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x42, 0x41, + 0x44, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x43, 0x48, + 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, + 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x5f, 0x53, 0x54, 0x4f, + 0x4c, 0x45, 0x4e, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x45, 0x52, 0x52, 0x5f, 0x44, 0x4d, 0x41, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x44, 0x53, + 0x50, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, + 0x52, 0x5f, 0x44, 0x53, 0x50, 0x5f, 0x44, 0x4f, 0x4e, 0x54, 0x50, 0x52, + 0x4f, 0x43, 0x45, 0x53, 0x53, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x44, 0x53, 0x50, 0x5f, 0x46, + 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x44, 0x53, 0x50, 0x5f, 0x49, + 0x4e, 0x55, 0x53, 0x45, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x44, 0x53, 0x50, 0x5f, 0x4e, 0x4f, + 0x54, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x44, 0x53, 0x50, 0x5f, + 0x52, 0x45, 0x53, 0x45, 0x52, 0x56, 0x45, 0x44, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x44, 0x53, + 0x50, 0x5f, 0x53, 0x49, 0x4c, 0x45, 0x4e, 0x43, 0x45, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x44, + 0x53, 0x50, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x46, 0x49, 0x4c, + 0x45, 0x5f, 0x42, 0x41, 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, + 0x43, 0x4f, 0x55, 0x4c, 0x44, 0x4e, 0x4f, 0x54, 0x53, 0x45, 0x45, 0x4b, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, + 0x52, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x44, 0x49, 0x53, 0x4b, 0x45, + 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x46, 0x49, 0x4c, 0x45, + 0x5f, 0x45, 0x4f, 0x46, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x45, + 0x4e, 0x44, 0x4f, 0x46, 0x44, 0x41, 0x54, 0x41, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x46, 0x49, + 0x4c, 0x45, 0x5f, 0x4e, 0x4f, 0x54, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, + 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x48, 0x45, 0x41, + 0x44, 0x45, 0x52, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, + 0x52, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x48, 0x54, 0x54, 0x50, + 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x48, 0x54, 0x54, + 0x50, 0x5f, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x41, 0x55, 0x54, 0x48, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, + 0x52, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x48, 0x54, 0x54, + 0x50, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x49, + 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, + 0x52, 0x52, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, + 0x45, 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x45, 0x52, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, + 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x46, 0x4c, + 0x4f, 0x41, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x45, 0x52, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, + 0x5f, 0x48, 0x41, 0x4e, 0x44, 0x4c, 0x45, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x49, 0x4e, 0x56, + 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x50, 0x41, 0x52, 0x41, 0x4d, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, + 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x50, 0x4f, 0x53, 0x49, + 0x54, 0x49, 0x4f, 0x4e, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, + 0x44, 0x5f, 0x53, 0x50, 0x45, 0x41, 0x4b, 0x45, 0x52, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x50, + 0x4f, 0x49, 0x4e, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, + 0x44, 0x5f, 0x54, 0x48, 0x52, 0x45, 0x41, 0x44, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x49, 0x4e, + 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x56, 0x45, 0x43, 0x54, 0x4f, 0x52, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, + 0x52, 0x5f, 0x4d, 0x41, 0x58, 0x41, 0x55, 0x44, 0x49, 0x42, 0x4c, 0x45, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, + 0x52, 0x5f, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x59, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x4d, 0x45, + 0x4d, 0x4f, 0x52, 0x59, 0x5f, 0x43, 0x41, 0x4e, 0x54, 0x50, 0x4f, 0x49, + 0x4e, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x45, 0x52, 0x52, 0x5f, 0x4e, 0x45, 0x45, 0x44, 0x53, 0x33, 0x44, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, + 0x5f, 0x4e, 0x45, 0x45, 0x44, 0x53, 0x48, 0x41, 0x52, 0x44, 0x57, 0x41, + 0x52, 0x45, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x45, 0x52, 0x52, 0x5f, 0x4e, 0x45, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, + 0x45, 0x43, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x45, 0x52, 0x52, 0x5f, 0x4e, 0x45, 0x54, 0x5f, 0x53, 0x4f, 0x43, + 0x4b, 0x45, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x4e, + 0x45, 0x54, 0x5f, 0x55, 0x52, 0x4c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x4e, 0x45, 0x54, 0x5f, + 0x57, 0x4f, 0x55, 0x4c, 0x44, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, + 0x5f, 0x4e, 0x4f, 0x54, 0x52, 0x45, 0x41, 0x44, 0x59, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x4f, + 0x55, 0x54, 0x50, 0x55, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x41, + 0x54, 0x45, 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x45, 0x52, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x5f, + 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x42, 0x55, 0x46, 0x46, 0x45, 0x52, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, + 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x5f, 0x44, 0x52, 0x49, + 0x56, 0x45, 0x52, 0x43, 0x41, 0x4c, 0x4c, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x4f, 0x55, 0x54, + 0x50, 0x55, 0x54, 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, + 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, + 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x5f, 0x4e, 0x4f, 0x44, 0x52, + 0x49, 0x56, 0x45, 0x52, 0x53, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x50, 0x4c, 0x55, 0x47, 0x49, + 0x4e, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, + 0x52, 0x52, 0x5f, 0x50, 0x4c, 0x55, 0x47, 0x49, 0x4e, 0x5f, 0x4d, 0x49, + 0x53, 0x53, 0x49, 0x4e, 0x47, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x50, 0x4c, 0x55, 0x47, 0x49, + 0x4e, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, + 0x50, 0x4c, 0x55, 0x47, 0x49, 0x4e, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, + 0x4f, 0x4e, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x45, 0x52, 0x52, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, + 0x52, 0x45, 0x56, 0x45, 0x52, 0x42, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x4e, + 0x45, 0x4c, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x52, 0x45, 0x56, + 0x45, 0x52, 0x42, 0x5f, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, 0x43, 0x45, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, + 0x52, 0x5f, 0x53, 0x55, 0x42, 0x53, 0x4f, 0x55, 0x4e, 0x44, 0x53, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, + 0x5f, 0x53, 0x55, 0x42, 0x53, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x41, 0x4c, + 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x45, 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x53, 0x55, 0x42, + 0x53, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x43, 0x41, 0x4e, 0x54, 0x4d, 0x4f, + 0x56, 0x45, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x45, 0x52, 0x52, 0x5f, 0x54, 0x41, 0x47, 0x4e, 0x4f, 0x54, 0x46, 0x4f, + 0x55, 0x4e, 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x45, 0x52, 0x52, 0x5f, 0x54, 0x4f, 0x4f, 0x4d, 0x41, 0x4e, 0x59, + 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x53, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x54, 0x52, + 0x55, 0x4e, 0x43, 0x41, 0x54, 0x45, 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x55, 0x4e, 0x49, + 0x4d, 0x50, 0x4c, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x45, 0x44, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, + 0x55, 0x4e, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x45, + 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, + 0x52, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, + 0x45, 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x45, 0x52, 0x52, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, + 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x4c, 0x52, 0x45, 0x41, + 0x44, 0x59, 0x5f, 0x4c, 0x4f, 0x41, 0x44, 0x45, 0x44, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x45, + 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x4c, 0x49, 0x56, 0x45, 0x55, 0x50, 0x44, + 0x41, 0x54, 0x45, 0x5f, 0x42, 0x55, 0x53, 0x59, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x45, 0x56, + 0x45, 0x4e, 0x54, 0x5f, 0x4c, 0x49, 0x56, 0x45, 0x55, 0x50, 0x44, 0x41, + 0x54, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x45, 0x56, + 0x45, 0x4e, 0x54, 0x5f, 0x4c, 0x49, 0x56, 0x45, 0x55, 0x50, 0x44, 0x41, + 0x54, 0x45, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x45, 0x56, + 0x45, 0x4e, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x46, 0x4f, 0x55, 0x4e, 0x44, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, + 0x52, 0x5f, 0x53, 0x54, 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x55, 0x4e, 0x49, + 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x45, 0x44, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, + 0x53, 0x54, 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x4c, + 0x4f, 0x41, 0x44, 0x45, 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, + 0x49, 0x44, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, 0x41, + 0x4c, 0x52, 0x45, 0x41, 0x44, 0x59, 0x5f, 0x4c, 0x4f, 0x43, 0x4b, 0x45, + 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, + 0x52, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x4c, 0x4f, 0x43, 0x4b, 0x45, + 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, + 0x52, 0x52, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x5f, 0x44, 0x49, + 0x53, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x5f, + 0x54, 0x4f, 0x4f, 0x4d, 0x41, 0x4e, 0x59, 0x53, 0x41, 0x4d, 0x50, 0x4c, + 0x45, 0x53, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2e, + 0x65, 0x61, 0x63, 0x68, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x20, 0x64, 0x6f, 0x20, 0x7c, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x2c, 0x20, 0x69, 0x7c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x5f, 0x73, 0x65, 0x74, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2c, + 0x20, 0x69, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, + 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x20, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x20, + 0x3d, 0x20, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, + 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x20, + 0x3d, 0x20, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, + 0x41, 0x58, 0x20, 0x3d, 0x20, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x25, 0x77, 0x5b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x41, 0x55, 0x54, 0x4f, 0x44, 0x45, 0x54, 0x45, 0x43, 0x54, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x55, 0x4e, 0x4b, + 0x4e, 0x4f, 0x57, 0x4e, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x4e, 0x4f, 0x53, 0x4f, 0x55, 0x4e, 0x44, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x57, 0x41, 0x56, 0x57, 0x52, + 0x49, 0x54, 0x45, 0x52, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x4e, 0x4f, 0x53, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x4e, 0x52, + 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x57, + 0x41, 0x56, 0x57, 0x52, 0x49, 0x54, 0x45, 0x52, 0x5f, 0x4e, 0x52, 0x54, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x57, 0x41, + 0x53, 0x41, 0x50, 0x49, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x41, 0x53, 0x49, 0x4f, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x50, 0x55, 0x4c, 0x53, 0x45, 0x41, 0x55, 0x44, + 0x49, 0x4f, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x41, 0x4c, 0x53, 0x41, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x43, 0x4f, 0x52, 0x45, 0x41, 0x55, 0x44, 0x49, 0x4f, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x55, 0x44, + 0x49, 0x4f, 0x54, 0x52, 0x41, 0x43, 0x4b, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x4f, 0x50, 0x45, 0x4e, 0x53, 0x4c, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x55, 0x44, + 0x49, 0x4f, 0x4f, 0x55, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x41, 0x55, 0x44, 0x49, 0x4f, 0x33, 0x44, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x57, 0x45, 0x42, 0x41, + 0x55, 0x44, 0x49, 0x4f, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x4e, 0x4e, 0x41, 0x55, 0x44, 0x49, 0x4f, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x57, 0x49, 0x4e, 0x53, 0x4f, + 0x4e, 0x49, 0x43, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x41, 0x41, 0x55, 0x44, 0x49, 0x4f, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x55, 0x44, 0x49, 0x4f, 0x57, 0x4f, + 0x52, 0x4b, 0x4c, 0x45, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x4d, 0x41, 0x58, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x5d, 0x2e, 0x65, 0x61, 0x63, 0x68, 0x5f, 0x77, 0x69, 0x74, + 0x68, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x64, 0x6f, 0x20, 0x7c, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2c, 0x20, 0x69, 0x7c, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x74, 0x28, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x2c, 0x20, 0x69, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4d, + 0x6f, 0x64, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, + 0x54, 0x59, 0x20, 0x3d, 0x20, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x46, 0x49, 0x4c, 0x45, 0x20, 0x3d, 0x20, 0x31, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x41, 0x4c, 0x4c, 0x42, 0x41, + 0x43, 0x4b, 0x20, 0x3d, 0x20, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x53, 0x70, 0x65, 0x61, 0x6b, 0x65, + 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, 0x3d, 0x20, 0x30, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x41, 0x57, 0x20, + 0x3d, 0x20, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, + 0x4f, 0x4e, 0x4f, 0x20, 0x3d, 0x20, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x53, 0x54, 0x45, 0x52, 0x45, 0x4f, 0x20, 0x3d, 0x20, + 0x33, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x51, 0x55, 0x41, + 0x44, 0x20, 0x3d, 0x20, 0x34, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x53, 0x55, 0x52, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x20, 0x3d, 0x20, + 0x35, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x35, 0x50, + 0x4f, 0x49, 0x4e, 0x54, 0x31, 0x20, 0x3d, 0x20, 0x36, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x37, 0x50, 0x4f, 0x49, 0x4e, 0x54, + 0x31, 0x20, 0x3d, 0x20, 0x37, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x5f, 0x37, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x31, 0x50, 0x4f, 0x49, + 0x4e, 0x54, 0x34, 0x20, 0x3d, 0x20, 0x38, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x4d, 0x41, 0x58, 0x20, 0x3d, 0x20, 0x39, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x53, 0x70, + 0x65, 0x61, 0x6b, 0x65, 0x72, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x25, 0x77, 0x5b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x4e, 0x4f, 0x4e, 0x45, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x4c, 0x45, + 0x46, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x52, 0x4f, + 0x4e, 0x54, 0x5f, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x4f, 0x57, 0x5f, 0x46, + 0x52, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x59, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x55, 0x52, 0x52, 0x4f, 0x55, + 0x4e, 0x44, 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x55, 0x52, 0x52, 0x4f, 0x55, 0x4e, + 0x44, 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x45, + 0x46, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x4f, 0x50, 0x5f, + 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x4f, 0x50, 0x5f, + 0x46, 0x52, 0x4f, 0x4e, 0x54, 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x4f, 0x50, + 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x4f, 0x50, 0x5f, + 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x41, 0x58, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2e, 0x65, 0x61, 0x63, + 0x68, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x20, 0x64, 0x6f, 0x20, 0x7c, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2c, 0x20, + 0x69, 0x7c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x73, + 0x65, 0x74, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2c, 0x20, 0x69, 0x20, + 0x2d, 0x20, 0x31, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x20, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4f, 0x72, + 0x64, 0x65, 0x72, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x25, + 0x77, 0x5b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x57, 0x41, 0x56, 0x45, 0x46, 0x4f, 0x52, + 0x4d, 0x41, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x4f, 0x4c, 0x53, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x4c, 0x4c, 0x4d, 0x4f, + 0x4e, 0x4f, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x41, 0x4c, 0x4c, 0x53, 0x54, 0x45, 0x52, 0x45, 0x4f, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x4c, 0x53, 0x41, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x41, 0x58, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2e, 0x65, 0x61, + 0x63, 0x68, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x20, 0x64, 0x6f, 0x20, 0x7c, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2c, + 0x20, 0x69, 0x7c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, + 0x73, 0x65, 0x74, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2c, 0x20, 0x69, + 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, + 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, + 0x20, 0x3d, 0x20, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x43, 0x4f, 0x44, 0x45, 0x43, 0x20, 0x3d, 0x20, 0x31, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x53, 0x50, 0x20, 0x3d, 0x20, 0x32, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x41, 0x58, 0x20, + 0x3d, 0x20, 0x33, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x20, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x25, 0x77, 0x5b, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x55, 0x4e, 0x4b, + 0x4e, 0x4f, 0x57, 0x4e, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x41, 0x49, 0x46, 0x46, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x41, 0x53, 0x46, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x4c, 0x53, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x4c, 0x41, 0x43, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x53, 0x42, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x54, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x49, 0x44, + 0x49, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, + 0x4f, 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x4d, 0x50, 0x45, 0x47, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x4f, 0x47, 0x47, 0x56, 0x4f, 0x52, 0x42, 0x49, 0x53, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x4c, 0x41, + 0x59, 0x4c, 0x49, 0x53, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x52, 0x41, 0x57, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x53, 0x33, 0x4d, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x55, 0x53, 0x45, 0x52, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x57, 0x41, 0x56, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x4d, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x4d, 0x41, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x55, 0x44, + 0x49, 0x4f, 0x51, 0x55, 0x45, 0x55, 0x45, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x54, 0x39, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x56, 0x4f, 0x52, 0x42, 0x49, 0x53, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x45, + 0x44, 0x49, 0x41, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x45, 0x44, 0x49, 0x41, + 0x43, 0x4f, 0x44, 0x45, 0x43, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x46, 0x41, 0x44, 0x50, 0x43, 0x4d, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4f, 0x50, 0x55, 0x53, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x41, 0x58, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2e, 0x65, 0x61, + 0x63, 0x68, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x20, 0x64, 0x6f, 0x20, 0x7c, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2c, + 0x20, 0x69, 0x7c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, + 0x73, 0x65, 0x74, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2c, 0x20, 0x69, + 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, + 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x4f, 0x4e, 0x45, 0x20, + 0x3d, 0x20, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, + 0x43, 0x4d, 0x38, 0x20, 0x3d, 0x20, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x50, 0x43, 0x4d, 0x31, 0x36, 0x20, 0x3d, 0x20, 0x32, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x43, 0x4d, 0x32, + 0x34, 0x20, 0x3d, 0x20, 0x33, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x50, 0x43, 0x4d, 0x33, 0x32, 0x20, 0x3d, 0x20, 0x34, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x43, 0x4d, 0x46, 0x4c, 0x4f, + 0x41, 0x54, 0x20, 0x3d, 0x20, 0x35, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x42, 0x49, 0x54, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x20, + 0x3d, 0x20, 0x36, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, + 0x41, 0x58, 0x20, 0x3d, 0x20, 0x37, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x4f, 0x52, 0x4d, + 0x41, 0x4c, 0x20, 0x3d, 0x20, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x4d, 0x55, 0x54, 0x45, 0x20, 0x3d, 0x20, 0x31, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x4c, + 0x4f, 0x57, 0x45, 0x53, 0x54, 0x20, 0x3d, 0x20, 0x32, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x41, 0x58, 0x20, 0x3d, 0x20, 0x33, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, + 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x54, 0x79, + 0x70, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x45, + 0x4e, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x56, 0x49, 0x52, 0x54, 0x55, 0x41, 0x4c, 0x56, 0x4f, 0x49, + 0x43, 0x45, 0x20, 0x3d, 0x20, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x53, 0x59, 0x4e, 0x43, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x20, + 0x3d, 0x20, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4f, + 0x43, 0x43, 0x4c, 0x55, 0x53, 0x49, 0x4f, 0x4e, 0x20, 0x3d, 0x20, 0x33, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x41, 0x58, 0x20, + 0x3d, 0x20, 0x34, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x20, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x44, 0x53, 0x50, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x48, 0x45, 0x41, + 0x44, 0x20, 0x3d, 0x20, 0x2d, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x46, 0x41, 0x44, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x2d, 0x32, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x41, 0x49, 0x4c, + 0x20, 0x3d, 0x20, 0x2d, 0x33, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x61, + 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x25, 0x77, 0x5b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x4e, 0x4f, 0x4e, 0x45, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x48, 0x41, + 0x4e, 0x4e, 0x45, 0x4c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x47, 0x52, 0x4f, + 0x55, 0x50, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x43, 0x4f, 0x4e, 0x54, 0x52, + 0x4f, 0x4c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x53, 0x4f, 0x55, 0x4e, 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x53, 0x4f, 0x55, 0x4e, 0x44, 0x47, 0x52, 0x4f, 0x55, + 0x50, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, + 0x53, 0x50, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x44, 0x53, 0x50, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, + 0x4e, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x47, + 0x45, 0x4f, 0x4d, 0x45, 0x54, 0x52, 0x59, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x45, 0x56, 0x45, 0x52, 0x42, 0x33, + 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, + 0x54, 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, + 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x44, 0x45, + 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x55, 0x44, 0x49, + 0x4f, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x49, 0x4e, 0x53, 0x54, 0x41, + 0x4e, 0x43, 0x45, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x53, 0x54, 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x50, 0x41, 0x52, 0x41, + 0x4d, 0x45, 0x54, 0x45, 0x52, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, 0x43, + 0x45, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, + 0x54, 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x42, 0x55, 0x53, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x55, 0x44, 0x49, + 0x4f, 0x5f, 0x56, 0x43, 0x41, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x53, 0x54, 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x42, 0x41, + 0x4e, 0x4b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x53, 0x54, 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x41, + 0x4e, 0x44, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x59, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2e, 0x65, 0x61, 0x63, 0x68, 0x5f, 0x77, + 0x69, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x64, 0x6f, + 0x20, 0x7c, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2c, 0x20, 0x69, 0x7c, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x74, 0x28, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2c, 0x20, 0x69, 0x29, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x44, 0x53, 0x50, 0x52, + 0x65, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x20, + 0x3d, 0x20, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, + 0x4f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x50, 0x20, 0x3d, 0x20, 0x31, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x49, 0x4e, 0x45, 0x41, + 0x52, 0x20, 0x3d, 0x20, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x43, 0x55, 0x42, 0x49, 0x43, 0x20, 0x3d, 0x20, 0x33, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x50, 0x4c, 0x49, 0x4e, 0x45, + 0x20, 0x3d, 0x20, 0x34, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x4d, 0x41, 0x58, 0x20, 0x3d, 0x20, 0x35, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x44, 0x53, 0x50, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x41, 0x4e, + 0x44, 0x41, 0x52, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x53, 0x49, 0x44, 0x45, 0x43, 0x48, 0x41, 0x49, + 0x4e, 0x20, 0x3d, 0x20, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x53, 0x45, 0x4e, 0x44, 0x20, 0x3d, 0x20, 0x32, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x53, 0x49, + 0x44, 0x45, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x20, 0x3d, 0x20, 0x33, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x41, 0x58, 0x20, 0x3d, + 0x20, 0x34, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, + 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x20, 0x54, 0x61, 0x67, 0x54, 0x79, 0x70, 0x65, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x25, 0x77, 0x5b, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, + 0x4e, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, + 0x44, 0x33, 0x56, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x49, 0x44, 0x33, 0x56, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x56, 0x4f, 0x52, 0x42, 0x49, 0x53, 0x43, + 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x53, 0x48, 0x4f, 0x55, 0x54, 0x43, 0x41, 0x53, + 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, + 0x43, 0x45, 0x43, 0x41, 0x53, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x41, 0x53, 0x46, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x49, 0x44, 0x49, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x4c, 0x41, 0x59, 0x4c, + 0x49, 0x53, 0x54, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x46, 0x4d, 0x4f, 0x44, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x55, 0x53, 0x45, 0x52, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x41, 0x58, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2e, 0x65, 0x61, 0x63, 0x68, 0x5f, 0x77, + 0x69, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x64, 0x6f, + 0x20, 0x7c, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2c, 0x20, 0x69, 0x7c, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x74, 0x28, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2c, 0x20, 0x69, 0x29, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x54, 0x61, 0x67, 0x44, + 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x20, 0x3d, 0x20, + 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x4e, 0x54, + 0x20, 0x3d, 0x20, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x20, 0x3d, 0x20, 0x32, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x20, + 0x3d, 0x20, 0x33, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, + 0x54, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x55, 0x54, 0x46, 0x31, 0x36, 0x20, + 0x3d, 0x20, 0x34, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, + 0x54, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x55, 0x54, 0x46, 0x31, 0x36, 0x42, + 0x45, 0x20, 0x3d, 0x20, 0x35, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x55, 0x54, 0x46, 0x38, + 0x20, 0x3d, 0x20, 0x36, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x4d, 0x41, 0x58, 0x20, 0x3d, 0x20, 0x37, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x50, 0x6f, 0x72, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, + 0x55, 0x53, 0x49, 0x43, 0x20, 0x3d, 0x20, 0x30, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x43, 0x4f, 0x50, 0x59, 0x52, 0x49, 0x47, 0x48, + 0x54, 0x5f, 0x4d, 0x55, 0x53, 0x49, 0x43, 0x20, 0x3d, 0x20, 0x31, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x56, 0x4f, 0x49, 0x43, 0x45, + 0x20, 0x3d, 0x20, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x4c, 0x45, 0x52, 0x20, 0x3d, + 0x20, 0x33, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x45, + 0x52, 0x53, 0x4f, 0x4e, 0x41, 0x20, 0x3d, 0x20, 0x34, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x56, 0x49, 0x42, 0x52, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x20, 0x3d, 0x20, 0x35, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x41, 0x55, 0x58, 0x20, 0x3d, 0x20, 0x36, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x41, 0x58, 0x20, 0x3d, 0x20, 0x37, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x20, 0x53, 0x74, 0x75, 0x64, 0x69, 0x6f, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x4d, 0x45, + 0x4d, 0x4f, 0x52, 0x59, 0x5f, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x4d, 0x45, + 0x4e, 0x54, 0x20, 0x3d, 0x20, 0x33, 0x32, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x49, 0x6e, + 0x69, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x49, 0x56, 0x45, 0x55, 0x50, + 0x44, 0x41, 0x54, 0x45, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49, + 0x4e, 0x47, 0x5f, 0x50, 0x4c, 0x55, 0x47, 0x49, 0x4e, 0x53, 0x20, 0x3d, + 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x59, 0x4e, 0x43, 0x48, + 0x52, 0x4f, 0x4e, 0x4f, 0x55, 0x53, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, + 0x45, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x34, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x45, + 0x46, 0x45, 0x52, 0x52, 0x45, 0x44, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x42, + 0x41, 0x43, 0x4b, 0x53, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x38, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x46, 0x52, 0x4f, 0x4d, 0x5f, 0x55, + 0x50, 0x44, 0x41, 0x54, 0x45, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x59, 0x5f, 0x54, 0x52, 0x41, + 0x43, 0x4b, 0x49, 0x4e, 0x47, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x32, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x52, 0x45, 0x41, 0x44, 0x4f, 0x4e, 0x4c, 0x59, + 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x55, 0x54, + 0x4f, 0x4d, 0x41, 0x54, 0x49, 0x43, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x49, 0x53, 0x43, 0x52, 0x45, + 0x54, 0x45, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x38, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, + 0x41, 0x42, 0x45, 0x4c, 0x45, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x54, 0x79, 0x70, + 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x41, 0x4c, + 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x50, 0x52, 0x45, 0x55, 0x50, 0x44, + 0x41, 0x54, 0x45, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x43, 0x41, 0x4c, 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x50, 0x4f, 0x53, + 0x54, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x20, 0x3d, 0x20, 0x30, 0x78, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x43, 0x41, 0x4c, 0x4c, 0x42, 0x41, 0x43, 0x4b, + 0x5f, 0x42, 0x41, 0x4e, 0x4b, 0x5f, 0x55, 0x4e, 0x4c, 0x4f, 0x41, 0x44, + 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x34, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x41, 0x4c, + 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x56, 0x45, 0x55, 0x50, + 0x44, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, + 0x45, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x38, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, + 0x41, 0x4c, 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x56, 0x45, + 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x44, 0x49, 0x53, 0x43, 0x4f, + 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x43, 0x41, 0x4c, 0x4c, 0x42, 0x41, 0x43, 0x4b, + 0x5f, 0x41, 0x4c, 0x4c, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x46, 0x46, 0x46, + 0x46, 0x46, 0x46, 0x46, 0x46, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x20, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x43, 0x61, + 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, + 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, 0x45, + 0x53, 0x54, 0x52, 0x4f, 0x59, 0x45, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x41, 0x52, 0x54, 0x49, 0x4e, 0x47, + 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x34, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x41, + 0x52, 0x54, 0x45, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x38, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x52, 0x45, 0x53, 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, 0x20, 0x3d, + 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x4f, 0x50, 0x50, + 0x45, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x32, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, + 0x54, 0x41, 0x52, 0x54, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x20, + 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x30, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x52, 0x45, 0x41, + 0x54, 0x45, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x41, 0x4d, 0x4d, 0x45, + 0x52, 0x5f, 0x53, 0x4f, 0x55, 0x4e, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x30, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f, 0x59, 0x5f, + 0x50, 0x52, 0x4f, 0x47, 0x52, 0x41, 0x4d, 0x4d, 0x45, 0x52, 0x5f, 0x53, + 0x4f, 0x55, 0x4e, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x31, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x50, 0x4c, 0x55, 0x47, 0x49, 0x4e, 0x5f, 0x43, 0x52, 0x45, 0x41, + 0x54, 0x45, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x32, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x50, 0x4c, 0x55, 0x47, 0x49, 0x4e, 0x5f, 0x44, 0x45, 0x53, 0x54, 0x52, + 0x4f, 0x59, 0x45, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x34, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x54, 0x49, 0x4d, 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x5f, 0x4d, 0x41, + 0x52, 0x4b, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x38, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x54, 0x49, 0x4d, 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x5f, 0x42, 0x45, + 0x41, 0x54, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x31, + 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, + 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x50, 0x4c, 0x41, 0x59, 0x45, 0x44, 0x20, + 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x32, 0x30, 0x30, 0x30, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x4f, 0x55, 0x4e, + 0x44, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x34, 0x30, 0x30, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x45, 0x41, 0x4c, 0x5f, 0x54, + 0x4f, 0x5f, 0x56, 0x49, 0x52, 0x54, 0x55, 0x41, 0x4c, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x38, 0x30, 0x30, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x56, 0x49, 0x52, 0x54, 0x55, 0x41, + 0x4c, 0x5f, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x4c, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, + 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, + 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x32, 0x30, 0x30, + 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x45, + 0x53, 0x54, 0x45, 0x44, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4c, 0x49, 0x4e, + 0x45, 0x5f, 0x42, 0x45, 0x41, 0x54, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, + 0x30, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x41, 0x4c, 0x4c, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x46, + 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x4c, 0x6f, 0x61, 0x64, 0x42, + 0x61, 0x6e, 0x6b, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x20, 0x3d, + 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x4f, 0x4e, 0x42, 0x4c, + 0x4f, 0x43, 0x4b, 0x49, 0x4e, 0x47, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x44, 0x45, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, + 0x53, 0x5f, 0x53, 0x41, 0x4d, 0x50, 0x4c, 0x45, 0x53, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x55, 0x4e, 0x45, 0x4e, 0x43, 0x52, + 0x59, 0x50, 0x54, 0x45, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x43, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x46, 0x6c, 0x61, 0x67, + 0x73, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x4f, 0x52, + 0x4d, 0x41, 0x4c, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x46, 0x49, 0x4c, 0x45, 0x46, 0x4c, 0x55, 0x53, 0x48, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x4b, 0x49, 0x50, 0x5f, 0x49, + 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, + 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x70, 0x6c, + 0x61, 0x79, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x20, 0x3d, 0x20, + 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x4b, 0x49, 0x50, 0x5f, 0x43, + 0x4c, 0x45, 0x41, 0x4e, 0x55, 0x50, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x46, 0x41, 0x53, 0x54, 0x5f, 0x46, 0x4f, 0x52, 0x57, + 0x41, 0x52, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x53, 0x4b, 0x49, 0x50, 0x5f, 0x42, 0x41, 0x4e, 0x4b, 0x5f, 0x4c, 0x4f, + 0x41, 0x44, 0x20, 0x3d, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x34, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x46, 0x4f, 0x52, 0x43, + 0x45, 0x49, 0x4e, 0x54, 0x20, 0x3d, 0x20, 0x36, 0x35, 0x35, 0x33, 0x36, + 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x20, 0x4c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x55, + 0x4e, 0x4c, 0x4f, 0x41, 0x44, 0x49, 0x4e, 0x47, 0x20, 0x3d, 0x20, 0x30, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x55, 0x4e, 0x4c, 0x4f, + 0x41, 0x44, 0x45, 0x44, 0x20, 0x3d, 0x20, 0x31, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x4c, 0x4f, 0x41, 0x44, 0x49, 0x4e, 0x47, 0x20, + 0x3d, 0x20, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4c, + 0x4f, 0x41, 0x44, 0x45, 0x44, 0x20, 0x3d, 0x20, 0x33, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x20, 0x3d, + 0x20, 0x34, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, + 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x20, 0x4c, 0x6f, 0x61, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, + 0x4d, 0x6f, 0x64, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x59, 0x20, 0x3d, 0x20, 0x30, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x59, + 0x5f, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x20, 0x3d, 0x20, 0x31, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x47, 0x41, 0x4d, 0x45, 0x5f, + 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x4c, 0x45, 0x44, 0x20, 0x3d, + 0x20, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x55, + 0x54, 0x4f, 0x4d, 0x41, 0x54, 0x49, 0x43, 0x5f, 0x44, 0x49, 0x53, 0x54, + 0x41, 0x4e, 0x43, 0x45, 0x20, 0x3d, 0x20, 0x31, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x41, 0x55, 0x54, 0x4f, 0x4d, 0x41, 0x54, 0x49, + 0x43, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x45, + 0x5f, 0x41, 0x4e, 0x47, 0x4c, 0x45, 0x20, 0x3d, 0x20, 0x32, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x55, 0x54, 0x4f, 0x4d, 0x41, + 0x54, 0x49, 0x43, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x4f, 0x52, + 0x49, 0x45, 0x4e, 0x54, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x20, 0x3d, 0x20, + 0x33, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x55, 0x54, + 0x4f, 0x4d, 0x41, 0x54, 0x49, 0x43, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, + 0x54, 0x49, 0x4f, 0x4e, 0x20, 0x3d, 0x20, 0x34, 0x0d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x41, 0x55, 0x54, 0x4f, 0x4d, 0x41, 0x54, 0x49, + 0x43, 0x5f, 0x45, 0x4c, 0x45, 0x56, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x20, + 0x3d, 0x20, 0x35, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, + 0x55, 0x54, 0x4f, 0x4d, 0x41, 0x54, 0x49, 0x43, 0x5f, 0x4c, 0x49, 0x53, + 0x54, 0x45, 0x4e, 0x45, 0x52, 0x5f, 0x4f, 0x52, 0x49, 0x45, 0x4e, 0x54, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x20, 0x3d, 0x20, 0x36, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x55, 0x54, 0x4f, 0x4d, 0x41, 0x54, + 0x49, 0x43, 0x5f, 0x53, 0x50, 0x45, 0x45, 0x44, 0x20, 0x3d, 0x20, 0x37, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x55, 0x54, 0x4f, + 0x4d, 0x41, 0x54, 0x49, 0x43, 0x5f, 0x53, 0x50, 0x45, 0x45, 0x44, 0x5f, + 0x41, 0x42, 0x53, 0x4f, 0x4c, 0x55, 0x54, 0x45, 0x20, 0x3d, 0x20, 0x38, + 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x55, 0x54, 0x4f, + 0x4d, 0x41, 0x54, 0x49, 0x43, 0x5f, 0x44, 0x49, 0x53, 0x54, 0x41, 0x4e, + 0x43, 0x45, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x49, 0x5a, 0x45, + 0x44, 0x20, 0x3d, 0x20, 0x39, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x20, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, + 0x20, 0x3d, 0x20, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x20, 0x3d, 0x20, 0x31, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x4c, 0x4f, 0x41, 0x54, + 0x20, 0x3d, 0x20, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x20, 0x3d, 0x20, 0x33, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x48, 0x41, 0x4e, 0x4e, + 0x45, 0x4c, 0x50, 0x52, 0x49, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x20, 0x3d, + 0x20, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x43, + 0x48, 0x45, 0x44, 0x55, 0x4c, 0x45, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, + 0x20, 0x3d, 0x20, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x53, 0x43, 0x48, 0x45, 0x44, 0x55, 0x4c, 0x45, 0x5f, 0x4c, 0x4f, 0x4f, + 0x4b, 0x41, 0x48, 0x45, 0x41, 0x44, 0x20, 0x3d, 0x20, 0x32, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x49, 0x4e, 0x49, 0x4d, 0x55, + 0x4d, 0x5f, 0x44, 0x49, 0x53, 0x54, 0x41, 0x4e, 0x43, 0x45, 0x20, 0x3d, + 0x20, 0x33, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x41, + 0x58, 0x49, 0x4d, 0x55, 0x4d, 0x5f, 0x44, 0x49, 0x53, 0x54, 0x41, 0x4e, + 0x43, 0x45, 0x20, 0x3d, 0x20, 0x34, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x43, 0x4f, 0x4f, 0x4c, 0x44, 0x4f, 0x57, 0x4e, 0x20, 0x3d, + 0x20, 0x35, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x41, + 0x58, 0x20, 0x3d, 0x20, 0x36, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x20, 0x50, 0x6c, 0x61, 0x79, 0x62, 0x61, 0x63, + 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x50, 0x4c, 0x41, 0x59, 0x49, 0x4e, 0x47, 0x20, 0x3d, 0x20, + 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x55, 0x53, + 0x54, 0x41, 0x49, 0x4e, 0x49, 0x4e, 0x47, 0x20, 0x3d, 0x20, 0x31, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, 0x4f, 0x50, 0x50, + 0x45, 0x44, 0x20, 0x3d, 0x20, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x53, 0x54, 0x41, 0x52, 0x54, 0x49, 0x4e, 0x47, 0x20, 0x3d, + 0x20, 0x33, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x54, + 0x4f, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x20, 0x3d, 0x20, 0x34, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x53, 0x74, + 0x6f, 0x70, 0x4d, 0x6f, 0x64, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x46, 0x41, 0x44, 0x45, 0x4f, + 0x55, 0x54, 0x20, 0x3d, 0x20, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x49, 0x4d, 0x4d, 0x45, 0x44, 0x49, 0x41, 0x54, 0x45, 0x20, + 0x3d, 0x20, 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, + 0x4f, 0x4e, 0x45, 0x20, 0x3d, 0x20, 0x30, 0x0d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x20, 0x3d, 0x20, + 0x31, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x56, 0x45, + 0x4e, 0x54, 0x44, 0x45, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, + 0x4e, 0x20, 0x3d, 0x20, 0x32, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, + 0x43, 0x45, 0x20, 0x3d, 0x20, 0x33, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x50, 0x41, 0x52, 0x41, 0x4d, 0x45, 0x54, 0x45, 0x52, 0x49, + 0x4e, 0x53, 0x54, 0x41, 0x4e, 0x43, 0x45, 0x20, 0x3d, 0x20, 0x34, 0x0d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x42, 0x55, 0x53, 0x20, 0x3d, + 0x20, 0x35, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x56, 0x43, + 0x41, 0x20, 0x3d, 0x20, 0x36, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x42, 0x41, 0x4e, 0x4b, 0x20, 0x3d, 0x20, 0x37, 0x0d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, + 0x52, 0x45, 0x50, 0x4c, 0x41, 0x59, 0x20, 0x3d, 0x20, 0x38, 0x0d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0d, 0x0a, 0x65, 0x6e, 0x64, 0x0d, 0x0a +}; +unsigned int fmod_enums_len = 18813; diff --git a/binding-mri/fmod-binding/studio/bank.cpp b/binding-mri/fmod-binding/studio/bank.cpp new file mode 100644 index 00000000..2df22a31 --- /dev/null +++ b/binding-mri/fmod-binding/studio/bank.cpp @@ -0,0 +1,357 @@ +#include "binding-util.h" +#include "fmod_bindings.h" +#ifdef AUTO_CLEAN_FMOD +#include "debugwriter.h" +#include +#endif + +/* +? Bank bindings +? Why is RB_UNUSED_PARAM used everywhere? I have no idea! +? MKXP has them *everywhere*, and I don't know why! +? +? Most of these abuse macros and the C preprocessor to +? shrink code. You may want to read up on these macros +? first. +*/ + +DEF_TYPE(Bank); +/* +? Custom bank destructor +? Automatically unloads the bank when +? the bank is garbage collected from ruby +*/ +Bank::~Bank() +{ + #ifdef AUTO_CLEAN_FMOD + Debug() << "Warning: auto unloading bank (garbage collected?)"; + Debug() << "Bank unloading result: " << FMOD_ErrorString(FMOD_Studio_Bank_Unload(p)); + #endif +} + +VALUE rb_cBank = Qnil; + +FMOD_VALID_FUNC(FMOD_Studio_Bank, Bank); + +FMOD_ID_FUNC(FMOD_Studio_Bank, Bank); + +FMOD_PATH_FUNC(FMOD_Studio_Bank, Bank); + +RB_METHOD(bankUnload) +{ + RB_UNUSED_PARAM; + + //? Get wrapper + Bank *b = getPrivateData(self); + + //? Unload bank + FMOD_RESULT result = FMOD_Studio_Bank_Unload(b->p); + + //? Return only the result + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(bankLoadSampleData) +{ + RB_UNUSED_PARAM; + + //? Get wrapper + Bank *b = getPrivateData(self); + + //? Load sample data + FMOD_RESULT result = FMOD_Studio_Bank_LoadSampleData(b->p); + + //? Return only the result + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(bankUnloadSampleData) +{ + RB_UNUSED_PARAM; + + //? Get wrapper + Bank *b = getPrivateData(self); + + //? Unload sample data + FMOD_RESULT result = FMOD_Studio_Bank_UnloadSampleData(b->p); + + //? Return only the result + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(bankGetLoadingState) +{ + RB_UNUSED_PARAM; + + //? Get wrapper + Bank *b = getPrivateData(self); + FMOD_STUDIO_LOADING_STATE state; + + //? Call function + FMOD_RESULT result = FMOD_Studio_Bank_GetLoadingState(b->p, &state); + + //? Return result & value + FMOD_RESULT_CONVERT(state, INT2NUM); +} + +RB_METHOD(bankGetSampleLoadingState) +{ + RB_UNUSED_PARAM; + + //? Get wrapper + Bank *b = getPrivateData(self); + FMOD_STUDIO_LOADING_STATE state; + + //? Call function + FMOD_RESULT result = FMOD_Studio_Bank_GetSampleLoadingState(b->p, &state); + + //? Return result & value + FMOD_RESULT_CONVERT(state, INT2NUM); +} + +RB_METHOD(bankGetStringCount) +{ + RB_UNUSED_PARAM; + //? Get wrapper + Bank *b = getPrivateData(self); + int count; + + //? Call function + FMOD_RESULT result = FMOD_Studio_Bank_GetStringCount(b->p, &count); + + //? Return result & value + FMOD_RESULT_CONVERT(count, INT2NUM); +} + +//! Oh boy +RB_METHOD(bankGetStringInfo) +{ + //? Get the index we are using + int index; + rb_get_args(argc, argv, "i", &index RB_ARG_END); + + //? Get wrapper + Bank *b = getPrivateData(self); + //? Set up variables, guid and path are intentionally null + //? so we don't allocate memory for them if the function is + //? unsuccessful + int retrieved; + char *path = NULL; + FMOD_GUID guid; + + FMOD_RESULT result = FMOD_Studio_Bank_GetStringInfo( + b->p, index, NULL, NULL, 0, &retrieved); + + //? If function was successful + if (result == FMOD_OK) + { + //? Allocate memory for the string like in GetPath + path = new char[retrieved]; + //? Create the GUID + guid = FMOD_GUID(); + + //? Finally call the function for real + //? Oh boy that was horrible + result = FMOD_Studio_Bank_GetStringInfo( + b->p, index, &guid, path, retrieved, &retrieved); + } + + //? Not many functions need more than 1 return value + //? and the functions that do are specialized, so no + //? fancy macro here unfortunately + FMOD_RESULT_BASE; + if (path) + { + VALUE return_val = fmodFMOD_GUID2rb(guid); + rb_ary_push(return_ary, return_val); + rb_ary_push(return_ary, rb_str_new_cstr(path)); + } + //? Hell is over! + FMOD_RESULT_RET; +} + +FMOD_USERDATA_FUNC(FMOD_Studio_Bank, Bank); + +RB_METHOD(bankGetVCACount) +{ + RB_UNUSED_PARAM; + //? Get wrapper + Bank *b = getPrivateData(self); + int count; + + //? Call function + FMOD_RESULT result = FMOD_Studio_Bank_GetVCACount(b->p, &count); + + //? Return result & value + FMOD_RESULT_CONVERT(count, INT2NUM); +} + +//! HERE BE DRAGONS +RB_METHOD(bankGetVCAList) +{ + RB_UNUSED_PARAM; + + //? Get wrapper + Bank *b = getPrivateData(self); + + //? Find size of array we need (because we need to allocate memory) + //? I absolutely hate doing this kind of process but y'know what + //? whatever it works + int count; + FMOD_STUDIO_VCA **array = NULL; + FMOD_RESULT result = FMOD_Studio_Bank_GetVCACount(b->p, &count); + + if (result == FMOD_OK) + { + //? Allocate array (god i hate this) + array = new FMOD_STUDIO_VCA *[count]; + + result = FMOD_Studio_Bank_GetVCAList( + b->p, array, count, NULL); + } + + FMOD_RESULT_BASE; + if (array && result == FMOD_OK) + { + //? Convert the vca array to a ruby array, painfully + VALUE vca_ary = rb_ary_new(); + //? Iterate over all elements in the array + //? May potentially crash if the amount of elements + //? is different from count + for (int i = 0; i < count; i++) + { + //? Convert VCA and add it to the array + VALUE ele = rb_obj_alloc(rb_cVCA); + setPrivateData(ele, new VCA(array[i])); + rb_ary_push(vca_ary, ele); + } + //? Add the result array and we are done! + //? This likely memory leaks I think, but we'll see + rb_ary_push(return_ary, vca_ary); + delete array; //? This shouldn't free the elements? + } + FMOD_RESULT_RET; +} + +RB_METHOD(bankGetBusCount) +{ + RB_UNUSED_PARAM; + Bank *b = getPrivateData(self); + int count; + + FMOD_RESULT result = FMOD_Studio_Bank_GetBusCount(b->p, &count); + + FMOD_RESULT_CONVERT(count, INT2NUM); +} + +RB_METHOD(bankGetBusList) +{ + RB_UNUSED_PARAM; + + Bank *b = getPrivateData(self); + + int count; + FMOD_STUDIO_BUS **array = NULL; + FMOD_RESULT result = FMOD_Studio_Bank_GetBusCount(b->p, &count); + + if (result == FMOD_OK) + { + array = new FMOD_STUDIO_BUS *[count]; + + result = FMOD_Studio_Bank_GetBusList( + b->p, array, count, NULL); + } + + FMOD_RESULT_BASE; + if (array && result == FMOD_OK) + { + VALUE bus_ary = rb_ary_new(); + + for (int i = 0; i < count; i++) + { + VALUE ele = rb_obj_alloc(rb_cBus); + setPrivateData(ele, new Bus(array[i])); + rb_ary_push(bus_ary, ele); + } + + rb_ary_push(return_ary, bus_ary); + delete array; + } + FMOD_RESULT_RET; +} + +RB_METHOD(bankGetEventCount) +{ + RB_UNUSED_PARAM; + Bank *b = getPrivateData(self); + int count; + + FMOD_RESULT result = FMOD_Studio_Bank_GetEventCount(b->p, &count); + + FMOD_RESULT_CONVERT(count, INT2NUM); +} + +RB_METHOD(bankGetEventList) +{ + RB_UNUSED_PARAM; + + Bank *b = getPrivateData(self); + + int count; + FMOD_STUDIO_EVENTDESCRIPTION **array = NULL; + FMOD_RESULT result = FMOD_Studio_Bank_GetEventCount(b->p, &count); + + if (result == FMOD_OK) + { + array = new FMOD_STUDIO_EVENTDESCRIPTION *[count]; + + result = FMOD_Studio_Bank_GetEventList( + b->p, array, count, NULL); + } + + FMOD_RESULT_BASE; + if (array && result == FMOD_OK) + { + VALUE event_ary = rb_ary_new(); + + for (int i = 0; i < count; i++) + { + VALUE ele = rb_obj_alloc(rb_cEventDescription); + setPrivateData(ele, new EventDescription(array[i])); + rb_ary_push(event_ary, ele); + } + + rb_ary_push(return_ary, event_ary); + delete array; + } + FMOD_RESULT_RET; +} + +FMOD_EQUAL_FUNC(Bank); + +void bindFmodStudioBank() +{ + rb_cBank = rb_define_class_under(rb_mFMOD_Studio, "Bank", rb_cObject); + rb_define_alloc_func(rb_cBank, classAllocate<&BankType>); + _rb_define_method(rb_cBank, "initialize", fmodErrorInit); + _rb_define_method(rb_cBank, "==", fmodEqual); + + _rb_define_method(rb_cBank, "is_valid", fmodIsValid); + _rb_define_method(rb_cBank, "get_id", fmodGetID); + _rb_define_method(rb_cBank, "get_path", fmodGetPath); + _rb_define_method(rb_cBank, "unload", bankUnload); + _rb_define_method(rb_cBank, "load_sample_data", bankLoadSampleData); + _rb_define_method(rb_cBank, "unload_sample_data", bankUnloadSampleData); + _rb_define_method(rb_cBank, "get_loading_state", bankGetLoadingState); + _rb_define_method(rb_cBank, "get_sample_loading_state", bankGetSampleLoadingState); + _rb_define_method(rb_cBank, "get_string_count", bankGetStringCount); + _rb_define_method(rb_cBank, "get_string_info", bankGetStringInfo); + _rb_define_method(rb_cBank, "get_user_data", fmodGetUserData); + _rb_define_method(rb_cBank, "set_user_data", fmodSetUserData); + _rb_define_method(rb_cBank, "get_vca_count", bankGetVCACount); + _rb_define_method(rb_cBank, "get_vca_list", bankGetVCAList); + _rb_define_method(rb_cBank, "get_bus_count", bankGetBusCount); + _rb_define_method(rb_cBank, "get_bus_list", bankGetBusList); + _rb_define_method(rb_cBank, "get_event_count", bankGetEventCount); + _rb_define_method(rb_cBank, "get_event_list", bankGetEventList); +} diff --git a/binding-mri/fmod-binding/studio/bus.cpp b/binding-mri/fmod-binding/studio/bus.cpp new file mode 100644 index 00000000..bda9bad9 --- /dev/null +++ b/binding-mri/fmod-binding/studio/bus.cpp @@ -0,0 +1,117 @@ +#include "fmod_bindings.h" +#include "binding-util.h" +#include "debugwriter.h" + +DEF_TYPE(Bus); +Bus::~Bus() +{ + // Debug() << "Warning: Bus deconstructed (garbage collected?)"; +} + +VALUE rb_cBus = Qnil; + +FMOD_VALID_FUNC(FMOD_Studio_Bus, Bus); + +FMOD_ID_FUNC(FMOD_Studio_Bus, Bus); + +FMOD_PATH_FUNC(FMOD_Studio_Bus, Bus); + +FMOD_VOLUME_FUNC(FMOD_Studio_Bus, Bus); + +FMOD_PAUSED_FUNC(FMOD_Studio_Bus, Bus); + +RB_METHOD(busStopAllEvents) +{ + int mode; + rb_get_args(argc, argv, "i", &mode RB_ARG_END); + + Bus *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_Bus_StopAllEvents( + b->p, (FMOD_STUDIO_STOP_MODE)mode); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(busGetPortIndex) +{ + RB_UNUSED_PARAM; + + Bus *b = getPrivateData(self); + unsigned long long port; + + FMOD_RESULT result = FMOD_Studio_Bus_GetPortIndex( + b->p, &port); + + FMOD_RESULT_CONVERT(port, ULL2NUM); +} + +RB_METHOD(busSetPortIndex) +{ + unsigned long long port; + VALUE rb_port; + rb_get_args(argc, argv, "o", &port RB_ARG_END); + port = NUM2ULL(rb_port); //? Hack since mkxp doesn't support ull's from rb_get_args + + Bus *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_Bus_SetPortIndex( + b->p, port); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(busLockChannelGroup) +{ + RB_UNUSED_PARAM; + Bus *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_Bus_LockChannelGroup( + b->p); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(busUnlockChannelGroup) +{ + RB_UNUSED_PARAM; + Bus *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_Bus_UnlockChannelGroup( + b->p); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(busGetChannelGroup) { + // TODO +} + +FMOD_CPU_USAGE_FUNC(FMOD_Studio_Bus, Bus); +FMOD_MEMORY_USAGE_FUNC(FMOD_Studio_Bus, Bus); + +FMOD_EQUAL_FUNC(Bus); + +void bindFmodStudioBus() +{ + rb_cBus = rb_define_class_under(rb_mFMOD_Studio, "Bus", rb_cObject); + rb_define_alloc_func(rb_cBus, classAllocate<&BusType>); + _rb_define_method(rb_cBus, "initialize", fmodErrorInit); + _rb_define_method(rb_cBus, "==", fmodEqual); + + _rb_define_method(rb_cBus, "is_valid", fmodIsValid); + _rb_define_method(rb_cBus, "get_id", fmodGetID); + _rb_define_method(rb_cBus, "get_path", fmodGetPath); + _rb_define_method(rb_cBus, "get_volume", fmodGetVolume); + _rb_define_method(rb_cBus, "set_volume", fmodSetVolume); + _rb_define_method(rb_cBus, "get_paused", fmodGetPaused); + _rb_define_method(rb_cBus, "set_paused", fmodSetPaused); + _rb_define_method(rb_cBus, "stop_all_events", busStopAllEvents); + _rb_define_method(rb_cBus, "get_port_index", busGetPortIndex); + _rb_define_method(rb_cBus, "set_port_index", busSetPortIndex); + _rb_define_method(rb_cBus, "lock_channelgroup", busLockChannelGroup); + _rb_define_method(rb_cBus, "unlock_channelgroup", busUnlockChannelGroup); + _rb_define_method(rb_cBus, "get_channelgroup", busGetChannelGroup); + _rb_define_method(rb_cBus, "get_cpu_usage", fmodGetCPUUsage); + _rb_define_method(rb_cBus, "get_memory_usage", fmodGetMemoryUsage); +} diff --git a/binding-mri/fmod-binding/studio/commandreplay.cpp b/binding-mri/fmod-binding/studio/commandreplay.cpp new file mode 100644 index 00000000..b8f0ec01 --- /dev/null +++ b/binding-mri/fmod-binding/studio/commandreplay.cpp @@ -0,0 +1,256 @@ +#include "fmod_bindings.h" +#include "binding-util.h" +#ifdef AUTO_CLEAN_FMOD +#include "debugwriter.h" +#include +#endif + +DEF_TYPE(CommandReplay); +CommandReplay::~CommandReplay() +{ +#ifdef AUTO_CLEAN_FMOD + Debug() << "Warning: auto releasing command replay (garbage collected?)"; + Debug() << "Command replay release result: " << FMOD_ErrorString(FMOD_Studio_CommandReplay_Release(p)); +#endif +} + +VALUE rb_cCommandReplay = Qnil; + +FMOD_VALID_FUNC(FMOD_Studio_CommandReplay, CommandReplay); + +RB_METHOD(commandReplayGetSystem) +{ + RB_UNUSED_PARAM; + + CommandReplay *b = getPrivateData(self); + FMOD_STUDIO_SYSTEM *system; + + FMOD_RESULT result = FMOD_Studio_CommandReplay_GetSystem(b->p, &system); + + FMOD_RESULT_WRAP(system, StudioSystem); +} + +RB_METHOD(commandReplayGetLength) +{ + RB_UNUSED_PARAM; + + CommandReplay *b = getPrivateData(self); + float length; + + FMOD_RESULT result = FMOD_Studio_CommandReplay_GetLength(b->p, &length); + + FMOD_RESULT_CONVERT(length, DBL2NUM); +} + +RB_METHOD(commandReplayGetCommandCount) +{ + RB_UNUSED_PARAM; + + CommandReplay *b = getPrivateData(self); + int count; + + FMOD_RESULT result = FMOD_Studio_CommandReplay_GetCommandCount(b->p, &count); + + FMOD_RESULT_CONVERT(count, INT2NUM); +} + +RB_METHOD(commandReplayGetCommandInfo) +{ + int index; + rb_get_args(argc, argv, "i", &index RB_ARG_END); + + CommandReplay *b = getPrivateData(self); + FMOD_STUDIO_COMMAND_INFO info = FMOD_STUDIO_COMMAND_INFO(); + + FMOD_RESULT result = FMOD_Studio_CommandReplay_GetCommandInfo(b->p, index, &info); + + FMOD_RESULT_NO_WRAP(info, FMOD_STUDIO_COMMAND_INFO); +} + +RB_METHOD(commandReplayGetCommandString) +{ + int index; + rb_get_args(argc, argv, "i", &index RB_ARG_END); + + CommandReplay *b = getPrivateData(self); + + //! WHY DOES THIS FUNCTION ACT DIFFERNTLY!?!?!?! + int length = 256; + char *path = new char[length]; + + FMOD_RESULT result = FMOD_Studio_CommandReplay_GetCommandString(b->p, index, path, length); + + //! Make string longer while it's too short + while (result == FMOD_ERR_TRUNCATED) + { + delete path; + length *= 2; + path = new char[length]; + result = FMOD_Studio_CommandReplay_GetCommandString(b->p, index, path, length); + } + + if (result != FMOD_OK) + delete path; //! Normally the string would never be allocated if the function didn't return ok + //! but here since we ALWAYS allocate the string we need to free it + //! This also would not normally be a problem with other functions since they + //! usually take in a statically allocated argument, but here since it's a string, + //! we need to free it. + + //! This also means that the string is too long, but that's fine since ruby controls the string now + FMOD_RESULT_CONVERT(path, rb_str_new_cstr); +} + +RB_METHOD(commandReplayGetCommandAtTime) { + float time; + rb_get_args(argc, argv, "f", &time RB_ARG_END); + + CommandReplay *b = getPrivateData(self); + int index; + + FMOD_RESULT result = FMOD_Studio_CommandReplay_GetCommandAtTime(b->p, time, &index); + + FMOD_RESULT_CONVERT(index, INT2NUM); +} + +RB_METHOD(commandReplaySetBankPath) { + char* path; + rb_get_args(argc, argv, "z", &path RB_ARG_END); + + CommandReplay *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_CommandReplay_SetBankPath(b->p, path); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(commandReplayStart) { + RB_UNUSED_PARAM; + + CommandReplay *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_CommandReplay_Start(b->p); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(commandReplayStop) { + RB_UNUSED_PARAM; + + CommandReplay *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_CommandReplay_Stop(b->p); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(commandReplaySeekToTime) { + float time; + rb_get_args(argc, argv, "f", &time RB_ARG_END); + + CommandReplay *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_CommandReplay_SeekToTime(b->p, time); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(commandReplaySeekToCommand) { + int index; + rb_get_args(argc, argv, "i", &index RB_ARG_END); + + CommandReplay *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_CommandReplay_SeekToCommand(b->p, index); + + FMOD_RESULT_SIMPLE; +} + +FMOD_PAUSED_FUNC(FMOD_Studio_CommandReplay, CommandReplay); + +RB_METHOD(commandReplayGetPlaybackState) { + RB_UNUSED_PARAM; + + CommandReplay *b = getPrivateData(self); + + FMOD_STUDIO_PLAYBACK_STATE state; + + FMOD_RESULT result = FMOD_Studio_CommandReplay_GetPlaybackState(b->p, &state); + + FMOD_RESULT_CONVERT(state, INT2NUM); +} + +RB_METHOD(commandReplayGetCurrentCommand) { + RB_UNUSED_PARAM; + + CommandReplay *b = getPrivateData(self); + + int index; + float time; + + FMOD_RESULT result = FMOD_Studio_CommandReplay_GetCurrentCommand(b->p, &index, &time); + + FMOD_RESULT_BASE; + if (result == FMOD_OK) { + rb_ary_push(return_ary, INT2NUM(index)); + rb_ary_push(return_ary, DBL2NUM(time)); + } + FMOD_RESULT_RET; +} + +RB_METHOD(commandReplayRelease) { + RB_UNUSED_PARAM; + + CommandReplay *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_CommandReplay_Release(b->p); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(commandReplaySetFrameCallback) { + // TODO +} + +RB_METHOD(commandReplaySetLoadBankCallback) { + // TODO +} + +RB_METHOD(commandReplaySetCreateInstanceCallback) { + // TODO +} + +FMOD_USERDATA_FUNC(FMOD_Studio_CommandReplay, CommandReplay); + +FMOD_EQUAL_FUNC(CommandReplay); + +void bindFmodStudioCommandReplay() +{ + rb_cCommandReplay = rb_define_class_under( + rb_mFMOD_Studio, "CommandReplay", rb_cObject); + rb_define_alloc_func(rb_cCommandReplay, classAllocate<&CommandReplayType>); + _rb_define_method(rb_cCommandReplay, "initialize", fmodErrorInit); + _rb_define_method(rb_cCommandReplay, "==", fmodEqual); + + _rb_define_method(rb_cCommandReplay, "is_valid", fmodIsValid); + _rb_define_method(rb_cCommandReplay, "get_system", commandReplayGetSystem); + _rb_define_method(rb_cCommandReplay, "get_length", commandReplayGetLength); + _rb_define_method(rb_cCommandReplay, "get_command_count", commandReplayGetCommandCount); + _rb_define_method(rb_cCommandReplay, "get_command_info", commandReplayGetCommandInfo); + _rb_define_method(rb_cCommandReplay, "get_command_string", commandReplayGetCommandString); + _rb_define_method(rb_cCommandReplay, "get_command_at_time", commandReplayGetCommandAtTime); + _rb_define_method(rb_cCommandReplay, "set_bank_path", commandReplaySetBankPath); + _rb_define_method(rb_cCommandReplay, "start", commandReplayStart); + _rb_define_method(rb_cCommandReplay, "stop", commandReplayStop); + _rb_define_method(rb_cCommandReplay, "seek_to_time", commandReplaySeekToTime); + _rb_define_method(rb_cCommandReplay, "seek_to_command", commandReplaySeekToCommand); + _rb_define_method(rb_cCommandReplay, "get_paused", fmodGetPaused); + _rb_define_method(rb_cCommandReplay, "set_paused", fmodSetPaused); + _rb_define_method(rb_cCommandReplay, "get_playback_state", commandReplayGetPlaybackState); + _rb_define_method(rb_cCommandReplay, "get_current_command", commandReplayGetCurrentCommand); + _rb_define_method(rb_cCommandReplay, "release", commandReplayRelease); + _rb_define_method(rb_cCommandReplay, "set_frame_callback", commandReplaySetFrameCallback); + _rb_define_method(rb_cCommandReplay, "set_load_bank_callback", commandReplaySetLoadBankCallback); + _rb_define_method(rb_cCommandReplay, "set_create_instance_callback", commandReplaySetCreateInstanceCallback); + _rb_define_method(rb_cCommandReplay, "get_user_data", fmodGetUserData); + _rb_define_method(rb_cCommandReplay, "set_user_data", fmodSetUserData); +} diff --git a/binding-mri/fmod-binding/studio/common_structs.cpp b/binding-mri/fmod-binding/studio/common_structs.cpp new file mode 100644 index 00000000..9effbac7 --- /dev/null +++ b/binding-mri/fmod-binding/studio/common_structs.cpp @@ -0,0 +1,185 @@ +#include "common_structs.h" +#include "fmod_bindings.h" +#include + +VALUE rb_cMemoryUsage = Qnil; +DECLARE_FMOD2RB(FMOD_STUDIO_MEMORY_USAGE, rb_cMemoryUsage); +FMOD2RB(exclusive, INT2NUM); +FMOD2RB(inclusive, INT2NUM); +FMOD2RB(sampledata, INT2NUM); +FMOD2RB_END; + +VALUE rb_cParameterDescription = Qnil; +DECLARE_FMOD2RB(FMOD_STUDIO_PARAMETER_DESCRIPTION, rb_cParameterDescription); +FMOD2RB(name, rb_str_new_cstr); +FMOD2RB_STRUCT(id, FMOD_STUDIO_PARAMETER_ID); +FMOD2RB(minimum, DBL2NUM); +FMOD2RB(maximum, DBL2NUM); +FMOD2RB_NAME(default_value, defaultvalue, DBL2NUM); +FMOD2RB(type, INT2NUM); +FMOD2RB(flags, INT2NUM); +FMOD2RB_STRUCT(guid, FMOD_GUID); +FMOD2RB_END; + +VALUE rb_cParameterID = Qnil; +DECLARE_FMOD2RB(FMOD_STUDIO_PARAMETER_ID, rb_cParameterID); +FMOD2RB(data1, UINT2NUM); +FMOD2RB(data2, UINT2NUM); +FMOD2RB_END; + +DECLARE_RB2FMOD(FMOD_STUDIO_PARAMETER_ID, rb_cParameterID); +RB2FMOD(data1, NUM2UINT); +RB2FMOD(data2, NUM2UINT); +RB2FMOD_END; + +VALUE rb_cUserProperty = Qnil; +DECLARE_FMOD2RB(FMOD_STUDIO_USER_PROPERTY, rb_cUserProperty); +FMOD2RB(name, rb_str_new_cstr); +FMOD2RB(type, INT2NUM); +switch (p.type) +{ + case FMOD_STUDIO_USER_PROPERTY_TYPE_INTEGER: + rb_iv_set(self, "@value", INT2NUM(p.intvalue)); + break; + case FMOD_STUDIO_USER_PROPERTY_TYPE_BOOLEAN: + rb_iv_set(self, "@value", BOOL2RB(p.boolvalue)); + break; + case FMOD_STUDIO_USER_PROPERTY_TYPE_FLOAT: + rb_iv_set(self, "@value", DBL2NUM(p.floatvalue)); + break; + case FMOD_STUDIO_USER_PROPERTY_TYPE_STRING: + rb_iv_set(self, "@value", rb_str_new_cstr(p.stringvalue)); + break; + default: + rb_raise(rb_eRuntimeError, "User property type is invalid"); + break; +} +FMOD2RB_END; + +VALUE rb_cCommandInfo = Qnil; +DECLARE_FMOD2RB(FMOD_STUDIO_COMMAND_INFO, rb_cCommandInfo); +FMOD2RB_NAME(command_name, commandname, rb_str_new_cstr); +FMOD2RB_NAME(parent_command_index, parentcommandindex, INT2NUM); +FMOD2RB_NAME(frame_number, framenumber, INT2NUM); +FMOD2RB_NAME(frame_time, frametime, DBL2NUM); +FMOD2RB_NAME(instance_type, instancetype, INT2NUM); +FMOD2RB_NAME(output_type, outputtype, INT2NUM); +FMOD2RB_NAME(instance_handle, instancehandle, UINT2NUM); +FMOD2RB_NAME(output_handle, outputhandle, UINT2NUM); +FMOD2RB_END; + +VALUE rb_cAdvancedSettings = Qnil; +DECLARE_FMOD2RB(FMOD_STUDIO_ADVANCEDSETTINGS, rb_cAdvancedSettings); +FMOD2RB_NAME(cb_size, cbsize, INT2NUM); +FMOD2RB_NAME(command_queue_size, commandqueuesize, UINT2NUM); +FMOD2RB_NAME(handle_initial_size, handleinitialsize, UINT2NUM); +FMOD2RB_NAME(studio_update_period, studioupdateperiod, INT2NUM); +FMOD2RB_NAME(idle_sample_data_pool_size, idlesampledatapoolsize, INT2NUM); +FMOD2RB_NAME(streaming_schedule_delay, streamingscheduledelay, UINT2NUM); +FMOD2RB_NAME(encryption_key, encryptionkey, rb_str_new_cstr); +FMOD2RB_END; + +DECLARE_RB2FMOD(FMOD_STUDIO_ADVANCEDSETTINGS, rb_cAdvancedSettings); +RB2FMOD_NAME(cb_size, cbsize, NUM2INT); +RB2FMOD_NAME(command_queue_size, commandqueuesize, NUM2UINT); +RB2FMOD_NAME(handle_initial_size, handleinitialsize, NUM2UINT); +RB2FMOD_NAME(studio_update_period, studioupdateperiod, NUM2INT); +RB2FMOD_NAME(idle_sample_data_pool_size, idlesampledatapoolsize, NUM2INT); +RB2FMOD_NAME(streaming_schedule_delay, streamingscheduledelay, NUM2UINT); +RB2FMOD_NAME(encryption_key, encryptionkey, RSTRING_PTR); +RB2FMOD_END; + +VALUE rb_cSoundInfo = Qnil; +DECLARE_FMOD2RB(FMOD_STUDIO_SOUND_INFO, rb_cSoundInfo); +FMOD2RB(name_or_data, rb_str_new_cstr); +FMOD2RB(mode, UINT2NUM); +FMOD2RB_STRUCT_NAME(ex_info, exinfo, FMOD_CREATESOUNDEXINFO); +FMOD2RB_NAME(subsound_index, subsoundindex, INT2NUM); +FMOD2RB_END; + +VALUE rb_cStudioCPUUsage = Qnil; +DECLARE_FMOD2RB(FMOD_STUDIO_CPU_USAGE, rb_cStudioCPUUsage); +FMOD2RB(update, DBL2NUM); +FMOD2RB_END; + +VALUE rb_cBufferUsage = Qnil; +DECLARE_FMOD2RB(FMOD_STUDIO_BUFFER_USAGE, rb_cBufferUsage); +FMOD2RB_STRUCT_NAME(studio_command_queue, studiocommandqueue, FMOD_STUDIO_BUFFER_INFO); +FMOD2RB_STRUCT_NAME(studio_handle, studiohandle, FMOD_STUDIO_BUFFER_INFO); +FMOD2RB_END; + +VALUE rb_cBufferInfo = Qnil; +DECLARE_FMOD2RB(FMOD_STUDIO_BUFFER_INFO, rb_cBufferInfo); +FMOD2RB_NAME(current_usage, currentusage, INT2NUM); +FMOD2RB_NAME(peak_usage, peakusage, INT2NUM); +FMOD2RB(capacity, INT2NUM); +FMOD2RB_NAME(stall_count, stallcount, INT2NUM); +FMOD2RB_NAME(stall_time, stalltime, DBL2NUM); +FMOD2RB_END; + +void bindFmodStudioStructs() +{ + rb_cMemoryUsage = rb_define_class_under(rb_mFMOD_Studio, "MemoryUsage", rb_cObject); + ATTR(rb_cMemoryUsage, exclusive); + ATTR(rb_cMemoryUsage, inclusive); + ATTR(rb_cMemoryUsage, sampledata); + + rb_cParameterDescription = rb_define_class_under( + rb_mFMOD_Studio, "ParameterDescription", rb_cObject); + ATTR(rb_cParameterDescription, name); + ATTR(rb_cParameterDescription, id); + ATTR(rb_cParameterDescription, minimum); + ATTR(rb_cParameterDescription, maximum); + ATTR(rb_cParameterDescription, default_value); + ATTR(rb_cParameterDescription, type); + ATTR(rb_cParameterDescription, flags); + ATTR(rb_cParameterDescription, guid); + + rb_cParameterID = rb_define_class_under(rb_mFMOD_Studio, "ParameterID", rb_cObject); + ATTR(rb_cParameterID, data1); + ATTR(rb_cParameterID, data2); + + rb_cUserProperty = rb_define_class_under(rb_mFMOD_Studio, "UserProperty", rb_cObject); + ATTR(rb_cUserProperty, name); + ATTR(rb_cUserProperty, type); + ATTR(rb_cUserProperty, value); + + rb_cCommandInfo = rb_define_class_under(rb_mFMOD_Studio, "CommandInfo", rb_cObject); + ATTR(rb_cCommandInfo, command_name); + ATTR(rb_cCommandInfo, parent_command_index); + ATTR(rb_cCommandInfo, frame_number); + ATTR(rb_cCommandInfo, frame_time); + ATTR(rb_cCommandInfo, instance_type); + ATTR(rb_cCommandInfo, output_type); + ATTR(rb_cCommandInfo, instance_handle); + ATTR(rb_cCommandInfo, output_handle); + + rb_cAdvancedSettings = rb_define_class_under(rb_mFMOD_Studio, "AdvancedSettings", rb_cObject); + ATTR(rb_cAdvancedSettings, cb_size); + ATTR(rb_cAdvancedSettings, command_queue_size); + ATTR(rb_cAdvancedSettings, handle_initial_size); + ATTR(rb_cAdvancedSettings, studio_update_period); + ATTR(rb_cAdvancedSettings, idle_sample_data_pool_size); + ATTR(rb_cAdvancedSettings, streaming_schedule_delay); + ATTR(rb_cAdvancedSettings, encryption_key); + + rb_cSoundInfo = rb_define_class_under(rb_mFMOD_Studio, "SoundInfo", rb_cObject); + ATTR(rb_cSoundInfo, name_or_data); + ATTR(rb_cSoundInfo, mode); + ATTR(rb_cSoundInfo, ex_info); + ATTR(rb_cSoundInfo, subsound_index); + + rb_cStudioCPUUsage = rb_define_class_under(rb_mFMOD_Studio, "CPUUsage", rb_cObject); + ATTR(rb_cStudioCPUUsage, update); + + rb_cBufferUsage = rb_define_class_under(rb_mFMOD_Studio, "BufferUsage", rb_cObject); + ATTR(rb_cBufferUsage, studio_command_queue); + ATTR(rb_cBufferUsage, studio_handle); + + rb_cBufferInfo = rb_define_class_under(rb_mFMOD_Studio, "BufferInfo", rb_cObject); + ATTR(rb_cBufferInfo, current_usage); + ATTR(rb_cBufferInfo, peak_usage); + ATTR(rb_cBufferInfo, capacity); + ATTR(rb_cBufferInfo, stall_count); + ATTR(rb_cBufferInfo, stall_time); +} diff --git a/binding-mri/fmod-binding/studio/eventdescription.cpp b/binding-mri/fmod-binding/studio/eventdescription.cpp new file mode 100644 index 00000000..7d6cb775 --- /dev/null +++ b/binding-mri/fmod-binding/studio/eventdescription.cpp @@ -0,0 +1,452 @@ +#include "fmod_bindings.h" +#include "binding-util.h" +#include "debugwriter.h" + +DEF_TYPE(EventDescription); +EventDescription::~EventDescription() +{ +} + +VALUE rb_cEventDescription = Qnil; + +FMOD_VALID_FUNC(FMOD_Studio_EventDescription, EventDescription); + +FMOD_ID_FUNC(FMOD_Studio_EventDescription, EventDescription); + +FMOD_PATH_FUNC(FMOD_Studio_EventDescription, EventDescription); + +RB_METHOD(descriptionGetParameterCount) +{ + RB_UNUSED_PARAM; + + EventDescription *b = getPrivateData(self); + int count; + + FMOD_RESULT result = FMOD_Studio_EventDescription_GetParameterDescriptionCount( + b->p, &count); + + FMOD_RESULT_CONVERT(count, INT2NUM); +} + +RB_METHOD(descriptionGetParameterIndex) +{ + int index; + rb_get_args(argc, argv, "i", &index RB_ARG_END); + + EventDescription *b = getPrivateData(self); + FMOD_STUDIO_PARAMETER_DESCRIPTION description = FMOD_STUDIO_PARAMETER_DESCRIPTION(); + + FMOD_RESULT result = FMOD_Studio_EventDescription_GetParameterDescriptionByIndex( + b->p, index, &description); + + FMOD_RESULT_NO_WRAP(description, FMOD_STUDIO_PARAMETER_DESCRIPTION); +} + +RB_METHOD(descriptionGetParameterName) +{ + char *name; + rb_get_args(argc, argv, "z", &name RB_ARG_END); + + EventDescription *b = getPrivateData(self); + FMOD_STUDIO_PARAMETER_DESCRIPTION description = FMOD_STUDIO_PARAMETER_DESCRIPTION(); + + FMOD_RESULT result = FMOD_Studio_EventDescription_GetParameterDescriptionByName( + b->p, name, &description); + + FMOD_RESULT_NO_WRAP(description, FMOD_STUDIO_PARAMETER_DESCRIPTION); +} + +RB_METHOD(descriptionGetParameterID) +{ + VALUE rb_id; + rb_get_args(argc, argv, "o", &rb_id RB_ARG_END); + + FMOD_STUDIO_PARAMETER_ID id = rb2FMOD_STUDIO_PARAMETER_ID(rb_id); + EventDescription *b = getPrivateData(self); + FMOD_STUDIO_PARAMETER_DESCRIPTION description = FMOD_STUDIO_PARAMETER_DESCRIPTION(); + + FMOD_RESULT result = FMOD_Studio_EventDescription_GetParameterDescriptionByID( + b->p, id, &description); + + FMOD_RESULT_NO_WRAP(description, FMOD_STUDIO_PARAMETER_DESCRIPTION); +} + +RB_METHOD(descriptionGetParameterLabelIndex) +{ + int index; + int labelindex; + rb_get_args(argc, argv, "ii", &index, &labelindex RB_ARG_END); + + EventDescription *b = getPrivateData(self); + char *label = NULL; + int retrieved; + + FMOD_RESULT result = FMOD_Studio_EventDescription_GetParameterLabelByIndex( + b->p, index, labelindex, NULL, 0, &retrieved); + if (result == FMOD_OK) + { + label = new char[retrieved]; + + result = FMOD_Studio_EventDescription_GetParameterLabelByIndex( + b->p, index, labelindex, label, retrieved, &retrieved); + } + + FMOD_RESULT_CONVERT(label, rb_str_new_cstr); +} + +RB_METHOD(descriptionGetParameterLabelName) +{ + char *name; + int labelindex; + rb_get_args(argc, argv, "zi", &name, &labelindex RB_ARG_END); + + EventDescription *b = getPrivateData(self); + char *label = NULL; + int retrieved; + + FMOD_RESULT result = FMOD_Studio_EventDescription_GetParameterLabelByName( + b->p, name, labelindex, NULL, 0, &retrieved); + if (result == FMOD_OK) + { + label = new char[retrieved]; + + result = FMOD_Studio_EventDescription_GetParameterLabelByName( + b->p, name, labelindex, label, retrieved, &retrieved); + } + + FMOD_RESULT_CONVERT(label, rb_str_new_cstr); +} + +RB_METHOD(descriptionGetParameterLabelID) +{ + VALUE rb_id; + int labelindex; + rb_get_args(argc, argv, "oi", &rb_id, &labelindex RB_ARG_END); + + FMOD_STUDIO_PARAMETER_ID id = rb2FMOD_STUDIO_PARAMETER_ID(rb_id); + EventDescription *b = getPrivateData(self); + char *label = NULL; + int retrieved; + + FMOD_RESULT result = FMOD_Studio_EventDescription_GetParameterLabelByID( + b->p, id, labelindex, NULL, 0, &retrieved); + if (result == FMOD_OK) + { + label = new char[retrieved]; + + result = FMOD_Studio_EventDescription_GetParameterLabelByID( + b->p, id, labelindex, label, retrieved, &retrieved); + } + + FMOD_RESULT_CONVERT(label, rb_str_new_cstr); +} + +RB_METHOD(descriptionGetUserCount) +{ + RB_UNUSED_PARAM; + + EventDescription *b = getPrivateData(self); + int count; + + FMOD_RESULT result = FMOD_Studio_EventDescription_GetUserPropertyCount( + b->p, &count); + + FMOD_RESULT_CONVERT(count, INT2NUM); +} + +RB_METHOD(descriptionGetUserIndex) +{ + int index; + rb_get_args(argc, argv, "i", &index RB_ARG_END); + + EventDescription *b = getPrivateData(self); + FMOD_STUDIO_USER_PROPERTY property = FMOD_STUDIO_USER_PROPERTY(); + + FMOD_RESULT result = FMOD_Studio_EventDescription_GetUserPropertyByIndex( + b->p, index, &property); + + FMOD_RESULT_NO_WRAP(property, FMOD_STUDIO_USER_PROPERTY); +} + +RB_METHOD(descriptionGetUser) +{ + char *name; + rb_get_args(argc, argv, "z", &name RB_ARG_END); + + EventDescription *b = getPrivateData(self); + FMOD_STUDIO_USER_PROPERTY property = FMOD_STUDIO_USER_PROPERTY(); + + FMOD_RESULT result = FMOD_Studio_EventDescription_GetUserProperty( + b->p, name, &property); + + FMOD_RESULT_NO_WRAP(property, FMOD_STUDIO_USER_PROPERTY); +} + +RB_METHOD(descriptionGetLength) +{ + RB_UNUSED_PARAM; + + EventDescription *b = getPrivateData(self); + int length; + + FMOD_RESULT result = FMOD_Studio_EventDescription_GetLength( + b->p, &length); + + FMOD_RESULT_CONVERT(length, INT2NUM); +} + +RB_METHOD(descriptionGetMinMax) +{ + RB_UNUSED_PARAM; + + EventDescription *b = getPrivateData(self); + float min; + float max; + + FMOD_RESULT result = FMOD_Studio_EventDescription_GetMinMaxDistance( + b->p, &min, &max); + + FMOD_RESULT_BASE; + if (result == FMOD_OK) + { + rb_ary_push(return_ary, DBL2NUM(min)); + rb_ary_push(return_ary, DBL2NUM(max)); + } + FMOD_RESULT_RET; +} + +RB_METHOD(descriptionIsSnapshot) +{ + RB_UNUSED_PARAM; + + EventDescription *b = getPrivateData(self); + FMOD_BOOL isSnapshot; + + FMOD_RESULT result = FMOD_Studio_EventDescription_IsSnapshot( + b->p, &isSnapshot); + + FMOD_RESULT_CONVERT(isSnapshot, BOOL2RB); +} + +RB_METHOD(descriptionIsOneshot) +{ + RB_UNUSED_PARAM; + + EventDescription *b = getPrivateData(self); + FMOD_BOOL isOneshot; + + FMOD_RESULT result = FMOD_Studio_EventDescription_IsOneshot( + b->p, &isOneshot); + + FMOD_RESULT_CONVERT(isOneshot, BOOL2RB); +} + +RB_METHOD(descriptionIsStream) +{ + RB_UNUSED_PARAM; + + EventDescription *b = getPrivateData(self); + FMOD_BOOL isStream; + + FMOD_RESULT result = FMOD_Studio_EventDescription_IsStream( + b->p, &isStream); + + FMOD_RESULT_CONVERT(isStream, BOOL2RB); +} + +RB_METHOD(descriptionIs3D) +{ + RB_UNUSED_PARAM; + + EventDescription *b = getPrivateData(self); + FMOD_BOOL is3D; + + FMOD_RESULT result = FMOD_Studio_EventDescription_Is3D( + b->p, &is3D); + + FMOD_RESULT_CONVERT(is3D, BOOL2RB); +} + +RB_METHOD(descriptionDopplerEnabled) +{ + RB_UNUSED_PARAM; + + EventDescription *b = getPrivateData(self); + FMOD_BOOL isDopplerEnabled; + + FMOD_RESULT result = FMOD_Studio_EventDescription_IsDopplerEnabled( + b->p, &isDopplerEnabled); + + FMOD_RESULT_CONVERT(isDopplerEnabled, BOOL2RB); +} + +RB_METHOD(descriptionHasSustainPoint) +{ + RB_UNUSED_PARAM; + + EventDescription *b = getPrivateData(self); + FMOD_BOOL hasSustainPoint; + + FMOD_RESULT result = FMOD_Studio_EventDescription_HasSustainPoint( + b->p, &hasSustainPoint); + + FMOD_RESULT_CONVERT(hasSustainPoint, BOOL2RB); +} + +RB_METHOD(descriptionCreateInstance) +{ + RB_UNUSED_PARAM; + + EventDescription *b = getPrivateData(self); + FMOD_STUDIO_EVENTINSTANCE *instance = NULL; + + FMOD_RESULT result = FMOD_Studio_EventDescription_CreateInstance( + b->p, &instance); + + FMOD_RESULT_WRAP(instance, EventInstance); +} + +RB_METHOD(descriptionGetInstanceCount) +{ + RB_UNUSED_PARAM; + + EventDescription *b = getPrivateData(self); + int count; + + FMOD_RESULT result = FMOD_Studio_EventDescription_GetInstanceCount( + b->p, &count); + + FMOD_RESULT_CONVERT(count, INT2NUM); +} + +RB_METHOD(descriptionGetInstanceList) +{ + RB_UNUSED_PARAM; + + EventDescription *b = getPrivateData(self); + FMOD_STUDIO_EVENTINSTANCE **array = NULL; + int count; + + FMOD_RESULT result = FMOD_Studio_EventDescription_GetInstanceCount( + b->p, &count); + + + if (result == FMOD_OK) { + array = new FMOD_STUDIO_EVENTINSTANCE*[count]; + result = FMOD_Studio_EventDescription_GetInstanceList( + b->p, array, count, NULL); + } + + FMOD_RESULT_BASE; + if (array && result == FMOD_OK) + { + VALUE instance_ary = rb_ary_new(); + + for (int i = 0; i < count; i++) + { + VALUE ele = rb_obj_alloc(rb_cEventInstance); + setPrivateData(ele, new EventInstance(array[i])); + rb_ary_push(instance_ary, ele); + } + + rb_ary_push(return_ary, instance_ary); + delete array; + } + FMOD_RESULT_RET; +} + +RB_METHOD(descriptionLoadSampleData) +{ + RB_UNUSED_PARAM; + + EventDescription *b = getPrivateData(self); + FMOD_RESULT result = FMOD_Studio_EventDescription_LoadSampleData( + b->p); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(descriptionUnloadSampleData) +{ + RB_UNUSED_PARAM; + + EventDescription *b = getPrivateData(self); + FMOD_RESULT result = FMOD_Studio_EventDescription_UnloadSampleData( + b->p); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(descriptionGetSampleLoadingState) +{ + RB_UNUSED_PARAM; + + EventDescription *b = getPrivateData(self); + FMOD_STUDIO_LOADING_STATE state; + + FMOD_RESULT result = FMOD_Studio_EventDescription_GetSampleLoadingState( + b->p, &state); + + FMOD_RESULT_CONVERT(state, INT2NUM); +} + +RB_METHOD(descriptionReleaseAllInstances) +{ + RB_UNUSED_PARAM; + + EventDescription *b = getPrivateData(self); + FMOD_RESULT result = FMOD_Studio_EventDescription_ReleaseAllInstances( + b->p); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(descriptionSetCallback) +{ + // TODO +} + +FMOD_USERDATA_FUNC(FMOD_Studio_EventDescription, EventDescription); + +FMOD_EQUAL_FUNC(EventDescription); + +void bindFmodStudioEventDescription() +{ + rb_cEventDescription = rb_define_class_under( + rb_mFMOD_Studio, "EventDescription", rb_cObject); + rb_define_alloc_func(rb_cEventDescription, classAllocate<&EventDescriptionType>); + _rb_define_method(rb_cEventDescription, "initialize", fmodErrorInit); + _rb_define_method(rb_cEventDescription, "==", fmodEqual); + + _rb_define_method(rb_cEventDescription, "is_valid", fmodIsValid); + _rb_define_method(rb_cEventDescription, "get_id", fmodGetID); + _rb_define_method(rb_cEventDescription, "get_path", fmodGetPath); + _rb_define_method(rb_cEventDescription, "get_parameter_description_count", descriptionGetParameterCount); + _rb_define_method(rb_cEventDescription, "get_parameter_description_by_index", descriptionGetParameterIndex); + _rb_define_method(rb_cEventDescription, "get_parameter_description_by_name", descriptionGetParameterName); + _rb_define_method(rb_cEventDescription, "get_parameter_description_by_id", descriptionGetParameterID); + _rb_define_method(rb_cEventDescription, "get_parameter_label_by_index", descriptionGetParameterLabelIndex); + _rb_define_method(rb_cEventDescription, "get_parameter_label_by_name", descriptionGetParameterLabelName); + _rb_define_method(rb_cEventDescription, "get_parameter_label_by_id", descriptionGetParameterLabelID); + _rb_define_method(rb_cEventDescription, "get_user_property_count", descriptionGetUserCount); + _rb_define_method(rb_cEventDescription, "get_user_property_by_index", descriptionGetUserIndex); + _rb_define_method(rb_cEventDescription, "get_user_property", descriptionGetUser); + _rb_define_method(rb_cEventDescription, "get_length", descriptionGetLength); + _rb_define_method(rb_cEventDescription, "get_min_max", descriptionGetMinMax); + _rb_define_method(rb_cEventDescription, "is_snapshot", descriptionIsSnapshot); + _rb_define_method(rb_cEventDescription, "is_oneshot", descriptionIsOneshot); + _rb_define_method(rb_cEventDescription, "is_stream", descriptionIsStream); + _rb_define_method(rb_cEventDescription, "is_3d", descriptionIs3D); + _rb_define_method(rb_cEventDescription, "is_doppler_enabled", descriptionDopplerEnabled); + _rb_define_method(rb_cEventDescription, "has_sustain_point", descriptionHasSustainPoint); + _rb_define_method(rb_cEventDescription, "create_instance", descriptionCreateInstance); + _rb_define_method(rb_cEventDescription, "get_instance_count", descriptionGetInstanceCount); + _rb_define_method(rb_cEventDescription, "get_instance_list", descriptionGetInstanceList); + _rb_define_method(rb_cEventDescription, "load_sample_data", descriptionLoadSampleData); + _rb_define_method(rb_cEventDescription, "unload_sample_data", descriptionUnloadSampleData); + _rb_define_method(rb_cEventDescription, "get_sample_loading_state", descriptionGetSampleLoadingState); + _rb_define_method(rb_cEventDescription, "release_all_instances", descriptionReleaseAllInstances); + _rb_define_method(rb_cEventDescription, "set_callback", descriptionSetCallback); + _rb_define_method(rb_cEventDescription, "get_user_data", fmodGetUserData); + _rb_define_method(rb_cEventDescription, "set_user_data", fmodSetUserData); +} diff --git a/binding-mri/fmod-binding/studio/eventinstance.cpp b/binding-mri/fmod-binding/studio/eventinstance.cpp new file mode 100644 index 00000000..d41c84eb --- /dev/null +++ b/binding-mri/fmod-binding/studio/eventinstance.cpp @@ -0,0 +1,466 @@ +#include "fmod_bindings.h" +#include "binding-util.h" +#ifdef AUTO_CLEAN_FMOD +#include "debugwriter.h" +#include +#endif + +DEF_TYPE(EventInstance); +EventInstance::~EventInstance() +{ +#ifdef AUTO_CLEAN_FMOD + Debug() << "Warning: auto releasing event instance (garbage collected?)"; + Debug() << "Event instance release result: " << FMOD_ErrorString(FMOD_Studio_EventInstance_Release(p)); +#endif +} + +FMOD_VALID_FUNC(FMOD_Studio_EventInstance, EventInstance); + +RB_METHOD(eventInstanceGetDescription) +{ + RB_UNUSED_PARAM; + + EventInstance *b = getPrivateData(self); + FMOD_STUDIO_EVENTDESCRIPTION *description = NULL; + + FMOD_RESULT result = FMOD_Studio_EventInstance_GetDescription( + b->p, &description); + + FMOD_RESULT_WRAP(description, EventDescription); +} + +FMOD_VOLUME_FUNC(FMOD_Studio_EventInstance, EventInstance); + +RB_METHOD(eventInstanceGetPitch) +{ + RB_UNUSED_PARAM; + + EventInstance *b = getPrivateData(self); + float pitch; + float finalpitch; + + FMOD_RESULT result = FMOD_Studio_EventInstance_GetPitch(b->p, &pitch, &finalpitch); + + FMOD_RESULT_BASE; + if (result == FMOD_OK) + { + rb_ary_push(return_ary, DBL2NUM(pitch)); + rb_ary_push(return_ary, DBL2NUM(finalpitch)); + } + FMOD_RESULT_RET; +} + +RB_METHOD(eventInstanceSetPitch) +{ + float pitch; + rb_get_args(argc, argv, "f", &pitch RB_ARG_END); + + EventInstance *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_EventInstance_SetPitch(b->p, pitch); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(eventInstanceGet3DAttributes) +{ + RB_UNUSED_PARAM; + + EventInstance *b = getPrivateData(self); + FMOD_3D_ATTRIBUTES attributes = FMOD_3D_ATTRIBUTES(); + + FMOD_RESULT result = FMOD_Studio_EventInstance_Get3DAttributes(b->p, &attributes); + + FMOD_RESULT_NO_WRAP(attributes, FMOD_3D_ATTRIBUTES); +} + +RB_METHOD(eventInstanceSet3DAttributes) +{ + VALUE rb_attributes; + rb_get_args(argc, argv, "o", &rb_attributes RB_ARG_END); + + FMOD_3D_ATTRIBUTES attributes = rb2FMOD_3D_ATTRIBUTES(rb_attributes); + EventInstance *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_EventInstance_Set3DAttributes(b->p, &attributes); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(eventInstanceGetListenerMask) +{ + RB_UNUSED_PARAM; + + EventInstance *b = getPrivateData(self); + unsigned int mask; + + FMOD_RESULT result = FMOD_Studio_EventInstance_GetListenerMask(b->p, &mask); + + FMOD_RESULT_CONVERT(mask, UINT2NUM); +} + +RB_METHOD(eventInstanceSetListenerMask) +{ + VALUE mask; + rb_get_args(argc, argv, "o", &mask RB_ARG_END); + + EventInstance *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_EventInstance_SetListenerMask(b->p, NUM2UINT(mask)); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(eventInstanceGetProperty) +{ + int index; + rb_get_args(argc, argv, "i", &index RB_ARG_END); + + EventInstance *b = getPrivateData(self); + float value; + + FMOD_RESULT result = FMOD_Studio_EventInstance_GetProperty( + b->p, (FMOD_STUDIO_EVENT_PROPERTY)index, &value); + + FMOD_RESULT_CONVERT(value, DBL2NUM); +} + +RB_METHOD(eventInstanceSetProperty) +{ + int index; + float value; + rb_get_args(argc, argv, "if", &index, &value RB_ARG_END); + + EventInstance *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_EventInstance_SetProperty( + b->p, (FMOD_STUDIO_EVENT_PROPERTY)index, value); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(eventInstanceGetReverbLevel) +{ + int index; + rb_get_args(argc, argv, "i", &index RB_ARG_END); + + EventInstance *b = getPrivateData(self); + float level; + + FMOD_RESULT result = FMOD_Studio_EventInstance_GetReverbLevel( + b->p, index, &level); + + FMOD_RESULT_CONVERT(level, DBL2NUM); +} + +RB_METHOD(eventInstanceSetReverbLevel) +{ + int index; + float level; + rb_get_args(argc, argv, "if", &index, &level RB_ARG_END); + + EventInstance *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_EventInstance_SetReverbLevel( + b->p, index, level); + + FMOD_RESULT_SIMPLE; +} + +FMOD_PAUSED_FUNC(FMOD_Studio_EventInstance, EventInstance); + +RB_METHOD(eventInstanceStart) +{ + RB_UNUSED_PARAM; + + EventInstance *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_EventInstance_Start(b->p); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(eventInstanceStop) +{ + int mode; + rb_get_args(argc, argv, "i", &mode RB_ARG_END); + + EventInstance *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_EventInstance_Stop(b->p, (FMOD_STUDIO_STOP_MODE)mode); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(eventInstanceGetTimelinePosition) +{ + RB_UNUSED_PARAM; + + EventInstance *b = getPrivateData(self); + int position; + + FMOD_RESULT result = FMOD_Studio_EventInstance_GetTimelinePosition(b->p, &position); + + FMOD_RESULT_CONVERT(position, INT2NUM); +} + +RB_METHOD(eventInstanceSetTimelinePosition) +{ + int position; + rb_get_args(argc, argv, "i", &position RB_ARG_END); + + EventInstance *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_EventInstance_SetTimelinePosition(b->p, position); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(eventInstanceGetChannelGroup) +{ + // TODO +} + +RB_METHOD(eventInstanceGetMinMaxDistance) +{ + RB_UNUSED_PARAM; + + EventInstance *b = getPrivateData(self); + float min; + float max; + + FMOD_RESULT result = FMOD_Studio_EventInstance_GetMinMaxDistance( + b->p, &min, &max); + + FMOD_RESULT_BASE; + if (result == FMOD_OK) + { + rb_ary_push(return_ary, DBL2NUM(min)); + rb_ary_push(return_ary, DBL2NUM(max)); + } + FMOD_RESULT_RET; +} + +RB_METHOD(eventInstanceRelease) +{ + RB_UNUSED_PARAM; + + EventInstance *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_EventInstance_Release(b->p); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(eventInstanceIsVirtual) +{ + RB_UNUSED_PARAM; + + EventInstance *b = getPrivateData(self); + FMOD_BOOL isVirtual; + + FMOD_RESULT result = FMOD_Studio_EventInstance_IsVirtual(b->p, &isVirtual); + + FMOD_RESULT_CONVERT(isVirtual, BOOL2RB); +} + +#define RETURN_PARAMETER \ + FMOD_RESULT_BASE; \ + if (result == FMOD_OK) \ + { \ + rb_ary_push(return_ary, DBL2NUM(value)); \ + rb_ary_push(return_ary, DBL2NUM(finalvalue)); \ + } \ + FMOD_RESULT_RET; + +RB_METHOD(eventInstanceGetParameterByName) +{ + char *name; + rb_get_args(argc, argv, "z", &name RB_ARG_END); + + EventInstance *b = getPrivateData(self); + float value, finalvalue; + + FMOD_RESULT result = FMOD_Studio_EventInstance_GetParameterByName( + b->p, name, &value, &finalvalue); + + RETURN_PARAMETER; +} + +RB_METHOD(eventInstanceSetParameterByName) { + char* name; + float value; + bool ignoreseekspeed; + rb_get_args(argc, argv, "zfb", &name, &value, &ignoreseekspeed RB_ARG_END); + + EventInstance *b = getPrivateData(self); + FMOD_RESULT result = FMOD_Studio_EventInstance_SetParameterByName( + b->p, name, value, (FMOD_BOOL) ignoreseekspeed); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(eventInstanceSetParameterByNameLabel) { + char* name; + char* label; + bool ignoreseekspeed; + rb_get_args(argc, argv, "zfb", &name, &label, &ignoreseekspeed RB_ARG_END); + + EventInstance *b = getPrivateData(self); + FMOD_RESULT result = FMOD_Studio_EventInstance_SetParameterByNameWithLabel( + b->p, name, label, (FMOD_BOOL) ignoreseekspeed); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(eventInstanceGetParameterByID) { + VALUE rb_id; + rb_get_args(argc, argv, "o", &rb_id RB_ARG_END); + + FMOD_STUDIO_PARAMETER_ID id = rb2FMOD_STUDIO_PARAMETER_ID(rb_id); + EventInstance *b = getPrivateData(self); + float value, finalvalue; + + FMOD_RESULT result = FMOD_Studio_EventInstance_GetParameterByID( + b->p, id, &value, &finalvalue); + + RETURN_PARAMETER; +} + +RB_METHOD(eventInstanceSetParameterByID) { + VALUE rb_id; + float value; + bool ignoreseekspeed; + rb_get_args(argc, argv, "ofb", &rb_id, &value, &ignoreseekspeed RB_ARG_END); + + FMOD_STUDIO_PARAMETER_ID id = rb2FMOD_STUDIO_PARAMETER_ID(rb_id); + EventInstance *b = getPrivateData(self); + FMOD_RESULT result = FMOD_Studio_EventInstance_SetParameterByID( + b->p, id, value, (FMOD_BOOL) ignoreseekspeed); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(eventInstanceSetParameterByIDLabel) { + VALUE rb_id; + char* label; + bool ignoreseekspeed; + rb_get_args(argc, argv, "ozfb", &rb_id, &label, &ignoreseekspeed RB_ARG_END); + + FMOD_STUDIO_PARAMETER_ID id = rb2FMOD_STUDIO_PARAMETER_ID(rb_id); + EventInstance *b = getPrivateData(self); + FMOD_RESULT result = FMOD_Studio_EventInstance_SetParameterByIDWithLabel( + b->p, id, label, (FMOD_BOOL) ignoreseekspeed); + + FMOD_RESULT_SIMPLE; +} + +//! Here be dragons +RB_METHOD(eventInstanceSetParametersByIDs) { + //! Get ruby arrays + VALUE rb_ids; + VALUE rb_values; + bool ignoreseekspeed; + rb_get_args(argc, argv, "oob", &rb_ids, &rb_values, &ignoreseekspeed RB_ARG_END); + + //! Check lengths are equal + if (rb_array_len(rb_values) != rb_array_len(rb_ids)) + { + rb_raise(rb_eArgError, "Array lengths must match"); + } + //! Get length of arrays + int count = rb_array_len(rb_values); + + //! Create C side arrays + float* values = new float[count]; + FMOD_STUDIO_PARAMETER_ID* ids = new FMOD_STUDIO_PARAMETER_ID[count]; + //! Convert ruby arrays to C side arrays + for (int i = 0; i < count; i++) + { + ids[i] = rb2FMOD_STUDIO_PARAMETER_ID(rb_ary_entry(rb_ids, i)); + values[i] = NUM2DBL(rb_ary_entry(rb_values, i)); + } + + //! Call the function + EventInstance *b = getPrivateData(self); + FMOD_RESULT result = FMOD_Studio_EventInstance_SetParametersByIDs( + b->p, ids, values, count, (FMOD_BOOL) ignoreseekspeed); + + //! Clean up + delete[] ids; + delete[] values; + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(eventInstanceKeyOff) { + RB_UNUSED_PARAM; + + EventInstance *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_EventInstance_KeyOff(b->p); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(eventInstanceSetCallback) { + // TODO +} + +FMOD_USERDATA_FUNC(FMOD_Studio_EventInstance, EventInstance); + +FMOD_CPU_USAGE_FUNC(FMOD_Studio_EventInstance, EventInstance); + +FMOD_MEMORY_USAGE_FUNC(FMOD_Studio_EventInstance, EventInstance); + +FMOD_EQUAL_FUNC(EventInstance); + +VALUE rb_cEventInstance = Qnil; + +void bindFmodStudioEventInstance() +{ + rb_cEventInstance = rb_define_class_under( + rb_mFMOD_Studio, "EventInstance", rb_cObject); + rb_define_alloc_func(rb_cEventInstance, classAllocate<&EventInstanceType>); + _rb_define_method(rb_cEventInstance, "initialize", fmodErrorInit); + _rb_define_method(rb_cEventInstance, "==", fmodEqual); + + _rb_define_method(rb_cEventInstance, "is_valid", fmodIsValid); + _rb_define_method(rb_cEventInstance, "get_description", eventInstanceGetDescription); + _rb_define_method(rb_cEventInstance, "get_volume", fmodGetVolume); + _rb_define_method(rb_cEventInstance, "set_volume", fmodSetVolume); + _rb_define_method(rb_cEventInstance, "get_pitch", eventInstanceGetPitch); + _rb_define_method(rb_cEventInstance, "set_pitch", eventInstanceSetPitch); + _rb_define_method(rb_cEventInstance, "get_3d_attributes", eventInstanceGet3DAttributes); + _rb_define_method(rb_cEventInstance, "set_3d_attributes", eventInstanceSet3DAttributes); + _rb_define_method(rb_cEventInstance, "get_listener_mask", eventInstanceGetListenerMask); + _rb_define_method(rb_cEventInstance, "set_listener_mask", eventInstanceSetListenerMask); + _rb_define_method(rb_cEventInstance, "get_property", eventInstanceGetProperty); + _rb_define_method(rb_cEventInstance, "set_property", eventInstanceSetProperty); + _rb_define_method(rb_cEventInstance, "get_reverb_level", eventInstanceGetReverbLevel); + _rb_define_method(rb_cEventInstance, "set_reverb_level", eventInstanceSetReverbLevel); + _rb_define_method(rb_cEventInstance, "get_paused", fmodGetPaused); + _rb_define_method(rb_cEventInstance, "set_paused", fmodSetPaused); + _rb_define_method(rb_cEventInstance, "start", eventInstanceStart); + _rb_define_method(rb_cEventInstance, "stop", eventInstanceStop); + _rb_define_method(rb_cEventInstance, "get_timeline_position", eventInstanceGetTimelinePosition); + _rb_define_method(rb_cEventInstance, "set_timeline_position", eventInstanceSetTimelinePosition); + _rb_define_method(rb_cEventInstance, "get_channel_group", eventInstanceGetChannelGroup); + _rb_define_method(rb_cEventInstance, "get_min_max_distance", eventInstanceGetMinMaxDistance); + _rb_define_method(rb_cEventInstance, "release", eventInstanceRelease); + _rb_define_method(rb_cEventInstance, "is_virtual", eventInstanceIsVirtual); + _rb_define_method(rb_cEventInstance, "get_parameter_by_name", eventInstanceGetParameterByName); + _rb_define_method(rb_cEventInstance, "set_parameter_by_name", eventInstanceSetParameterByName); + _rb_define_method( + rb_cEventInstance, "set_parameter_by_name_with_label", eventInstanceSetParameterByNameLabel); + _rb_define_method(rb_cEventInstance, "get_parameter_by_id", eventInstanceGetParameterByID); + _rb_define_method(rb_cEventInstance, "set_parameter_by_id", eventInstanceSetParameterByID); + _rb_define_method( + rb_cEventInstance, "set_parameter_by_id_with_label", eventInstanceSetParameterByIDLabel); + _rb_define_method(rb_cEventInstance, "set_parameters_by_ids", eventInstanceSetParametersByIDs); + _rb_define_method(rb_cEventInstance, "key_off", eventInstanceKeyOff); + _rb_define_method(rb_cEventInstance, "set_callback", eventInstanceSetCallback); + _rb_define_method(rb_cEventInstance, "get_user_data", fmodGetUserData); + _rb_define_method(rb_cEventInstance, "set_user_data", fmodSetUserData); + _rb_define_method(rb_cEventInstance, "get_cpu_usage", fmodGetCPUUsage); + _rb_define_method(rb_cEventInstance, "get_memory_usage", fmodGetMemoryUsage); +} diff --git a/binding-mri/fmod-binding/studio/fmod-studio-binding.cpp b/binding-mri/fmod-binding/studio/fmod-studio-binding.cpp new file mode 100644 index 00000000..a5b06586 --- /dev/null +++ b/binding-mri/fmod-binding/studio/fmod-studio-binding.cpp @@ -0,0 +1,21 @@ +#include "binding-util.h" +#include "sharedstate.h" +#include "fmod_bindings.h" + +#include +#include + +VALUE rb_mFMOD_Studio = Qnil; + +void fmodStudioBindingInit() +{ + rb_mFMOD_Studio = rb_define_module_under(rb_mFMOD, "Studio"); + + bindFmodStudioSystem(); + bindFmodStudioStructs(); + bindFmodStudioBank(); + bindFmodStudioVCA(); + bindFmodStudioBus(); + bindFmodStudioEventDescription(); + bindFmodStudioEventInstance(); +} diff --git a/binding-mri/fmod-binding/studio/system.cpp b/binding-mri/fmod-binding/studio/system.cpp new file mode 100644 index 00000000..db0d1e23 --- /dev/null +++ b/binding-mri/fmod-binding/studio/system.cpp @@ -0,0 +1,814 @@ +#include "binding-util.h" +#include "fmod_bindings.h" +#ifdef AUTO_CLEAN_FMOD +#include "debugwriter.h" +#include +#endif + +DEF_TYPE(StudioSystem); +StudioSystem::~StudioSystem() +{ + #ifdef AUTO_CLEAN_FMOD + Debug() << "Warning: auto releasing studio system (garbage collected?)"; + Debug() << "Studio system release result: " << FMOD_ErrorString(FMOD_Studio_System_Release(p)); + #endif +} + +FMOD_VALID_FUNC(FMOD_Studio_System, StudioSystem); + +RB_METHOD(systemSetAdvancedSettings) { + VALUE rb_settings; + rb_get_args(argc, argv, "o", &rb_settings); + + FMOD_STUDIO_ADVANCEDSETTINGS settings = rb2FMOD_STUDIO_ADVANCEDSETTINGS(rb_settings); + StudioSystem *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_System_SetAdvancedSettings(b->p, &settings); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(systemGetAdvancedSettings) { + RB_UNUSED_PARAM; + + FMOD_STUDIO_ADVANCEDSETTINGS settings = FMOD_STUDIO_ADVANCEDSETTINGS(); + StudioSystem *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_System_GetAdvancedSettings(b->p, &settings); + + FMOD_RESULT_NO_WRAP(settings, FMOD_STUDIO_ADVANCEDSETTINGS); +} + +//! Need to define custom new function because Ruby +//! does not allow for custom return values from initialize. +RB_METHOD(systemNew) { + int maxchannels; + int studioflags; + int flags; + rb_get_args(argc, argv, "iii", &maxchannels, &studioflags, &flags RB_ARG_END); + + FMOD_STUDIO_SYSTEM *system = NULL; + FMOD_RESULT result = FMOD_Studio_System_Create(&system, FMOD_VERSION); + + if (result == FMOD_OK) { + result = FMOD_Studio_System_Initialize(system, maxchannels, studioflags, flags, NULL); + } + + FMOD_RESULT_BASE; + if (result == FMOD_OK) { + VALUE self = rb_obj_alloc(rb_cStudioSystem); //! Manually allocate the object + setPrivateData(self, new StudioSystem(system)); + rb_ary_push(return_ary, self); + } + FMOD_RESULT_RET; +} + +RB_METHOD(systemRelease) { + RB_UNUSED_PARAM; + + StudioSystem *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_System_Release(b->p); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(systemUpdate) { + RB_UNUSED_PARAM; + + StudioSystem *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_System_Update(b->p); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(systemGetCoreSystem) { + RB_UNUSED_PARAM; + + StudioSystem *b = getPrivateData(self); + FMOD_SYSTEM *system = NULL; + + FMOD_RESULT result = FMOD_Studio_System_GetCoreSystem(b->p, &system); + + FMOD_RESULT_WRAP(system, System); +} + +#define GET_PATHORID \ +char* pathorid; \ +rb_get_args(argc, argv, "z", &pathorid RB_ARG_END); + +RB_METHOD(systemGetEvent) { + GET_PATHORID; + + StudioSystem *b = getPrivateData(self); + FMOD_STUDIO_EVENTDESCRIPTION *event = NULL; + + FMOD_RESULT result = FMOD_Studio_System_GetEvent(b->p, pathorid, &event); + + FMOD_RESULT_WRAP(event, EventDescription); +} + +RB_METHOD(systemGetBus) { + GET_PATHORID; + + StudioSystem *b = getPrivateData(self); + FMOD_STUDIO_BUS *bus = NULL; + + FMOD_RESULT result = FMOD_Studio_System_GetBus(b->p, pathorid, &bus); + + FMOD_RESULT_WRAP(bus, Bus); +} + +RB_METHOD(systemGetVCA) { + GET_PATHORID; + + StudioSystem *b = getPrivateData(self); + FMOD_STUDIO_VCA *vca = NULL; + + FMOD_RESULT result = FMOD_Studio_System_GetVCA(b->p, pathorid, &vca); + + FMOD_RESULT_WRAP(vca, VCA); +} + +RB_METHOD(systemGetBank) { + GET_PATHORID; + + StudioSystem *b = getPrivateData(self); + FMOD_STUDIO_BANK *bank = NULL; + + FMOD_RESULT result = FMOD_Studio_System_GetBank(b->p, pathorid, &bank); + + FMOD_RESULT_WRAP(bank, Bank); +} + +#define GET_ID \ +VALUE rb_id; \ +rb_get_args(argc, argv, "o", &rb_id RB_ARG_END); \ +FMOD_GUID id = rb2FMOD_GUID(rb_id); + +RB_METHOD(systemGetEventByID) { + GET_ID; + + StudioSystem *b = getPrivateData(self); + FMOD_STUDIO_EVENTDESCRIPTION *event = NULL; + + FMOD_RESULT result = FMOD_Studio_System_GetEventByID(b->p, &id, &event); + + FMOD_RESULT_WRAP(event, EventDescription); +} + +RB_METHOD(systemGetBusByID) { + GET_ID; + + StudioSystem *b = getPrivateData(self); + FMOD_STUDIO_BUS *bus = NULL; + + FMOD_RESULT result = FMOD_Studio_System_GetBusByID(b->p, &id, &bus); + + FMOD_RESULT_WRAP(bus, Bus); +} + +RB_METHOD(systemGetVCAByID) { + GET_ID; + + StudioSystem *b = getPrivateData(self); + FMOD_STUDIO_VCA *vca = NULL; + + FMOD_RESULT result = FMOD_Studio_System_GetVCAByID(b->p, &id, &vca); + + FMOD_RESULT_WRAP(vca, VCA); +} + +RB_METHOD(systemGetBankByID) { + GET_ID; + + StudioSystem *b = getPrivateData(self); + FMOD_STUDIO_BANK *bank = NULL; + + FMOD_RESULT result = FMOD_Studio_System_GetBankByID(b->p, &id, &bank); + + FMOD_RESULT_WRAP(bank, Bank); +} + +RB_METHOD(systemGetSoundInfo) { + char* key; + rb_get_args(argc, argv, "z", &key RB_ARG_END); + + StudioSystem *b = getPrivateData(self); + FMOD_STUDIO_SOUND_INFO info = FMOD_STUDIO_SOUND_INFO(); + + FMOD_RESULT result = FMOD_Studio_System_GetSoundInfo(b->p, key, &info); + + FMOD_RESULT_NO_WRAP(info, FMOD_STUDIO_SOUND_INFO); +} + +RB_METHOD(systemGetParameterDescriptionName) { + char* name; + rb_get_args(argc, argv, "z", &name RB_ARG_END); + + StudioSystem *b = getPrivateData(self); + FMOD_STUDIO_PARAMETER_DESCRIPTION description = FMOD_STUDIO_PARAMETER_DESCRIPTION(); + + FMOD_RESULT result = FMOD_Studio_System_GetParameterDescriptionByName(b->p, name, &description); + + FMOD_RESULT_NO_WRAP(description, FMOD_STUDIO_PARAMETER_DESCRIPTION); +} + +RB_METHOD(systemGetParameterDescriptionID) { + VALUE rb_id; + rb_get_args(argc, argv, "o", &rb_id RB_ARG_END); + + FMOD_STUDIO_PARAMETER_ID id = rb2FMOD_STUDIO_PARAMETER_ID(rb_id); + StudioSystem *b = getPrivateData(self); + FMOD_STUDIO_PARAMETER_DESCRIPTION description = FMOD_STUDIO_PARAMETER_DESCRIPTION(); + + FMOD_RESULT result = FMOD_Studio_System_GetParameterDescriptionByID(b->p, id, &description); + + FMOD_RESULT_NO_WRAP(description, FMOD_STUDIO_PARAMETER_DESCRIPTION); +} + +RB_METHOD(systemGetParameterLabelByName) { + char* name; + int labelindex; + rb_get_args(argc, argv, "zi", &name, &labelindex RB_ARG_END); + + StudioSystem *b = getPrivateData(self); + char* label = NULL; + int retrieved; + + FMOD_RESULT result = FMOD_Studio_System_GetParameterLabelByName(b->p, name, labelindex, NULL, 0 , &retrieved); + + if (result == FMOD_OK) { + label = new char[retrieved]; + + result = FMOD_Studio_System_GetParameterLabelByName(b->p, name, labelindex, label, retrieved, &retrieved); + } + + FMOD_RESULT_CONVERT(label, rb_str_new_cstr); +} + +RB_METHOD(systemGetParameterLabelByID) { + VALUE rb_id; + int labelindex; + rb_get_args(argc, argv, "zoi", &rb_id, &labelindex RB_ARG_END); + + FMOD_STUDIO_PARAMETER_ID id = rb2FMOD_STUDIO_PARAMETER_ID(rb_id); + StudioSystem *b = getPrivateData(self); + char* label = NULL; + int retrieved; + + FMOD_RESULT result = FMOD_Studio_System_GetParameterLabelByID(b->p, id, labelindex, NULL, 0 , &retrieved); + + if (result == FMOD_OK) { + label = new char[retrieved]; + + result = FMOD_Studio_System_GetParameterLabelByID(b->p, id, labelindex, label, retrieved, &retrieved); + } + + FMOD_RESULT_CONVERT(label, rb_str_new_cstr); +} + +#define RETURN_PARAMETER \ + FMOD_RESULT_BASE; \ + if (result == FMOD_OK) \ + { \ + rb_ary_push(return_ary, DBL2NUM(value)); \ + rb_ary_push(return_ary, DBL2NUM(finalvalue)); \ + } \ + FMOD_RESULT_RET; + +RB_METHOD(systemGetParameterByID) { + VALUE rb_id; + rb_get_args(argc, argv, "o", &rb_id RB_ARG_END); + + FMOD_STUDIO_PARAMETER_ID id = rb2FMOD_STUDIO_PARAMETER_ID(rb_id); + StudioSystem *b = getPrivateData(self); + float value, finalvalue; + + FMOD_RESULT result = FMOD_Studio_System_GetParameterByID(b->p, id, &value, &finalvalue); + + RETURN_PARAMETER; +} + +RB_METHOD(systemSetParameterByID) { + VALUE rb_id; + float value; + bool ignoreseekspeed; + rb_get_args(argc, argv, "ofb", &rb_id, &value, &ignoreseekspeed RB_ARG_END); + + FMOD_STUDIO_PARAMETER_ID id = rb2FMOD_STUDIO_PARAMETER_ID(rb_id); + StudioSystem *b = getPrivateData(self); + FMOD_RESULT result = FMOD_Studio_System_SetParameterByID( + b->p, id, value, (FMOD_BOOL) ignoreseekspeed); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(systemSetParameterByIDWithLabel) { + VALUE rb_id; + char* label; + bool ignoreseekspeed; + rb_get_args(argc, argv, "ozfb", &rb_id, &label, &ignoreseekspeed RB_ARG_END); + + FMOD_STUDIO_PARAMETER_ID id = rb2FMOD_STUDIO_PARAMETER_ID(rb_id); + StudioSystem *b = getPrivateData(self); + FMOD_RESULT result = FMOD_Studio_System_SetParameterByIDWithLabel( + b->p, id, label, (FMOD_BOOL) ignoreseekspeed); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(systemSetParametersByIDs) { + VALUE rb_ids; + VALUE rb_values; + bool ignoreseekspeed; + rb_get_args(argc, argv, "oob", &rb_ids, &rb_values, &ignoreseekspeed RB_ARG_END); + + if (rb_array_len(rb_values) != rb_array_len(rb_ids)) + { + rb_raise(rb_eArgError, "Array lengths must match"); + } + int count = rb_array_len(rb_values); + + float* values = new float[count]; + FMOD_STUDIO_PARAMETER_ID* ids = new FMOD_STUDIO_PARAMETER_ID[count]; + for (int i = 0; i < count; i++) + { + ids[i] = rb2FMOD_STUDIO_PARAMETER_ID(rb_ary_entry(rb_ids, i)); + values[i] = NUM2DBL(rb_ary_entry(rb_values, i)); + } + + StudioSystem *b = getPrivateData(self); + FMOD_RESULT result = FMOD_Studio_System_SetParametersByIDs( + b->p, ids, values, count, (FMOD_BOOL) ignoreseekspeed); + + delete[] ids; + delete[] values; + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(systemGetParameterByName) { + char* name; + rb_get_args(argc, argv, "z", &name RB_ARG_END); + + StudioSystem *b = getPrivateData(self); + float value, finalvalue; + + FMOD_RESULT result = FMOD_Studio_System_GetParameterByName(b->p, name, &value, &finalvalue); + + RETURN_PARAMETER; +} + +RB_METHOD(systemSetParameterByName) { + char* name; + float value; + bool ignoreseekspeed; + rb_get_args(argc, argv, "zfb", &name, &value, &ignoreseekspeed RB_ARG_END); + + StudioSystem *b = getPrivateData(self); + FMOD_RESULT result = FMOD_Studio_System_SetParameterByName( + b->p, name, value, (FMOD_BOOL) ignoreseekspeed); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(systemSetParameterByNameWithLabel) { + char* name; + char* label; + bool ignoreseekspeed; + rb_get_args(argc, argv, "zzb", &name, &label, &ignoreseekspeed RB_ARG_END); + + StudioSystem *b = getPrivateData(self); + FMOD_RESULT result = FMOD_Studio_System_SetParameterByNameWithLabel( + b->p, name, label, (FMOD_BOOL) ignoreseekspeed); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(systemLookupID) { + char* path; + rb_get_args(argc, argv, "z", &path RB_ARG_END); + + StudioSystem *b = getPrivateData(self); + FMOD_GUID id = FMOD_GUID(); + FMOD_RESULT result = FMOD_Studio_System_LookupID(b->p, path, &id); + + FMOD_RESULT_NO_WRAP(id, FMOD_GUID); +} + +RB_METHOD(systemLookupPath) { + VALUE rb_id; + rb_get_args(argc, argv, "o", &rb_id RB_ARG_END); + + FMOD_GUID id = rb2FMOD_GUID(rb_id); + StudioSystem *b = getPrivateData(self); + char* path = NULL; + int retrieved; + + FMOD_RESULT result = FMOD_Studio_System_LookupPath(b->p, &id, NULL, 0, &retrieved); + + if (result == FMOD_OK) + { + path = new char[retrieved]; + result = FMOD_Studio_System_LookupPath(b->p, &id, path, retrieved, &retrieved); + } + + FMOD_RESULT_CONVERT(path, rb_str_new_cstr); +} + +RB_METHOD(systemGetNumListeners) { + RB_UNUSED_PARAM; + + StudioSystem *b = getPrivateData(self); + int numlisteners; + + FMOD_RESULT result = FMOD_Studio_System_GetNumListeners(b->p, &numlisteners); + + FMOD_RESULT_CONVERT(numlisteners, INT2NUM); +} + +RB_METHOD(systemSetNumListeners) { + int numlisteners; + rb_get_args(argc, argv, "i", &numlisteners RB_ARG_END); + + StudioSystem *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_System_SetNumListeners(b->p, numlisteners); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(systemGetListenerAttributes) { + int listener; + rb_get_args(argc, argv, "i", &listener RB_ARG_END); + + StudioSystem *b = getPrivateData(self); + FMOD_3D_ATTRIBUTES attributes = FMOD_3D_ATTRIBUTES(); + FMOD_VECTOR attenuationposition = FMOD_VECTOR(); + + FMOD_RESULT result = FMOD_Studio_System_GetListenerAttributes(b->p, listener, &attributes, &attenuationposition); + + FMOD_RESULT_BASE; + if (result == FMOD_OK) { + rb_ary_push(return_ary, fmodFMOD_3D_ATTRIBUTES2rb(attributes)); + rb_ary_push(return_ary, fmodFMOD_VECTOR2rb(attenuationposition)); + } + FMOD_RESULT_RET; +} + +RB_METHOD(systemSetListenerAttributes) { + int listener; + VALUE rb_attributes, rb_attenuationposition; + rb_get_args(argc, argv, "ioo", &listener, &rb_attributes, &rb_attenuationposition RB_ARG_END); + + StudioSystem *b = getPrivateData(self); + FMOD_3D_ATTRIBUTES attributes = rb2FMOD_3D_ATTRIBUTES(rb_attributes); + FMOD_VECTOR attenuationposition = rb2FMOD_VECTOR(rb_attenuationposition); + + FMOD_RESULT result = FMOD_Studio_System_SetListenerAttributes(b->p, listener, &attributes, &attenuationposition); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(systemGetListenerWeight) { + int listener; + rb_get_args(argc, argv, "i", &listener RB_ARG_END); + + StudioSystem *b = getPrivateData(self); + float weight; + + FMOD_RESULT result = FMOD_Studio_System_GetListenerWeight(b->p, listener, &weight); + + FMOD_RESULT_CONVERT(weight, DBL2NUM); +} + +RB_METHOD(systemSetListenerWeight) { + int listener; + float weight; + rb_get_args(argc, argv, "if", &listener, &weight RB_ARG_END); + + StudioSystem *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_System_SetListenerWeight(b->p, listener, weight); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(systemLoadBankFile) { + const char* filename; + int flags; + + rb_get_args(argc, argv, "zi", &filename, &flags RB_ARG_END); + + StudioSystem *b = getPrivateData(self); + + //? Initialize bank as a NULL pointer + FMOD_STUDIO_BANK* bank = NULL; + //? Load bank + FMOD_RESULT result = FMOD_Studio_System_LoadBankFile( + b->p, filename, flags, &bank + ); + + //? Wrap bank result and return it + FMOD_RESULT_WRAP(bank, Bank); +} + +RB_METHOD(systemLoadBankMemory) { + char* buffer; + int flags; + rb_get_args(argc, argv, "zi", &buffer, &flags RB_ARG_END); + int length = strlen(buffer); //! Unsafe bad very bad + + StudioSystem *b = getPrivateData(self); + FMOD_STUDIO_BANK *bank = NULL; + + FMOD_RESULT result = FMOD_Studio_System_LoadBankMemory( + b->p, buffer, length, FMOD_STUDIO_LOAD_MEMORY, flags, &bank + ); + + FMOD_RESULT_WRAP(bank, Bank); +} + +RB_METHOD(systemLoadBankCustom) { + // TODO +} + +RB_METHOD(systemRegisterPlugin) { + // TODO +} + +RB_METHOD(systemUnregisterPlugin) { + char* name; + rb_get_args(argc, argv, "z", &name RB_ARG_END); + + StudioSystem *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_System_UnregisterPlugin(b->p, name); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(systemUnloadAll) { + RB_UNUSED_PARAM; + + StudioSystem *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_System_UnloadAll(b->p); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(systemFlushCommands) { + RB_UNUSED_PARAM; + + StudioSystem *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_System_FlushCommands(b->p); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(systemFlushSampleLoading) { + RB_UNUSED_PARAM; + + StudioSystem *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_System_FlushSampleLoading(b->p); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(systemStartCommandCapture) { + char* filename; + int flags; + + rb_get_args(argc, argv, "zi", &filename, &flags RB_ARG_END); + + StudioSystem *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_System_StartCommandCapture(b->p, filename, flags); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(systemStopCommandCapture) { + RB_UNUSED_PARAM; + + StudioSystem *b = getPrivateData(self); + + FMOD_RESULT result = FMOD_Studio_System_StopCommandCapture(b->p); + + FMOD_RESULT_SIMPLE; +} + +RB_METHOD(systemLoadCommandReplay) { + char* filename; + int flags; + + rb_get_args(argc, argv, "zi", &filename, &flags RB_ARG_END); + + StudioSystem *b = getPrivateData(self); + + FMOD_STUDIO_COMMANDREPLAY *replay = NULL; + + FMOD_RESULT result = FMOD_Studio_System_LoadCommandReplay( + b->p, filename, flags, &replay + ); + + FMOD_RESULT_WRAP(replay, CommandReplay); +} + +RB_METHOD(systemGetBankCount) { + RB_UNUSED_PARAM; + + StudioSystem *b = getPrivateData(self); + + int count; + FMOD_RESULT result = FMOD_Studio_System_GetBankCount(b->p, &count); + + FMOD_RESULT_CONVERT(count, INT2NUM); +} + +RB_METHOD(systemGetBankList) { + RB_UNUSED_PARAM; + + StudioSystem *b = getPrivateData(self); + + int count; + FMOD_STUDIO_BANK **array = NULL; + FMOD_RESULT result = FMOD_Studio_System_GetBankCount(b->p, &count); + + if (result == FMOD_OK) + { + array = new FMOD_STUDIO_BANK *[count]; + + result = FMOD_Studio_System_GetBankList( + b->p, array, count, NULL); + } + + FMOD_RESULT_BASE; + if (array && result == FMOD_OK) + { + VALUE bank_ary = rb_ary_new(); + + for (int i = 0; i < count; i++) + { + VALUE ele = rb_obj_alloc(rb_cBank); + setPrivateData(ele, new Bank(array[i])); + rb_ary_push(bank_ary, ele); + } + + rb_ary_push(return_ary, bank_ary); + delete array; + } + FMOD_RESULT_RET; +} + +RB_METHOD(systemGetParameterDescriptionCount) { + RB_UNUSED_PARAM; + + StudioSystem *b = getPrivateData(self); + + int count; + FMOD_RESULT result = FMOD_Studio_System_GetParameterDescriptionCount(b->p, &count); + + FMOD_RESULT_CONVERT(count, INT2NUM); +} + +RB_METHOD(systemGetParameterDescriptionList) { + RB_UNUSED_PARAM; + + StudioSystem *b = getPrivateData(self); + + int count; + FMOD_STUDIO_PARAMETER_DESCRIPTION *array = NULL; + FMOD_RESULT result = FMOD_Studio_System_GetParameterDescriptionCount(b->p, &count); + + if (result == FMOD_OK) + { + array = new FMOD_STUDIO_PARAMETER_DESCRIPTION[count]; + + result = FMOD_Studio_System_GetParameterDescriptionList( + b->p, array, count, NULL); + } + + FMOD_RESULT_BASE; + if (array && result == FMOD_OK) + { + VALUE param_ary = rb_ary_new(); + + for (int i = 0; i < count; i++) + { + VALUE ele = fmodFMOD_STUDIO_PARAMETER_DESCRIPTION2rb(array[i]); + rb_ary_push(param_ary, ele); + } + + rb_ary_push(return_ary, param_ary); + delete[] array; + } + FMOD_RESULT_RET; +} + +RB_METHOD(systemGetCPUUsage) { + RB_UNUSED_PARAM; + + StudioSystem *b = getPrivateData(self); + + FMOD_STUDIO_CPU_USAGE usage = FMOD_STUDIO_CPU_USAGE(); + FMOD_CPU_USAGE core_usage = FMOD_CPU_USAGE(); + FMOD_RESULT result = FMOD_Studio_System_GetCPUUsage(b->p, &usage, &core_usage); + + FMOD_RESULT_BASE; + if (result == FMOD_OK) { + rb_ary_push(return_ary, fmodFMOD_STUDIO_CPU_USAGE2rb(usage)); + rb_ary_push(return_ary, fmodFMOD_CPU_USAGE2rb(core_usage)); + } + FMOD_RESULT_RET; +} + +RB_METHOD(systemGetBufferUsage) { + RB_UNUSED_PARAM; + + StudioSystem *b = getPrivateData(self); + + FMOD_STUDIO_BUFFER_USAGE usage = FMOD_STUDIO_BUFFER_USAGE(); + FMOD_RESULT result = FMOD_Studio_System_GetBufferUsage(b->p, &usage); + + FMOD_RESULT_NO_WRAP(usage, FMOD_STUDIO_BUFFER_USAGE); +} + +RB_METHOD(systemSetCallback) { + // TODO +} + +FMOD_USERDATA_FUNC(FMOD_Studio_System, StudioSystem); + +FMOD_MEMORY_USAGE_FUNC(FMOD_Studio_System, StudioSystem); + +FMOD_EQUAL_FUNC(StudioSystem); + +VALUE rb_cStudioSystem = Qnil; + +void bindFmodStudioSystem() { + rb_cStudioSystem = rb_define_class_under(rb_mFMOD_Studio, "System", rb_cObject); + rb_define_alloc_func(rb_cStudioSystem, classAllocate<&StudioSystemType>); + _rb_define_method(rb_cStudioSystem, "==", fmodEqual); + + _rb_define_module_function(rb_cStudioSystem, "new", systemNew); + _rb_define_method(rb_cStudioSystem, "is_valid", fmodIsValid); + _rb_define_method(rb_cStudioSystem, "set_advanced_settings", systemSetAdvancedSettings); + _rb_define_method(rb_cStudioSystem, "get_advanced_settings", systemGetAdvancedSettings); + _rb_define_method(rb_cStudioSystem, "release", systemRelease); + _rb_define_method(rb_cStudioSystem, "update", systemUpdate); + _rb_define_method(rb_cStudioSystem, "get_core_system", systemGetCoreSystem); + _rb_define_method(rb_cStudioSystem, "get_event", systemGetEvent); + _rb_define_method(rb_cStudioSystem, "get_bus", systemGetBus); + _rb_define_method(rb_cStudioSystem, "get_vca", systemGetVCA); + _rb_define_method(rb_cStudioSystem, "get_bank", systemGetBank); + _rb_define_method(rb_cStudioSystem, "get_event_by_id", systemGetEventByID); + _rb_define_method(rb_cStudioSystem, "get_bus_by_id", systemGetBusByID); + _rb_define_method(rb_cStudioSystem, "get_vca_by_id", systemGetVCAByID); + _rb_define_method(rb_cStudioSystem, "get_bank_by_id", systemGetBankByID); + _rb_define_method(rb_cStudioSystem, "get_sound_info", systemGetSoundInfo); + _rb_define_method(rb_cStudioSystem, "get_parameter_description_by_name", systemGetParameterDescriptionName); + _rb_define_method(rb_cStudioSystem, "get_parameter_description_by_id", systemGetParameterDescriptionID); + _rb_define_method(rb_cStudioSystem, "get_parameter_label_by_name", systemGetParameterLabelByName); + _rb_define_method(rb_cStudioSystem, "get_parameter_label_by_id", systemGetParameterLabelByID); + _rb_define_method(rb_cStudioSystem, "get_parameter_by_id", systemGetParameterByID); + _rb_define_method(rb_cStudioSystem, "set_parameter_by_id", systemSetParameterByID); + _rb_define_method(rb_cStudioSystem, "set_parameter_by_id_with_label", systemSetParameterByIDWithLabel); + _rb_define_method(rb_cStudioSystem, "set_parameters_by_ids", systemSetParametersByIDs); + _rb_define_method(rb_cStudioSystem, "get_parameter_by_name", systemGetParameterByName); + _rb_define_method(rb_cStudioSystem, "set_parameter_by_name", systemSetParameterByName); + _rb_define_method(rb_cStudioSystem, "set_parameter_by_name_with_label", systemSetParameterByNameWithLabel); + _rb_define_method(rb_cStudioSystem, "lookup_id", systemLookupID); + _rb_define_method(rb_cStudioSystem, "lookup_path", systemLookupPath); + _rb_define_method(rb_cStudioSystem, "get_num_listeners", systemGetNumListeners); + _rb_define_method(rb_cStudioSystem, "set_num_listeners", systemSetNumListeners); + _rb_define_method(rb_cStudioSystem, "get_listener_attributes", systemGetListenerAttributes); + _rb_define_method(rb_cStudioSystem, "set_listener_attributes", systemSetListenerAttributes); + _rb_define_method(rb_cStudioSystem, "get_listener_weight", systemGetListenerWeight); + _rb_define_method(rb_cStudioSystem, "set_listener_weight", systemSetListenerWeight); + _rb_define_method(rb_cStudioSystem, "load_bank_file", systemLoadBankFile); + _rb_define_method(rb_cStudioSystem, "load_bank_memory", systemLoadBankMemory); + _rb_define_method(rb_cStudioSystem, "load_bank_custom", systemLoadBankCustom); + _rb_define_method(rb_cStudioSystem, "register_plugin", systemRegisterPlugin); + _rb_define_method(rb_cStudioSystem, "unregister_plugin", systemUnregisterPlugin); + _rb_define_method(rb_cStudioSystem, "unload_all", systemUnloadAll); + _rb_define_method(rb_cStudioSystem, "flush_commands", systemFlushCommands); + _rb_define_method(rb_cStudioSystem, "flush_sample_loading", systemFlushSampleLoading); + _rb_define_method(rb_cStudioSystem, "start_command_capture", systemStartCommandCapture); + _rb_define_method(rb_cStudioSystem, "stop_command_capture", systemStopCommandCapture); + _rb_define_method(rb_cStudioSystem, "load_command_replay", systemLoadCommandReplay); + _rb_define_method(rb_cStudioSystem, "get_bank_count", systemGetBankCount); + _rb_define_method(rb_cStudioSystem, "get_bank_list", systemGetBankList); + _rb_define_method(rb_cStudioSystem, "get_parameter_description_count", systemGetParameterDescriptionCount); + _rb_define_method(rb_cStudioSystem, "get_parameter_description_list", systemGetParameterDescriptionList); + _rb_define_method(rb_cStudioSystem, "get_cpu_usage", systemGetCPUUsage); + _rb_define_method(rb_cStudioSystem, "get_buffer_usage", systemGetBufferUsage); + _rb_define_method(rb_cStudioSystem, "set_callback", systemSetCallback); + _rb_define_method(rb_cStudioSystem, "set_user_data", fmodSetUserData); + _rb_define_method(rb_cStudioSystem, "get_user_data", fmodGetUserData); + _rb_define_method(rb_cStudioSystem, "get_memory_usage", fmodGetMemoryUsage); +} diff --git a/binding-mri/fmod-binding/studio/vca.cpp b/binding-mri/fmod-binding/studio/vca.cpp new file mode 100644 index 00000000..21d4827a --- /dev/null +++ b/binding-mri/fmod-binding/studio/vca.cpp @@ -0,0 +1,35 @@ +#include "binding-util.h" +#include "fmod_bindings.h" +#include "debugwriter.h" + +DEF_TYPE(VCA); +VCA::~VCA() +{ + // Debug() << "Warning: VCA deconstructed (garbage collected?)"; +} + +VALUE rb_cVCA = Qnil; + +FMOD_VALID_FUNC(FMOD_Studio_VCA, VCA); + +FMOD_ID_FUNC(FMOD_Studio_VCA, VCA); + +FMOD_PATH_FUNC(FMOD_Studio_VCA, VCA); + +FMOD_VOLUME_FUNC(FMOD_Studio_VCA, VCA); + +FMOD_EQUAL_FUNC(VCA); + +void bindFmodStudioVCA() +{ + rb_cVCA = rb_define_class_under(rb_mFMOD_Studio, "VCA", rb_cObject); + rb_define_alloc_func(rb_cVCA, classAllocate<&VCAType>); + _rb_define_method(rb_cVCA, "initialize", fmodErrorInit); + _rb_define_method(rb_cVCA, "==", fmodEqual); + + _rb_define_method(rb_cVCA, "is_valid", fmodIsValid); + _rb_define_method(rb_cVCA, "get_id", fmodGetID); + _rb_define_method(rb_cVCA, "get_path", fmodGetPath); + _rb_define_method(rb_cVCA, "get_volume", fmodGetVolume); + _rb_define_method(rb_cVCA, "set_volume", fmodSetVolume); +} diff --git a/binding-mri/meson.build b/binding-mri/meson.build index 916a3218..50ce9e1a 100644 --- a/binding-mri/meson.build +++ b/binding-mri/meson.build @@ -12,8 +12,6 @@ endif global_include_dirs += include_directories('.') binding_source = [files( - 'aleffect-binding.cpp', - 'audio-binding.cpp', 'binding-mri.cpp', 'binding-util.cpp', 'bitmap-binding.cpp', @@ -38,4 +36,28 @@ binding_source = [files( 'window-binding.cpp', )] +if fmod +global_sources += [files( + 'fmod-binding/studio/fmod-studio-binding.cpp', + 'fmod-binding/studio/system.cpp', + 'fmod-binding/studio/bank.cpp', + 'fmod-binding/studio/vca.cpp', + 'fmod-binding/studio/bus.cpp', + 'fmod-binding/studio/eventdescription.cpp', + 'fmod-binding/studio/eventinstance.cpp', + 'fmod-binding/studio/commandreplay.cpp', + 'fmod-binding/studio/common_structs.cpp', + 'fmod-binding/core/fmod-core-binding.cpp', + 'fmod-binding/core/system.cpp', + 'fmod-binding/core/common_structs.cpp', + 'fmod-binding/fmod_enums.cpp', +)] +global_include_dirs += include_directories('fmod-binding') +else +global_sources += [files( + 'al-binding/aleffect-binding.cpp', + 'al-binding/audio-binding.cpp' +)] +endif + global_sources += binding_source diff --git a/meson.build b/meson.build index 62980c09..bdc2149a 100644 --- a/meson.build +++ b/meson.build @@ -6,7 +6,7 @@ project( license: 'GPL-2.0', meson_version: '>=0.60.0', default_options: [ - 'cpp_std=c++14', + 'cpp_std=c++17', 'buildtype=release' ] ) @@ -41,6 +41,11 @@ elif gfx_backend == 'gl' global_dependencies += dependency('gl') endif +fmod = get_option('fmod') +if get_option('auto_clean_fmod') + global_args += '-DAUTO_CLEAN_FMOD' +endif + # ==================== # Main source # ==================== @@ -106,6 +111,10 @@ subdir('scripts') global_include_dirs += include_directories('src', 'binding-mri') +if fmod + global_include_dirs += include_directories('fmod/api/core/inc', 'fmod/api/fsbank/inc', 'fmod/api/studio/inc') +endif + rpath = '' if host_system == 'windows' subdir('windows') diff --git a/meson_options.txt b/meson_options.txt index cefa1b48..cfc6f162 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -10,3 +10,10 @@ option('steam', type: 'boolean', value: false, description: 'Add steamworks supp option('build_static', type: 'boolean', value: true, description: 'Use static libraries') option('gfx_backend', type: 'combo', value: 'gl', choices: ['gl', 'gles'], description: 'Graphics rendering API to use.') + +option('fmod', type: 'boolean', value: false, description: 'Use FMOD bindings instead of OpenAL') + +option('fmod_core_lib_dir', type: 'string', value: '', description: 'Manual fmod lib dir') +option('fmod_fsbank_lib_dir', type: 'string', value: '', description: 'Manual fmod fsbank lib dir') +option('fmod_studio_lib_dir', type: 'string', value: '', description: 'Manual fmod studio lib dir') +option('auto_clean_fmod', type: 'boolean', value: false, description: 'Automatically release some fmod resources') diff --git a/scripts/meson.build b/scripts/meson.build index 7b718f9e..3b81d86e 100644 --- a/scripts/meson.build +++ b/scripts/meson.build @@ -7,5 +7,6 @@ global_sources += custom_target('pack scripts', '-o', '@OUTPUT@' ], install: true, - install_dir: 'Data' + install_dir: 'Data', + build_always_stale: true ) diff --git a/scripts/rgss/Main.rb b/scripts/rgss/Main.rb index 1efbc73c..fe0e154b 100644 --- a/scripts/rgss/Main.rb +++ b/scripts/rgss/Main.rb @@ -26,8 +26,8 @@ Oneshot.allow_exit false Oneshot.exiting false -# x = Oneshot.textinput("Foo Bar") -# print("#{x}") + # x = Oneshot.textinput("Foo Bar") + # print("#{x}") # Call main method as long as $scene is effective while $scene != nil @@ -38,9 +38,9 @@ Graphics.transition(20) if Journal.active? - Journal.set '' + Journal.set "" end - + Oneshot.allow_exit true rescue Errno::ENOENT # Supplement Errno::ENOENT exception diff --git a/src/audio/headers/al-util.h b/src/al/headers/al-util.h similarity index 100% rename from src/audio/headers/al-util.h rename to src/al/headers/al-util.h diff --git a/src/audio/headers/aldatasource.h b/src/al/headers/aldatasource.h similarity index 100% rename from src/audio/headers/aldatasource.h rename to src/al/headers/aldatasource.h diff --git a/src/audio/headers/alstream.h b/src/al/headers/alstream.h similarity index 100% rename from src/audio/headers/alstream.h rename to src/al/headers/alstream.h diff --git a/src/audio/headers/audio.h b/src/al/headers/audio.h similarity index 100% rename from src/audio/headers/audio.h rename to src/al/headers/audio.h diff --git a/src/audio/headers/audiochannels.h b/src/al/headers/audiochannels.h similarity index 100% rename from src/audio/headers/audiochannels.h rename to src/al/headers/audiochannels.h diff --git a/src/audio/headers/audiostream.h b/src/al/headers/audiostream.h similarity index 100% rename from src/audio/headers/audiostream.h rename to src/al/headers/audiostream.h diff --git a/src/audio/headers/soundemitter.h b/src/al/headers/soundemitter.h similarity index 100% rename from src/audio/headers/soundemitter.h rename to src/al/headers/soundemitter.h diff --git a/src/audio/source/alstream.cpp b/src/al/source/alstream.cpp similarity index 100% rename from src/audio/source/alstream.cpp rename to src/al/source/alstream.cpp diff --git a/src/audio/source/audio.cpp b/src/al/source/audio.cpp similarity index 100% rename from src/audio/source/audio.cpp rename to src/al/source/audio.cpp diff --git a/src/audio/source/audiochannels.cpp b/src/al/source/audiochannels.cpp similarity index 100% rename from src/audio/source/audiochannels.cpp rename to src/al/source/audiochannels.cpp diff --git a/src/audio/source/audiostream.cpp b/src/al/source/audiostream.cpp similarity index 100% rename from src/audio/source/audiostream.cpp rename to src/al/source/audiostream.cpp diff --git a/src/audio/source/sdlsoundsource.cpp b/src/al/source/sdlsoundsource.cpp similarity index 100% rename from src/audio/source/sdlsoundsource.cpp rename to src/al/source/sdlsoundsource.cpp diff --git a/src/audio/source/soundemitter.cpp b/src/al/source/soundemitter.cpp similarity index 100% rename from src/audio/source/soundemitter.cpp rename to src/al/source/soundemitter.cpp diff --git a/src/audio/source/vorbissource.cpp b/src/al/source/vorbissource.cpp similarity index 100% rename from src/audio/source/vorbissource.cpp rename to src/al/source/vorbissource.cpp diff --git a/src/filesystem/source/filesystem.cpp b/src/filesystem/source/filesystem.cpp index 4f2820cf..87dc3908 100644 --- a/src/filesystem/source/filesystem.cpp +++ b/src/filesystem/source/filesystem.cpp @@ -31,7 +31,9 @@ #include +#ifndef USE_FMOD #include +#endif #include #include diff --git a/src/main.cpp b/src/main.cpp index 6f95501d..18a74ff5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -19,12 +19,19 @@ ** along with mkxp. If not, see . */ +#ifndef USE_FMOD #include +#endif #include #include #include +#ifndef USE_FMOD #include +#else +#include +#include +#endif #include #ifdef _MSC_VER @@ -133,6 +140,7 @@ int rgssThreadFun(void *userdata) GLDebugLogger dLogger; #endif + #ifndef USE_FMOD /* Setup AL context */ ALCcontext *alcCtx = alcCreateContext(threadData->alcDev, 0); @@ -145,6 +153,7 @@ int rgssThreadFun(void *userdata) } alcMakeContextCurrent(alcCtx); + #endif try { @@ -153,7 +162,9 @@ int rgssThreadFun(void *userdata) catch (const Exception &exc) { rgssThreadError(threadData, exc.msg); + #ifndef USE_FMOD alcDestroyContext(alcCtx); + #endif SDL_GL_DeleteContext(glCtx); return 0; @@ -167,7 +178,9 @@ int rgssThreadFun(void *userdata) SharedState::finiInstance(); + #ifndef USE_FMOD alcDestroyContext(alcCtx); + #endif SDL_GL_DeleteContext(glCtx); return 0; @@ -301,7 +314,7 @@ int main(int argc, char *argv[]) { showInitError(std::string("Unable to switch into gameFolder ") + conf.gameFolder); return 0; } - + #ifdef __WIN32 // Create a debug console in debug mode if (conf.winConsole) { @@ -342,6 +355,7 @@ int main(int argc, char *argv[]) { return 0; } + #ifndef USE_FMOD if (Sound_Init() == 0) { showInitError(std::string("Error initializing SDL_sound: ") + Sound_GetError()); @@ -351,6 +365,7 @@ int main(int argc, char *argv[]) { return 0; } + #endif SDL_Window *win; Uint32 winFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_INPUT_FOCUS; //| SDL_WINDOW_ALLOW_HIGHDPI; @@ -380,6 +395,8 @@ int main(int argc, char *argv[]) { (void) setupWindowIcon; #endif + #ifndef USE_FMOD + ALCdevice *alcDev = alcOpenDevice(0); if (!alcDev) @@ -396,6 +413,22 @@ int main(int argc, char *argv[]) { if(alcIsExtensionPresent(alcDev, "ALC_EXT_EFX") != ALC_TRUE) { showInitError("OpenAL device does not support Effects extension."); } + #else + //FMOD_RESULT result; + //FMOD_STUDIO_SYSTEM *system = NULL; + // + //result = FMOD_Studio_System_Create(&system, FMOD_VERSION); + //if (result != FMOD_OK) { + // showInitError(std::string("Error creating FMOD system: ") + FMOD_ErrorString(result)); + // return 0; + //} + + //result = FMOD_Studio_System_Initialize(system, conf.maxFmodChannels, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, 0); + //if (result != FMOD_OK) { + // showInitError(std::string("Error initializing FMOD system: ") + FMOD_ErrorString(result)); + // return 0; + //} + #endif SDL_DisplayMode mode; SDL_GetDisplayMode(0, 0, &mode); @@ -406,7 +439,12 @@ int main(int argc, char *argv[]) { EventThread eventThread; RGSSThreadData rtData(&eventThread, win, - alcDev, mode.refresh_rate, conf); + #ifndef USE_FMOD + alcDev, + #else + // system, + #endif + mode.refresh_rate, conf); #ifndef STEAM /* Add controller bindings from embedded controller DB */ @@ -476,10 +514,14 @@ int main(int argc, char *argv[]) { unloadLocale(); unloadLanguageMetadata(); + #ifndef USE_FMOD alcCloseDevice(alcDev); + #endif SDL_DestroyWindow(win); + #ifndef USE_FMOD Sound_Quit(); + #endif TTF_Quit(); IMG_Quit(); SDL_Quit(); diff --git a/src/meson.build b/src/meson.build index 121b2de3..80793e0c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,13 +1,8 @@ boost = dependency('boost', version: '>=1.49', modules: ['program_options'], static: build_static) physfs = dependency('physfs', version: '>=2.1', static: build_static) -openal = dependency('openal') -vorbisfile = dependency('vorbisfile', static: build_static) -vorbis = dependency('vorbis', static: build_static) -ogg = dependency('ogg', static: build_static) -sdl2 = dependency('SDL2') +sdl2 = dependency('SDL2', static: build_static) freetype = dependency('freetype2', static: build_static) harfbuzz = dependency('harfbuzz', static: build_static) -sdl_sound = dependency('SDL2_sound', static: build_static) sdl2_ttf = dependency('SDL2_ttf', static: build_static) sdl2_image = dependency('SDL2_image', static: build_static) sigcxx = dependency('sigc++-2.0', static: build_static) @@ -19,6 +14,50 @@ webp = dependency('libwebp', static: build_static) zlib = dependency('zlib', static: build_static) nsgif = dependency('libnsgif', static: build_static) +fmod_arch_prefix = '' +if host_system == 'windows' + fmod_arch_prefix = 'x64' +else + fmod_arch_prefix = 'x86_64' +endif + +if fmod + # FUck + fmod_lib_path = get_option('fmod_core_lib_dir') + if fmod_lib_path == '' + fmod_lib_path = join_paths( + meson.global_source_root(), 'fmod/api/core/lib/' + fmod_arch_prefix + ) + endif + + fsbank_lib_path = get_option('fmod_fsbank_lib_dir') + if fsbank_lib_path == '' + fsbank_lib_path = join_paths( + meson.global_source_root(), 'fmod/api/fsbank/lib/' + fmod_arch_prefix + ) + endif + + studio_lib_path = get_option('fmod_studio_lib_dir') + if studio_lib_path == '' + studio_lib_path = join_paths( + meson.global_source_root(), 'fmod/api/studio/lib/' + fmod_arch_prefix + ) + endif + + fmod_lib = compilers['cpp'].find_library('fmod', dirs: fmod_lib_path) + fsbank = compilers['cpp'].find_library('fsbank', dirs: fsbank_lib_path) + studio = compilers['cpp'].find_library('fmodstudio', dirs: studio_lib_path) + global_dependencies += [fmod_lib, fsbank, studio] +else + # FMOD does not require these libraries + openal = dependency('openal') + vorbisfile = dependency('vorbisfile', static: build_static) + vorbis = dependency('vorbis', static: build_static) + ogg = dependency('ogg', static: build_static) + sdl_sound = dependency('SDL2_sound', static: build_static) + global_dependencies += [openal, vorbisfile, vorbis, ogg, sdl_sound] +endif + if host_system == 'windows' bz2 = dependency('bzip2') iconv = compilers['cpp'].find_library('iconv') @@ -31,6 +70,7 @@ else endif # Windows needs to be treated like a special needs child here +# Windows is a special needs child explicit_libs = '' if host_system == 'windows' # Newer versions of Ruby will refuse to link without these @@ -44,7 +84,6 @@ foreach l : explicit_libs.split(';') endforeach global_include_dirs += include_directories('.', - 'audio/headers', 'filesystem/headers', 'graphics/headers', 'input/headers', @@ -56,7 +95,7 @@ global_include_dirs += include_directories('.', 'util/headers' ) -global_dependencies += [boost, bz2, openal, zlib, sdl2, sdl_sound, pixman, physfs, vorbisfile, vorbis, iconv, ogg, sdl2_ttf, sigcxx, sdl2_image, png, jpeg, nsgif, freetype, tiff, webp, harfbuzz] +global_dependencies += [boost, bz2, zlib, sdl2, pixman, physfs, iconv, sdl2_ttf, sigcxx, sdl2_image, png, jpeg, nsgif, freetype, tiff, webp, harfbuzz] if host_system == 'windows' global_dependencies += compilers['cpp'].find_library('wsock32') @@ -67,13 +106,6 @@ if host_system == 'windows' endif main_source = files( - 'audio/source/alstream.cpp', - 'audio/source/audiostream.cpp', - 'audio/source/audiochannels.cpp', - 'audio/source/audio.cpp', - 'audio/source/soundemitter.cpp', - 'audio/source/sdlsoundsource.cpp', - 'audio/source/vorbissource.cpp', 'filesystem/source/filesystem.cpp', 'filesystem/source/rgssad.cpp', 'graphics/source/autotiles.cpp', @@ -126,6 +158,21 @@ if steam == true global_args += '-DSTEAM' endif +if fmod + global_args += '-DUSE_FMOD' +else + global_include_dirs += include_directories('al/headers') + global_sources += files( + 'al/source/alstream.cpp', + 'al/source/audiostream.cpp', + 'al/source/audiochannels.cpp', + 'al/source/audio.cpp', + 'al/source/soundemitter.cpp', + 'al/source/sdlsoundsource.cpp', + 'al/source/vorbissource.cpp', + ) +endif + if host_system == 'windows' global_sources += files('modshot/source/notifications_win32.cpp') else diff --git a/src/thread/headers/eventthread.h b/src/thread/headers/eventthread.h index 16f8bfb0..2992d905 100644 --- a/src/thread/headers/eventthread.h +++ b/src/thread/headers/eventthread.h @@ -37,7 +37,11 @@ #include +#ifndef USE_FMOD #include +#else +#include +#endif struct RGSSThreadData; struct SDL_Window; @@ -262,7 +266,11 @@ struct RGSSThreadData SyncPoint syncPoint; SDL_Window *window; + #ifndef USE_FMOD ALCdevice *alcDev; + #else + //FMOD_STUDIO_SYSTEM *fmodSystem; + #endif Vec2 sizeResoRatio; Vec2i screenOffset; @@ -276,13 +284,21 @@ struct RGSSThreadData RGSSThreadData(EventThread *ethread, SDL_Window *window, + #ifndef USE_FMOD ALCdevice *alcDev, + #else + //FMOD_STUDIO_SYSTEM *system, + #endif int refreshRate, const Config& newconf) : allowExit(true), ethread(ethread), window(window), + #ifndef USE_FMOD alcDev(alcDev), + #else + //fmodSystem(system), + #endif sizeResoRatio(1, 1), refreshRate(refreshRate), config(newconf) diff --git a/src/thread/headers/sharedstate.h b/src/thread/headers/sharedstate.h index 28641e70..7fc5a50b 100644 --- a/src/thread/headers/sharedstate.h +++ b/src/thread/headers/sharedstate.h @@ -23,6 +23,9 @@ #define SHAREDSTATE_H #include +#ifdef USE_FMOD +#include +#endif #define shState SharedState::instance #define glState shState->_glState() @@ -73,11 +76,16 @@ struct SharedState Graphics &graphics() const; Input &input() const; + #ifndef USE_FMOD Audio &audio() const; + #else + //FMOD_STUDIO_SYSTEM* studio_system() const; + //FMOD_SYSTEM* core_system() const; + #endif Oneshot &oneshot() const; - + #ifdef STEAM Steam &steam() const; #endif diff --git a/src/thread/source/eventthread.cpp b/src/thread/source/eventthread.cpp index 8908e4f5..f5510156 100644 --- a/src/thread/source/eventthread.cpp +++ b/src/thread/source/eventthread.cpp @@ -30,12 +30,18 @@ #include #include +#ifndef USE_FMOD #include +#endif #include "sharedstate.h" #include "graphics.h" #include "settingsmenu.h" + +#ifndef USE_FMOD #include "al-util.h" +#endif + #include "debugwriter.h" #include "oneshot.h" @@ -51,6 +57,7 @@ #define KEYCODE_TO_SCUFFEDCODE(keycode) (((keycode & 0xff) | ((keycode & 0x180) == 0x100 ? 0x180 : 0)) + SDL_NUM_SCANCODES) +#ifndef USE_FMOD typedef void (ALC_APIENTRY *LPALCDEVICEPAUSESOFT) (ALCdevice *device); typedef void (ALC_APIENTRY *LPALCDEVICERESUMESOFT) (ALCdevice *device); @@ -79,6 +86,7 @@ initALCFunctions(ALCdevice *alcDev) } #define HAVE_ALC_DEVICE_PAUSE alc.DevicePause +#endif uint8_t EventThread::keyStates[]; Uint16 EventThread::modkeys; @@ -131,7 +139,9 @@ void EventThread::process(RGSSThreadData &rtData) SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); #endif + #ifndef USE_FMOD initALCFunctions(rtData.alcDev); + #endif // XXX this function breaks input focus on OSX #ifndef __APPLE__ @@ -399,7 +409,7 @@ void EventThread::process(RGSSThreadData &rtData) break; } - + if (event.key.keysym.scancode == SDL_SCANCODE_F3 && rtData.allowForceQuit) { // ModShot addition: force quit the game, no prompting or saving Debug() << "Force terminating ModShot"; @@ -663,8 +673,10 @@ int EventThread::eventFilter(void *data, SDL_Event *event) case SDL_APP_WILLENTERBACKGROUND : Debug() << "SDL_APP_WILLENTERBACKGROUND"; + #ifndef USE_FMOD if (HAVE_ALC_DEVICE_PAUSE) alc.DevicePause(rtData.alcDev); + #endif rtData.syncPoint.haltThreads(); @@ -681,8 +693,10 @@ int EventThread::eventFilter(void *data, SDL_Event *event) case SDL_APP_DIDENTERFOREGROUND : Debug() << "SDL_APP_DIDENTERFOREGROUND"; + #ifndef USE_FMOD if (HAVE_ALC_DEVICE_PAUSE) alc.DeviceResume(rtData.alcDev); + #endif rtData.syncPoint.resumeThreads(); diff --git a/src/thread/source/sharedstate.cpp b/src/thread/source/sharedstate.cpp index 70f15133..dfaad6c5 100644 --- a/src/thread/source/sharedstate.cpp +++ b/src/thread/source/sharedstate.cpp @@ -25,7 +25,11 @@ #include "filesystem.h" #include "graphics.h" #include "input.h" +#ifndef USE_FMOD #include "audio.h" +#else +#include +#endif #include "oneshot.h" #ifdef STEAM #include "steam.h" @@ -65,7 +69,12 @@ struct SharedStatePrivate Graphics graphics; Input input; + #ifndef USE_FMOD Audio audio; + #else + //FMOD_STUDIO_SYSTEM *studio_system; + //FMOD_SYSTEM *core_system; + #endif Oneshot oneshot; #ifdef STEAM @@ -102,7 +111,11 @@ struct SharedStatePrivate config(threadData->config), graphics(threadData), input(*threadData), + #ifndef USE_FMOD audio(*threadData), + #else + //studio_system(threadData->fmodSystem), + #endif oneshot(*threadData), _glState(threadData->config), fontState(threadData->config), @@ -133,6 +146,12 @@ struct SharedStatePrivate /* Reuse starting values */ TEXFBO::allocEmpty(gpTexFBO, globalTexW, globalTexH); TEXFBO::linkFBO(gpTexFBO); + + #ifdef USE_FMOD + //if (FMOD_Studio_System_GetCoreSystem(studio_system, &core_system) != FMOD_OK) { + // throw Exception(Exception::MKXPError, "Failed to get core fmod system"); + //} + #endif } ~SharedStatePrivate() @@ -204,7 +223,12 @@ GSATT(RGSSThreadData&, rtData) GSATT(Config&, config) GSATT(Graphics&, graphics) GSATT(Input&, input) +#ifndef USE_FMOD GSATT(Audio&, audio) +#else +//GSATT(FMOD_STUDIO_SYSTEM*, studio_system); +//GSATT(FMOD_SYSTEM*, core_system); +#endif GSATT(Oneshot&, oneshot) #ifdef STEAM GSATT(Steam&, steam) diff --git a/src/util/headers/config.h b/src/util/headers/config.h index 4042eb9b..1d3005e4 100644 --- a/src/util/headers/config.h +++ b/src/util/headers/config.h @@ -92,14 +92,10 @@ struct Config int yjitMaxVersions; bool yjitGreedyVersioning; - // This is for older versions of Ruby (3.0.* and below) - bool jitEnabled; - int jitVerbosity; - int jitMaxCache; - int jitMinCalls; - bool winConsole; + //int maxFmodChannels; + std::string iconPath; struct diff --git a/src/util/source/config.cpp b/src/util/source/config.cpp index 9f02bcac..25b334a3 100644 --- a/src/util/source/config.cpp +++ b/src/util/source/config.cpp @@ -101,15 +101,12 @@ void Config::read(int argc, char *argv[]) PO_DESC(mjitVerbosity, int, 0) \ PO_DESC(mjitMaxCache, int, 100) \ PO_DESC(mjitMinCalls, int, 10000) \ - PO_DESC(jitEnabled, bool, false) \ - PO_DESC(jitVerbosity, int, 0) \ - PO_DESC(jitMaxCache, int, 100) \ - PO_DESC(jitMinCalls, int, 10000) \ PO_DESC(yjitEnabled, bool, false) \ PO_DESC(yjitCallThreshold, int, 10) \ PO_DESC(yjitMaxVersions, int, 4) \ PO_DESC(yjitGreedyVersioning, bool, false) \ PO_DESC(winConsole, bool, false) + //PO_DESC(maxFmodChannels, int, 512) // Not gonna take your shit boost #define GUARD_ALL( exp ) try { exp } catch(...) {} @@ -198,7 +195,7 @@ void Config::read(int argc, char *argv[]) game.title = "OneShot"; game.scripts = "Data/xScripts.rxdata"; gameFolder = ".."; - + defScreenW = 640; defScreenH = 480; diff --git a/windows/Makefile b/windows/Makefile index c4bd42bf..ecd5b719 100644 --- a/windows/Makefile +++ b/windows/Makefile @@ -71,7 +71,7 @@ ruby: init_dirs $(BUILD_PREFIX)/$(RB_PREFIX)-ruby$(RUBY_DLL_VER).dll $(BUILD_PREFIX)/$(RB_PREFIX)-ruby$(RUBY_DLL_VER).dll: $(DOWNLOADS)/ruby/Makefile cd $(DOWNLOADS)/ruby; \ - make -j$(NPROC); make install + make -j$(NPROC); make install -j$(NPROC) $(DOWNLOADS)/ruby/Makefile: $(DOWNLOADS)/ruby/configure cd $(DOWNLOADS)/ruby; \ diff --git a/windows/install.sh b/windows/install.sh index 008b22fe..2dceeb9d 100644 --- a/windows/install.sh +++ b/windows/install.sh @@ -18,14 +18,11 @@ function copy_dependencies() { if [[ ${2@L} = /c/windows/* ]]; then return fi - if [[ -f "$DESTDIR/$1" ]]; then - return - fi echo "Copying $1..." [[ ! $1 =~ ^[a-zA-Z0-9+\._-]*$ ]] && fail "The library $1 has weird characters!" - cp "$2" "$DESTDIR/$1" + cp "$2" "$DESTDIR/$1" -f ldd "$2" | while read -ra line; do [[ ${line[1]} != '=>' ]] && echo ${line[*]} && fail "ldd's output isn't what this script expected!" [[ ! ${line[3]} =~ ^\(0x[0-9a-f]*\)$ ]] && echo ${line[*]} && fail "ldd's output isn't what this script expected!" diff --git a/xxd+/main.cpp b/xxd+/main.cpp deleted file mode 100644 index 4115b8f6..00000000 --- a/xxd+/main.cpp +++ /dev/null @@ -1,164 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include -#include - -static const char intro[] = - "extern const %1 %2[] = {\n"; -static const char outro[] = - "\n};\nextern const %1 %2 = %3;"; - -int writeDump(const QString &srcFilename, - const QString &dstFilename, - const QString &dataType, - const QString &lenType, - const QString &dataSymbol, - bool addNullTerm) -{ - QFile srcFile(srcFilename); - if (!srcFile.open(QFile::ReadOnly)) - return 1; - - QFile dstFile(dstFilename); - if (!dstFile.open(QFile::WriteOnly)) - return 1; - - QByteArray srcData = srcFile.readAll(); - if (addNullTerm) - srcData.append('\0'); - - QBuffer srcBuffer(&srcData); - srcBuffer.open(QBuffer::ReadOnly); - - QDataStream in(&srcBuffer); - QTextStream out(&dstFile); - - QString introStr = QString(intro).arg(dataType, dataSymbol); - out << introStr; - - const int byteColumns = 0x10; - int columnInd = 0; - int byteCount = 0; - - while (!in.atEnd()) - { - uchar byte; - in >> byte; - - out << " "; - if (columnInd == 0) - out << " "; - - out << "0x"; - if (byte < 0x10) - out << "0"; - out << QString::number(byte, 0x10); - - if (!in.atEnd()) - out << ","; - - if (++columnInd == byteColumns) - { - out << "\n"; - columnInd = 0; - } - - ++byteCount; - } - - if (addNullTerm) - --byteCount; - - QString outroStr = QString(outro).arg(lenType, dataSymbol+"_len", QString::number(byteCount)); - out << outroStr; - - return 0; -} - -QString getNamedOption(const QStringList &args, - const QString &optName, - const QString &defValue) -{ - QString value = defValue; - - if (args.contains(optName)) - { - int argInd = args.indexOf(optName); - if (argInd < args.count()) - value = args.at(argInd+1); - } - - return value; -} - -static const char usageStr[] = - "Usage: %1 file [options]\n" - "Options:\n" - " -o [filename] Override default output filename.\n" - " --symbol [sym] Override default data C symbol.\n" - " --null-terminated Add null byte to data (not reflected in \"len\").\n" - " --string Use char for data array. Implies \"--null-terminated\".\n" - " --help Yo dawg.\n"; - -void usage(const QString &argv0) -{ - QTextStream out(stdout); - - out << QString(usageStr).arg(argv0); -} - - -int main(int argc, char *argv[]) -{ - (void) argc; (void) argv; - - if (argc < 2) - { - usage(*argv); - return 0; - } - - QString inFile(argv[1]); - QFileInfo finfo(inFile); - - QStringList restArg; - for (int i = 2; i < argc; ++i) - restArg << argv[i]; - - if (restArg.contains("--help")) - { - usage(*argv); - return 0; - } - - bool nullTerm = false; - bool stringData = false; - - if (restArg.contains("--null-terminated")) - nullTerm = true; - - if (restArg.contains("--string")) - { - stringData = true; - nullTerm = true; - } - - QString outSymbol = finfo.baseName(); - outSymbol.replace(".", "_"); - - QString outFile; - - outFile = getNamedOption(restArg, "-o", finfo.fileName() + ".xxd"); - outSymbol = getNamedOption(restArg, "--symbol", outSymbol); - - QString dataType = stringData ? "char" : "unsigned char"; - - return writeDump(inFile, outFile, - dataType, "unsigned int", - outSymbol, nullTerm); -} diff --git a/xxd+/xxd+.pro b/xxd+/xxd+.pro deleted file mode 100644 index 173fbac9..00000000 --- a/xxd+/xxd+.pro +++ /dev/null @@ -1,12 +0,0 @@ -###################################################################### -# Automatically generated by qmake (2.01a) Sun Aug 18 13:46:33 2013 -###################################################################### - -TEMPLATE = app -TARGET = -DEPENDPATH += . -INCLUDEPATH += . -QT = core - -# Input -SOURCES += main.cpp