mirror of
https://github.com/open-goal/launcher.git
synced 2024-10-20 19:07:36 -04:00
Merge pull request #27 from xTVaser/v/requirements
setup: Check for minimum requirements before allowing installation
This commit is contained in:
commit
c0c14da9ec
|
@ -20,3 +20,4 @@ if (process.platform === "win32") {
|
||||||
writeFileSync(`./src-tauri/bin/extractor${extension}`, "dummy");
|
writeFileSync(`./src-tauri/bin/extractor${extension}`, "dummy");
|
||||||
writeFileSync(`./src-tauri/bin/gk${extension}`, "dummy");
|
writeFileSync(`./src-tauri/bin/gk${extension}`, "dummy");
|
||||||
writeFileSync(`./src-tauri/bin/goalc${extension}`, "dummy");
|
writeFileSync(`./src-tauri/bin/goalc${extension}`, "dummy");
|
||||||
|
writeFileSync(`./src-tauri/bin/glewinfo${extension}`, "dummy");
|
||||||
|
|
|
@ -35,6 +35,12 @@ async function main() {
|
||||||
`src-tauri/bin/goalc-${targetTriple}${extension}`
|
`src-tauri/bin/goalc-${targetTriple}${extension}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (existsSync(`src-tauri/bin/glewinfo${extension}`)) {
|
||||||
|
renameSync(
|
||||||
|
`src-tauri/bin/glewinfo${extension}`,
|
||||||
|
`src-tauri/bin/glewinfo-${targetTriple}${extension}`
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
main().catch((e) => {
|
main().catch((e) => {
|
||||||
|
|
|
@ -27,3 +27,7 @@ copyFileSync(
|
||||||
"../jak-project/out/build/Release/bin/goalc.exe",
|
"../jak-project/out/build/Release/bin/goalc.exe",
|
||||||
"./src-tauri/bin/goalc.exe"
|
"./src-tauri/bin/goalc.exe"
|
||||||
);
|
);
|
||||||
|
copyFileSync(
|
||||||
|
"./third-party/glew_2.1.0/windows/glewinfo.exe",
|
||||||
|
"./src-tauri/bin/glewinfo.exe"
|
||||||
|
);
|
||||||
|
|
30
src-tauri/src/commands.rs
Normal file
30
src-tauri/src/commands.rs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
use tauri::{command};
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Serialize)]
|
||||||
|
pub enum CommandError {
|
||||||
|
ArchitectureNotx86,
|
||||||
|
AVXNotSupported,
|
||||||
|
Unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
pub fn get_highest_simd() -> Result<String, CommandError> {
|
||||||
|
return highest_simd();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
fn highest_simd() -> Result<String, CommandError> {
|
||||||
|
if is_x86_feature_detected!("avx2") {
|
||||||
|
return Ok("AVX2".to_string());
|
||||||
|
} else if is_x86_feature_detected!("avx") {
|
||||||
|
return Ok("AVX".to_string());
|
||||||
|
} else {
|
||||||
|
return Err(CommandError::AVXNotSupported);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "x86_64"))]
|
||||||
|
fn highest_simd() -> Result<String, CommandError> {
|
||||||
|
return Err(CommandError::ArchitectureNotx86);
|
||||||
|
}
|
|
@ -5,9 +5,15 @@
|
||||||
|
|
||||||
use tauri_plugin_store::PluginBuilder;
|
use tauri_plugin_store::PluginBuilder;
|
||||||
|
|
||||||
|
mod commands;
|
||||||
|
use commands::{get_highest_simd};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
.plugin(PluginBuilder::default().build())
|
.plugin(PluginBuilder::default().build())
|
||||||
|
.invoke_handler(tauri::generate_handler![
|
||||||
|
get_highest_simd,
|
||||||
|
])
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
.expect("error while running tauri application");
|
.expect("error while running tauri application");
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
"icons/icon.ico"
|
"icons/icon.ico"
|
||||||
],
|
],
|
||||||
"resources": [],
|
"resources": [],
|
||||||
"externalBin": ["bin/extractor", "bin/gk", "bin/goalc"],
|
"externalBin": ["bin/extractor", "bin/gk", "bin/goalc", "bin/glewinfo"],
|
||||||
"copyright": "",
|
"copyright": "",
|
||||||
"category": "DeveloperTool",
|
"category": "DeveloperTool",
|
||||||
"shortDescription": "",
|
"shortDescription": "",
|
||||||
|
@ -75,6 +75,12 @@
|
||||||
"sidecar": true,
|
"sidecar": true,
|
||||||
"cmd": "ignored",
|
"cmd": "ignored",
|
||||||
"args": true
|
"args": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "bin/glewinfo",
|
||||||
|
"sidecar": true,
|
||||||
|
"cmd": "ignored",
|
||||||
|
"args": true
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -159,6 +159,7 @@ body {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
width: 90vw;
|
width: 90vw;
|
||||||
max-width: 90vw;
|
max-width: 90vw;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-center {
|
.flex-center {
|
||||||
|
@ -271,3 +272,21 @@ body {
|
||||||
details > summary:hover {
|
details > summary:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.progress-row a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #ffa500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-row a:hover {
|
||||||
|
color: #ffbd42;
|
||||||
|
}
|
||||||
|
|
||||||
|
.orange-text {
|
||||||
|
color: #ffa500;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.no-decoration {
|
||||||
|
list-style-type: none;
|
||||||
|
padding-left: 2em;
|
||||||
|
}
|
||||||
|
|
13
src/lib/commands.js
Normal file
13
src/lib/commands.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { invoke } from "@tauri-apps/api/tauri";
|
||||||
|
|
||||||
|
export async function getHighestSimd() {
|
||||||
|
try {
|
||||||
|
return await invoke("get_highest_simd");
|
||||||
|
} catch (e) {
|
||||||
|
if (e === "AVXNotSupported") {
|
||||||
|
return "noavx";
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
import { Command } from "@tauri-apps/api/shell";
|
import { Command } from "@tauri-apps/api/shell";
|
||||||
import { resourceDir } from "@tauri-apps/api/path";
|
import { resourceDir } from "@tauri-apps/api/path";
|
||||||
|
import { os } from "@tauri-apps/api";
|
||||||
|
import { getHighestSimd } from "/src/lib/commands";
|
||||||
|
|
||||||
export class InstallationStatus {
|
export class InstallationStatus {
|
||||||
static Pending = Symbol("pending");
|
static Pending = Symbol("pending");
|
||||||
|
@ -8,6 +10,13 @@ export class InstallationStatus {
|
||||||
static Success = Symbol("success");
|
static Success = Symbol("success");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class RequirementStatus {
|
||||||
|
static Unknown = Symbol("unknown");
|
||||||
|
static Met = Symbol("met");
|
||||||
|
static Failed = Symbol("failed");
|
||||||
|
static Checking = Symbol("checking");
|
||||||
|
}
|
||||||
|
|
||||||
// TODO - is this set to `production` properly in release mode?
|
// TODO - is this set to `production` properly in release mode?
|
||||||
function isInDebugMode() {
|
function isInDebugMode() {
|
||||||
return process.env.NODE_ENV === "development";
|
return process.env.NODE_ENV === "development";
|
||||||
|
@ -21,6 +30,37 @@ if (isInDebugMode()) {
|
||||||
debugPath += "\\launcher\\bundle-test\\data";
|
debugPath += "\\launcher\\bundle-test\\data";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function isAVXSupported() {
|
||||||
|
let highestSIMD = await getHighestSimd();
|
||||||
|
if (highestSIMD === undefined) {
|
||||||
|
return RequirementStatus.Unknown;
|
||||||
|
}
|
||||||
|
if (highestSIMD.toLowerCase().startsWith("avx")) {
|
||||||
|
return RequirementStatus.Met;
|
||||||
|
}
|
||||||
|
return RequirementStatus.Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function isOpenGLVersionSupported(version) {
|
||||||
|
// TODO - glewinfo not pre-compiled to work on linux yet!
|
||||||
|
if ((await os.platform()) === "darwin") {
|
||||||
|
return RequirementStatus.Unknown;
|
||||||
|
}
|
||||||
|
// Otherwise, query for the version
|
||||||
|
let command = Command.sidecar("bin/glewinfo", ["-version", version], {
|
||||||
|
cwd: "bin",
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
let output = await command.execute();
|
||||||
|
if (output.code === 0) {
|
||||||
|
return RequirementStatus.Met;
|
||||||
|
}
|
||||||
|
return RequirementStatus.Failed;
|
||||||
|
} catch {
|
||||||
|
return RequirementStatus.Failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {String} filePath
|
* @param {String} filePath
|
||||||
* @returns {Promise<ChildProcess>}
|
* @returns {Promise<ChildProcess>}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
|
import { onMount } from "svelte";
|
||||||
import { Link, navigate } from "svelte-routing";
|
import { Link, navigate } from "svelte-routing";
|
||||||
import { filePrompt } from "/src/lib/utils/file";
|
import { filePrompt } from "/src/lib/utils/file";
|
||||||
import {
|
import {
|
||||||
|
@ -6,9 +7,11 @@
|
||||||
decompileGameData,
|
decompileGameData,
|
||||||
extractISO,
|
extractISO,
|
||||||
validateGameData,
|
validateGameData,
|
||||||
|
isAVXSupported,
|
||||||
|
isOpenGLVersionSupported,
|
||||||
} from "/src/lib/setup";
|
} from "/src/lib/setup";
|
||||||
import { SupportedGame, setInstallStatus } from "/src/lib/config";
|
import { SupportedGame, setInstallStatus } from "/src/lib/config";
|
||||||
import { InstallationStatus } from "/src/lib/setup";
|
import { InstallationStatus, RequirementStatus } from "/src/lib/setup";
|
||||||
import {
|
import {
|
||||||
appendToInstallLog,
|
appendToInstallLog,
|
||||||
appendToInstallErrorLog,
|
appendToInstallErrorLog,
|
||||||
|
@ -18,6 +21,19 @@
|
||||||
let setupInProgress = false;
|
let setupInProgress = false;
|
||||||
let isoPath = undefined;
|
let isoPath = undefined;
|
||||||
|
|
||||||
|
let requirementChecks = [
|
||||||
|
{
|
||||||
|
status: RequirementStatus.Checking,
|
||||||
|
text: `CPU Supports <a href="https://en.wikipedia.org/wiki/Advanced_Vector_Extensions"><strong>AVX or AVX2</strong></a>`,
|
||||||
|
check: async () => await isAVXSupported(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: RequirementStatus.Checking,
|
||||||
|
text: `GPU Supports OpenGL <span class="orange-text"><strong>4.3</strong></span>`,
|
||||||
|
check: async () => await isOpenGLVersionSupported("4.3"),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
let currStep = 0;
|
let currStep = 0;
|
||||||
let installSteps = [
|
let installSteps = [
|
||||||
{
|
{
|
||||||
|
@ -46,18 +62,42 @@
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// TODO - move this to the enum
|
||||||
function statusIndicator(status) {
|
function statusIndicator(status) {
|
||||||
if (status === InstallationStatus.InProgress) {
|
if (
|
||||||
return `spinner`;
|
status === InstallationStatus.InProgress ||
|
||||||
} else if (status === InstallationStatus.Success) {
|
status === RequirementStatus.Checking
|
||||||
|
) {
|
||||||
|
return `<div class="loader" />`;
|
||||||
|
} else if (
|
||||||
|
status === InstallationStatus.Success ||
|
||||||
|
status === RequirementStatus.Met
|
||||||
|
) {
|
||||||
return "✅";
|
return "✅";
|
||||||
} else if (status === InstallationStatus.Failed) {
|
} else if (
|
||||||
|
status === InstallationStatus.Failed ||
|
||||||
|
status === RequirementStatus.Failed
|
||||||
|
) {
|
||||||
return "❌";
|
return "❌";
|
||||||
|
} else if (status === RequirementStatus.Unknown) {
|
||||||
|
return "⚠️";
|
||||||
} else {
|
} else {
|
||||||
return "⏳";
|
return "⏳";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function areRequirementsMet(checks) {
|
||||||
|
for (let i = 0; i < checks.length; i++) {
|
||||||
|
if (
|
||||||
|
checks[i].status !== RequirementStatus.Met &&
|
||||||
|
checks[i].status !== RequirementStatus.Unknown
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function finishStep(output) {
|
function finishStep(output) {
|
||||||
appendLogs(output);
|
appendLogs(output);
|
||||||
installSteps[currStep].status =
|
installSteps[currStep].status =
|
||||||
|
@ -72,7 +112,10 @@
|
||||||
|
|
||||||
async function appendLogs(output) {
|
async function appendLogs(output) {
|
||||||
const separator = `----${installSteps[currStep].text}----\n`;
|
const separator = `----${installSteps[currStep].text}----\n`;
|
||||||
await appendToInstallLog(SupportedGame.Jak1, "\n" + separator + output.stdout);
|
await appendToInstallLog(
|
||||||
|
SupportedGame.Jak1,
|
||||||
|
"\n" + separator + output.stdout
|
||||||
|
);
|
||||||
await appendToInstallErrorLog(
|
await appendToInstallErrorLog(
|
||||||
SupportedGame.Jak1,
|
SupportedGame.Jak1,
|
||||||
"\n" + separator + output.stderr
|
"\n" + separator + output.stderr
|
||||||
|
@ -111,6 +154,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
|
onMount(async () => {
|
||||||
|
for (let i = 0; i < requirementChecks.length; i++) {
|
||||||
|
requirementChecks[i].status = await requirementChecks[i].check();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
async function onClickBrowse() {
|
async function onClickBrowse() {
|
||||||
isoPath = await filePrompt();
|
isoPath = await filePrompt();
|
||||||
installProcess();
|
installProcess();
|
||||||
|
@ -119,9 +168,26 @@
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h1>Setup Process</h1>
|
<h1>Setup Process</h1>
|
||||||
|
<h2>Minimum Requirements</h2>
|
||||||
|
<ul class="no-decoration">
|
||||||
|
{#each requirementChecks as check}
|
||||||
|
<li>
|
||||||
|
<span class="progress-row">
|
||||||
|
{@html statusIndicator(check.status)}
|
||||||
|
{@html check.text}
|
||||||
|
</span>
|
||||||
|
{#if check.status === RequirementStatus.Unknown}
|
||||||
|
<ul class="no-decoration">
|
||||||
|
<li>Unable to determine this requirement</li>
|
||||||
|
</ul>
|
||||||
|
{/if}
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
{#if areRequirementsMet(requirementChecks)}
|
||||||
<p>Browse for your ISO - Obtained by dumping your own legitimate copy</p>
|
<p>Browse for your ISO - Obtained by dumping your own legitimate copy</p>
|
||||||
<div>
|
<div>
|
||||||
<button class="btn" on:click={onClickBrowse}>Browse for ISO</button>
|
<button class="btn" disabled={setupInProgress} on:click={onClickBrowse}>Browse for ISO</button>
|
||||||
{#if isoPath}
|
{#if isoPath}
|
||||||
{isoPath}
|
{isoPath}
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -136,15 +202,11 @@
|
||||||
{:else}
|
{:else}
|
||||||
<div>
|
<div>
|
||||||
<h2>Progress</h2>
|
<h2>Progress</h2>
|
||||||
<ul>
|
<ul class="no-decoration">
|
||||||
{#each installSteps as step}
|
{#each installSteps as step}
|
||||||
<li>
|
<li>
|
||||||
<span class="progress-row">
|
<span class="progress-row">
|
||||||
{#if step.status === InstallationStatus.InProgress}
|
{@html statusIndicator(step.status)}
|
||||||
<div class="loader" />
|
|
||||||
{:else}
|
|
||||||
{statusIndicator(step.status)}
|
|
||||||
{/if}
|
|
||||||
{step.text}
|
{step.text}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
|
@ -169,4 +231,5 @@
|
||||||
</details>
|
</details>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
73
third-party/glew_2.1.0/LICENSE
vendored
Normal file
73
third-party/glew_2.1.0/LICENSE
vendored
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
The OpenGL Extension Wrangler Library
|
||||||
|
Copyright (C) 2002-2007, Milan Ikits <milan ikits[]ieee org>
|
||||||
|
Copyright (C) 2002-2007, Marcelo E. Magallon <mmagallo[]debian org>
|
||||||
|
Copyright (C) 2002, Lev Povalahev
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
* The name of the author may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||||
|
THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
Mesa 3-D graphics library
|
||||||
|
Version: 7.0
|
||||||
|
|
||||||
|
Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included
|
||||||
|
in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (c) 2007 The Khronos Group Inc.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and/or associated documentation files (the
|
||||||
|
"Materials"), to deal in the Materials without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Materials, and to
|
||||||
|
permit persons to whom the Materials are furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included
|
||||||
|
in all copies or substantial portions of the Materials.
|
||||||
|
|
||||||
|
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
BIN
third-party/glew_2.1.0/linux/glewinfo_2.1.0
vendored
Normal file
BIN
third-party/glew_2.1.0/linux/glewinfo_2.1.0
vendored
Normal file
Binary file not shown.
BIN
third-party/glew_2.1.0/windows/glewinfo.exe
vendored
Normal file
BIN
third-party/glew_2.1.0/windows/glewinfo.exe
vendored
Normal file
Binary file not shown.
Loading…
Reference in a new issue