This commit is contained in:
2025-11-24 14:19:51 +05:30
commit f5c1412b28
6734 changed files with 1527575 additions and 0 deletions

View File

@ -0,0 +1,479 @@
/*-
* Parts of this code are copyright 2003-2005 Colin Percival
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted providing that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
/*
* This file was taken from RakNet 4.082.
* Please see licenses/RakNet license.txt for the underlying license and related copyright.
*
* Modified work: Copyright (c) 2016-2020, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
* Alternatively you are permitted to license the modifications under the Simplified BSD License.
*/
#if 0
__FBSDID("$FreeBSD: src/usr.bin/bsdiff/bspatch/bspatch.c,v 1.1 2005/08/06 01:59:06 cperciva Exp $");
#endif
#include "MemoryCompressor.h"
#include <bzlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifndef _WIN32
// KevinJ - Windows compatibility
#include <err.h>
#include <unistd.h>
#else
typedef int ssize_t;
#include <wchar.h>
#include <io.h>
#include "slikenet/linux_adapter.h"
#include "slikenet/osx_adapter.h"
#define fseeko fseek
static void err(int i, ...)
{
exit(i);
}
static void errx(int i, ...)
{
exit(i);
}
#endif
#include <fcntl.h>
#ifndef _O_BINARY
#define _O_BINARY 0
#endif
#ifndef O_BINARY
#define O_BINARY _O_BINARY
#endif
static off_t offtin(unsigned char *buf)
{
off_t y;
y=buf[7]&0x7F;
y=y*256;y+=buf[6];
y=y*256;y+=buf[5];
y=y*256;y+=buf[4];
y=y*256;y+=buf[3];
y=y*256;y+=buf[2];
y=y*256;y+=buf[1];
y=y*256;y+=buf[0];
if(buf[7]&0x80) y=-y;
return y;
}
// This function modifies the main() function included in bspatch.c of bsdiff-4.3 found at http://www.daemonology.net/bsdiff/
// It is changed to be a standalone function, to work entirely in memory, and to use my class MemoryDecompressor as an interface to BZip
// Up to the caller to deallocate new
bool ApplyPatch(char *old, unsigned int oldsize, char **_new, unsigned int *newsize, char *patch, unsigned int patchsize )
{
// FILE * f, * cpf, * dpf, * epf;
// BZFILE * cpfbz2, * dpfbz2, * epfbz2;
// int cbz2err, dbz2err, ebz2err;
// int fd;
// ssize_t oldsize,newsize;
ssize_t bzctrllen,bzdatalen;
//unsigned char header[32];
unsigned char buf[8];
// unsigned char *old, *_new;
off_t oldpos,newpos;
off_t ctrl[3];
// off_t lenread;
off_t i;
MemoryDecompressor decompress;
unsigned int coff, doff, eoff;
// if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);
/* Open patch file */
// if (fopen_s(&f, argv[3], "rb") != 0)
// err(1, "fopen(%s)", argv[3]);
/*
File format:
0 8 "BSDIFF40"
8 8 X
16 8 Y
24 8 sizeof(newfile)
32 X bzip2(control block)
32+X Y bzip2(diff block)
32+X+Y ??? bzip2(extra block)
with control block a set of triples (x,y,z) meaning "add x bytes
from oldfile to x bytes from the diff block; copy y bytes from the
extra block; seek forwards in oldfile by z bytes".
*/
/* Read header */
// if (fread(header, 1, 32, f) < 32) {
// if (feof(f))
// errx(1, "Corrupt patch\n",0);
// err(1, "fread(%s)", argv[3]);
// }
// memcpy(header, patch, 32);
/* Check for appropriate magic */
if (memcmp(patch, "BSDIFF40", 8) != 0)
// errx(1, "Corrupt patch\n",0);
return false;
/* Read lengths from header */
bzctrllen=offtin((unsigned char*)patch+8);
bzdatalen=offtin((unsigned char*)patch+16);
*newsize=offtin((unsigned char*)patch+24);
if((bzctrllen<0) || (bzdatalen<0) || (*newsize<0))
// errx(1,"Corrupt patch\n",0);
return false;
/* Close patch file and re-open it via libbzip2 at the right places */
// if (fclose(f))
// err(1, "fclose(%s)", argv[3]);
// if (fopen_s(&cpf, argv[3], "rb") != 0)
// err(1, "fopen(%s)", argv[3]);
// if (fseeko(cpf, 32, SEEK_SET))
// err(1, "fseeko(%s, %lld)", argv[3],
// (long long)32);
// if ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, cpf, 0, 0, nullptr, 0)) == nullptr)
// errx(1, "BZ2_bzReadOpen, bz2err = %d", cbz2err);
// if (fopen_s(&dpf, argv[3], "rb") != 0)
// err(1, "fopen(%s)", argv[3]);
// if (fseeko(dpf, 32 + bzctrllen, SEEK_SET))
// err(1, "fseeko(%s, %lld)", argv[3],
// (long long)(32 + bzctrllen));
// if ((dpfbz2 = BZ2_bzReadOpen(&dbz2err, dpf, 0, 0, nullptr, 0)) == nullptr)
// errx(1, "BZ2_bzReadOpen, bz2err = %d", dbz2err);
// if (fopen_s(&epf, argv[3], "rb") != 0)
// err(1, "fopen(%s)", argv[3]);
// if (fseeko(epf, 32 + bzctrllen + bzdatalen, SEEK_SET))
// err(1, "fseeko(%s, %lld)", argv[3],
// (long long)(32 + bzctrllen + bzdatalen));
// if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, nullptr, 0)) == nullptr)
// errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err);
// decompress.Decompress((char*)patch+32, patchsize-32, true);
coff=0;
if (decompress.Decompress((char*)patch+32, bzctrllen, false)==false)
return false;
doff=decompress.GetTotalOutputSize();
if (decompress.Decompress((char*)patch+32+bzctrllen, bzdatalen, false)==false)
return false;
eoff=decompress.GetTotalOutputSize();
if (decompress.Decompress((char*)patch+32+bzctrllen+bzdatalen, patchsize-(32+bzctrllen+bzdatalen), true)==false)
return false;
// if(((fd=_open(argv[1],O_RDONLY | _O_BINARY,0))<0) ||
// ((oldsize=_lseek(fd,0,SEEK_END))==-1) ||
// ((old=(unsigned char*)malloc(oldsize+1))==nullptr) ||
// (_lseek(fd,0,SEEK_SET)!=0) ||
// (_read(fd,old,oldsize)!=oldsize) ||
// (_close(fd)==-1)) err(1,"%s",argv[1]);
// if((_new=(unsigned char*)malloc(newsize+1))==nullptr) err(1,nullptr);
*_new = new char[*newsize+1];
oldpos=0;newpos=0;
while(newpos<(off_t)*newsize) {
/* Read control data */
for(i=0;i<=2;i++) {
// lenread = BZ2_bzRead(&cbz2err, cpfbz2, buf, 8);
// if ((lenread < 8) || ((cbz2err != BZ_OK) &&
// (cbz2err != BZ_STREAM_END)))
// errx(1, "Corrupt patch\n");
memcpy(buf, decompress.GetOutput()+coff, 8);
coff+=8;
ctrl[i]=offtin(buf);
};
/* Sanity-check */
if(newpos+ctrl[0]>(off_t)*newsize)
{
delete [] (*_new);
return false;
}
/* Read diff string */
//lenread = BZ2_bzRead(&dbz2err, dpfbz2, _new + newpos, ctrl[0]);
//if ((lenread < ctrl[0]) ||
// ((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END)))
// errx(1, "Corrupt patch\n");
memcpy(*_new + newpos, decompress.GetOutput()+doff, ctrl[0]);
doff+=ctrl[0];
/* Add old data to diff string */
for(i=0;i<ctrl[0];i++)
if((oldpos+i>=0) && (oldpos+i<(off_t)oldsize))
(*_new)[newpos+i]+=old[oldpos+i];
/* Adjust pointers */
newpos+=ctrl[0];
oldpos+=ctrl[0];
/* Sanity-check */
if(newpos+ctrl[1]>(off_t)*newsize)
{
delete [] (*_new);
return false;
}
/* Read extra string */
//lenread = BZ2_bzRead(&ebz2err, epfbz2, _new + newpos, ctrl[1]);
//if ((lenread < ctrl[1]) ||
// ((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END)))
// errx(1, "Corrupt patch\n");
memcpy(*_new + newpos, decompress.GetOutput()+eoff, ctrl[1]);
eoff+=ctrl[1];
/* Adjust pointers */
newpos+=ctrl[1];
oldpos+=ctrl[2];
};
/* Clean up the bzip2 reads */
// BZ2_bzReadClose(&cbz2err, cpfbz2);
// BZ2_bzReadClose(&dbz2err, dpfbz2);
// BZ2_bzReadClose(&ebz2err, epfbz2);
// if (fclose(cpf) || fclose(dpf) || fclose(epf))
// err(1, "fclose(%s)", argv[3]);
/* Write the new file */
// if(((fd=_open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0666))<0) ||
// (_write(fd,_new,newsize)!=newsize) || (_close(fd)==-1))
// err(1,"%s",argv[2]);
// free(_new);
// free(old);
return true;
}
int TestPatchInMemory(int argc,char *argv[])
{
FILE *patchFile, *newFile, *oldFile;
char *patch,*_new,*old;
unsigned patchSize, oldSize;
unsigned int newSize;
int res;
if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);
fopen_s(&patchFile, argv[3], "rb");
fopen_s(&newFile, argv[2], "wb");
fopen_s(&oldFile, argv[1], "rb");
fseeko(patchFile, 0, SEEK_END);
fseeko(oldFile, 0, SEEK_END);
patchSize=ftell(patchFile);
oldSize=ftell(oldFile);
fseeko(patchFile, 0, SEEK_SET);
fseeko(oldFile, 0, SEEK_SET);
patch = new char [patchSize];
old = new char [oldSize];
fread(patch, patchSize, 1, patchFile);
fread(old, oldSize, 1, oldFile);
// #low Should not allocate memory in ApplyPatch and then free it in the caller again
// also return value looks inconsistent
res = (ApplyPatch( old, oldSize, &_new, &newSize,patch, patchSize) ? 1 : 0);
delete[] old;
delete[] patch;
fwrite(_new, newSize, 1, newFile);
if (res == 1) {
// if res == 0, _new was already cleared in ApplyPatch
delete[] _new;
}
fclose(patchFile);
fclose(newFile);
fclose(oldFile);
return res;
}
int PATCH_main(int argc,char * argv[])
{
FILE * f, * cpf, * dpf, * epf;
BZFILE * cpfbz2, * dpfbz2, * epfbz2;
int cbz2err, dbz2err, ebz2err;
int fd;
ssize_t oldsize,newsize;
ssize_t bzctrllen,bzdatalen;
unsigned char header[32],buf[8];
unsigned char *old, *_new;
off_t oldpos,newpos;
off_t ctrl[3];
off_t lenread;
off_t i;
unsigned bytesRead=0;
if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);
/* Open patch file */
if (fopen_s(&f, argv[3], "rb") != 0)
err(1, "fopen(%s)", argv[3]);
/*
File format:
0 8 "BSDIFF40"
8 8 X
16 8 Y
24 8 sizeof(newfile)
32 X bzip2(control block)
32+X Y bzip2(diff block)
32+X+Y ??? bzip2(extra block)
with control block a set of triples (x,y,z) meaning "add x bytes
from oldfile to x bytes from the diff block; copy y bytes from the
extra block; seek forwards in oldfile by z bytes".
*/
/* Read header */
if (fread(header, 1, 32, f) < 32) {
if (feof(f))
errx(1, "Corrupt patch\n");
err(1, "fread(%s)", argv[3]);
}
/* Check for appropriate magic */
if (memcmp(header, "BSDIFF40", 8) != 0)
errx(1, "Corrupt patch\n");
/* Read lengths from header */
bzctrllen=offtin(header+8);
bzdatalen=offtin(header+16);
newsize=offtin(header+24);
if((bzctrllen<0) || (bzdatalen<0) || (newsize<0))
errx(1,"Corrupt patch\n");
/* Close patch file and re-open it via libbzip2 at the right places */
if (fclose(f))
err(1, "fclose(%s)", argv[3]);
if (fopen_s(&cpf, argv[3], "rb") != 0)
err(1, "fopen(%s)", argv[3]);
if (fseeko(cpf, 32, SEEK_SET))
err(1, "fseeko(%s, %lld)", argv[3],
(long long)32);
if ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, cpf, 0, 0, nullptr, 0)) == nullptr)
errx(1, "BZ2_bzReadOpen, bz2err = %d", cbz2err);
if (fopen_s(&dpf, argv[3], "rb") != 0)
err(1, "fopen(%s)", argv[3]);
if (fseeko(dpf, 32 + bzctrllen, SEEK_SET))
err(1, "fseeko(%s, %lld)", argv[3],
(long long)(32 + bzctrllen));
if ((dpfbz2 = BZ2_bzReadOpen(&dbz2err, dpf, 0, 0, nullptr, 0)) == nullptr)
errx(1, "BZ2_bzReadOpen, bz2err = %d", dbz2err);
if (fopen_s(&epf, argv[3], "rb") != 0)
err(1, "fopen(%s)", argv[3]);
if (fseeko(epf, 32 + bzctrllen + bzdatalen, SEEK_SET))
err(1, "fseeko(%s, %lld)", argv[3],
(long long)(32 + bzctrllen + bzdatalen));
if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, nullptr, 0)) == nullptr)
errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err);
if(((fd=_open(argv[1],O_RDONLY|O_BINARY,0))<0) ||
((oldsize=_lseek(fd,0,SEEK_END))==-1) ||
((old=(unsigned char*)malloc(oldsize+1))== nullptr) ||
(_lseek(fd,0,SEEK_SET)!=0) ||
(_read(fd,old,oldsize)!=oldsize) ||
(_close(fd)==-1)) err(1,"%s",argv[1]);
if((_new=(unsigned char*)malloc(newsize+1))== nullptr) err(1, nullptr);
oldpos=0;newpos=0;
while(newpos<newsize) {
/* Read control data */
for(i=0;i<=2;i++) {
lenread = BZ2_bzRead(&cbz2err, cpfbz2, buf, 8);
if ((lenread < 8) || ((cbz2err != BZ_OK) &&
(cbz2err != BZ_STREAM_END)))
errx(1, "Corrupt patch\n");
bytesRead+=8;
//printf("cbz2err cpfbz2 %i %i\n", 8, bytesRead);
ctrl[i]=offtin(buf);
};
/* Sanity-check */
if(newpos+ctrl[0]>newsize)
errx(1,"Corrupt patch\n");
/* Read diff string */
lenread = BZ2_bzRead(&dbz2err, dpfbz2, _new + newpos, ctrl[0]);
bytesRead+=8;
// printf("dbz2err dpfbz2 %i %i\n", ctrl[0], bytesRead);
if ((lenread < ctrl[0]) ||
((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END)))
errx(1, "Corrupt patch\n");
/* Add old data to diff string */
for(i=0;i<ctrl[0];i++)
if((oldpos+i>=0) && (oldpos+i<oldsize))
_new[newpos+i]+=old[oldpos+i];
/* Adjust pointers */
newpos+=ctrl[0];
oldpos+=ctrl[0];
/* Sanity-check */
if(newpos+ctrl[1]>newsize)
errx(1,"Corrupt patch\n");
/* Read extra string */
lenread = BZ2_bzRead(&ebz2err, epfbz2, _new + newpos, ctrl[1]);
bytesRead+=8;
// printf("ebz2err epfbz2 %i %i\n", ctrl[1], bytesRead);
if ((lenread < ctrl[1]) ||
((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END)))
errx(1, "Corrupt patch\n");
/* Adjust pointers */
newpos+=ctrl[1];
oldpos+=ctrl[2];
};
/* Clean up the bzip2 reads */
BZ2_bzReadClose(&cbz2err, cpfbz2);
BZ2_bzReadClose(&dbz2err, dpfbz2);
BZ2_bzReadClose(&ebz2err, epfbz2);
if (fclose(cpf) || fclose(dpf) || fclose(epf))
err(1, "fclose(%s)", argv[3]);
/* Write the new file */
if(((fd=_open(argv[2],O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))<0) ||
(_write(fd,_new,newsize)!=newsize) || (_close(fd)==-1))
err(1,"%s",argv[2]);
free(_new);
free(old);
return 0;
}

View File

@ -0,0 +1,8 @@
/*
* This file was taken from RakNet 4.082 without any modifications.
* Please see licenses/RakNet license.txt for the underlying license and related copyright.
*/
/// Apply \a patch to \a old. Will return the new file in \a _new which is allocated for you.
bool ApplyPatch( char *old, unsigned int oldsize, char **_new, unsigned int *newsize, char *patch, unsigned int patchsize );

View File

@ -0,0 +1,683 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "AutopatcherClient.h"
#include "slikenet/DirectoryDeltaTransfer.h"
#include "slikenet/FileList.h"
#include "slikenet/StringCompressor.h"
#include "slikenet/peerinterface.h"
#include "slikenet/FileListTransfer.h"
#include "slikenet/FileListTransferCBInterface.h"
#include "slikenet/BitStream.h"
#include "slikenet/MessageIdentifiers.h"
#include "slikenet/AutopatcherPatchContext.h"
#include "ApplyPatch.h"
#include "slikenet/FileOperations.h"
//#include "slikenet/DR_SHA1.h"
#include <stdio.h>
#include "slikenet/FileOperations.h"
#include "slikenet/assert.h"
#include "slikenet/ThreadPool.h"
#include "slikenet/linux_adapter.h"
#include "slikenet/osx_adapter.h"
using namespace SLNet;
#include "slikenet/SuperFastHash.h"
static const unsigned HASH_LENGTH=4;
#define COPY_ON_RESTART_EXTENSION ".patched.tmp"
// -----------------------------------------------------------------
PatchContext AutopatcherClientCBInterface::ApplyPatchBase(const char *oldFilePath, char **newFileContents, unsigned int *newFileSize, char *patchContents, unsigned int patchSize, uint32_t patchAlgorithm)
{
// unused parameters
(void)patchAlgorithm;
return ApplyPatchBSDiff(oldFilePath, newFileContents, newFileSize, patchContents, patchSize);
}
PatchContext AutopatcherClientCBInterface::ApplyPatchBSDiff(const char *oldFilePath, char **newFileContents, unsigned int *newFileSize, char *patchContents, unsigned int patchSize)
{
FILE *fp;
if (fopen_s(&fp, oldFilePath, "rb")!=0)
return PC_ERROR_PATCH_TARGET_MISSING;
fseek(fp, 0, SEEK_END);
unsigned int prePatchLength = ftell(fp);
fseek(fp, 0, SEEK_SET);
char *prePatchFile = (char*) rakMalloc_Ex(prePatchLength, _FILE_AND_LINE_);
fread(prePatchFile, prePatchLength, 1, fp);
fclose(fp);
bool result = ApplyPatch(prePatchFile, prePatchLength, newFileContents, newFileSize, patchContents, patchSize);
rakFree_Ex(prePatchFile, _FILE_AND_LINE_);
if (result==false)
return PC_ERROR_PATCH_APPLICATION_FAILURE;
return PC_WRITE_FILE;
}
// -----------------------------------------------------------------
struct AutopatcherClientThreadInfo
{
FileListTransferCBInterface::OnFileStruct onFileStruct;
char applicationDirectory[512];
PatchContext result;
// unsigned prePatchLength;
// char *prePatchFile;
// postPatchFile is passed in PC_NOTICE_WILL_COPY_ON_RESTART
char *postPatchFile;
unsigned postPatchLength;
AutopatcherClientCBInterface *cbInterface;
};
// -----------------------------------------------------------------
AutopatcherClientThreadInfo* AutopatcherClientWorkerThread(AutopatcherClientThreadInfo* input, bool *returnOutput, void* perThreadData)
{
// unused parameters
(void)perThreadData;
char fullPathToDir[1024];
*returnOutput=true;
strcpy_s(fullPathToDir, input->applicationDirectory);
strcat_s(fullPathToDir, input->onFileStruct.fileName);
if (input->onFileStruct.context.op==PC_WRITE_FILE)
{
if (WriteFileWithDirectories(fullPathToDir, (char*)input->onFileStruct.fileData, input->onFileStruct.byteLengthOfThisFile)==false)
{
char newDir[1024];
strcpy_s(newDir, fullPathToDir);
strcat_s(newDir, COPY_ON_RESTART_EXTENSION);
if (WriteFileWithDirectories(newDir, (char*)input->onFileStruct.fileData, input->onFileStruct.byteLengthOfThisFile))
{
input->result=PC_NOTICE_WILL_COPY_ON_RESTART;
}
else
{
input->result=PC_ERROR_FILE_WRITE_FAILURE;
}
}
else
{
input->result=(PatchContext) input->onFileStruct.context.op;
}
}
else
{
RakAssert(input->onFileStruct.context.op==PC_HASH_1_WITH_PATCH || input->onFileStruct.context.op==PC_HASH_2_WITH_PATCH);
// CSHA1 sha1;
// printf("apply patch %i bytes\n", byteLengthOfThisFile-SHA1_LENGTH);
// for (int i=0; i < byteLengthOfThisFile-SHA1_LENGTH; i++)
// printf("%i ", fileData[SHA1_LENGTH+i]);
// printf("\n");
int hashMultiplier;
if (input->onFileStruct.context.op==PC_HASH_1_WITH_PATCH)
hashMultiplier=1;
else
hashMultiplier=2; // else op==PC_HASH_2_WITH_PATCH
PatchContext result = input->cbInterface->ApplyPatchBase(fullPathToDir, &input->postPatchFile, &input->postPatchLength, (char*)input->onFileStruct.fileData+HASH_LENGTH*hashMultiplier, input->onFileStruct.byteLengthOfThisFile-HASH_LENGTH*hashMultiplier, input->onFileStruct.context.flnc_extraData2);
if (result == PC_ERROR_PATCH_APPLICATION_FAILURE || input->result==PC_ERROR_PATCH_TARGET_MISSING)
{
input->result=result;
return input;
}
unsigned int hash = SuperFastHash(input->postPatchFile, input->postPatchLength);
if (SLNet::BitStream::DoEndianSwap())
SLNet::BitStream::ReverseBytesInPlace((unsigned char*) &hash, sizeof(hash));
//if (memcmp(sha1.GetHash(), input->onFileStruct.fileData, HASH_LENGTH)!=0)
if (memcmp(&hash, input->onFileStruct.fileData+HASH_LENGTH*(hashMultiplier-1), HASH_LENGTH)!=0)
{
input->result=PC_ERROR_PATCH_RESULT_CHECKSUM_FAILURE;
}
else
{
// Write postPatchFile over the existing file
if (WriteFileWithDirectories(fullPathToDir, (char*)input->postPatchFile, input->postPatchLength)==false)
{
char newDir[1024];
strcpy_s(newDir, fullPathToDir);
strcat_s(newDir, COPY_ON_RESTART_EXTENSION);
if (WriteFileWithDirectories(newDir, (char*)input->postPatchFile, input->postPatchLength))
{
input->result=PC_NOTICE_WILL_COPY_ON_RESTART;
}
else
{
input->result=PC_ERROR_FILE_WRITE_FAILURE;
}
}
else
{
input->result=(PatchContext)input->onFileStruct.context.op;
}
}
}
return input;
}
// -----------------------------------------------------------------
namespace SLNet
{
class AutopatcherClientCallback : public FileListTransferCBInterface
{
public:
ThreadPool<AutopatcherClientThreadInfo*,AutopatcherClientThreadInfo*> threadPool;
char applicationDirectory[512];
AutopatcherClientCBInterface *onFileCallback;
AutopatcherClient *client;
bool downloadComplete;
bool canDeleteUser;
AutopatcherClientCallback(void)
{
threadPool.StartThreads(1,0);
canDeleteUser=false;
downloadComplete=false;
}
virtual ~AutopatcherClientCallback(void)
{
StopThreads();
}
void StopThreads(void)
{
threadPool.StopThreads();
RakAssert(threadPool.NumThreadsWorking()==0);
unsigned i;
AutopatcherClientThreadInfo* info;
for (i=0; i < threadPool.InputSize(); i++)
{
info = threadPool.GetInputAtIndex(i);
// if (info->prePatchFile)
// rakFree_Ex(info->prePatchFile, _FILE_AND_LINE_ );
if (info->postPatchFile)
rakFree_Ex(info->postPatchFile, _FILE_AND_LINE_ );
if (info->onFileStruct.fileData)
rakFree_Ex(info->onFileStruct.fileData, _FILE_AND_LINE_ );
SLNet::OP_DELETE(info, _FILE_AND_LINE_);
}
threadPool.ClearInput();
for (i=0; i < threadPool.OutputSize(); i++)
{
info = threadPool.GetOutputAtIndex(i);
// if (info->prePatchFile)
// rakFree_Ex(info->prePatchFile, _FILE_AND_LINE_ );
if (info->postPatchFile)
rakFree_Ex(info->postPatchFile, _FILE_AND_LINE_ );
if (info->onFileStruct.fileData)
rakFree_Ex(info->onFileStruct.fileData, _FILE_AND_LINE_ );
SLNet::OP_DELETE(info, _FILE_AND_LINE_);
}
threadPool.ClearOutput();
}
// Update is run in the user thread
virtual bool Update(void)
{
if (threadPool.HasOutputFast() && threadPool.HasOutput())
{
AutopatcherClientThreadInfo *threadInfo = threadPool.GetOutput();
// #med - add proper range-check for threadInfo->result
threadInfo->onFileStruct.context.op=static_cast<unsigned char>(threadInfo->result);
switch (threadInfo->result)
{
case PC_NOTICE_WILL_COPY_ON_RESTART:
{
client->CopyAndRestart(threadInfo->onFileStruct.fileName);
if (threadInfo->onFileStruct.context.op==PC_WRITE_FILE)
{
// Regular file in use but we can write the temporary file. Restart and copy it over the existing
onFileCallback->OnFile(&threadInfo->onFileStruct);
}
else
{
// Regular file in use but we can write the temporary file. Restart and copy it over the existing
rakFree_Ex(threadInfo->onFileStruct.fileData, _FILE_AND_LINE_ );
threadInfo->onFileStruct.fileData=threadInfo->postPatchFile;
onFileCallback->OnFile(&threadInfo->onFileStruct);
threadInfo->onFileStruct.fileData=0;
}
}
break;
case PC_ERROR_FILE_WRITE_FAILURE:
{
if (threadInfo->onFileStruct.context.op==PC_WRITE_FILE)
{
onFileCallback->OnFile(&threadInfo->onFileStruct);
}
else
{
rakFree_Ex(threadInfo->onFileStruct.fileData, _FILE_AND_LINE_ );
threadInfo->onFileStruct.fileData=threadInfo->postPatchFile;
threadInfo->onFileStruct.byteLengthOfThisFile=threadInfo->postPatchLength;
onFileCallback->OnFile(&threadInfo->onFileStruct);
threadInfo->onFileStruct.fileData=0;
}
}
break;
case PC_ERROR_PATCH_TARGET_MISSING:
{
onFileCallback->OnFile(&threadInfo->onFileStruct);
client->Redownload(threadInfo->onFileStruct.fileName);
}
break;
case PC_ERROR_PATCH_APPLICATION_FAILURE:
{
// Failure - signal class and download this file.
onFileCallback->OnFile(&threadInfo->onFileStruct);
client->Redownload(threadInfo->onFileStruct.fileName);
}
break;
case PC_ERROR_PATCH_RESULT_CHECKSUM_FAILURE:
{
// Failure - signal class and download this file.
onFileCallback->OnFile(&threadInfo->onFileStruct);
client->Redownload(threadInfo->onFileStruct.fileName);
}
break;
default:
{
if (threadInfo->onFileStruct.context.op==PC_WRITE_FILE)
{
onFileCallback->OnFile(&threadInfo->onFileStruct);
}
else
{
rakFree_Ex(threadInfo->onFileStruct.fileData, _FILE_AND_LINE_ );
threadInfo->onFileStruct.fileData=threadInfo->postPatchFile;
onFileCallback->OnFile(&threadInfo->onFileStruct);
threadInfo->onFileStruct.fileData=0;
}
}
break;
}
// if (threadInfo->prePatchFile)
// rakFree_Ex(threadInfo->prePatchFile, _FILE_AND_LINE_ );
if (threadInfo->postPatchFile)
rakFree_Ex(threadInfo->postPatchFile, _FILE_AND_LINE_ );
if (threadInfo->onFileStruct.fileData)
rakFree_Ex(threadInfo->onFileStruct.fileData, _FILE_AND_LINE_ );
SLNet::OP_DELETE(threadInfo, _FILE_AND_LINE_);
}
// If both input and output are empty, we are done.
if (onFileCallback->Update()==false)
canDeleteUser=true;
if ( downloadComplete &&
canDeleteUser &&
threadPool.IsWorking()==false)
{
// Stop threads before calling OnThreadCompletion, in case the other thread starts a new instance of this thread.
StopThreads();
client->OnThreadCompletion();
return false;
}
return true;
}
virtual bool OnDownloadComplete(DownloadCompleteStruct *dcs)
{
downloadComplete=true;
if (onFileCallback->OnDownloadComplete(dcs)==false)
{
canDeleteUser=true;
}
return true;
};
virtual void OnDereference(void)
{
onFileCallback->OnDereference();
StopThreads();
}
virtual bool OnFile(OnFileStruct *onFileStruct)
{
AutopatcherClientThreadInfo *inStruct = SLNet::OP_NEW<AutopatcherClientThreadInfo>( _FILE_AND_LINE_ );
memset(inStruct,0,sizeof(AutopatcherClientThreadInfo));
// inStruct->prePatchFile=0;
inStruct->postPatchFile=0;
inStruct->cbInterface=onFileCallback;
memcpy(&(inStruct->onFileStruct), onFileStruct, sizeof(OnFileStruct));
strcpy_s(inStruct->applicationDirectory,applicationDirectory);
if (onFileStruct->context.op==PC_HASH_1_WITH_PATCH || onFileStruct->context.op==PC_HASH_2_WITH_PATCH)
onFileStruct->context.op=PC_NOTICE_FILE_DOWNLOADED_PATCH;
else
onFileStruct->context.op=PC_NOTICE_FILE_DOWNLOADED;
onFileCallback->OnFile(onFileStruct);
threadPool.AddInput(AutopatcherClientWorkerThread, inStruct);
// Return false means don't delete OnFileStruct::data
return false;
}
virtual void OnFileProgress(FileProgressStruct *fps)
{
char fullPathToDir[1024];
if (fps->onFileStruct->fileName)
{
strcpy_s(fullPathToDir, applicationDirectory);
strcat_s(fullPathToDir, fps->onFileStruct->fileName);
onFileCallback->OnFileProgress(fps);
}
}
};
}
AutopatcherClient::AutopatcherClient()
{
serverId=UNASSIGNED_SYSTEM_ADDRESS;
// #med - use unsigned short max?
serverIdIndex=static_cast<unsigned short>(-1);
applicationDirectory[0]=0;
fileListTransfer=0;
priority=HIGH_PRIORITY;
orderingChannel=0;
serverDate=0;
userCB=0;
processThreadCompletion=false;
}
AutopatcherClient::~AutopatcherClient()
{
Clear();
}
void AutopatcherClient::Clear(void)
{
if (fileListTransfer)
fileListTransfer->RemoveReceiver(serverId);
serverId=UNASSIGNED_SYSTEM_ADDRESS;
setId=(unsigned short)-1;
redownloadList.Clear();
copyAndRestartList.Clear();
}
void AutopatcherClient::SetUploadSendParameters(PacketPriority _priority, char _orderingChannel)
{
priority=_priority;
orderingChannel=_orderingChannel;
}
void AutopatcherClient::SetFileListTransferPlugin(FileListTransfer *flt)
{
fileListTransfer=flt;
}
double AutopatcherClient::GetServerDate(void) const
{
return serverDate;
}
void AutopatcherClient::CancelDownload(void)
{
fileListTransfer->CancelReceive(setId);
Clear();
}
void AutopatcherClient::OnThreadCompletion(void)
{
processThreadCompletionMutex.Lock();
processThreadCompletion=true;
processThreadCompletionMutex.Unlock();
}
bool AutopatcherClient::IsPatching(void) const
{
return fileListTransfer->IsHandlerActive(setId);
}
bool AutopatcherClient::PatchApplication(const char *_applicationName, const char *_applicationDirectory, double lastUpdateDate, SystemAddress host, AutopatcherClientCBInterface *onFileCallback, const char *restartOutputFilename, const char *pathToRestartExe)
{
RakAssert(applicationName);
RakAssert(applicationDirectory);
RakAssert(pathToRestartExe);
RakAssert(restartOutputFilename);
// if (rakPeerInterface->GetIndexFromSystemAddress(host)==-1)
// return false;
if (IsPatching())
return false; // Already in the middle of patching.
strcpy_s(applicationDirectory, _applicationDirectory);
FileList::FixEndingSlash(applicationDirectory, 512);
strcpy_s(applicationName, _applicationName);
serverId=host;
patchComplete=false;
userCB=onFileCallback;
strcpy_s(copyOnRestartOut, restartOutputFilename);
strcpy_s(restartExe, pathToRestartExe);
processThreadCompletionMutex.Lock();
processThreadCompletion=false;
processThreadCompletionMutex.Unlock();
SLNet::BitStream outBitStream;
outBitStream.Write((unsigned char)ID_AUTOPATCHER_GET_CHANGELIST_SINCE_DATE);
StringCompressor::Instance()->EncodeString(applicationName, 512, &outBitStream);
outBitStream.Write(lastUpdateDate);
SendUnified(&outBitStream, priority, RELIABLE_ORDERED, orderingChannel, host, false);
return true;
}
void AutopatcherClient::Update(void)
{
processThreadCompletionMutex.Lock();
if (processThreadCompletion)
{
processThreadCompletion=false;
processThreadCompletionMutex.Unlock();
fileListTransfer->RemoveReceiver(serverId);
// If redownload list, process it
if (redownloadList.fileList.Size())
{
SLNet::BitStream outBitStream;
AutopatcherClientCallback *transferCallback;
transferCallback = SLNet::OP_NEW<AutopatcherClientCallback>( _FILE_AND_LINE_ );
strcpy_s(transferCallback->applicationDirectory, applicationDirectory);
transferCallback->onFileCallback=userCB;
transferCallback->client=this;
setId = fileListTransfer->SetupReceive(transferCallback, true, serverId);
// Ask for patches for the files in the list that are different from what we have.
outBitStream.Write((unsigned char)ID_AUTOPATCHER_GET_PATCH);
outBitStream.Write(setId);
double lastUpdateData=0;
outBitStream.Write(lastUpdateData);
StringCompressor::Instance()->EncodeString(applicationName, 512, &outBitStream);
redownloadList.Serialize(&outBitStream);
SendUnified(&outBitStream, priority, RELIABLE_ORDERED, orderingChannel, serverId, false);
redownloadList.Clear();
}
else if (copyAndRestartList.fileList.Size())
{
Packet *p = AllocatePacketUnified(1);
p->bitSize=p->length*8;
p->data[0]=ID_AUTOPATCHER_RESTART_APPLICATION;
p->systemAddress=serverId;
p->systemAddress.systemIndex=serverIdIndex;
PushBackPacketUnified(p,false);
FILE *fp;
errno_t error = fopen_s(&fp, copyOnRestartOut, "wt");
RakAssert(error == 0);
if (error == 0)
{
fprintf(fp, "#Sleep 1000\n");
unsigned i;
for (i=0; i < copyAndRestartList.fileList.Size(); i++)
{
#ifdef _WIN32
fprintf(fp, "del /q \"%s%s\"\n", applicationDirectory, copyAndRestartList.fileList[i].filename.C_String());
RakString sourceFn = copyAndRestartList.fileList[i].filename;
RakString bareFilename = sourceFn;
bareFilename.StartAfterLastCharacter('/');
fprintf(fp, "rename \"%s%s%s\" \"%s\"\n", applicationDirectory, bareFilename.C_String(), COPY_ON_RESTART_EXTENSION, copyAndRestartList.fileList[i].filename.C_String());
#else
fprintf(fp, "rm -f \"%s%s\"\n", applicationDirectory, copyAndRestartList.fileList[i].filename.C_String());
fprintf(fp, "mv \"%s%s%s\" \"%s\"\n", applicationDirectory, copyAndRestartList.fileList[i].filename.C_String(), COPY_ON_RESTART_EXTENSION, copyAndRestartList.fileList[i].filename.C_String());
#endif
}
#ifdef _WIN32
fprintf(fp, "#CreateProcess \"%s\"\n", restartExe);
#else
fprintf(fp, "chmod +x \"%s\"\n", restartExe);
fprintf(fp, "#CreateProcess \"%s\" &\n", restartExe);
#endif
fprintf(fp, "#DeleteThisFile\n");
fclose(fp);
}
}
else
{
Packet *p = AllocatePacketUnified(1);
p->bitSize=p->length*8;
p->data[0]=ID_AUTOPATCHER_FINISHED;
p->systemAddress=serverId;
p->systemAddress.systemIndex=serverIdIndex;
PushBackPacketUnified(p,false);
}
}
else
{
processThreadCompletionMutex.Unlock();
}
}
void AutopatcherClient::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
{
// unused parameters
(void)rakNetGUID;
(void)lostConnectionReason;
if (systemAddress==serverId)
Clear();
}
PluginReceiveResult AutopatcherClient::OnReceive(Packet *packet)
{
switch (packet->data[0])
{
case ID_AUTOPATCHER_CREATION_LIST:
return OnCreationList(packet);
case ID_AUTOPATCHER_DELETION_LIST:
OnDeletionList(packet);
return RR_STOP_PROCESSING_AND_DEALLOCATE;
case ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR:
case ID_AUTOPATCHER_CANNOT_DOWNLOAD_ORIGINAL_UNMODIFIED_FILES:
fileListTransfer->RemoveReceiver(serverId);
Clear();
return RR_CONTINUE_PROCESSING;
case ID_AUTOPATCHER_FINISHED_INTERNAL:
return OnDownloadFinishedInternal(packet);
case ID_AUTOPATCHER_FINISHED:
return OnDownloadFinished(packet);
}
return RR_CONTINUE_PROCESSING;
}
void AutopatcherClient::OnShutdown(void)
{
// TODO
}
PluginReceiveResult AutopatcherClient::OnCreationList(Packet *packet)
{
RakAssert(fileListTransfer);
if (packet->systemAddress!=serverId)
return RR_STOP_PROCESSING_AND_DEALLOCATE;
SLNet::BitStream inBitStream(packet->data, packet->length, false);
SLNet::BitStream outBitStream;
FileList remoteFileList, missingOrChanged;
inBitStream.IgnoreBits(8);
if (remoteFileList.Deserialize(&inBitStream)==false)
return RR_STOP_PROCESSING_AND_DEALLOCATE;
inBitStream.Read(serverDate);
double patchApplicationLastUpdateDate;
inBitStream.Read(patchApplicationLastUpdateDate);
// Go through the list of hashes. For each file we already have, remove it from the list.
remoteFileList.ListMissingOrChangedFiles(applicationDirectory, &missingOrChanged, true, false);
if (missingOrChanged.fileList.Size()==0)
{
packet->data[0]=ID_AUTOPATCHER_FINISHED;
return RR_CONTINUE_PROCESSING; // Pass to user
}
// Prepare the transfer plugin to get a file list.
AutopatcherClientCallback *transferCallback;
transferCallback = SLNet::OP_NEW<AutopatcherClientCallback>( _FILE_AND_LINE_ );
strcpy_s(transferCallback->applicationDirectory, applicationDirectory);
transferCallback->onFileCallback=userCB;
transferCallback->client=this;
setId = fileListTransfer->SetupReceive(transferCallback, true, packet->systemAddress);
// Ask for patches for the files in the list that are different from what we have.
outBitStream.Write((unsigned char)ID_AUTOPATCHER_GET_PATCH);
outBitStream.Write(setId);
outBitStream.Write(patchApplicationLastUpdateDate);
StringCompressor::Instance()->EncodeString(applicationName, 512, &outBitStream);
missingOrChanged.Serialize(&outBitStream);
SendUnified(&outBitStream, priority, RELIABLE_ORDERED, orderingChannel, packet->systemAddress, false);
return RR_STOP_PROCESSING_AND_DEALLOCATE; // Absorb this message
}
void AutopatcherClient::OnDeletionList(Packet *packet)
{
if (packet->systemAddress!=serverId)
return;
SLNet::BitStream inBitStream(packet->data, packet->length, false);
SLNet::BitStream outBitStream;
inBitStream.IgnoreBits(8);
FileList fileList;
if (fileList.Deserialize(&inBitStream)==false)
return;
fileList.DeleteFiles(applicationDirectory);
}
PluginReceiveResult AutopatcherClient::OnDownloadFinished(Packet *packet)
{
SLNet::BitStream inBitStream(packet->data, packet->length, false);
inBitStream.IgnoreBits(8);
// This may have been created internally, with no serverDate written (line 469 or so)
if (inBitStream.GetNumberOfUnreadBits()>7)
{
inBitStream.Read(serverDate);
}
serverId=packet->systemAddress;
serverIdIndex=packet->systemAddress.systemIndex;
return RR_CONTINUE_PROCESSING;
}
PluginReceiveResult AutopatcherClient::OnDownloadFinishedInternal(Packet *packet)
{
SLNet::BitStream inBitStream(packet->data, packet->length, false);
inBitStream.IgnoreBits(8);
serverId=packet->systemAddress;
serverIdIndex=packet->systemAddress.systemIndex;
inBitStream.Read(serverDate);
return RR_STOP_PROCESSING_AND_DEALLOCATE;
}
void AutopatcherClient::CopyAndRestart(const char *filePath)
{
// We weren't able to write applicationDirectory + filePath so we wrote applicationDirectory + filePath + COPY_ON_RESTART_EXTENSION instead
copyAndRestartList.AddFile(filePath,filePath, 0, 0, 0, FileListNodeContext(0,0,0,0));
}
void AutopatcherClient::Redownload(const char *filePath)
{
redownloadList.AddFile(filePath,filePath, 0, 0, 0, FileListNodeContext(0,0,0,0));
}

View File

@ -0,0 +1,131 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
/// \file
/// \brief Client plugin for the autopatcher
#ifndef __AUTOPATCHER_CLIENT_H
#define __AUTOPATCHER_CLIENT_H
#include "slikenet/types.h"
#include "slikenet/Export.h"
#include "slikenet/PluginInterface2.h"
#include "slikenet/PacketPriority.h"
#include "slikenet/FileList.h"
#include "slikenet/SimpleMutex.h"
#include "slikenet/FileListTransferCBInterface.h"
#include "slikenet/AutopatcherPatchContext.h"
namespace SLNet
{
class RakPeerInterface;
struct Packet;
class FileListTransfer;
class RAK_DLL_EXPORT AutopatcherClientCBInterface : public FileListTransferCBInterface
{
public:
virtual PatchContext ApplyPatchBSDiff(const char *oldFilePath, char **newFileContents, unsigned int *newFileSize, char *patchContents, unsigned int patchSize);
virtual PatchContext ApplyPatchBase(const char *oldFilePath, char **newFileContents, unsigned int *newFileSize, char *patchContents, unsigned int patchSize, uint32_t patchAlgorithm);
};
/// \ingroup Autopatcher
class RAK_DLL_EXPORT AutopatcherClient : public PluginInterface2
{
public:
// Constructor
AutopatcherClient();
// Destructor
~AutopatcherClient();
/// Are we in the middle of patching?
/// \return True if yes, false otherwise.
bool IsPatching(void) const;
/// What parameters to use for the RakPeerInterface::Send() call when uploading files.
/// \param[in] _priority See RakPeerInterface::Send()
/// \param[in] _orderingChannel See RakPeerInterface::Send()
void SetUploadSendParameters(PacketPriority _priority, char _orderingChannel);
/// This plugin has a dependency on the FileListTransfer plugin, which it uses to actually send the files.
/// So you need an instance of that plugin registered with RakPeerInterface, and a pointer to that interface should be passed here.
/// \param[in] flt A pointer to a registered instance of FileListTransfer
void SetFileListTransferPlugin(FileListTransfer *flt);
/// Patches a certain directory associated with a named application to match the same named application on the patch server
/// \param[in] _applicationName The name of the application
/// \param[in] _applicationDirectory The directory to write the output to.
/// \param[in] lastUpdateDate Returned by time() (seconds since EPOCH) on the server, as well as returned in GetServerDate() after you call PatchApplication successfully. When distributing your application, set to the server time() when the distribution was created. You can pass 0 as well, however this will do a full scan of the entire game so is very slow. See 'Optimizing for large games' in the manual under Help/autopatcher.html
/// \param[in] host The address of the remote system to send the message to.
/// \param[in] onFileCallback Callback to call per-file (optional). When fileIndex+1==setCount in the callback then the download is done
/// \param[in] _restartOutputFilename If it is necessary to restart this application, where to write the restart data to. You can include a path in this filename.
/// \param[in] pathToRestartExe What exe to launch from the AutopatcherClientRestarter . argv[0] will work to relaunch this application.
/// \return true on success, false on failure. On failure, ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR is returned, with the error message written using the stringCompressor class starting after the message id.
bool PatchApplication(const char *_applicationName, const char *_applicationDirectory, double lastUpdateDate, SystemAddress host, AutopatcherClientCBInterface *onFileCallback, const char *restartOutputFilename, const char *pathToRestartExe);
/// After getting ID_AUTOPATCHER_FINISHED or ID_AUTOPATCHER_RESTART_APPLICATION, the server date will be internally recorded. You can send this to PatchApplication::lastUpdateDate to only check for files newer than that date.
double GetServerDate(void) const;
/// Stop processing the current download
/// \note The files in progress will continue to transfer. The only way to stop it is to call CloseConnection(true), then reconnect to the server once you get ID_DISCONNECTION_NOTIFICATION
void CancelDownload(void);
/// Free internal memory.
void Clear(void);
/// \internal For plugin handling
virtual void Update(void);
/// \internal For plugin handling
virtual PluginReceiveResult OnReceive(Packet *packet);
void OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason );
/// \internal For plugin handling
virtual void OnShutdown(void);
void OnThreadCompletion(void);
protected:
PluginReceiveResult OnCreationList(Packet *packet);
void OnDeletionList(Packet *packet);
PluginReceiveResult OnDownloadFinishedInternal(Packet *packet);
PluginReceiveResult OnDownloadFinished(Packet *packet);
friend class AutopatcherClientCallback;
void CopyAndRestart(const char *filePath);
void Redownload(const char *filePath);
char applicationDirectory[512];
char applicationName[512];
char copyOnRestartOut[512];
char restartExe[512];
double serverDate;
FileListTransfer *fileListTransfer;
PacketPriority priority;
SystemAddress serverId;
SystemIndex serverIdIndex;
char orderingChannel;
unsigned short setId;
AutopatcherClientCBInterface *userCB;
bool patchComplete;
FileList redownloadList, copyAndRestartList;
bool processThreadCompletion;
SimpleMutex processThreadCompletionMutex;
};
} // namespace SLNet
#endif

View File

@ -0,0 +1,844 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2016-2018, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "slikenet/string.h"
#include "AutopatcherMySQLRepository.h"
#include "slikenet/AutopatcherPatchContext.h"
#include "slikenet/FileList.h"
#include "slikenet/assert.h"
#include "slikenet/DS_List.h"
// ntohl
#ifdef _WIN32
#include <Winsock2.h>
#else
#include <netinet/in.h>
#endif
// If you get fatal error C1083: Cannot open include file: 'mysql.h' then you need to install MySQL. See readme.txt in this sample directory.
#include "mysql.h"
#include "CreatePatch.h"
#include "slikenet/AutopatcherPatchContext.h"
// #include "slikenet/DR_SHA1.h"
#include <stdlib.h>
#include "slikenet/LinuxStrings.h"
#include "slikenet/linux_adapter.h"
#include "slikenet/osx_adapter.h"
using namespace SLNet;
static const unsigned HASH_LENGTH=sizeof(unsigned int);
struct FileInfo
{
SLNet::RakString filename;
char contentHash [HASH_LENGTH];
bool createFile;
};
// alloca
#ifdef _COMPATIBILITY_1
#elif defined(_WIN32)
#include <malloc.h>
#else
//#include <stdlib.h>
#endif
#define PQEXECPARAM_FORMAT_TEXT 0
#define PQEXECPARAM_FORMAT_BINARY 1
AutopatcherMySQLRepository::AutopatcherMySQLRepository()
{
filePartConnection=0;
}
AutopatcherMySQLRepository::~AutopatcherMySQLRepository()
{
if (filePartConnection)
mysql_close(filePartConnection);
}
bool AutopatcherMySQLRepository::CreateAutopatcherTables(void)
{
if (!IsConnected())
return false;
//sqlCommandMutex.Lock();
ExecuteBlockingCommand("BEGIN;");
if (!ExecuteBlockingCommand(
"CREATE TABLE Applications ("
"applicationID INT AUTO_INCREMENT,"
"applicationName VARCHAR(255) NOT NULL UNIQUE,"
"changeSetID integer NOT NULL DEFAULT 0,"
"userName TEXT NOT NULL,"
"PRIMARY KEY (applicationID));"
)) {Rollback(); return false;}
if (!ExecuteBlockingCommand(
"CREATE TABLE FileVersionHistory ("
"fileID INT AUTO_INCREMENT,"
"applicationID INT NOT NULL, "
"filename VARCHAR(255) NOT NULL,"
"fileLength INT,"
"content LONGBLOB,"
"contentHash TINYBLOB,"
"patch LONGBLOB,"
"createFile TINYINT NOT NULL,"
"modificationDate double precision DEFAULT (EXTRACT(EPOCH FROM now())),"
"lastSentDate double precision,"
"timesSent INT NOT NULL DEFAULT 0,"
"changeSetID INT NOT NULL,"
"userName TEXT NOT NULL,"
"PRIMARY KEY (fileID)); "
)) {Rollback(); return false;}
if (!ExecuteBlockingCommand(
"CREATE INDEX FV_appID on FileVersionHistory(applicationID);"
)) {Rollback(); return false;}
if (!ExecuteBlockingCommand(
"CREATE INDEX FV_fname on FileVersionHistory(filename);"
)) {Rollback(); return false;}
if (!ExecuteBlockingCommand(
"CREATE VIEW AutoPatcherView AS SELECT "
"FileVersionHistory.applicationid,"
"Applications.applicationName,"
"FileVersionHistory.fileID,"
"FileVersionHistory.fileName,"
"FileVersionHistory.createFile,"
"FileVersionHistory.fileLength,"
"FileVersionHistory.changeSetID,"
"FileVersionHistory.lastSentDate,"
"FileVersionHistory.modificationDate,"
"FileVersionHistory.timesSent "
"FROM (FileVersionHistory JOIN Applications ON "
"( FileVersionHistory.applicationID = Applications.applicationID )) "
"ORDER BY Applications.applicationID ASC, FileVersionHistory.fileID ASC;"
)) {Rollback(); return false;}
bool b = ExecuteBlockingCommand("COMMIT;");
//sqlCommandMutex.Unlock();
return b;
}
bool AutopatcherMySQLRepository::DestroyAutopatcherTables(void)
{
if (!IsConnected())
return false;
//sqlCommandMutex.Lock();
ExecuteBlockingCommand("DROP INDEX FV_appID;");
ExecuteBlockingCommand("DROP INDEX FV_fname;");
ExecuteBlockingCommand("DROP TABLE Applications CASCADE;");
ExecuteBlockingCommand("DROP TABLE FileVersionHistory CASCADE;");
bool b = ExecuteBlockingCommand("DROP VIEW AutoPatcherView;");
//sqlCommandMutex.Unlock();
return b;
}
bool AutopatcherMySQLRepository::AddApplication(const char *applicationName, const char *userName)
{
// mysql_real_escape_string
char query[512];
sprintf_s(query, "INSERT INTO Applications (applicationName, userName) VALUES ('%s', '%s');", GetEscapedString(applicationName).C_String(), GetEscapedString(userName).C_String());
//sqlCommandMutex.Lock();
bool b = ExecuteBlockingCommand(query);
//sqlCommandMutex.Unlock();
return b;
}
bool AutopatcherMySQLRepository::RemoveApplication(const char *applicationName)
{
char query[512];
sprintf_s(query, "DELETE FROM Applications WHERE applicationName='%s';", GetEscapedString(applicationName).C_String());
//sqlCommandMutex.Lock();
bool b = ExecuteBlockingCommand(query);
//sqlCommandMutex.Unlock();
return b;
}
bool AutopatcherMySQLRepository::GetChangelistSinceDate(const char *applicationName, FileList *addedOrModifiedFilesWithHashData, FileList *deletedFiles, double sinceDate)
{
char query[512];
SLNet::RakString escapedApplicationName = GetEscapedString(applicationName);
sprintf_s(query, "SELECT applicationID FROM Applications WHERE applicationName='%s';", escapedApplicationName.C_String());
int applicationID;
//sqlCommandMutex.Lock();
if (!ExecuteQueryReadInt(query, &applicationID))
{
// This message covers the lost connection to the SQL server
//sqlCommandMutex.Unlock();
//sprintf_s(lastError,"ERROR: %s not found in UpdateApplicationFiles\n",escapedApplicationName.C_String());
return false;
}
//sqlCommandMutex.Unlock();
if (sinceDate!=0)
sprintf_s(query,
"SELECT filename, fileLength, contentHash, createFile, fileId FROM FileVersionHistory "
"JOIN (SELECT max(fileId) maxId FROM FileVersionHistory WHERE applicationId=%i AND modificationDate > %f GROUP BY fileName) MaxId "
"ON FileVersionHistory.fileId = MaxId.maxId "
"ORDER BY filename DESC;", applicationID,sinceDate);
else
sprintf_s(query,
"SELECT filename, fileLength, contentHash, createFile, fileId FROM FileVersionHistory "
"JOIN (SELECT max(fileId) maxId FROM FileVersionHistory WHERE applicationId=%i GROUP BY fileName) MaxId "
"ON FileVersionHistory.fileId = MaxId.maxId "
"ORDER BY filename DESC;", applicationID);
MYSQL_RES * result = 0;
//sqlCommandMutex.Lock();
if (!ExecuteBlockingCommand (query, &result))
{
//sqlCommandMutex.Unlock();
return false;
}
//sqlCommandMutex.Unlock();
MYSQL_ROW row;
while ((row = mysql_fetch_row (result)) != 0)
{
const char * createFileResult = row [3];
const char * hardDriveFilename = row [0];
if (createFileResult[0]=='1')
{
const char * hardDriveHash = row [2];
int fileLength = atoi (row [1]);
addedOrModifiedFilesWithHashData->AddFile(hardDriveFilename, hardDriveFilename, hardDriveHash, HASH_LENGTH, fileLength, FileListNodeContext(), false);
}
else
{
deletedFiles->AddFile(hardDriveFilename,hardDriveFilename,0,0,0,FileListNodeContext(), false);
}
}
mysql_free_result (result);
return true;
}
int AutopatcherMySQLRepository::GetPatches(const char *applicationName, FileList *input, bool allowDownloadOfOriginalUnmodifiedFiles, FileList *patchList)
{
char query[512];
SLNet::RakString escapedApplicationName = GetEscapedString(applicationName);
sprintf_s(query, "SELECT applicationID FROM Applications WHERE applicationName='%s';", escapedApplicationName.C_String());
int applicationID;
//sqlCommandMutex.Lock();
if (!ExecuteQueryReadInt (query, &applicationID))
{
//sqlCommandMutex.Unlock();
sprintf_s(lastError,"ERROR: %s not found in GetPatches\n",applicationName);
return false;
}
//sqlCommandMutex.Unlock();
// Go through the input list.
for (unsigned inputIndex=0; inputIndex < input->fileList.Size(); inputIndex++)
{
const char * userHash=input->fileList[inputIndex].data;
const char * userFilename=input->fileList[inputIndex].filename;
char *fn = new char [(strlen(userFilename))*2+1];
mysql_real_escape_string(mySqlConnection, fn, userFilename, (unsigned long) strlen(userFilename));
if (userHash==0)
{
// If the user does not have a hash in the input list, get the contents of latest version of this named file and write it to the patch list
// sprintf_s(query, "SELECT content FROM FileVersionHistory "
// "JOIN (SELECT max(fileId) maxId FROM FileVersionHistory WHERE applicationId=%i AND filename='%s') MaxId "
// "ON FileVersionHistory.fileId = MaxId.maxId",
// applicationID, fn);
sprintf_s(query, "SELECT fileId, fileLength, changeSetID FROM FileVersionHistory "
"JOIN (SELECT max(fileId) maxId FROM FileVersionHistory WHERE applicationId=%i AND filename='%s') MaxId "
"ON FileVersionHistory.fileId = MaxId.maxId",
applicationID, fn);
MYSQL_RES * result = 0;
//sqlCommandMutex.Lock();
if (!ExecuteBlockingCommand (query, &result))
{
//sqlCommandMutex.Unlock();
delete [] fn;
return false;
}
//sqlCommandMutex.Unlock();
MYSQL_ROW row = mysql_fetch_row (result);
if (row != 0)
{
//const char * content = row [0];
//unsigned long contentLength=mysql_fetch_lengths (result) [0];
//patchList->AddFile(userFilename, content, contentLength, contentLength, FileListNodeContext(PC_WRITE_FILE,0));
const int fileId = atoi (row [0]);
const int fileLength = atoi (row [1]);
const int changeSetID = atoi (row [2]);
if (allowDownloadOfOriginalUnmodifiedFiles==false && changeSetID==0)
{
printf("Failure: allowDownloadOfOriginalUnmodifiedFiles==false for %s length %i\n", userFilename, fileLength);
mysql_free_result(result);
return false;
}
patchList->AddFile(userFilename,userFilename, 0, fileLength, fileLength, FileListNodeContext(PC_WRITE_FILE,fileId,0,0), true);
}
mysql_free_result(result);
}
else // Assuming the user does have a hash.
{
if (input->fileList[inputIndex].dataLengthBytes!=HASH_LENGTH)
{
delete [] fn;
return false;
}
// Get the hash and ID of the latest version of this file, by filename.
sprintf_s(query,
"SELECT contentHash, fileId, fileLength FROM FileVersionHistory "
"JOIN (SELECT max(fileId) maxId FROM FileVersionHistory WHERE applicationId=%i AND filename='%s') MaxId "
"ON FileVersionHistory.fileId = MaxId.maxId",
applicationID, fn);
MYSQL_RES * result = 0;
//sqlCommandMutex.Lock();
if (!ExecuteBlockingCommand (query, &result))
{
//sqlCommandMutex.Unlock();
delete [] fn;
return false;
}
//sqlCommandMutex.Unlock();
MYSQL_ROW row = mysql_fetch_row (result);
if (row != 0)
{
const char * contentHash = row [0];
const int fileId = atoi (row [1]);
const int fileLength = atoi (row [2]); // double check if this works
if (memcmp(contentHash, userHash, HASH_LENGTH)!=0)
{
char buf [2 * HASH_LENGTH + 1];
mysql_real_escape_string(mySqlConnection, buf, userHash, HASH_LENGTH);
sprintf_s(query, "SELECT patch FROM FileVersionHistory WHERE applicationId=%i AND filename='%s' AND contentHash='%s'; ", applicationID, fn, buf);
MYSQL_RES * patchResult = 0;
//sqlCommandMutex.Lock();
if (!ExecuteBlockingCommand (query, &patchResult))
{
//sqlCommandMutex.Unlock();
delete [] fn;
return false;
}
//sqlCommandMutex.Unlock();
row = mysql_fetch_row (patchResult);
if (row==0)
{
// If no patch found, then this is a non-release version, or a very old version we are no longer tracking.
// Get the contents of latest version of this named file by fileId and return it.
/*
sprintf_s(query, "SELECT content FROM FileVersionHistory WHERE fileId=%d;", fileId);
if (mysql_query (mySqlConnection, query) != 0)
{
delete [] fn;
strcpy (lastError, mysql_error (mySqlConnection));
return false;
}
MYSQL_RES * substrresult = mysql_store_result (mySqlConnection);
row = mysql_fetch_row (substrresult);
char * file = row [0];
unsigned long contentLength = mysql_fetch_lengths (substrresult) [0];
patchList->AddFile(userFilename, file, fileLength, contentLength, FileListNodeContext(PC_WRITE_FILE,0));
mysql_free_result(substrresult);
*/
patchList->AddFile(userFilename,userFilename, 0, fileLength, fileLength, FileListNodeContext(PC_WRITE_FILE,fileId,0,0), true);
}
else
{
// Otherwise, write the hash of the new version and then write the patch to get to that version.
//
char * patch = row [0];
unsigned long patchLength = mysql_fetch_lengths (patchResult) [0];
char *temp = new char [patchLength + HASH_LENGTH];
memcpy(temp, contentHash, HASH_LENGTH);
memcpy(temp+HASH_LENGTH, patch, patchLength);
patchList->AddFile(userFilename,userFilename, temp, HASH_LENGTH+patchLength, fileLength, FileListNodeContext(PC_HASH_1_WITH_PATCH,0,0,0) );
delete [] temp;
}
mysql_free_result(patchResult);
}
else
{
// else if the hash of this file matches what the user has, the user has the latest version. Done.
}
}
else
{
// else if there is no such file, skip this file.
}
mysql_free_result(result);
}
delete [] fn;
}
return true;
}
bool AutopatcherMySQLRepository::GetMostRecentChangelistWithPatches(SLNet::RakString &applicationName, FileList *patchedFiles, FileList *addedFiles, FileList *addedOrModifiedFileHashes, FileList *deletedFiles, double *priorRowPatchTime, double *mostRecentRowPatchTime)
{
// unused parameters
(void)applicationName;
(void)patchedFiles;
(void)addedFiles;
(void)addedOrModifiedFileHashes;
(void)deletedFiles;
(void)priorRowPatchTime;
(void)mostRecentRowPatchTime;
// Not yet implemented
return false;
}
bool AutopatcherMySQLRepository::UpdateApplicationFiles(const char *applicationName, const char *applicationDirectory, const char *userName, FileListProgress *cb)
{
MYSQL_STMT *stmt;
MYSQL_BIND bind[3];
char query[512];
FileList filesOnHarddrive;
filesOnHarddrive.AddCallback(cb);
int prepareResult;
my_bool falseVar=false;
SLNet::RakString escapedApplicationName = GetEscapedString(applicationName);
filesOnHarddrive.AddFilesFromDirectory(applicationDirectory,"", true, true, true, FileListNodeContext());
if (filesOnHarddrive.fileList.Size()==0)
{
sprintf_s(lastError,"ERROR: Can't find files at %s in UpdateApplicationFiles\n",applicationDirectory);
return false;
}
sprintf_s(query, "SELECT applicationID FROM Applications WHERE applicationName='%s';", escapedApplicationName.C_String());
int applicationID;
//sqlCommandMutex.Lock();
if (!ExecuteQueryReadInt(query, &applicationID))
{
//sqlCommandMutex.Unlock();
sprintf_s(lastError,"ERROR: %s not found in UpdateApplicationFiles\n",escapedApplicationName.C_String());
return false;
}
if (!ExecuteBlockingCommand("BEGIN;"))
{
//sqlCommandMutex.Unlock();
return false;
}
//sqlCommandMutex.Unlock();
sprintf_s(query, "UPDATE Applications SET changeSetId = changeSetId + 1 where applicationID=%i;", applicationID);
//sqlCommandMutex.Lock();
if (!ExecuteBlockingCommand(query))
{
Rollback ();
//sqlCommandMutex.Unlock();
return false;
}
//sqlCommandMutex.Unlock();
int changeSetId = 0;
sprintf_s(query, "SELECT changeSetId FROM Applications WHERE applicationID=%i;", applicationID);
//sqlCommandMutex.Lock();
if (!ExecuteQueryReadInt(query, &changeSetId))
{
Rollback ();
//sqlCommandMutex.Unlock();
return false;
}
//sqlCommandMutex.Unlock();
// +1 was added in the update
changeSetId--;
// Gets all newest files
sprintf_s(query, "SELECT filename, contentHash, createFile FROM FileVersionHistory "
"JOIN (SELECT max(fileId) maxId FROM FileVersionHistory WHERE applicationId=%i GROUP BY fileName) MaxId "
"ON FileVersionHistory.fileId = MaxId.maxId "
"ORDER BY filename DESC;", applicationID);
MYSQL_RES *result = 0;
//sqlCommandMutex.Lock();
if (!ExecuteBlockingCommand(query, &result))
{
Rollback();
//sqlCommandMutex.Unlock();
return false;
}
//sqlCommandMutex.Unlock();
DataStructures::List <FileInfo> newestFiles;
MYSQL_ROW row;
while ((row = mysql_fetch_row (result)) != 0)
{
FileInfo fi;
fi.filename = row [0];
fi.createFile = (atoi (row [2]) != 0);
if (fi.createFile)
{
RakAssert(mysql_fetch_lengths (result) [1] == HASH_LENGTH); // check the data is sensible
memcpy (fi.contentHash, row [1], HASH_LENGTH);
}
newestFiles.Insert (fi, _FILE_AND_LINE_ );
}
mysql_free_result(result);
FileList newFiles;
// Loop through files on filesOnHarddrive
// If the file in filesOnHarddrive does not exist in the query result, or if it does but the hash is different or non-existent, add this file to the create list
for (unsigned fileListIndex=0; fileListIndex < filesOnHarddrive.fileList.Size(); fileListIndex++)
{
bool addFile=true;
if (fileListIndex%10==0)
printf("Hashing files %i/%i\n", fileListIndex+1, filesOnHarddrive.fileList.Size());
const char * hardDriveFilename=filesOnHarddrive.fileList[fileListIndex].filename;
const char * hardDriveHash=filesOnHarddrive.fileList[fileListIndex].data;
for (unsigned i = 0; i != newestFiles.Size (); ++i)
{
const FileInfo & fi = newestFiles [i];
if (_stricmp(hardDriveFilename, fi.filename)==0)
{
if (fi.createFile && memcmp(fi.contentHash, hardDriveHash, HASH_LENGTH)==0)
{
// File exists in database and is the same
addFile=false;
}
break;
}
}
// Unless set to false, file does not exist in query result or is different.
if (addFile)
{
newFiles.AddFile(hardDriveFilename,hardDriveFilename, filesOnHarddrive.fileList[fileListIndex].data, filesOnHarddrive.fileList[fileListIndex].dataLengthBytes, filesOnHarddrive.fileList[fileListIndex].fileLengthBytes, FileListNodeContext(), false, true);
filesOnHarddrive.fileList[fileListIndex].data=0;
}
}
// Go through query results that are marked as create
// If a file that is currently in the database is not on the harddrive, add it to the delete list
FileList deletedFiles;
for (unsigned i = 0; i != newestFiles.Size (); ++i)
{
const FileInfo & fi = newestFiles [i];
if (!fi.createFile)
continue; // If already false don't mark false again.
bool fileOnHarddrive=false;
for (unsigned fileListIndex=0; fileListIndex < filesOnHarddrive.fileList.Size(); fileListIndex++)
{
const char * hardDriveFilename=filesOnHarddrive.fileList[fileListIndex].filename;
//hardDriveHash=filesOnHarddrive.fileList[fileListIndex].data;
if (_stricmp(hardDriveFilename, fi.filename)==0)
{
fileOnHarddrive=true;
break;
}
}
if (!fileOnHarddrive)
deletedFiles.AddFile(fi.filename,fi.filename,0,0,0,FileListNodeContext(), false);
}
// files on harddrive no longer needed. Free this memory since generating all the patches is memory intensive.
filesOnHarddrive.Clear();
// For each file in the delete list add a row indicating file deletion
for (unsigned fileListIndex=0; fileListIndex < deletedFiles.fileList.Size(); fileListIndex++)
{
if (fileListIndex%10==0)
printf("Tagging deleted files %i/%i\n", fileListIndex+1, deletedFiles.fileList.Size());
sprintf_s(query, "INSERT INTO FileVersionHistory(applicationID, filename, createFile, changeSetID, userName) VALUES (%i, '%s', FALSE,%i,'%s');",
applicationID, GetEscapedString(deletedFiles.fileList[fileListIndex].filename).C_String(), changeSetId, GetEscapedString(userName).C_String());
//sqlCommandMutex.Lock();
if (!ExecuteBlockingCommand (query))
{
Rollback();
//sqlCommandMutex.Unlock();
deletedFiles.Clear();
newFiles.Clear();
return false;
}
//sqlCommandMutex.Unlock();
}
// Clear the delete list as it is no longer needed.
deletedFiles.Clear();
// For each file in the create list
for (unsigned fileListIndex=0; fileListIndex < newFiles.fileList.Size(); fileListIndex++)
{
if (fileListIndex%10==0)
printf("Adding file %i/%i\n", fileListIndex+1, newFiles.fileList.Size());
const char * hardDriveFilename=newFiles.fileList[fileListIndex].filename;
const char * hardDriveData=newFiles.fileList[fileListIndex].data+HASH_LENGTH;
const char * hardDriveHash=newFiles.fileList[fileListIndex].data;
unsigned hardDriveDataLength=newFiles.fileList[fileListIndex].fileLengthBytes;
sprintf_s( query, "SELECT fileID from FileVersionHistory WHERE applicationID=%i AND filename='%s' AND createFile=TRUE;", applicationID, GetEscapedString(hardDriveFilename).C_String() );
MYSQL_RES * res = 0;
//sqlCommandMutex.Lock();
if (!ExecuteBlockingCommand (query, &res))
{
Rollback();
//sqlCommandMutex.Unlock();
newFiles.Clear();
return false;
}
//sqlCommandMutex.Unlock();
// Create new patches for every create version
while ((row = mysql_fetch_row (res)) != 0)
{
const char * fileID = row [0];
// The last query handled all the relevant comparisons
sprintf_s(query, "SELECT content from FileVersionHistory WHERE fileID=%s", fileID );
MYSQL_RES * queryResult = 0;
//sqlCommandMutex.Lock();
if (!ExecuteBlockingCommand (query, &queryResult))
{
Rollback();
//sqlCommandMutex.Unlock();
newFiles.Clear();
mysql_free_result(res);
return false;
}
//sqlCommandMutex.Unlock();
MYSQL_ROW queryRow = mysql_fetch_row (queryResult);
const unsigned contentLength=mysql_fetch_lengths (queryResult) [0];
const char * content=queryRow [0];
char *patch;
unsigned patchLength;
if (!CreatePatch(content, contentLength, (char *) hardDriveData, hardDriveDataLength, &patch, &patchLength))
{
strcpy_s(lastError,"CreatePatch failed.\n");
Rollback();
newFiles.Clear();
mysql_free_result(res);
mysql_free_result(queryResult);
return false;
}
char buf[512];
stmt = mysql_stmt_init(mySqlConnection);
sprintf (buf, "UPDATE FileVersionHistory SET patch=? where fileID=%s;", fileID);
if ((prepareResult=mysql_stmt_prepare(stmt, buf, (unsigned long) strlen(buf)))!=0)
{
strcpy (lastError, mysql_stmt_error (stmt));
mysql_stmt_close(stmt);
Rollback();
return false;
}
memset(bind, 0, sizeof(bind));
unsigned long l1;
l1=patchLength;
bind[0].buffer_type= MYSQL_TYPE_LONG_BLOB;
bind[0].buffer= patch;
bind[0].buffer_length= patchLength;
bind[0].is_null= &falseVar;
bind[0].length=&l1;
if (mysql_stmt_bind_param(stmt, bind))
{
strcpy (lastError, mysql_stmt_error (stmt));
mysql_stmt_close(stmt);
Rollback();
return false;
}
//sqlCommandMutex.Lock();
if (mysql_stmt_execute(stmt))
{
strcpy (lastError, mysql_stmt_error (stmt));
mysql_stmt_close(stmt);
Rollback();
//sqlCommandMutex.Unlock();
newFiles.Clear();
mysql_free_result(res);
mysql_free_result(queryResult);
delete [] patch;
return false;
}
//sqlCommandMutex.Unlock();
mysql_stmt_close(stmt);
delete [] patch;
mysql_free_result(queryResult);
}
mysql_free_result(res);
stmt = mysql_stmt_init(mySqlConnection);
sprintf_s(query, "INSERT INTO FileVersionHistory (applicationID, filename, fileLength, content, contentHash, createFile, changeSetID, userName) "
"VALUES (%i, ?, %i,?,?, TRUE, %i, '%s' );",
applicationID, hardDriveDataLength, changeSetId, GetEscapedString(userName).C_String());
if ((prepareResult=mysql_stmt_prepare(stmt, query, (unsigned long) strlen(query)))!=0)
{
strcpy (lastError, mysql_stmt_error (stmt));
mysql_stmt_close(stmt);
Rollback();
return false;
}
memset(bind, 0, sizeof(bind));
unsigned long l2,l3,l4;
l2=(unsigned long) strlen(hardDriveFilename);
l3=hardDriveDataLength;
l4=HASH_LENGTH;
bind[0].buffer_type= MYSQL_TYPE_STRING;
bind[0].buffer= (void*) hardDriveFilename;
bind[0].buffer_length= (unsigned long) strlen(hardDriveFilename);
bind[0].is_null= &falseVar;
bind[0].length=&l2;
bind[1].buffer_type= MYSQL_TYPE_LONG_BLOB;
bind[1].buffer= (void*) hardDriveData;
bind[1].buffer_length= hardDriveDataLength;
bind[1].is_null= &falseVar;
bind[1].length=&l3;
bind[2].buffer_type= MYSQL_TYPE_TINY_BLOB;
bind[2].buffer= (void*) hardDriveHash;
bind[2].buffer_length= HASH_LENGTH;
bind[2].is_null= &falseVar;
bind[2].length=&l4;
if (mysql_stmt_bind_param(stmt, bind))
{
strcpy (lastError, mysql_stmt_error (stmt));
mysql_stmt_close(stmt);
Rollback();
return false;
}
//sqlCommandMutex.Lock();
if (mysql_stmt_execute(stmt))
{
strcpy (lastError, mysql_stmt_error (stmt));
mysql_stmt_close(stmt);
Rollback();
//sqlCommandMutex.Unlock();
return false;
}
//sqlCommandMutex.Unlock();
mysql_stmt_close(stmt);
}
//sqlCommandMutex.Lock();
if (!ExecuteBlockingCommand("COMMIT;"))
{
Rollback ();
//sqlCommandMutex.Unlock();
return false;
}
//sqlCommandMutex.Unlock();
return true;
}
const char *AutopatcherMySQLRepository::GetLastError(void) const
{
return MySQLInterface::GetLastError();
}
unsigned int AutopatcherMySQLRepository::GetFilePart( const char *filename, unsigned int startReadBytes, unsigned int numBytesToRead, void *preallocatedDestination, FileListNodeContext context)
{
// unused parameters
(void)filename;
char query[512];
sprintf_s(query, "SELECT substring(content from %i for %i) FROM FileVersionHistory WHERE fileId=%i;", startReadBytes+1,numBytesToRead,context.flnc_extraData1);
// CREATE NEW CONNECTION JUST FOR THIS QUERY
// This is because the autopatcher is sharing this class, but this is called from multiple threads and mysql is not threadsafe
MYSQL_RES * result;
char error[512];
filePartConnectionMutex.Lock();
if (filePartConnection==0)
{
filePartConnection = mysql_init(0);
mysql_real_connect (filePartConnection, _host, _user, _passwd, _db, _port, _unix_socket, _clientflag);
}
if (mysql_query(filePartConnection, query)!=0)
{
// #med - review --- should this set the class member maybe?
strcpy (error, mysql_error (filePartConnection));
}
result = mysql_store_result (filePartConnection);
if (result)
{
// This has very poor performance with any size for GetIncrementalReadChunkSize, but especially for larger sizes
MYSQL_ROW row = mysql_fetch_row (result);
if (row != 0)
{
const char * content = row [0];
unsigned long contentLength=mysql_fetch_lengths (result) [0];
memcpy(preallocatedDestination,content,contentLength);
mysql_free_result (result);
filePartConnectionMutex.Unlock();
return contentLength;
}
mysql_free_result (result);
}
filePartConnectionMutex.Unlock();
return 0;
}
const int AutopatcherMySQLRepository::GetIncrementalReadChunkSize(void) const
{
// AutopatcherMySQLRepository::GetFilePart is extremely slow with larger files
return 262144*4;
}

View File

@ -0,0 +1,110 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
/// \file
/// \brief An implementation of the AutopatcherRepositoryInterface to use MySQL to store the relevant data
///
#ifndef __MYSQL_REPOSITORY_H
#define __MYSQL_REPOSITORY_H
#include "slikenet/AutopatcherRepositoryInterface.h"
#include "MySQLInterface.h"
#include "slikenet/Export.h"
namespace SLNet
{
class FileListProgress;
/// \ingroup Autopatcher
/// An implementation of the AutopatcherRepositoryInterface to use MySQL to store the relevant data
class RAK_DLL_EXPORT AutopatcherMySQLRepository : public AutopatcherRepositoryInterface, public MySQLInterface
{
public:
AutopatcherMySQLRepository();
~AutopatcherMySQLRepository();
/// Create the tables used by the autopatcher, for all applications. Call this first.
/// \return True on success, false on failure.
bool CreateAutopatcherTables(void);
/// Destroy the tables used by the autopatcher. Don't call this unless you don't want to use the autopatcher anymore, or are testing.
/// \return True on success, false on failure.
bool DestroyAutopatcherTables(void);
/// Add an application for use by files. Call this second.
/// \param[in] applicationName A null terminated string.
/// \param[in] userName Stored in the database, but otherwise unused. Useful to track who added this application.
/// \return True on success, false on failure.
bool AddApplication(const char *applicationName, const char *userName);
/// Remove an application and files used by that application.
/// \param[in] applicationName A null terminated string previously passed to AddApplication
/// \return True on success, false on failure.
bool RemoveApplication(const char *applicationName);
/// Update all the files for an application to match what is at the specified directory. Call this third.
/// Be careful not to call this with the wrong directory.
/// This is implemented in a Begin and Rollback block so you won't a messed up database from get partial updates.
/// \param[in] applicationName A null terminated string previously passed to AddApplication
/// \param[in] applicationDirectory The base directory of your application. All files in this directory and subdirectories are added.
/// \param[in] userName Stored in the database, but otherwise unused. Useful to track who added this revision
/// \param[in] cb Callback to get progress updates. Pass 0 to not use.
/// \return True on success, false on failure.
bool UpdateApplicationFiles(const char *applicationName, const char *applicationDirectory, const char *userName, FileListProgress *cb);
/// Get list of files added and deleted since a certain date. This is used by AutopatcherServer and not usually explicitly called.
/// \param[in] applicationName A null terminated string previously passed to AddApplication
/// \param[out] addedFiles A list of the current versions of filenames with SHA1_LENGTH byte hashes as their data that were created after \a sinceData
/// \param[out] deletedFiles A list of the current versions of filenames that were deleted after \a sinceData
/// \param[in] An input date, in the string format of a timestamp.
/// \return True on success, false on failure.
virtual bool GetChangelistSinceDate(const char *applicationName, FileList *addedOrModifiedFilesWithHashData, FileList *deletedFiles, double sinceDate);
/// Get patches (or files) for every file in input, assuming that input has a hash for each of those files. This is used by AutopatcherServer and not usually explicitly called.
/// \param[in] applicationName A null terminated string previously passed to AddApplication
/// \param[in] input A list of files with hashes to get from the database. If this hash exists, a patch to the current version is returned if this file is not the current version. Otherwise the current version is returned.
/// \param[out] patchList A list of files with either the filedata or the patch. This is a subset of \a input. The context data for each file will be either PC_WRITE_FILE (to just write the file) or PC_HASH_WITH_PATCH (to patch). If PC_HASH_WITH_PATCH, then the file contains a SHA1_LENGTH byte patch followed by the hash. The datalength is patchlength + SHA1_LENGTH
/// \return 1 on success, 0 on database failure, -1 on tried to download original unmodified file
virtual int GetPatches(const char *applicationName, FileList *input, bool allowDownloadOfOriginalUnmodifiedFiles, FileList *patchList);
// Not yet implemented
virtual bool GetMostRecentChangelistWithPatches(SLNet::RakString &applicationName, FileList *patchedFiles, FileList *addedFiles, FileList *addedOrModifiedFileHashes, FileList *deletedFiles, double *priorRowPatchTime, double *mostRecentRowPatchTime);
/// If any of the above functions fail, the error string is stored internally. Call this to get it.
virtual const char *GetLastError(void) const;
/// Read part of a file into \a destination
/// Return the number of bytes written. Return 0 when file is done.
/// \param[in] filename Filename to read
/// \param[in] startReadBytes What offset from the start of the file to read from
/// \param[in] numBytesToRead How many bytes to read. This is also how many bytes have been allocated to preallocatedDestination
/// \param[out] preallocatedDestination Write your data here
/// \return The number of bytes read, or 0 if none
virtual unsigned int GetFilePart( const char *filename, unsigned int startReadBytes, unsigned int numBytesToRead, void *preallocatedDestination, FileListNodeContext context);
/// \return Passed to FileListTransfer::Send() as the _chunkSize parameter.
virtual const int GetIncrementalReadChunkSize(void) const;
st_mysql *filePartConnection;
SimpleMutex filePartConnectionMutex;
};
} // namespace SLNet
#endif

View File

@ -0,0 +1,208 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug - Unicode|Win32">
<Configuration>Debug - Unicode</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release - Unicode|Win32">
<Configuration>Release - Unicode</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Retail - Unicode|Win32">
<Configuration>Retail - Unicode</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Retail|Win32">
<Configuration>Retail</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{9092C339-3CCA-41B4-8B80-FAED313D4168}</ProjectGuid>
<RootNamespace>AutopatcherMySQLRepository</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Retail|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Retail - Unicode|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Retail|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Retail - Unicode|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'">$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Retail|Win32'">$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'">$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Retail - Unicode|Win32'">$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>./../;./../../bzip2-1.0.6;./../../../Source;./../../MySQLInterface;C:\Program Files (x86)\MySQL\MySQL Server 5.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_LIB;__WIN__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Lib />
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>./../;./../../bzip2-1.0.6;./../../../Source;./../../MySQLInterface;C:\Program Files (x86)\MySQL\MySQL Server 5.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_LIB;__WIN__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Lib />
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>./../;./../../bzip2-1.0.6;./../../../Source;./../../MySQLInterface;C:\Program Files (x86)\MySQL\MySQL Server 5.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN32;NDEBUG;_LIB;__WIN__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<MinimalRebuild>true</MinimalRebuild>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Lib />
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Retail|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>./../;./../../bzip2-1.0.6;./../../../Source;./../../MySQLInterface;C:\Program Files (x86)\MySQL\MySQL Server 5.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN32;_RETAIL;NDEBUG;_LIB;__WIN__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<MinimalRebuild>true</MinimalRebuild>
<BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile>
<Lib />
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>./../;./../../bzip2-1.0.6;./../../../Source;./../../MySQLInterface;C:\Program Files (x86)\MySQL\MySQL Server 5.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN32;NDEBUG;_LIB;__WIN__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<MinimalRebuild>true</MinimalRebuild>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Lib />
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Retail - Unicode|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>./../;./../../bzip2-1.0.6;./../../../Source;./../../MySQLInterface;C:\Program Files (x86)\MySQL\MySQL Server 5.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN32;_RETAIL;NDEBUG;_LIB;__WIN__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<MinimalRebuild>true</MinimalRebuild>
<BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile>
<Lib />
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\ApplyPatch.cpp" />
<ClCompile Include="AutopatcherMySQLRepository.cpp" />
<ClCompile Include="..\..\MySQLInterface\MySQLInterface.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\ApplyPatch.h" />
<ClInclude Include="AutopatcherMySQLRepository.h" />
<ClInclude Include="..\..\MySQLInterface\MySQLInterface.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\ApplyPatch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="AutopatcherMySQLRepository.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\MySQLInterface\MySQLInterface.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\ApplyPatch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="AutopatcherMySQLRepository.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\MySQLInterface\MySQLInterface.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,27 @@
#
# This file was taken from RakNet 4.082.
# Please see licenses/RakNet license.txt for the underlying license and related copyright.
#
#
# Modified work: Copyright (c) 2017-2019, SLikeSoft UG (haftungsbeschränkt)
#
# This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
# license found in the license.txt file in the root directory of this source tree.
#
project(AutopatcherMySQLRepository)
FINDMYSQL()
IF(WIN32 AND NOT UNIX)
FILE(GLOB ALL_HEADER_SRCS *.h ${MySQLInterface_SOURCE_DIR}/MySQLInterFace.h ${Autopatcher_SOURCE_DIR}/ApplyPatch.h)
FILE(GLOB ALL_CPP_SRCS *.cpp ${MySQLInterface_SOURCE_DIR}/MySQLInterFace.cpp ${Autopatcher_SOURCE_DIR}/ApplyPatch.cpp)
include_directories(${SLIKENET_HEADER_FILES} ./ ${MySQLInterface_SOURCE_DIR} ${Autopatcher_SOURCE_DIR} ${MYSQL_INCLUDE_DIR} ${BZip2_SOURCE_DIR})
add_library(AutoPatcherMySQLRepository STATIC ${ALL_CPP_SRCS} ${ALL_HEADER_SRCS})
target_link_libraries (AutoPatcherMySQLRepository ${SLIKENET_COMMON_LIBS} ${MYSQL_LIBRARIES})
VSUBFOLDER(AutoPatcherMySQLRepository "Samples/AutoPatcher/Server/MySQL")
ELSE(WIN32 AND NOT UNIX)
FILE(GLOB ALL_HEADER_SRCS *.h)
FILE(GLOB ALL_CPP_SRCS *.cpp)
include_directories(${SLIKENET_HEADER_FILES} ./ ${MySQLInterface_SOURCE_DIR} ${Autopatcher_SOURCE_DIR} ${MYSQL_INCLUDE_DIR})
add_library(AutoPatcherMySQLRepository STATIC ${ALL_CPP_SRCS} ${ALL_HEADER_SRCS})
target_link_libraries (AutoPatcherMySQLRepository ${SLIKENET_COMMON_LIBS} LibAutopatcher LibMySQLInterface ${MYSQL_LIBRARIES})
ENDIF(WIN32 AND NOT UNIX)

View File

@ -0,0 +1,54 @@
# - Find MySQL
# Find the MySQL includes and client library
# This module defines
# MYSQL_INCLUDE_DIR, where to find mysql.h
# MYSQL_LIBRARIES, the libraries needed to use MySQL.
# MYSQL_FOUND, If false, do not try to use MySQL.
#
# Copyright (c) 2006, Jaroslaw Staniek, <js@iidea.pl>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
# Note: The referenced COPYING-CMAKE-SCRIPTS file was not present in the RakNet
# repository. We also failed to get in touch with the copyright holder by mail
# to clarify the situation. To the best of our knowledge the referenced license
# is the Modified BSD License.
if(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES)
set(MYSQL_FOUND TRUE)
else(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES)
find_path(MYSQL_INCLUDE_DIR mysql.h
/usr/include/mysql
/usr/local/include/mysql
$ENV{ProgramFiles}/MySQL/*/include
$ENV{SystemDrive}/MySQL/*/include
)
if(WIN32 AND MSVC)
find_library(MYSQL_LIBRARIES NAMES libmysql
PATHS
$ENV{ProgramFiles}/MySQL/*/lib/opt
$ENV{SystemDrive}/MySQL/*/lib/opt
)
else(WIN32 AND MSVC)
find_library(MYSQL_LIBRARIES NAMES mysqlclient
PATHS
/usr/lib/mysql
/usr/local/lib/mysql
)
endif(WIN32 AND MSVC)
if(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES)
set(MYSQL_FOUND TRUE)
message(STATUS "Found MySQL: ${MYSQL_INCLUDE_DIR}, ${MYSQL_LIBRARIES}")
else(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES)
set(MYSQL_FOUND FALSE)
message(STATUS "MySQL not found.")
endif(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES)
mark_as_advanced(MYSQL_INCLUDE_DIR MYSQL_LIBRARIES)
endif(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES)

View File

@ -0,0 +1,156 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
/// \file
/// \brief An implementation of the AutopatcherRepositoryInterface to use PostgreSQL to store the relevant data
#define _USE_POSTGRE_REPOSITORY
#ifdef _USE_POSTGRE_REPOSITORY
#include "slikenet/AutopatcherRepositoryInterface.h"
#include "PostgreSQLInterface.h"
#include "slikenet/Export.h"
struct pg_conn;
typedef struct pg_conn PGconn;
struct pg_result;
typedef struct pg_result PGresult;
#ifndef __POSTGRE_REPOSITORY_H
#define __POSTGRE_REPOSITORY_H
namespace SLNet
{
class FileListProgress;
/// \ingroup Autopatcher
/// An implementation of the AutopatcherRepositoryInterface to use PostgreSQL to store the relevant data
class RAK_DLL_EXPORT AutopatcherPostgreRepository : public AutopatcherRepositoryInterface, public PostgreSQLInterface
{
public:
AutopatcherPostgreRepository();
virtual ~AutopatcherPostgreRepository();
/// Create the tables used by the autopatcher, for all applications. Call this first.
/// \return True on success, false on failure.
virtual bool CreateAutopatcherTables(void);
/// Destroy the tables used by the autopatcher. Don't call this unless you don't want to use the autopatcher anymore, or are testing.
/// \return True on success, false on failure.
bool DestroyAutopatcherTables(void);
/// Add an application for use by files. Call this second.
/// \param[in] applicationName A null terminated string.
/// \param[in] userName Stored in the database, but otherwise unused. Useful to track who added this application.
/// \return True on success, false on failure.
bool AddApplication(const char *applicationName, const char *userName);
/// Remove an application and files used by that application.
/// \param[in] applicationName A null terminated string previously passed to AddApplication
/// \return True on success, false on failure.
bool RemoveApplication(const char *applicationName);
/// Update all the files for an application to match what is at the specified directory. Call this third.
/// Be careful not to call this with the wrong directory.
/// This is implemented in a Begin and Rollback block so you won't a messed up database from get partial updates.
/// \note It takes 10 bytes of memory to create a patch per byte on disk for a file. So you should not have any files larger than 1/10th your server memory.
/// \param[in] applicationName A null terminated string previously passed to AddApplication
/// \param[in] applicationDirectory The base directory of your application. All files in this directory and subdirectories are added.
/// \param[in] userName Stored in the database, but otherwise unused. Useful to track who added this revision
/// \param[in] cb Callback to get progress updates. Pass 0 to not use.
/// \return True on success, false on failure.
virtual bool UpdateApplicationFiles(const char *applicationName, const char *applicationDirectory, const char *userName, FileListProgress *cb);
/// Get list of files added and deleted since a certain date. This is used by AutopatcherServer and not usually explicitly called.
/// \param[in] applicationName A null terminated string previously passed to AddApplication
/// \param[out] addedFiles A list of the current versions of filenames with SHA1_LENGTH byte hashes as their data that were created after \a sinceData
/// \param[out] deletedFiles A list of the current versions of filenames that were deleted after \a sinceData
/// \param[in] sinceDate
/// \return True on success, false on failure.
virtual bool GetChangelistSinceDate(const char *applicationName, FileList *addedOrModifiedFilesWithHashData, FileList *deletedFiles, double sinceDate);
/// Get patches (or files) for every file in input, assuming that input has a hash for each of those files. This is used by AutopatcherServer and not usually explicitly called.
/// \param[in] applicationName A null terminated string previously passed to AddApplication
/// \param[in] input A list of files with hashes to get from the database. If this hash exists, a patch to the current version is returned if this file is not the current version. Otherwise the current version is returned.
/// \param[in] allowDownloadOfOriginalUnmodifiedFiles If false, then if a file has never been modified and there is no hash for it in the input list, return false. This is to prevent clients from just downloading the game from the autopatcher.
/// \param[out] patchList A list of files with either the filedata or the patch. This is a subset of \a input. The context data for each file will be either PC_WRITE_FILE (to just write the file) or PC_HASH_WITH_PATCH (to patch). If PC_HASH_WITH_PATCH, then the file contains a SHA1_LENGTH byte patch followed by the hash. The datalength is patchlength + SHA1_LENGTH
/// \return 1 on success, 0 on database failure, -1 on tried to download original unmodified file
virtual int GetPatches(const char *applicationName, FileList *input, bool allowDownloadOfOriginalUnmodifiedFiles, FileList *patchList);
/// For the most recent update, return files that were patched, added, or deleted. For files that were patched, return both the patch in \a patchedFiles and the current version in \a updatedFiles
/// \param[in,out] applicationName Name of the application to get patches for. If empty, uses the most recently updated application, and the string will be updated to reflect this name.
/// \param[out] patchedFiles A list of patched files with op PC_HASH_2_WITH_PATCH. It has 2 hashes, the priorHash and the currentHash. The currentHash is checked on the client after patching for patch success. The priorHash is checked in AutopatcherServer::OnGetPatch() to see if the client is able to hash with the version they currently have
/// \param[out] patchedFiles A list of new files. It contains the actual data in addition to the filename
/// \param[out] addedOrModifiedFileHashes A list of file hashes that were either modified or new. This is returned to the client when replying to ID_AUTOPATCHER_CREATION_LIST, which tells the client what files have changed on the server since a certain date
/// \param[out] deletedFiles A list of the current versions of filenames that were deleted in the most recent patch
/// \param[out] whenPatched time in seconds since epoch when patched. Use time() function to get this in C
/// \return true on success, false on failure
virtual bool GetMostRecentChangelistWithPatches(SLNet::RakString &applicationName, FileList *patchedFiles, FileList *addedFiles, FileList *addedOrModifiedFileHashes, FileList *deletedFiles, double *priorRowPatchTime, double *mostRecentRowPatchTime);
/// If any of the above functions fail, the error string is stored internally. Call this to get it.
virtual const char *GetLastError(void) const;
/// Read part of a file into \a destination
/// Return the number of bytes written. Return 0 when file is done.
/// \param[in] filename Filename to read
/// \param[in] startReadBytes What offset from the start of the file to read from
/// \param[in] numBytesToRead How many bytes to read. This is also how many bytes have been allocated to preallocatedDestination
/// \param[out] preallocatedDestination Write your data here
/// \return The number of bytes read, or 0 if none
virtual unsigned int GetFilePart( const char *filename, unsigned int startReadBytes, unsigned int numBytesToRead, void *preallocatedDestination, FileListNodeContext context);
/// \return Passed to FileListTransfer::Send() as the _chunkSize parameter.
virtual const int GetIncrementalReadChunkSize(void) const;
// Use a separate connection for file parts, because PGConn is not threadsafe
PGconn *filePartConnection;
SimpleMutex filePartConnectionMutex;
protected:
virtual unsigned int GetPatchPart( const char *filename, unsigned int startReadBytes, unsigned int numBytesToRead, void *preallocatedDestination, FileListNodeContext context);
};
// This version references the version on the harddrive, rather than store the patch in the database
// It is necessary if your game has files over about 400 megabytes.
class RAK_DLL_EXPORT AutopatcherPostgreRepository2 : public AutopatcherPostgreRepository
{
public:
virtual bool CreateAutopatcherTables(void);
virtual bool GetMostRecentChangelistWithPatches(SLNet::RakString &applicationName, FileList *patchedFiles, FileList *addedFiles, FileList *addedOrModifiedFileHashes, FileList *deletedFiles, double *priorRowPatchTime, double *mostRecentRowPatchTime);
virtual bool UpdateApplicationFiles(const char *applicationName, const char *applicationDirectory, const char *userName, FileListProgress *cb);
virtual unsigned int GetFilePart( const char *filename, unsigned int startReadBytes, unsigned int numBytesToRead, void *preallocatedDestination, FileListNodeContext context);
/// Can override this to create patches using a different tool
/// \param[in] oldFile Path to the old version of the file, on disk
/// \param[in] newFile Path to the updated file, on disk
/// \param[out] patch Pointer you should allocate, to hold the patch
/// \param[out] patchLength Write the length of the resultant patch here
/// \param[out] patchAlgorithm Stored in the database. Use if you want to represent what algorithm was used. Transmitted to the client for decompression
virtual int MakePatch(const char *oldFile, const char *newFile, char **patch, unsigned int *patchLength, int *patchAlgorithm);
protected:
// Implements MakePatch using bsDiff. Uses a lot of memory, should not use for files above about 100 megabytes.
virtual bool MakePatchBSDiff(FILE *fpOld, int contentLengthOld, FILE *fpNew, int contentLengthNew, char **patch, unsigned int *patchLength);
};
} // namespace SLNet
#endif
#endif

View File

@ -0,0 +1,221 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug - Unicode|Win32">
<Configuration>Debug - Unicode</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release - Unicode|Win32">
<Configuration>Release - Unicode</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Retail - Unicode|Win32">
<Configuration>Retail - Unicode</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Retail|Win32">
<Configuration>Retail</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>AutopatcherPostgreSQLRepository</ProjectName>
<ProjectGuid>{0FD54BD0-C49C-4681-80CE-AA22B8995CA8}</ProjectGuid>
<RootNamespace>AutopatcherPostgreSQLRepository</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Retail|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Retail - Unicode|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Retail|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Retail - Unicode|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'">$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Retail|Win32'">$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'">$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Retail - Unicode|Win32'">$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>./../;./../../bzip2-1.0.6;./../../../Source;./../../PostgreSQLInterface;C:\Program Files (x86)\PostgreSQL\9.2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Lib />
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>./../;./../../bzip2-1.0.6;./../../../Source;./../../PostgreSQLInterface;C:\Program Files (x86)\PostgreSQL\9.2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Lib />
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>./../;./../../bzip2-1.0.6;./../../../Source;./../../PostgreSQLInterface;C:\Program Files (x86)\PostgreSQL\9.2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<MinimalRebuild>true</MinimalRebuild>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Lib />
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Retail|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>./../;./../../bzip2-1.0.6;./../../../Source;./../../PostgreSQLInterface;C:\Program Files (x86)\PostgreSQL\9.2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN32;_RETAIL;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<MinimalRebuild>true</MinimalRebuild>
<BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile>
<Lib />
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>./../;./../../bzip2-1.0.6;./../../../Source;./../../PostgreSQLInterface;C:\Program Files (x86)\PostgreSQL\9.2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<MinimalRebuild>true</MinimalRebuild>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Lib />
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Retail - Unicode|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>./../;./../../bzip2-1.0.6;./../../../Source;./../../PostgreSQLInterface;C:\Program Files (x86)\PostgreSQL\9.2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;WIN32;_RETAIL;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<MinimalRebuild>true</MinimalRebuild>
<BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile>
<Lib />
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\ApplyPatch.cpp" />
<ClCompile Include="AutopatcherPostgreRepository.cpp" />
<ClCompile Include="..\..\PostgreSQLInterface\PostgreSQLInterface.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\ApplyPatch.h" />
<ClInclude Include="AutopatcherPostgreRepository.h" />
<ClInclude Include="..\..\PostgreSQLInterface\PostgreSQLInterface.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Lib\LibStatic\LibStatic.vcxproj">
<Project>{6533bdae-0f0c-45e4-8fe7-add0f37fe063}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\ApplyPatch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="AutopatcherPostgreRepository.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\PostgreSQLInterface\PostgreSQLInterface.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\ApplyPatch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="AutopatcherPostgreRepository.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\PostgreSQLInterface\PostgreSQLInterface.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,27 @@
#
# This file was taken from RakNet 4.082.
# Please see licenses/RakNet license.txt for the underlying license and related copyright.
#
#
# Modified work: Copyright (c) 2017-2019, SLikeSoft UG (haftungsbeschränkt)
#
# This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
# license found in the license.txt file in the root directory of this source tree.
#
project(AutopatcherPostgreRepository)
FINDPOSTGRE()
IF(WIN32 AND NOT UNIX)
FILE(GLOB ALL_HEADER_SRCS *.h ${PostgreSQLInterface_SOURCE_DIR}/PostgreSQLInterface.h ${Autopatcher_SOURCE_DIR}/ApplyPatch.h ${Autopatcher_SOURCE_DIR}/CreatePatch.h)
FILE(GLOB ALL_CPP_SRCS *.cpp ${PostgreSQLInterface_SOURCE_DIR}/PostgreSQLInterface.cpp ${Autopatcher_SOURCE_DIR}/ApplyPatch.cpp ${Autopatcher_SOURCE_DIR}/CreatePatch.cpp)
include_directories(${SLIKENET_HEADER_FILES} ./ ${PostgreSQLInterface_SOURCE_DIR} ${Autopatcher_SOURCE_DIR} ${POSTGRESQL_INCLUDE_DIR} ${BZip2_SOURCE_DIR})
add_library(AutopatcherPostgreRepository STATIC ${ALL_CPP_SRCS} ${ALL_HEADER_SRCS})
target_link_libraries (AutopatcherPostgreRepository ${SLIKENET_COMMON_LIBS} ${POSTGRESQL_LIBRARIES})
VSUBFOLDER(AutopatcherPostgreRepository "Samples/AutoPatcher/Server/PostgreSQL")
ELSE(WIN32 AND NOT UNIX)
FILE(GLOB ALL_HEADER_SRCS *.h)
FILE(GLOB ALL_CPP_SRCS *.cpp)
include_directories(${SLIKENET_HEADER_FILES} ./ ${PostgreSQLInterface_SOURCE_DIR} ${Autopatcher_SOURCE_DIR} ${POSTGRESQL_INCLUDE_DIR})
add_library(AutopatcherPostgreRepository STATIC ${ALL_CPP_SRCS} ${ALL_HEADER_SRCS})
target_link_libraries (AutopatcherPostgreRepository ${SLIKENET_COMMON_LIBS} LibAutopatcher LibPostgreSQLInterface ${POSTGRESQL_LIBRARIES})
ENDIF(WIN32 AND NOT UNIX)

View File

@ -0,0 +1,884 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2016-2020, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
/// \file
/// \brief The server plugin for the autopatcher. Must be running for the client to get patches.
#include "AutopatcherServer.h"
#include "slikenet/DirectoryDeltaTransfer.h"
#include "slikenet/FileList.h"
#include "slikenet/StringCompressor.h"
#include "slikenet/peerinterface.h"
#include "slikenet/FileListTransfer.h"
#include "slikenet/FileListTransferCBInterface.h"
#include "slikenet/BitStream.h"
#include "slikenet/MessageIdentifiers.h"
#include "slikenet/AutopatcherRepositoryInterface.h"
#include "slikenet/assert.h"
#include "slikenet/AutopatcherPatchContext.h"
#include <stdio.h>
#include <time.h>
using namespace SLNet;
const static unsigned HASH_LENGTH=4;
void AutopatcherServerLoadNotifier_Printf::OnQueueUpdate(SystemAddress remoteSystem, AutopatcherServerLoadNotifier::RequestType requestType, AutopatcherServerLoadNotifier::QueueOperation queueOperation, AutopatcherServerLoadNotifier::AutopatcherState *autopatcherState)
{
char *operationString;
char *requestTypeString;
char systemAddressString[32];
remoteSystem.ToString(true, systemAddressString, static_cast<size_t>(32));
if (requestType==ASUMC_GET_CHANGELIST)
requestTypeString="GetChangelist";
else
requestTypeString="GetPatch";
if (queueOperation==QO_WAS_ADDED)
operationString="added";
else if (queueOperation==QO_POPPED_ONTO_TO_PROCESSING_THREAD)
operationString="processing";
else // otherwise queueOperation == QO_WAS_ABORTED
operationString="aborted";
printf("%s %s %s. %i queued. %i working.\n", systemAddressString, requestTypeString, operationString, autopatcherState->requestsQueued, autopatcherState->requestsWorking);
}
void AutopatcherServerLoadNotifier_Printf::OnGetChangelistCompleted(
SystemAddress remoteSystem,
AutopatcherServerLoadNotifier::GetChangelistResult getChangelistResult,
AutopatcherServerLoadNotifier::AutopatcherState *autopatcherState)
{
char systemAddressString[32];
remoteSystem.ToString(true, systemAddressString, static_cast<size_t>(32));
char *changelistString;
if (getChangelistResult==GCR_DELETE_FILES)
changelistString="Delete files";
else if (getChangelistResult==GCR_ADD_FILES)
changelistString="Add files";
else if (getChangelistResult==GCR_ADD_AND_DELETE_FILES)
changelistString="Add and delete files";
else if (getChangelistResult==GCR_NOTHING_TO_DO)
changelistString="No files in changelist";
else // otherwise getChangelistResult == GCR_REPOSITORY_ERROR
changelistString="Repository error";
printf("%s GetChangelist complete. %s. %i queued. %i working.\n", systemAddressString, changelistString, autopatcherState->requestsQueued, autopatcherState->requestsWorking);
}
void AutopatcherServerLoadNotifier_Printf::OnGetPatchCompleted(SystemAddress remoteSystem, AutopatcherServerLoadNotifier::PatchResult patchResult, AutopatcherServerLoadNotifier::AutopatcherState *autopatcherState)
{
char systemAddressString[32];
remoteSystem.ToString(true, systemAddressString, static_cast<size_t>(32));
char *patchResultString;
if (patchResult==PR_NO_FILES_NEEDED_PATCHING)
patchResultString="No files needed patching";
else if (patchResult==PR_REPOSITORY_ERROR)
patchResultString="Repository error";
else if (patchResult==PR_DISALLOWED_DOWNLOADING_ORIGINAL_FILES)
patchResultString="Disallowed downloading original files";
else if (patchResult==PR_PATCHES_WERE_SENT)
patchResultString="Files pushed for patching";
else if (patchResult==PR_ABORTED_FROM_INPUT_THREAD)
patchResultString="Aborted from input thread";
else // otherwise patchResult == PR_ABORTED_FROM_DOWNLOAD_THREAD
patchResultString="Aborted from download thread";
printf("%s GetPatch complete. %s. %i queued. %i working.\n", systemAddressString, patchResultString, autopatcherState->requestsQueued, autopatcherState->requestsWorking);
}
AutopatcherServer::AutopatcherServer()
{
fileListTransfer=0;
priority=HIGH_PRIORITY;
orderingChannel=0;
// repository=0;
maxConcurrentUsers=0;
loadNotifier=0;
cache_minTime=0;
cache_maxTime=0;
cacheLoaded=false;
allowDownloadOfOriginalUnmodifiedFiles=true;
}
AutopatcherServer::~AutopatcherServer()
{
Clear();
}
void AutopatcherServer::SetUploadSendParameters(PacketPriority _priority, char _orderingChannel)
{
priority=_priority;
orderingChannel=_orderingChannel;
}
void AutopatcherServer::SetFileListTransferPlugin(FileListTransfer *flt)
{
if (fileListTransfer)
fileListTransfer->RemoveCallback(this);
fileListTransfer=flt;
if (fileListTransfer)
fileListTransfer->AddCallback(this);
}
void AutopatcherServer::StartThreads(int numThreads, int numSQLConnections, AutopatcherRepositoryInterface **sqlConnectionPtrArray)
{
RakAssert(numSQLConnections >= numThreads);
connectionPoolMutex.Lock();
for (int i=0; i < numSQLConnections; i++)
{
// Test the pointers passed, in case the user incorrectly casted an array of a different type
sqlConnectionPtrArray[i]->GetLastError();
connectionPool.Push(sqlConnectionPtrArray[i],_FILE_AND_LINE_);
}
connectionPoolMutex.Unlock();
threadPool.SetThreadDataInterface(this,0);
threadPool.StartThreads(numThreads, 0);
}
void AutopatcherServer::CacheMostRecentPatch(const char *applicationName)
{
if (connectionPool.Size()>0)
{
if (applicationName)
cache_appName=applicationName;
else
cache_appName.Clear();
cache_patchedFiles.Clear();
cache_addedFiles.Clear();
cache_deletedFiles.Clear();
cache_addedOrModifiedFileHashes.Clear();
cache_minTime=0;
cache_maxTime=0;
cacheLoaded = connectionPool[0]->GetMostRecentChangelistWithPatches(cache_appName, &cache_patchedFiles, &cache_addedFiles, &cache_addedOrModifiedFileHashes, &cache_deletedFiles, &cache_minTime, &cache_maxTime);
if (cacheLoaded==false)
{
printf("Warning: Cache not loaded. This is OK if no patch was ever saved.\n");
}
}
}
void AutopatcherServer::OnAttach(void)
{
}
void AutopatcherServer::OnDetach(void)
{
Clear();
}
void AutopatcherServer::Update(void)
{
while (PatchingUserLimitReached()==false && userRequestWaitingQueue.Size()>0)
{
Packet *packet = PopOffWaitingQueue();
switch (packet->data[0])
{
case ID_AUTOPATCHER_GET_CHANGELIST_SINCE_DATE:
OnGetChangelistSinceDateInt(packet);
break;
// Client sends ID_AUTOPATCHER_GET_PATCH with files that they have different or missing
case ID_AUTOPATCHER_GET_PATCH:
OnGetPatchInt(packet);
break;
}
DeallocPacketUnified(packet);
}
}
PluginReceiveResult AutopatcherServer::OnReceive(Packet *packet)
{
switch (packet->data[0])
{
case ID_AUTOPATCHER_GET_CHANGELIST_SINCE_DATE:
return OnGetChangelistSinceDate(packet);
case ID_AUTOPATCHER_GET_PATCH:
return OnGetPatch(packet);
}
return RR_CONTINUE_PROCESSING;
}
void AutopatcherServer::OnShutdown(void)
{
Clear();
}
void AutopatcherServer::Clear(void)
{
// Clear the waiting input and output from the thread pool.
unsigned i;
threadPool.StopThreads();
for (i=0; i < threadPool.InputSize(); i++)
{
if (DecrementPatchingUserCount(threadPool.GetInputAtIndex(i).systemAddress))
CallPatchCompleteCallback(threadPool.GetInputAtIndex(i).systemAddress, AutopatcherServerLoadNotifier::PR_ABORTED_FROM_INPUT_THREAD);
SLNet::OP_DELETE(threadPool.GetInputAtIndex(i).clientList, _FILE_AND_LINE_);
}
threadPool.ClearInput();
for (i=0; i < threadPool.OutputSize(); i++)
{
SLNet::OP_DELETE(threadPool.GetOutputAtIndex(i)->patchList, _FILE_AND_LINE_);
SLNet::OP_DELETE(threadPool.GetOutputAtIndex(i)->deletedFiles, _FILE_AND_LINE_);
SLNet::OP_DELETE(threadPool.GetOutputAtIndex(i)->addedOrModifiedFilesWithHashData, _FILE_AND_LINE_);
}
threadPool.ClearOutput();
while (userRequestWaitingQueue.Size())
DeallocPacketUnified(AbortOffWaitingQueue());
patchingUsers.Clear(true, _FILE_AND_LINE_);
}
void AutopatcherServer::OnStartup(RakPeerInterface *peer)
{
// unused parameters
(void)peer;
}
void AutopatcherServer::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
{
// unused parameters
(void)rakNetGUID;
(void)lostConnectionReason;
RemoveFromThreadPool(systemAddress);
unsigned int i=0;
patchingUsersMutex.Lock();
while (i < patchingUsers.Size())
{
if (patchingUsers[i]==systemAddress)
patchingUsers.RemoveAtIndexFast(i);
else
i++;
}
patchingUsersMutex.Unlock();
i=0;
while (i < userRequestWaitingQueue.Size())
{
if (userRequestWaitingQueue[i]->systemAddress==systemAddress)
userRequestWaitingQueue.RemoveAtIndex(i);
else
i++;
}
}
void AutopatcherServer::RemoveFromThreadPool(SystemAddress systemAddress)
{
unsigned int i = 0;
threadPool.LockInput();
while (i < threadPool.InputSize())
{
if (threadPool.GetInputAtIndex(i).systemAddress==systemAddress)
{
if (DecrementPatchingUserCount(systemAddress))
CallPatchCompleteCallback(threadPool.GetInputAtIndex(i).systemAddress, AutopatcherServerLoadNotifier::PR_ABORTED_FROM_INPUT_THREAD);
SLNet::OP_DELETE(threadPool.GetInputAtIndex(i).clientList, _FILE_AND_LINE_);
threadPool.RemoveInputAtIndex(i);
}
else
i++;
}
threadPool.UnlockInput();
i=0;
threadPool.LockOutput();
while (i < threadPool.OutputSize())
{
if (threadPool.GetOutputAtIndex(i)->systemAddress==systemAddress)
{
SLNet::OP_DELETE(threadPool.GetOutputAtIndex(i)->patchList, _FILE_AND_LINE_);
SLNet::OP_DELETE(threadPool.GetOutputAtIndex(i)->deletedFiles, _FILE_AND_LINE_);
SLNet::OP_DELETE(threadPool.GetOutputAtIndex(i)->addedOrModifiedFilesWithHashData, _FILE_AND_LINE_);
threadPool.RemoveOutputAtIndex(i);
}
else
i++;
}
threadPool.UnlockOutput();
}
namespace SLNet
{
AutopatcherServer::ResultTypeAndBitstream* GetChangelistSinceDateCB(AutopatcherServer::ThreadData threadData, bool *returnOutput, void* perThreadData)
{
AutopatcherRepositoryInterface *repository = (AutopatcherRepositoryInterface*)perThreadData;
FileList addedOrModifiedFilesWithHashData, deletedFiles;
AutopatcherServer *server = threadData.server;
//AutopatcherServer::ResultTypeAndBitstream *rtab = SLNet::OP_NEW<AutopatcherServer::ResultTypeAndBitstream>( _FILE_AND_LINE_ );
AutopatcherServer::ResultTypeAndBitstream rtab;
rtab.systemAddress=threadData.systemAddress;
// rtab.deletedFiles=SLNet::OP_NEW<FileList>( _FILE_AND_LINE_ );
// rtab.addedFiles=SLNet::OP_NEW<FileList>( _FILE_AND_LINE_ );
rtab.deletedFiles=&deletedFiles;
rtab.addedOrModifiedFilesWithHashData=&addedOrModifiedFilesWithHashData;
// Query the database for a changelist since this date
RakAssert(server);
//if (server->repository->GetChangelistSinceDate(threadData.applicationName.C_String(), rtab.addedFiles, rtab.deletedFiles, threadData.lastUpdateDate.C_String(), currentDate))
if (repository->GetChangelistSinceDate(threadData.applicationName.C_String(), rtab.addedOrModifiedFilesWithHashData, rtab.deletedFiles, threadData.lastUpdateDate))
{
rtab.resultCode=1;
}
else
{
rtab.resultCode=0;
}
rtab.operation=AutopatcherServer::ResultTypeAndBitstream::GET_CHANGELIST_SINCE_DATE;
rtab.currentDate=(double) time(nullptr);
// *returnOutput=true;
// return rtab;
if (rtab.resultCode==1)
{
if (rtab.deletedFiles->fileList.Size())
{
rtab.bitStream1.Write((unsigned char) ID_AUTOPATCHER_DELETION_LIST);
rtab.deletedFiles->Serialize(&rtab.bitStream1);
}
if (rtab.addedOrModifiedFilesWithHashData->fileList.Size())
{
rtab.bitStream2.Write((unsigned char) ID_AUTOPATCHER_CREATION_LIST);
rtab.addedOrModifiedFilesWithHashData->Serialize(&rtab.bitStream2);
rtab.bitStream2.Write(rtab.currentDate);
rtab.bitStream2.WriteCasted<double>(0);
rtab.addedOrModifiedFilesWithHashData->Clear();
}
else
{
rtab.bitStream2.Write((unsigned char) ID_AUTOPATCHER_FINISHED);
rtab.bitStream2.Write(rtab.currentDate);
}
}
else
{
rtab.bitStream2.Write((unsigned char) ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR);
StringCompressor::Instance()->EncodeString(repository->GetLastError(), 256, &rtab.bitStream2);
}
// SLNet::OP_DELETE(rtab.deletedFiles, _FILE_AND_LINE_);
// SLNet::OP_DELETE(rtab.addedFiles, _FILE_AND_LINE_);
*returnOutput=false;
if (server->DecrementPatchingUserCount(rtab.systemAddress))
{
if (rtab.bitStream1.GetNumberOfBitsUsed()>0)
server->SendUnified(&(rtab.bitStream1), server->priority, RELIABLE_ORDERED, server->orderingChannel, rtab.systemAddress, false);
if (rtab.bitStream2.GetNumberOfBitsUsed()>0)
server->SendUnified(&(rtab.bitStream2), server->priority, RELIABLE_ORDERED, server->orderingChannel, rtab.systemAddress, false);
if (server->loadNotifier)
{
AutopatcherServerLoadNotifier::AutopatcherState autopatcherState;
autopatcherState.requestsQueued=server->userRequestWaitingQueue.Size();
autopatcherState.requestsWorking=server->patchingUsers.Size();
AutopatcherServerLoadNotifier::GetChangelistResult getChangelistResult;
if (rtab.resultCode!=1)
getChangelistResult=AutopatcherServerLoadNotifier::GCR_REPOSITORY_ERROR;
else if (rtab.deletedFiles->fileList.Size()==0 && rtab.addedOrModifiedFilesWithHashData->fileList.Size()==0)
getChangelistResult=AutopatcherServerLoadNotifier::GCR_NOTHING_TO_DO;
else if (rtab.deletedFiles->fileList.Size()==0)
getChangelistResult=AutopatcherServerLoadNotifier::GCR_ADD_FILES;
else if (rtab.addedOrModifiedFilesWithHashData->fileList.Size()==0)
getChangelistResult=AutopatcherServerLoadNotifier::GCR_DELETE_FILES;
else
getChangelistResult=AutopatcherServerLoadNotifier::GCR_ADD_AND_DELETE_FILES;
server->loadNotifier->OnGetChangelistCompleted(rtab.systemAddress, getChangelistResult, &autopatcherState);
}
}
return 0;
}
}
PluginReceiveResult AutopatcherServer::OnGetChangelistSinceDate(Packet *packet)
{
SLNet::BitStream inBitStream(packet->data, packet->length, false);
ThreadData threadData;
threadData.clientList=0;
inBitStream.IgnoreBits(8);
inBitStream.ReadCompressed(threadData.applicationName);
inBitStream.Read(threadData.lastUpdateDate);
if (cacheLoaded && threadData.lastUpdateDate!=0 && threadData.applicationName==cache_appName)
{
SLNet::BitStream bitStream1;
SLNet::BitStream bitStream2;
double currentDate=(double) time(nullptr);
if (cache_maxTime!=0 && threadData.lastUpdateDate>cache_maxTime)
{
bitStream2.Write((unsigned char) ID_AUTOPATCHER_FINISHED);
bitStream2.Write(currentDate);
SendUnified(&bitStream2, priority, RELIABLE_ORDERED,orderingChannel, packet->systemAddress, false);
return RR_STOP_PROCESSING_AND_DEALLOCATE;
}
// Check in-memory cache, use if possible rather than accessing database
if (cache_minTime!=0 && threadData.lastUpdateDate>cache_minTime)
{
if (cache_deletedFiles.fileList.Size())
{
bitStream1.Write((unsigned char) ID_AUTOPATCHER_DELETION_LIST);
cache_deletedFiles.Serialize(&bitStream1);
SendUnified(&bitStream1, priority, RELIABLE_ORDERED,orderingChannel, packet->systemAddress, false);
}
if (cache_addedOrModifiedFileHashes.fileList.Size())
{
bitStream2.Write((unsigned char) ID_AUTOPATCHER_CREATION_LIST);
cache_addedOrModifiedFileHashes.Serialize(&bitStream2);
bitStream2.Write(currentDate);
bitStream2.Write(threadData.lastUpdateDate);
}
else
{
bitStream2.Write((unsigned char) ID_AUTOPATCHER_FINISHED);
bitStream2.Write(currentDate);
}
SendUnified(&bitStream2, priority, RELIABLE_ORDERED,orderingChannel, packet->systemAddress, false);
return RR_STOP_PROCESSING_AND_DEALLOCATE;
}
}
if (PatchingUserLimitReached())
{
AddToWaitingQueue(packet);
return RR_STOP_PROCESSING;
}
OnGetChangelistSinceDateInt(packet);
return RR_STOP_PROCESSING_AND_DEALLOCATE;
}
void AutopatcherServer::OnGetChangelistSinceDateInt(Packet *packet)
{
SLNet::BitStream inBitStream(packet->data, packet->length, false);
ThreadData threadData;
threadData.clientList=0;
inBitStream.IgnoreBits(8);
inBitStream.ReadCompressed(threadData.applicationName);
inBitStream.Read(threadData.lastUpdateDate);
if (IncrementPatchingUserCount(packet->systemAddress))
{
CallPacketCallback(packet, AutopatcherServerLoadNotifier::QO_POPPED_ONTO_TO_PROCESSING_THREAD);
threadData.server=this;
threadData.systemAddress=packet->systemAddress;
threadPool.AddInput(GetChangelistSinceDateCB, threadData);
}
}
namespace SLNet {
AutopatcherServer::ResultTypeAndBitstream* GetPatchCB(AutopatcherServer::ThreadData threadData, bool *returnOutput, void* perThreadData)
{
AutopatcherServer *server = threadData.server;
AutopatcherRepositoryInterface *repository = (AutopatcherRepositoryInterface*)perThreadData;
// AutopatcherServer::ResultTypeAndBitstream *rtab = SLNet::OP_NEW<AutopatcherServer::ResultTypeAndBitstream>( _FILE_AND_LINE_ );
AutopatcherServer::ResultTypeAndBitstream rtab;
rtab.systemAddress=threadData.systemAddress;
FileList fileList;
// rtab.patchList=SLNet::OP_NEW<FileList>( _FILE_AND_LINE_ );
rtab.patchList=&fileList;
RakAssert(server);
// RakAssert(server->repository);
// if (server->repository->GetPatches(threadData.applicationName.C_String(), threadData.clientList, rtab.patchList, currentDate))
rtab.resultCode = repository->GetPatches(threadData.applicationName.C_String(), threadData.clientList, server->allowDownloadOfOriginalUnmodifiedFiles, rtab.patchList);
rtab.operation=AutopatcherServer::ResultTypeAndBitstream::GET_PATCH;
rtab.setId=threadData.setId;
rtab.currentDate=(double) time(nullptr);
SLNet::OP_DELETE(threadData.clientList, _FILE_AND_LINE_);
if (rtab.resultCode==1)
{
if (rtab.patchList->fileList.Size())
{
//server->fileListTransfer->Send(rtab.patchList, 0, rtab.systemAddress, rtab.setId, server->priority, server->orderingChannel, false, server->repository);
server->fileListTransfer->Send(rtab.patchList, 0, rtab.systemAddress, rtab.setId, server->priority, server->orderingChannel, repository, repository->GetIncrementalReadChunkSize());
}
else
{
// No files needed to send
if (server->DecrementPatchingUserCount(rtab.systemAddress))
server->CallPatchCompleteCallback(rtab.systemAddress, AutopatcherServerLoadNotifier::PR_NO_FILES_NEEDED_PATCHING);
}
rtab.bitStream1.Write((unsigned char) ID_AUTOPATCHER_FINISHED_INTERNAL);
rtab.bitStream1.Write(rtab.currentDate);
}
else
{
AutopatcherServerLoadNotifier::PatchResult pr;
if (rtab.resultCode==0)
{
rtab.bitStream1.Write((unsigned char) ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR);
StringCompressor::Instance()->EncodeString(repository->GetLastError(), 256, &rtab.bitStream1);
pr = AutopatcherServerLoadNotifier::PR_REPOSITORY_ERROR;
}
else
{
rtab.bitStream1.Write((unsigned char) ID_AUTOPATCHER_CANNOT_DOWNLOAD_ORIGINAL_UNMODIFIED_FILES);
pr = AutopatcherServerLoadNotifier::PR_DISALLOWED_DOWNLOADING_ORIGINAL_FILES;
}
if (server->DecrementPatchingUserCount(rtab.systemAddress))
{
server->CallPatchCompleteCallback(rtab.systemAddress, pr);
}
else
{
*returnOutput=false;
return 0;
}
}
*returnOutput=false;
if (rtab.bitStream1.GetNumberOfBitsUsed()>0)
server->SendUnified(&(rtab.bitStream1), server->priority, RELIABLE_ORDERED, server->orderingChannel, rtab.systemAddress, false);
if (rtab.bitStream2.GetNumberOfBitsUsed()>0)
server->SendUnified(&(rtab.bitStream2), server->priority, RELIABLE_ORDERED, server->orderingChannel, rtab.systemAddress, false);
// 12/1/2010 This doesn't scale well. Changing to allocating a connection object per request
/*
// Wait for repository to finish
// This is so that the same sql connection is not used between two different plugins, which causes thrashing and bad performance
// Plus if fileListTransfer uses multiple threads, this will keep this thread and the fileListTransfer thread from using the same connection at the same time
// PostgreSQL possibly MySQL are not threadsafe for multiple threads on the same connection
int pendingFiles = server->fileListTransfer->GetPendingFilesToAddress(rtab.systemAddress);
while (pendingFiles>0)
{
RakSleep(pendingFiles*10);
pendingFiles = server->fileListTransfer->GetPendingFilesToAddress(rtab.systemAddress);
}
*/
// *returnOutput=true;
// return rtab;
return 0;
}
}
PluginReceiveResult AutopatcherServer::OnGetPatch(Packet *packet)
{
SLNet::BitStream inBitStream(packet->data, packet->length, false);
ThreadData threadData;
inBitStream.IgnoreBits(8);
inBitStream.Read(threadData.setId);
double lastUpdateDate;
inBitStream.Read(lastUpdateDate);
inBitStream.ReadCompressed(threadData.applicationName);
threadData.clientList=0;
// Check in-memory cache, use if possible rather than accessing database
if (threadData.applicationName==cache_appName && lastUpdateDate!=0 && cacheLoaded && cache_minTime!=0 && lastUpdateDate>cache_minTime)
{
threadData.systemAddress=packet->systemAddress;
threadData.server=this;
threadData.clientList= SLNet::OP_NEW<FileList>( _FILE_AND_LINE_ );
if (threadData.clientList->Deserialize(&inBitStream)==false)
{
SLNet::OP_DELETE(threadData.clientList, _FILE_AND_LINE_);
return RR_STOP_PROCESSING_AND_DEALLOCATE;
}
if (threadData.clientList->fileList.Size()==0)
{
RakAssert(0);
SLNet::OP_DELETE(threadData.clientList, _FILE_AND_LINE_);
return RR_STOP_PROCESSING_AND_DEALLOCATE;
}
char *userHash;
SLNet::RakString userFilename;
FileList patchList;
bool cacheUpdateFailed=false;
unsigned int i,j;
// FileList is the list of all files missing or changed as determined by the client
for (i=0; i < threadData.clientList->fileList.Size(); i++)
{
userHash=threadData.clientList->fileList[i].data;
userFilename=threadData.clientList->fileList[i].filename;
if (userHash)
{
// If the user has a hash, check for this file in cache_patchedFiles. If not found, or hash is wrong, use DB
if (threadData.clientList->fileList[i].dataLengthBytes!=HASH_LENGTH)
{
SLNet::OP_DELETE(threadData.clientList, _FILE_AND_LINE_);
return RR_STOP_PROCESSING_AND_DEALLOCATE;
}
for (j=0; j < cache_patchedFiles.fileList.Size(); j++)
{
if (userFilename == cache_patchedFiles.fileList[j].filename)
{
if (memcmp(cache_patchedFiles.fileList[j].data, userHash, HASH_LENGTH)==0)
{
// Send patch
RakAssert(cache_patchedFiles.fileList[j].context.op==PC_HASH_2_WITH_PATCH);
patchList.AddFile(userFilename,userFilename, 0, cache_patchedFiles.fileList[j].dataLengthBytes, cache_patchedFiles.fileList[j].fileLengthBytes, cache_patchedFiles.fileList[j].context, true, false);
}
else
{
// Bad hash
cacheUpdateFailed=true;
}
break;
}
}
if (j==cache_patchedFiles.fileList.Size())
{
// Didn't find the patch even though the client has an older version of the file
cacheUpdateFailed=true;
}
}
else
{
// If the user does not have a hash, check for this file in cache_addedFiles. If not found, use DB
for (j=0; j < cache_addedFiles.fileList.Size(); j++)
{
if (userFilename == cache_addedFiles.fileList[j].filename)
{
// Send added file
patchList.AddFile(userFilename,userFilename, 0, cache_addedFiles.fileList[j].dataLengthBytes, cache_addedFiles.fileList[j].fileLengthBytes, cache_addedFiles.fileList[j].context, true, false);
break;
}
}
if (j==cache_addedFiles.fileList.Size())
{
// Didn't find the file in the cache even though the client asked for it
cacheUpdateFailed=true;
}
}
if (cacheUpdateFailed==true)
{
// Failure to find file in cache
// Will fall to use database
patchList.Clear();
break;
}
}
if (patchList.fileList.Size()>0)
{
if (IncrementPatchingUserCount(packet->systemAddress))
{
fileListTransfer->Send(&patchList, 0, packet->systemAddress, threadData.setId, priority, orderingChannel, this, 262144*4*4);
SLNet::BitStream bitStream1;
bitStream1.Write((unsigned char) ID_AUTOPATCHER_FINISHED_INTERNAL);
double t =(double) time(nullptr);
bitStream1.Write(t);
SendUnified(&bitStream1, priority, RELIABLE_ORDERED, orderingChannel, packet->systemAddress, false);
SLNet::OP_DELETE(threadData.clientList, _FILE_AND_LINE_);
return RR_STOP_PROCESSING_AND_DEALLOCATE;
}
}
}
SLNet::OP_DELETE(threadData.clientList, _FILE_AND_LINE_);
if (PatchingUserLimitReached())
{
AddToWaitingQueue(packet);
return RR_STOP_PROCESSING;
}
OnGetPatchInt(packet);
return RR_STOP_PROCESSING_AND_DEALLOCATE;
}
void AutopatcherServer::OnGetPatchInt(Packet *packet)
{
SLNet::BitStream inBitStream(packet->data, packet->length, false);
ThreadData threadData;
inBitStream.IgnoreBits(8);
inBitStream.Read(threadData.setId);
double lastUpdateDate;
inBitStream.Read(lastUpdateDate);
inBitStream.ReadCompressed(threadData.applicationName);
threadData.systemAddress=packet->systemAddress;
threadData.server=this;
threadData.clientList= SLNet::OP_NEW<FileList>( _FILE_AND_LINE_ );
if (threadData.clientList->Deserialize(&inBitStream)==false)
{
SLNet::OP_DELETE(threadData.clientList, _FILE_AND_LINE_);
return;
}
if (threadData.clientList->fileList.Size()==0)
{
RakAssert(0);
SLNet::OP_DELETE(threadData.clientList, _FILE_AND_LINE_);
return;
}
if (IncrementPatchingUserCount(packet->systemAddress))
CallPacketCallback(packet, AutopatcherServerLoadNotifier::QO_POPPED_ONTO_TO_PROCESSING_THREAD);
threadPool.AddInput(GetPatchCB, threadData);
}
void* AutopatcherServer::PerThreadFactory(void *context)
{
(void)context;
AutopatcherRepositoryInterface* p;
connectionPoolMutex.Lock();
p=connectionPool.Pop();
connectionPoolMutex.Unlock();
return p;
}
void AutopatcherServer::PerThreadDestructor(void* factoryResult, void *context)
{
(void)context;
(void)factoryResult;
}
void AutopatcherServer::OnFilePushesComplete( SystemAddress systemAddress, unsigned short setID )
{
// unused parameters
(void)setID;
if (DecrementPatchingUserCount(systemAddress))
CallPatchCompleteCallback(systemAddress, AutopatcherServerLoadNotifier::PR_PATCHES_WERE_SENT);
}
void AutopatcherServer::OnSendAborted( SystemAddress systemAddress )
{
if (DecrementPatchingUserCount(systemAddress))
CallPatchCompleteCallback(systemAddress, AutopatcherServerLoadNotifier::PR_ABORTED_FROM_DOWNLOAD_THREAD);
}
bool AutopatcherServer::IncrementPatchingUserCount(SystemAddress sa)
{
// A system address may exist more than once in patchingUsers
patchingUsersMutex.Lock();
patchingUsers.Insert(sa, _FILE_AND_LINE_);
patchingUsersMutex.Unlock();
return true;
}
bool AutopatcherServer::DecrementPatchingUserCount(SystemAddress sa)
{
unsigned int i;
patchingUsersMutex.Lock();
for (i=0; i < patchingUsers.Size(); i++)
{
if (patchingUsers[i]==sa)
{
patchingUsers.RemoveAtIndexFast(i);
patchingUsersMutex.Unlock();
return true;
}
}
patchingUsersMutex.Unlock();
return false;
}
bool AutopatcherServer::PatchingUserLimitReached(void) const
{
if (maxConcurrentUsers==0)
return false;
return patchingUsers.Size()>=maxConcurrentUsers;
}
void AutopatcherServer::SetMaxConurrentUsers(unsigned int _maxConcurrentUsers)
{
maxConcurrentUsers=_maxConcurrentUsers;
}
unsigned int AutopatcherServer::GetMaxConurrentUsers(void) const
{
return maxConcurrentUsers;
}
void AutopatcherServer::CallPacketCallback(Packet *packet, AutopatcherServerLoadNotifier::QueueOperation queueOperation)
{
if (loadNotifier)
{
AutopatcherServerLoadNotifier::AutopatcherState autopatcherState;
autopatcherState.requestsQueued=userRequestWaitingQueue.Size();
autopatcherState.requestsWorking=patchingUsers.Size();
AutopatcherServerLoadNotifier::RequestType requestType;
if (packet->data[0]==ID_AUTOPATCHER_GET_CHANGELIST_SINCE_DATE)
requestType=AutopatcherServerLoadNotifier::ASUMC_GET_CHANGELIST;
else
requestType=AutopatcherServerLoadNotifier::ASUMC_GET_PATCH;
loadNotifier->OnQueueUpdate(packet->systemAddress, requestType, queueOperation, &autopatcherState);
}
}
void AutopatcherServer::CallPatchCompleteCallback(const SystemAddress &systemAddress, AutopatcherServerLoadNotifier::PatchResult patchResult)
{
if (loadNotifier)
{
AutopatcherServerLoadNotifier::AutopatcherState autopatcherState;
autopatcherState.requestsQueued=userRequestWaitingQueue.Size();
autopatcherState.requestsWorking=patchingUsers.Size();
loadNotifier->OnGetPatchCompleted(systemAddress, patchResult, &autopatcherState);
}
}
void AutopatcherServer::AddToWaitingQueue(Packet *packet)
{
userRequestWaitingQueue.Push(packet, _FILE_AND_LINE_);
CallPacketCallback(packet, AutopatcherServerLoadNotifier::QO_WAS_ADDED);
}
Packet *AutopatcherServer::AbortOffWaitingQueue(void)
{
Packet *packet = userRequestWaitingQueue.Pop();
CallPacketCallback(packet,AutopatcherServerLoadNotifier::QO_WAS_ABORTED);
return packet;
}
Packet *AutopatcherServer::PopOffWaitingQueue(void)
{
return userRequestWaitingQueue.Pop();;
}
void AutopatcherServer::SetLoadManagementCallback(AutopatcherServerLoadNotifier *asumc)
{
loadNotifier=asumc;
}
void AutopatcherServer::SetAllowDownloadOfOriginalUnmodifiedFiles(bool allow)
{
allowDownloadOfOriginalUnmodifiedFiles = allow;
}
unsigned int AutopatcherServer::GetFilePart( const char *filename, unsigned int startReadBytes, unsigned int numBytesToRead, void *preallocatedDestination, FileListNodeContext context)
{
// unused parameters
(void)filename;
/*
int offset;
if (context.op==PC_HASH_1_WITH_PATCH)
offset=HASH_LENGTH;
else if (context.op==PC_HASH_2_WITH_PATCH)
offset=HASH_LENGTH*2;
else
offset=0;
int bytesToRead;
if (startReadBytes + numBytesToRead > context.dataLength-offset)
bytesToRead=(context.dataLength-offset)-startReadBytes;
else
bytesToRead=numBytesToRead;
memcpy(preallocatedDestination, ((char*)context.dataPtr)+offset, bytesToRead);
*/
int bytesToRead;
if (startReadBytes + numBytesToRead > context.dataLength)
bytesToRead=(context.dataLength)-startReadBytes;
else
bytesToRead=numBytesToRead;
memcpy(preallocatedDestination, context.dataPtr, bytesToRead);
return bytesToRead;
}

View File

@ -0,0 +1,325 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
/// \file
/// \brief The server plugin for the autopatcher. Must be running for the client to get patches.
// TODO - bsdiff doesn't work for files above 100 megabytes.
// See http://xdelta.org/
// XDelta is GPL 2, however I could run that as a separate EXE and invoke to only transmit the delta file.
// See http://pocketsoft.com/rtpatch.html
// See use rdiff instead of bsdiff, or perhaps librsync
// See https://code.google.com/p/open-vcdiff/
// https://code.google.com/p/open-vcdiff/wiki/HowToUseOpenVcdiff
// https://github.com/gtoubassi/femtozip/wiki/Sdch
#ifndef __AUTOPATCHER_SERVER_H
#define __AUTOPATCHER_SERVER_H
#include "slikenet/types.h"
#include "slikenet/Export.h"
#include "slikenet/PluginInterface2.h"
#include "slikenet/PacketPriority.h"
#include "slikenet/ThreadPool.h"
#include "slikenet/BitStream.h"
#include "slikenet/string.h"
#include "slikenet/FileList.h"
#include "slikenet/IncrementalReadInterface.h"
namespace SLNet
{
/// Forward declarations
class RakPeerInterface;
struct Packet;
class AutopatcherRepositoryInterface;
class FileListTransfer;
class RAK_DLL_EXPORT AutopatcherServerLoadNotifier
{
public:
/// Current queue state of the autopatcher
struct AutopatcherState
{
/// How many requests have been queued to be processed later
unsigned int requestsQueued;
/// How many requests are currently working (including downloading files).
/// This will not normally exceed AutopatcherServer::SetMaxConurrentUsers()
unsigned int requestsWorking;
};
/// The server only handles two types of requests - to get a change list since a certain date, or to get a patch
enum RequestType
{
ASUMC_GET_CHANGELIST,
ASUMC_GET_PATCH,
};
enum QueueOperation
{
QO_WAS_ADDED,
QO_WAS_ABORTED,
QO_POPPED_ONTO_TO_PROCESSING_THREAD
};
enum GetChangelistResult
{
GCR_DELETE_FILES,
GCR_ADD_FILES,
GCR_ADD_AND_DELETE_FILES,
GCR_NOTHING_TO_DO,
GCR_REPOSITORY_ERROR,
};
enum PatchResult
{
PR_NO_FILES_NEEDED_PATCHING,
PR_REPOSITORY_ERROR,
PR_DISALLOWED_DOWNLOADING_ORIGINAL_FILES,
PR_PATCHES_WERE_SENT,
PR_ABORTED_FROM_INPUT_THREAD,
PR_ABORTED_FROM_DOWNLOAD_THREAD,
};
/// The server queues have been updated
/// \param[out] remoteSystem Which system this refers to
/// \param[out] requestType Either added to / removed a changelist request, or a get patch request
/// \param[out] queueOperation The operation was added to the queue, removed from the queue to be processed, or removed because it was aborted
/// \param[out] autopatcherState Current size of the request queue, and how many requests are working
virtual void OnQueueUpdate(SystemAddress remoteSystem,
AutopatcherServerLoadNotifier::RequestType requestType,
AutopatcherServerLoadNotifier::QueueOperation queueOperation,
AutopatcherServerLoadNotifier::AutopatcherState *autopatcherState)
{
// unused parameters
(void)remoteSystem;
(void)requestType;
(void)queueOperation;
(void)autopatcherState;
}
virtual void OnGetChangelistCompleted(
SystemAddress remoteSystem,
AutopatcherServerLoadNotifier::GetChangelistResult getChangelistResult,
AutopatcherServerLoadNotifier::AutopatcherState *autopatcherState)
{
// unused parameters
(void)remoteSystem;
(void)getChangelistResult;
(void)autopatcherState;
}
/// A file transfer has completed, or was not necessary
/// \param[out] remoteSystem Which system this refers to
/// \param[out] autopatcherState Current size of the request queue, and how many requests are working
virtual void OnGetPatchCompleted(SystemAddress remoteSystem,
AutopatcherServerLoadNotifier::PatchResult patchResult,
AutopatcherServerLoadNotifier::AutopatcherState *autopatcherState)
{
// unused parameters
(void)remoteSystem;
(void)patchResult;
(void)autopatcherState;
}
};
/// \brief Sample implementation of AutopatcherServerLoadNotifier using printf
class RAK_DLL_EXPORT AutopatcherServerLoadNotifier_Printf : public AutopatcherServerLoadNotifier
{
public:
virtual void OnQueueUpdate(SystemAddress remoteSystem,
AutopatcherServerLoadNotifier::RequestType requestType,
AutopatcherServerLoadNotifier::QueueOperation queueOperation,
AutopatcherServerLoadNotifier::AutopatcherState *autopatcherState);
virtual void OnGetChangelistCompleted(
SystemAddress remoteSystem,
AutopatcherServerLoadNotifier::GetChangelistResult getChangelistResult,
AutopatcherServerLoadNotifier::AutopatcherState *autopatcherState);
virtual void OnGetPatchCompleted(SystemAddress remoteSystem,
AutopatcherServerLoadNotifier::PatchResult patchResult,
AutopatcherServerLoadNotifier::AutopatcherState *autopatcherState);
};
/// \brief The server plugin for the autopatcher. Must be running for the client to get patches.
class RAK_DLL_EXPORT AutopatcherServer : public PluginInterface2 , public ThreadDataInterface, FileListProgress, IncrementalReadInterface
{
public:
// Constructor
AutopatcherServer();
// Destructor
~AutopatcherServer();
/// DO THIS FIRST
/// Implement to start the worker threads.
/// Before this is called, no queries will be performed
/// When this is called, AllocAutopatcherRepositoryInterface will be called with \a repositoryAllocationParameters
/// The system works in three phases.
/// 1. Get change list since a given date. This uses one of the worker threads.
/// 2. If either running a full scan, or files have changed since a given date, get the list of patches. This uses one of the worker threads and does an intensive comparison of the hashes the client has vs. the files in the database
/// 3. If the total amount of data to be sent exceeds DATABASE_READ_CHUNK_SIZE, defined in the cpp file, then the database will be read from incrementally during this download phase. This uses an sql connection object, which may or may not be also in use by one of the threads.
/// If you have more sql connections than threads, this tends to prevent the same connection from being used to incrementally read files for a downloader, and to be used in a worker thread.
/// \param[in] numThreads Number of processing threads, which handles the CPU intensive tasks of generating a patch list and comparing files
/// \param[in] numSQLConnections Number of SQL connection objects passed to \a sqlConnectionPtrArray. Must be greater than or equal to numThreads
/// \param[in] sqlConnectionPtrArray List of pointers to AutopatcherRepositoryInterface. C++ note: Don't just cast a derived class array, you need to take the pointer address of each item
void StartThreads(int numThreads, int numSQLConnections, AutopatcherRepositoryInterface **sqlConnectionPtrArray);
/// Load the most recent patch in memory and keep it there
/// This can take a lot of memory, but greatly speeds up serving patches, since disk access is not incurred
/// \param[in] applicationName 0 means all, otherwise the name of the application to cache
void CacheMostRecentPatch(const char *applicationName);
/// What parameters to use for the RakPeerInterface::Send() call when uploading files.
/// \param[in] _priority See RakPeerInterface::Send()
/// \param[in] _orderingChannel See RakPeerInterface::Send()
void SetUploadSendParameters(PacketPriority _priority, char _orderingChannel);
/// This plugin has a dependency on the FileListTransfer plugin, which it uses to actually send the files.
/// So you need an instance of that plugin registered with RakPeerInterface, and a pointer to that interface should be passed here.
/// \param[in] flt A pointer to a registered instance of FileListTransfer
void SetFileListTransferPlugin(FileListTransfer *flt);
/// This is the maximum number of users the patcher will service at one time (generally about equal to the number of downloads at once)
/// If this limit is exceeded, the request packet will be put into a queue and serviced when slots are available
/// Defaults to 0 (unlimited)
/// \param[in] maxConcurrentUsers Pass 0 for unlimited, otherwise the max users to serve at once
void SetMaxConurrentUsers(unsigned int _maxConcurrentUsers);
/// \return Returns what was passed to SetMaxConurrentUsers();
unsigned int GetMaxConurrentUsers(void) const;
/// Set a callback to get notifications of when user requests are queued and processed
/// This is primarily of use to load balance the server
/// \param[in] asumc An externally allocated instance of AutopatcherServerLoadNotifier. Pass 0 to disable.
void SetLoadManagementCallback(AutopatcherServerLoadNotifier *asumc);
/// Set whether or not the client can download files that were never modified, that they do not have
/// Defaults to true
/// Set to false to disallow downloading the entire game through the autopatcher. In this case, the user must have a copy of the game through other means (such as a CD install)
/// \param[in] allow True to allow downloading original game files, false to disallow
void SetAllowDownloadOfOriginalUnmodifiedFiles(bool allow);
/// Clear buffered input and output
void Clear(void);
/// \internal For plugin handling
virtual void OnAttach(void);
/// \internal For plugin handling
virtual void OnDetach(void);;
/// \internal For plugin handling
virtual void Update(void);
/// \internal For plugin handling
virtual PluginReceiveResult OnReceive(Packet *packet);
/// \internal For plugin handling
virtual void OnShutdown(void);
/// \internal For plugin handling
virtual void OnStartup(RakPeerInterface *peer);
/// \internal For plugin handling
virtual void OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason );
struct ThreadData
{
AutopatcherServer *server;
SLNet::RakString applicationName;
double lastUpdateDate;
SystemAddress systemAddress;
FileList *clientList;
unsigned short setId;
};
/// \deprecated
struct ResultTypeAndBitstream
{
ResultTypeAndBitstream() {patchList=0; deletedFiles=0; addedOrModifiedFilesWithHashData=0;}
int resultType;
SystemAddress systemAddress;
SLNet::BitStream bitStream1;
SLNet::BitStream bitStream2;
FileList *patchList;
FileList *deletedFiles, *addedOrModifiedFilesWithHashData;
// bool fatalError;
int resultCode; // 1 = success, 0 = unknown error, -1 = failed allowDownloadOfOriginalUnmodifiedFiles check
unsigned short setId;
double currentDate;
enum
{
GET_CHANGELIST_SINCE_DATE,
GET_PATCH,
} operation;
};
protected:
friend AutopatcherServer::ResultTypeAndBitstream* GetChangelistSinceDateCB(AutopatcherServer::ThreadData pap, bool *returnOutput, void* perThreadData);
friend AutopatcherServer::ResultTypeAndBitstream* GetPatchCB(AutopatcherServer::ThreadData pap, bool *returnOutput, void* perThreadData);
PluginReceiveResult OnGetChangelistSinceDate(Packet *packet);
PluginReceiveResult OnGetPatch(Packet *packet);
void OnGetChangelistSinceDateInt(Packet *packet);
void OnGetPatchInt(Packet *packet);
void* PerThreadFactory(void *context);
void PerThreadDestructor(void* factoryResult, void *context);
void RemoveFromThreadPool(SystemAddress systemAddress);
virtual unsigned int GetFilePart( const char *filename, unsigned int startReadBytes, unsigned int numBytesToRead, void *preallocatedDestination, FileListNodeContext context);
//AutopatcherRepositoryInterface *repository;
FileListTransfer *fileListTransfer;
PacketPriority priority;
char orderingChannel;
// The point of the threadPool is so that SQL queries, which are blocking, happen in the thread and don't slow down the rest of the application
// The threadPool has a queue for incoming processing requests. As systems disconnect their pending requests are removed from the list.
ThreadPool<ThreadData, ResultTypeAndBitstream*> threadPool;
SimpleMutex connectionPoolMutex;
DataStructures::Queue<AutopatcherRepositoryInterface *> connectionPool;
// How many users are currently patching
// unsigned int patchingUserCount;
SimpleMutex patchingUsersMutex;
DataStructures::List<SystemAddress> patchingUsers;
bool IncrementPatchingUserCount(SystemAddress sa);
bool DecrementPatchingUserCount(SystemAddress sa);
bool PatchingUserLimitReached(void) const;
virtual void OnFilePushesComplete( SystemAddress systemAddress, unsigned short setID );
virtual void OnSendAborted( SystemAddress systemAddress );
unsigned int maxConcurrentUsers;
// If maxConcurrentUsers is exceeded, then incoming requests are put into this queue
DataStructures::Queue<Packet *> userRequestWaitingQueue;
void AddToWaitingQueue(Packet *packet);
Packet *AbortOffWaitingQueue(void);
Packet *PopOffWaitingQueue(void);
AutopatcherServerLoadNotifier *loadNotifier;
void CallPacketCallback(Packet *packet, AutopatcherServerLoadNotifier::QueueOperation queueOperation);
void CallPatchCompleteCallback(const SystemAddress &systemAddress, AutopatcherServerLoadNotifier::PatchResult patchResult);
SLNet::RakString cache_appName;
FileList cache_patchedFiles;
FileList cache_addedFiles;
FileList cache_addedOrModifiedFileHashes;
FileList cache_deletedFiles;
double cache_minTime, cache_maxTime;
bool cacheLoaded;
bool allowDownloadOfOriginalUnmodifiedFiles;
};
} // namespace SLNet
#endif

View File

@ -0,0 +1,26 @@
#
# This file was taken from RakNet 4.082.
# Please see licenses/RakNet license.txt for the underlying license and related copyright.
#
#
# Modified work: Copyright (c) 2019, SLikeSoft UG (haftungsbeschr<68>nkt)
#
# This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
# license found in the license.txt file in the root directory of this source tree.
#
project(Autopatcher)
IF (UNIX AND NOT WIN32)
FILE(GLOB ALL_HEADER_SRCS *.h)
FILE(GLOB ALL_CPP_SRCS *.cpp)
include_directories(${SLIKENET_HEADER_FILES} ./ ${bzip2-1.0.3_SOURCE_DIR})
add_library(LibAutopatcher STATIC ${ALL_CPP_SRCS} ${ALL_HEADER_SRCS})
target_link_libraries (LibAutopatcher ${SLIKENET_COMMON_LIBS} LibBZip2)
ENDIF(UNIX AND NOT WIN32)
IF(USEMYSQL AND NOT DISABLEDEPENDENCIES)
add_subdirectory(AutopatcherMySQLRepository)
ENDIF(USEMYSQL AND NOT DISABLEDEPENDENCIES)
IF(USEPOSTGRESQL AND NOT DISABLEDEPENDENCIES)
add_subdirectory(AutopatcherPostgreRepository)
ENDIF(USEPOSTGRESQL AND NOT DISABLEDEPENDENCIES)

View File

@ -0,0 +1,872 @@
/*-
* Parts of this code are copyright 2003-2005 Colin Percival
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted providing that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
/*
* This file was taken from RakNet 4.082.
* Please see licenses/RakNet license.txt for the underlying license and related copyright.
*
* Modified work: Copyright (c) 2016-2020, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
* Alternatively you are permitted to license the modifications under the Simplified BSD License.
*/
#define NOMINMAX
#include "MemoryCompressor.h"
#if 0
__FBSDID("$FreeBSD: src/usr.bin/bsdiff/bsdiff/bsdiff.c,v 1.1 2005/08/06 01:59:05 cperciva Exp $");
#endif
#include <sys/types.h>
#include "bzlib.h"
#ifndef _WIN32
#include <err.h>
#include <unistd.h>
#include "slikenet/linux_adapter.h"
#include "slikenet/osx_adapter.h"
#else
// KevinJ - Windows compatibility
typedef int ssize_t;
typedef unsigned char u_char;
typedef long off_t;
#include <wchar.h>
#include <io.h>
#define fseeko fseek
#define ftello ftell
static void err(int i, ...)
{
exit(i);
}
static void errx(int i, ...)
{
exit(i);
}
#endif
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits> // used for std::numeric_limits
#include <algorithm> // used for std::max
#ifndef MIN
#define MIN(x,y) (((x)<(y)) ? (x) : (y))
#endif
#ifndef _O_BINARY
#define _O_BINARY 0
#endif
#ifndef O_BINARY
#define O_BINARY _O_BINARY
#endif
static void split(off_t *I,off_t *V,off_t start,off_t len,off_t h)
{
off_t i,j,k,x,tmp,jj,kk;
if(len<16) {
for(k=start;k<start+len;k+=j) {
j=1;x=V[I[k]+h];
for(i=1;k+i<start+len;i++) {
if(V[I[k+i]+h]<x) {
x=V[I[k+i]+h];
j=0;
};
if(V[I[k+i]+h]==x) {
tmp=I[k+j];I[k+j]=I[k+i];I[k+i]=tmp;
j++;
};
};
for(i=0;i<j;i++) V[I[k+i]]=k+j-1;
if(j==1) I[k]=-1;
};
return;
};
x=V[I[start+len/2]+h];
jj=0;kk=0;
for(i=start;i<start+len;i++) {
if(V[I[i]+h]<x) jj++;
if(V[I[i]+h]==x) kk++;
};
jj+=start;kk+=jj;
i=start;j=0;k=0;
while(i<jj) {
if(V[I[i]+h]<x) {
i++;
} else if(V[I[i]+h]==x) {
tmp=I[i];I[i]=I[jj+j];I[jj+j]=tmp;
j++;
} else {
tmp=I[i];I[i]=I[kk+k];I[kk+k]=tmp;
k++;
};
};
while(jj+j<kk) {
if(V[I[jj+j]+h]==x) {
j++;
} else {
tmp=I[jj+j];I[jj+j]=I[kk+k];I[kk+k]=tmp;
k++;
};
};
if(jj>start) split(I,V,start,jj-start,h);
for(i=0;i<kk-jj;i++) V[I[jj+i]]=kk-1;
if(jj==kk-1) I[jj]=-1;
if(start+len>kk) split(I,V,kk,start+len-kk,h);
}
static void qsufsort(off_t *I,off_t *V,u_char *old,off_t oldsize)
{
off_t buckets[256];
off_t i,h,len;
//for(i=0;i<256;i++) buckets[i]=0;
memset(buckets, 0, sizeof(buckets));
for(i=0;i<oldsize;i++) buckets[old[i]]++;
for(i=1;i<256;i++) buckets[i]+=buckets[i-1];
for(i=255;i>0;i--) buckets[i]=buckets[i-1];
buckets[0]=0;
for(i=0;i<oldsize;i++) I[++buckets[old[i]]]=i;
I[0]=oldsize;
for(i=0;i<oldsize;i++) V[i]=buckets[old[i]];
V[oldsize]=0;
for(i=1;i<256;i++) if(buckets[i]==buckets[i-1]+1) I[buckets[i]]=-1;
I[0]=-1;
for(h=1;I[0]!=-(oldsize+1);h+=h) {
len=0;
for(i=0;i<oldsize+1;) {
if(I[i]<0) {
len-=I[i];
i-=I[i];
} else {
if(len) I[i-len]=-len;
len=V[I[i]]+1-i;
split(I,V,i,len,h);
i+=len;
len=0;
};
};
if(len) I[i-len]=-len;
};
for(i=0;i<oldsize+1;i++) I[V[i]]=i;
}
static off_t matchlen(u_char *old,off_t oldsize,u_char *_new,off_t newsize)
{
off_t i;
for(i=0;(i<oldsize)&&(i<newsize);i++)
if(old[i]!=_new[i]) break;
return i;
}
static off_t search(off_t *I,u_char *old,off_t oldsize,
u_char *_new,off_t newsize,off_t st,off_t en,off_t *pos)
{
off_t x,y;
if(en-st<2) {
x=matchlen(old+I[st],oldsize-I[st],_new,newsize);
y=matchlen(old+I[en],oldsize-I[en],_new,newsize);
if(x>y) {
*pos=I[st];
return x;
} else {
*pos=I[en];
return y;
}
};
x=st+(en-st)/2;
if(memcmp(old+I[x],_new,MIN(oldsize-I[x],newsize))<0) {
return search(I,old,oldsize,_new,newsize,x,en,pos);
} else {
return search(I,old,oldsize,_new,newsize,st,x,pos);
};
}
static void offtout(off_t x,u_char *buf)
{
off_t y;
if(x<0) y=-x; else y=x;
/*
buf[0]=y%256;y-=buf[0];
y=y/256;buf[1]=y%256;y-=buf[1];
y=y/256;buf[2]=y%256;y-=buf[2];
y=y/256;buf[3]=y%256;y-=buf[3];
y=y/256;buf[4]=y%256;y-=buf[4];
y=y/256;buf[5]=y%256;y-=buf[5];
y=y/256;buf[6]=y%256;y-=buf[6];
y=y/256;buf[7]=y%256;
*/
// Thanks to Oliver Smith for pointing out this optimization
buf[0] = (u_char)(y&(off_t)0x000000ff); y >>= 8 ;
buf[1] = (u_char)(y&(off_t)0x000000ff); y >>= 8 ;
buf[2] = (u_char)(y&(off_t)0x000000ff); y >>= 8 ;
buf[3] = (u_char)(y&(off_t)0x000000ff); y >>= 8 ;
buf[4] = (u_char)(y&(off_t)0x000000ff); y >>= 8 ;
buf[5] = (u_char)(y&(off_t)0x000000ff); y >>= 8 ;
buf[6] = (u_char)(y&(off_t)0x000000ff); y >>= 8 ;
buf[7] = (u_char)(y&(off_t)0x000000ff);// y >>= 8 ;
if(x<0) buf[7]|=0x80;
}
// This function modifies the main() function included in bsdiff.c of bsdiff-4.3 found at http://www.daemonology.net/bsdiff/
// It is changed to be a standalone function, to work entirely in memory, and to use my class MemoryCompressor as an interface to BZip
// Up to the caller to delete out
static bool CreatePatchInternal(const char *old, off_t oldsize, char *_new, off_t newsize, char **out, unsigned *outSize)
{
// int fd;
// u_char *old,*new;
// off_t oldsize,newsize;
off_t *I,*V;
off_t scan,len;
off_t pos = 0; // #low review whether this really is unnecessary - (presumably) unnecessary assignment - added to workaround false-positive of C4701
off_t lastscan,lastpos,lastoffset;
off_t oldscore,scsc;
off_t s,Sf,lenf,Sb,lenb;
off_t overlap,Ss,lens;
off_t i;
off_t dblen,eblen;
u_char *db,*eb;
u_char buf[8];
u_char header[32];
MemoryCompressor patch;
// unsigned outWriteOffset;
// FILE * pf;
// BZFILE * pfbz2;
// int bz2err;
// if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);
/* Allocate oldsize+1 bytes instead of oldsize bytes to ensure
that we never try to malloc(0) and get a nullptr */
/*
if(((fd=_open(argv[1],O_RDONLY | _O_BINARY ,0))<0) ||
((oldsize=_lseek(fd,0,SEEK_END))==-1) ||
((old=malloc(oldsize+1))==nullptr) ||
(_lseek(fd,0,SEEK_SET)!=0) ||
(_read(fd,old,oldsize)!=oldsize) ||
(_close(fd)==-1)) err(1,"%s",argv[1]);
*/
if(((I=(off_t*)malloc((oldsize+1)*sizeof(off_t)))== nullptr) ||
((V=(off_t*)malloc((oldsize+1)*sizeof(off_t)))== nullptr))
// err(1,nullptr);
return false;
qsufsort(I,V,(u_char*)old,oldsize);
free(V);
/* Allocate newsize+1 bytes instead of newsize bytes to ensure
that we never try to malloc(0) and get a nullptr */
/*
if(((fd=_open(argv[2],O_RDONLY | _O_BINARY ,0))<0) ||
((newsize=_lseek(fd,0,SEEK_END))==-1) ||
((new=malloc(newsize+1))==nullptr) ||
(_lseek(fd,0,SEEK_SET)!=0) ||
(_read(fd,new,newsize)!=newsize) ||
(_close(fd)==-1)) err(1,"%s",argv[2]);
*/
if(((db=(u_char*)malloc(newsize+1))== nullptr) ||
((eb=(u_char*)malloc(newsize+1))== nullptr))
// err(1,nullptr);
{
free(I);
return false;
}
dblen=0;
eblen=0;
/* Create the patch file */
// if (fopen_s(&pf, argv[3], "wb") !=0)
// err(1, "%s", argv[3]);
/* Header is
0 8 "BSDIFF40"
8 8 length of bzip2ed ctrl block
16 8 length of bzip2ed diff block
24 8 length of new file */
/* File is
0 32 Header
32 ?? Bzip2ed ctrl block
?? ?? Bzip2ed diff block
?? ?? Bzip2ed extra block */
memcpy(header,"BSDIFF40",8);
offtout(0, header + 8);
offtout(0, header + 16);
offtout(newsize, header + 24);
// if (fwrite(header, 32, 1, pf) != 1)
// err(1, "fwrite(%s)", argv[3]);
// Allocate enough to hold any output
// *out = (char*) malloc(oldsize+newsize);
// Copy out the header
// memcpy(*out, header, 32);
//outWriteOffset=32;
/* Compute the differences, writing ctrl as we go */
// if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == nullptr)
// errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
scan=0;len=0;
lastscan=0;lastpos=0;lastoffset=0;
while(scan<newsize) {
oldscore=0;
for(scsc=scan+=len;scan<newsize;scan++) {
len=search(I,(u_char*)old,oldsize,(u_char*)_new+scan,newsize-scan,
0,oldsize,&pos);
for(;scsc<scan+len;scsc++)
if((scsc+lastoffset<oldsize) &&
(old[scsc+lastoffset] == _new[scsc]))
oldscore++;
if(((len==oldscore) && (len!=0)) ||
(len>oldscore+8)) break;
if((scan+lastoffset<oldsize) &&
(old[scan+lastoffset] == _new[scan]))
oldscore--;
};
if((len!=oldscore) || (scan==newsize)) {
s=0;Sf=0;lenf=0;
for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) {
if(old[lastpos+i]==_new[lastscan+i]) s++;
i++;
if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; };
};
lenb=0;
if(scan<newsize) {
s=0;Sb=0;
for(i=1;(scan>=lastscan+i)&&(pos>=i);i++) {
if(old[pos-i]==_new[scan-i]) s++;
if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; };
};
};
if(lastscan+lenf>scan-lenb) {
overlap=(lastscan+lenf)-(scan-lenb);
s=0;Ss=0;lens=0;
for(i=0;i<overlap;i++) {
if(_new[lastscan+lenf-overlap+i]==
old[lastpos+lenf-overlap+i]) s++;
if(_new[scan-lenb+i]==
old[pos-lenb+i]) s--;
if(s>Ss) { Ss=s; lens=i+1; };
};
lenf+=lens-overlap;
lenb-=lens;
};
for(i=0;i<lenf;i++)
db[dblen+i]=_new[lastscan+i]-old[lastpos+i];
for(i=0;i<(scan-lenb)-(lastscan+lenf);i++)
eb[eblen+i]=_new[lastscan+lenf+i];
dblen+=lenf;
eblen+=(scan-lenb)-(lastscan+lenf);
offtout(lenf,buf);
if (patch.Compress((char*)buf, 8, false)==false)
{
free(db);
free(eb);
free(I);
return false;
}
//BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
//if (bz2err != BZ_OK)
// errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
offtout((scan-lenb)-(lastscan+lenf),buf);
if (patch.Compress((char*)buf, 8, false)==false)
{
free(db);
free(eb);
free(I);
return false;
}
//BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
//if (bz2err != BZ_OK)
// errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
offtout((pos-lenb)-(lastpos+lenf),buf);
if (patch.Compress((char*)buf, 8, false)==false)
{
free(db);
free(eb);
free(I);
return false;
}
//BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
//if (bz2err != BZ_OK)
// errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
lastscan=scan-lenb;
lastpos=pos-lenb;
lastoffset=pos-scan;
};
};
// BZ2_bzWriteClose(&bz2err, pfbz2, 0, nullptr, nullptr);
// if (bz2err != BZ_OK)
// errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
/* Compute size of compressed ctrl data */
// if ((len = ftello(pf)) == -1)
// err(1, "ftello");
if (patch.Compress(0,0,true)==false)
{
free(db);
free(eb);
free(I);
return false;
}
len=patch.GetTotalOutputSize()+32; // test: len should be 188
offtout(len-32, header + 8);
//memcpy(*out+outWriteOffset, patch.GetOutput(), patch.GetTotalOutputSize());
//outWriteOffset+=patch.GetTotalOutputSize();
//patch.Clear(_FILE_AND_LINE_);
/* Write compressed diff data */
// if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == nullptr)
// errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
// BZ2_bzWrite(&bz2err, pfbz2, db, dblen);
if (patch.Compress((char*)db,dblen,true)==false)
{
free(db);
free(eb);
free(I);
return false;
}
// memcpy(*out+outWriteOffset, patch.GetOutput(), patch.GetTotalOutputSize());
// outWriteOffset+=patch.GetTotalOutputSize();
// patch.Clear(_FILE_AND_LINE_);
// if (bz2err != BZ_OK)
// errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
// BZ2_bzWriteClose(&bz2err, pfbz2, 0, nullptr, nullptr);
// if (bz2err != BZ_OK)
// errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
/* Compute size of compressed diff data */
// if ((newsize = ftello(pf)) == -1)
// err(1, "ftello");
newsize=32+patch.GetTotalOutputSize();
offtout(newsize - len, header + 16);
// memcpy(*out+outWriteOffset, patch.GetOutput(), patch.GetTotalOutputSize());
// outWriteOffset+=patch.GetTotalOutputSize();
// patch.Clear(_FILE_AND_LINE_);
/* Write compressed extra data */
// if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == nullptr)
// errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
// BZ2_bzWrite(&bz2err, pfbz2, eb, eblen);
if (patch.Compress((char*)eb,eblen,true)==false)
{
free(db);
free(eb);
free(I);
return false;
}
// memcpy(*out+outWriteOffset, patch.GetOutput(), patch.GetTotalOutputSize());
// outWriteOffset+=patch.GetTotalOutputSize();
// patch.Clear(_FILE_AND_LINE_);
// if (bz2err != BZ_OK)
// errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
// BZ2_bzWriteClose(&bz2err, pfbz2, 0, nullptr, nullptr);
// if (bz2err != BZ_OK)
// errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
/* Seek to the beginning, write the header, and close the file */
// if (fseeko(pf, 0, SEEK_SET))
// err(1, "fseeko");
// if (fwrite(header, 32, 1, pf) != 1)
// err(1, "fwrite(%s)", argv[3]);
// if (fclose(pf))
// err(1, "fclose");
// memcpy(*out,header,32);
// *out=(char*) realloc(*out, outWriteOffset);
// *outSize=outWriteOffset;
*outSize=patch.GetTotalOutputSize()+32;
*out = new char [*outSize];
memcpy(*out, header, 32);
memcpy(*out+32, patch.GetOutput(), patch.GetTotalOutputSize());
/* Free the memory we used */
free(db);
free(eb);
free(I);
//free(old);
//free(new);
return true;
}
// #med - deprecate/remove this overload (alongside the other overloads except for the off_t version)
// Note: overloads provided, so to ensure we are API-wise backwards compatible with RakNet 4.082
// (i.e. for callers passing int rather than off_t types which due to the added unsigned overload would
// now trigger compile errors due to the ambiguous parameters)
bool CreatePatch(const char *old, unsigned oldsize, char *_new, unsigned int newsize, char **out, unsigned *outSize)
{
// we must ensure that we don't pass >= off_t-max values to CreatePatch since otherwise the behavior is undefined due to
// internal integer overflows when processing the pointers (in certain cases)
// hence test the values first and simply error out if we get too large values (effectively limiting this function to work
// with file sizes of 2 GB on Windows and 32-bit Linux/OSx (Linux/OSx 64-bit: will remain working with 4GB sized files as RakNet did
// due to off_t being 64-bit)
if (std::max(oldsize, newsize) > static_cast<unsigned long>(std::numeric_limits<off_t>::max())) {
return false;
}
return CreatePatchInternal(old, static_cast<off_t>(oldsize), _new, static_cast<off_t>(newsize), out, outSize);
}
bool CreatePatch(const char *old, int oldsize, char *_new, int newsize, char **out, unsigned *outSize)
{
return CreatePatchInternal(old, static_cast<off_t>(oldsize), _new, static_cast<off_t>(newsize), out, outSize);
}
bool CreatePatch(const char *old, int oldsize, char *_new, unsigned int newsize, char **out, unsigned *outSize)
{
if (newsize > static_cast<unsigned long>(std::numeric_limits<off_t>::max())) {
return false;
}
return CreatePatchInternal(old, static_cast<off_t>(oldsize), _new, static_cast<off_t>(newsize), out, outSize);
}
bool CreatePatch(const char *old, unsigned oldsize, char *_new, int newsize, char **out, unsigned *outSize)
{
if (oldsize > static_cast<unsigned long>(std::numeric_limits<off_t>::max())) {
return false;
}
return CreatePatchInternal(old, static_cast<off_t>(oldsize), _new, static_cast<off_t>(newsize), out, outSize);
}
bool CreatePatch(const char *old, off_t oldsize, char *_new, off_t newsize, char **out, unsigned *outSize)
{
return CreatePatchInternal(old, oldsize, _new, newsize, out, outSize);
}
int TestDiffInMemory(int argc,char *argv[])
{
char *old = nullptr; // unnecessary assignment - added to workaround false-positive of C4701
off_t oldsize = 0; // unnecessary assignment - added to workaround false-positive of C4701
char *_new = nullptr; // unnecessary assignment - added to workaround false-positive of C4701
off_t newsize = 0; // unnecessary assignment - added to workaround false-positive of C4701
char *out;
unsigned outSize;
if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);
int fd;
FILE * pf;
if(((fd=_open(argv[1],O_RDONLY | _O_BINARY ,0))<0) ||
((oldsize=_lseek(fd,0,SEEK_END))==-1) ||
((old=(char*)malloc(oldsize+1))== nullptr) ||
(_lseek(fd,0,SEEK_SET)!=0) ||
(_read(fd,old,oldsize)!=oldsize) ||
(_close(fd)==-1)) err(1,"%s",argv[1]);
if(((fd=_open(argv[2],O_RDONLY | _O_BINARY ,0))<0) ||
((newsize=_lseek(fd,0,SEEK_END))==-1) ||
((_new=(char*)malloc(newsize+1))== nullptr) ||
(_lseek(fd,0,SEEK_SET)!=0) ||
(_read(fd,_new,newsize)!=newsize) ||
(_close(fd)==-1)) err(1,"%s",argv[2]);
int res = CreatePatch(old, oldsize, _new, newsize, &out, &outSize);
if (fopen_s(&pf, argv[3], "wb") != 0)
err(1, "%s", argv[3]);
fwrite(out,outSize,1,pf);
fclose(pf);
delete[] out;
return res;
}
int DIFF_main(int argc,char *argv[])
{
int fd;
u_char *old = nullptr; // unnecessary assignment - added to workaround false-positive of C4701
u_char *_new;
off_t oldsize = 0; // unnecessary assignment - added to workaround false-positive of C4701
off_t newsize = 0; // unnecessary assignment - added to workaround false-positive of C4701
off_t *I;
off_t *V = nullptr; // unnecessary assignment - added to workaround false-positive of C4701
off_t scan,len;
off_t pos = 0; // #low review whether this really is unnecessary - (presumably) unnecessary assignment - added to workaround false-positive of C4701
off_t lastscan,lastpos,lastoffset;
off_t oldscore,scsc;
off_t s,Sf,lenf,Sb,lenb;
off_t overlap,Ss,lens;
off_t i;
off_t dblen,eblen;
u_char *db,*eb;
u_char buf[8];
u_char header[32];
FILE * pf;
BZFILE * pfbz2;
int bz2err;
int bytesWritten=0;
if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);
/* Allocate oldsize+1 bytes instead of oldsize bytes to ensure
that we never try to malloc(0) and get a nullptr */
if(((fd=_open(argv[1],O_RDONLY|O_BINARY,0))<0) ||
((oldsize=_lseek(fd,0,SEEK_END))==-1) ||
((old=(u_char*)malloc(oldsize+1))== nullptr) ||
(_lseek(fd,0,SEEK_SET)!=0) ||
(_read(fd,old,oldsize)!=oldsize) ||
(_close(fd)==-1)) err(1,"%s",argv[1]);
if(((I=(off_t*)malloc((oldsize+1)*sizeof(off_t)))== nullptr) ||
((V=(off_t*)malloc((oldsize+1)*sizeof(off_t)))== nullptr)) err(1, nullptr);
qsufsort(I,V,old,oldsize);
free(V);
/* Allocate newsize+1 bytes instead of newsize bytes to ensure
that we never try to malloc(0) and get a nullptr */
if(((fd=_open(argv[2],O_RDONLY|O_BINARY,0))<0) ||
((newsize=_lseek(fd,0,SEEK_END))==-1) ||
((_new=(u_char*)malloc(newsize+1))== nullptr) ||
(_lseek(fd,0,SEEK_SET)!=0) ||
(_read(fd,_new,newsize)!=newsize) ||
(_close(fd)==-1)) err(1,"%s",argv[2]);
if(((db=(u_char*)malloc(newsize+1))== nullptr) ||
((eb=(u_char*)malloc(newsize+1))== nullptr)) err(1, nullptr);
dblen=0;
eblen=0;
/* Create the patch file */
if (fopen_s(&pf, argv[3], "wb") != 0)
err(1, "%s", argv[3]);
/* Header is
0 8 "BSDIFF40"
8 8 length of bzip2ed ctrl block
16 8 length of bzip2ed diff block
24 8 length of new file */
/* File is
0 32 Header
32 ?? Bzip2ed ctrl block
?? ?? Bzip2ed diff block
?? ?? Bzip2ed extra block */
memcpy(header,"BSDIFF40",8);
offtout(0, header + 8);
offtout(0, header + 16);
offtout(newsize, header + 24);
if (fwrite(header, 32, 1, pf) != 1)
err(1, "fwrite(%s)", argv[3]);
/* Compute the differences, writing ctrl as we go */
if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == nullptr)
errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
scan=0;len=0;
lastscan=0;lastpos=0;lastoffset=0;
while(scan<newsize) {
oldscore=0;
for(scsc=scan+=len;scan<newsize;scan++) {
len=search(I,old,oldsize,_new+scan,newsize-scan,
0,oldsize,&pos);
for(;scsc<scan+len;scsc++)
if((scsc+lastoffset<oldsize) &&
(old[scsc+lastoffset] == _new[scsc]))
oldscore++;
if(((len==oldscore) && (len!=0)) ||
(len>oldscore+8)) break;
if((scan+lastoffset<oldsize) &&
(old[scan+lastoffset] == _new[scan]))
oldscore--;
};
if((len!=oldscore) || (scan==newsize)) {
s=0;Sf=0;lenf=0;
for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) {
if(old[lastpos+i]==_new[lastscan+i]) s++;
i++;
if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; };
};
lenb=0;
if(scan<newsize) {
s=0;Sb=0;
for(i=1;(scan>=lastscan+i)&&(pos>=i);i++) {
if(old[pos-i]==_new[scan-i]) s++;
if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; };
};
};
if(lastscan+lenf>scan-lenb) {
overlap=(lastscan+lenf)-(scan-lenb);
s=0;Ss=0;lens=0;
for(i=0;i<overlap;i++) {
if(_new[lastscan+lenf-overlap+i]==
old[lastpos+lenf-overlap+i]) s++;
if(_new[scan-lenb+i]==
old[pos-lenb+i]) s--;
if(s>Ss) { Ss=s; lens=i+1; };
};
lenf+=lens-overlap;
lenb-=lens;
};
for(i=0;i<lenf;i++)
db[dblen+i]=_new[lastscan+i]-old[lastpos+i];
for(i=0;i<(scan-lenb)-(lastscan+lenf);i++)
eb[eblen+i]=_new[lastscan+lenf+i];
dblen+=lenf;
eblen+=(scan-lenb)-(lastscan+lenf);
offtout(lenf,buf);
BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
if (bz2err != BZ_OK)
errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
bytesWritten+=8;
// printf("bz2err 8 %i\n", bytesWritten);
offtout((scan-lenb)-(lastscan+lenf),buf);
BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
if (bz2err != BZ_OK)
errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
bytesWritten+=8;
// printf("bz2err 8 %i\n", bytesWritten);
offtout((pos-lenb)-(lastpos+lenf),buf);
BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
if (bz2err != BZ_OK)
errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
bytesWritten+=8;
// printf("bz2err 8 %i\n", bytesWritten);
lastscan=scan-lenb;
lastpos=pos-lenb;
lastoffset=pos-scan;
};
};
BZ2_bzWriteClose(&bz2err, pfbz2, 0, nullptr, nullptr);
if (bz2err != BZ_OK)
errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
/* Compute size of compressed ctrl data */
if ((len = ftello(pf)) == -1)
err(1, "ftello");
offtout(len-32, header + 8);
/* Write compressed diff data */
if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == nullptr)
errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
BZ2_bzWrite(&bz2err, pfbz2, db, dblen);
bytesWritten+=dblen;
// printf("bz2err dblen %i %i\n", dblen, bytesWritten);
if (bz2err != BZ_OK)
errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
BZ2_bzWriteClose(&bz2err, pfbz2, 0, nullptr, nullptr);
if (bz2err != BZ_OK)
errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
/* Compute size of compressed diff data */
if ((newsize = ftello(pf)) == -1)
err(1, "ftello");
offtout(newsize - len, header + 16);
/* Write compressed extra data */
if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == nullptr)
errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
BZ2_bzWrite(&bz2err, pfbz2, eb, eblen);
if (bz2err != BZ_OK)
errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
bytesWritten+=eblen;
//printf("bz2err eblen %i %i\n", eblen, bytesWritten);
BZ2_bzWriteClose(&bz2err, pfbz2, 0, nullptr, nullptr);
if (bz2err != BZ_OK)
errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
// REMOVEME
// if ((newsize = ftello(pf)) == -1)
// err(1, "ftello");
/* Seek to the beginning, write the header, and close the file */
if (fseeko(pf, 0, SEEK_SET))
err(1, "fseeko");
if (fwrite(header, 32, 1, pf) != 1)
err(1, "fwrite(%s)", argv[3]);
if (fclose(pf))
err(1, "fclose");
/* Free the memory we used */
free(db);
free(eb);
free(I);
free(old);
free(_new);
return 0;
}

View File

@ -0,0 +1,20 @@
/*
* This file was taken from RakNet 4.082.
* Please see licenses/RakNet license.txt for the underlying license and related copyright.
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#ifdef _WIN32
typedef long off_t;
#endif
/// Given \a old and \a new , return \a out which will contain a patch to get from \a old to \a new . \a out is allocated for you.
bool CreatePatch(const char *old, off_t oldsize, char *_new, off_t newsize, char **out, unsigned *outSize);
bool CreatePatch(const char *old, int oldsize, char *_new, int newsize, char **out, unsigned *outSize);
bool CreatePatch(const char *old, unsigned oldsize, char *_new, unsigned int newsize, char **out, unsigned *outSize);
bool CreatePatch(const char *old, int oldsize, char *_new, unsigned int newsize, char **out, unsigned *outSize);
bool CreatePatch(const char *old, unsigned oldsize, char *_new, int newsize, char **out, unsigned *outSize);

View File

@ -0,0 +1,242 @@
/*
* Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*/
// See http://www.bzip.org/1.0.3/bzip2-manual-1.0.3.html#low-level for docs on bzip
#include "MemoryCompressor.h"
#include <assert.h>
#include <stdlib.h>
CompressorBase::CompressorBase()
{
output=0;
allocatedSize=0;
streamInited=false;
stream.bzalloc=0;
stream.bzfree=0;
stream.opaque=0;
totalRead=totalWritten=0;
}
CompressorBase::~CompressorBase()
{
}
MemoryCompressor::MemoryCompressor()
{
compressedInputLength=0;
}
MemoryCompressor::~MemoryCompressor()
{
Clear();
}
MemoryDecompressor::~MemoryDecompressor()
{
Clear();
}
bool MemoryCompressor::Compress(char *input, const unsigned inputLength, bool finish)
{
int res;
unsigned inBefore,outBefore, read;
unsigned written;
if (output==0)
{
allocatedSize=inputLength;
if (allocatedSize < BZ_MAX_UNUSED)
allocatedSize=BZ_MAX_UNUSED;
output=(char*)malloc(allocatedSize);
}
if (streamInited==false)
{
res = BZ2_bzCompressInit ( &stream,
9, // x 100K Block size. Memory to use = 400k + ( 8 x block size ). So this is 400K + 9 x 900K = 7.6 megabytes. Larger sizes give better compression.
0, // Verbosity.
0 ); // Default work factor
streamInited=true;
if (res!=BZ_OK)
return false;
}
read=written=0;
unsigned readThisSession;
readThisSession=0;
compressedInputLength+=inputLength;
if (totalWritten==allocatedSize)
{
allocatedSize+=inputLength;
output=(char*)realloc(output, allocatedSize);
}
while(1)
{
stream.next_out=output+totalWritten;
stream.avail_in=inputLength-readThisSession;
stream.avail_out=allocatedSize-totalWritten;
stream.next_in=input+readThisSession;
inBefore=stream.total_in_lo32;
outBefore=stream.total_out_lo32;
//printf("%i\n", stream.avail_in);
res = BZ2_bzCompress( &stream, finish ? BZ_FINISH : BZ_RUN );
read=stream.total_in_lo32-inBefore;
written=stream.total_out_lo32-outBefore;
totalRead+=read;
totalWritten+=written;
readThisSession+=read;
if (stream.avail_out>0)
// if ((stream.avail_in==0 && stream.avail_out>0) || (read==0 && written==0))
{
if (finish)
{
allocatedSize=GetTotalOutputSize();
output=(char*)realloc(output,allocatedSize);
BZ2_bzCompressEnd( &stream );
streamInited=false;
}
return true;
}
if (totalWritten==allocatedSize || read==0)
{
allocatedSize*=2;
output=(char*)realloc(output, allocatedSize);
}
}
}
bool MemoryDecompressor::Decompress(char *input, const unsigned inputLength, bool ignoreStreamEnd)
{
unsigned inBefore,outBefore, read;
unsigned written;
int res;
if (output==0)
{
allocatedSize=inputLength*2;
if (allocatedSize < BZ_MAX_UNUSED)
allocatedSize=BZ_MAX_UNUSED;
output=(char*)malloc(allocatedSize);
}
if (streamInited==false)
{
res = BZ2_bzDecompressInit( &stream,
0, // Verbosity.
0 ); // Disable small memory usage
streamInited=true;
if (res!=BZ_OK)
return false;
}
unsigned readThisSession;
readThisSession=0;
read=written=0;
if (totalWritten==allocatedSize)
{
allocatedSize+=inputLength*4;
output=(char*)realloc(output, allocatedSize);
}
while(1)
{
stream.next_out=output+totalWritten;
stream.avail_in=inputLength-readThisSession;
stream.avail_out=allocatedSize-totalWritten;
stream.next_in=input+readThisSession;
inBefore=stream.total_in_lo32;
outBefore=stream.total_out_lo32;
res = BZ2_bzDecompress( &stream );
read=stream.total_in_lo32-inBefore;
written=stream.total_out_lo32-outBefore;
readThisSession+=read;
totalRead+=read;
totalWritten+=written;
if (res==BZ_STREAM_END)
{
BZ2_bzDecompressEnd( &stream );
if (ignoreStreamEnd==true)
{
// Stream end marker but there is more data so just keep reading
res = BZ2_bzDecompressInit( &stream,
0, // Verbosity.
0 ); // Disable small memory usage
}
else
{
streamInited=false;
return true;
}
}
else if ((stream.avail_in==0 && stream.avail_out>0) || (read==0 && written==0))
{
allocatedSize=GetTotalOutputSize();
output=(char*)realloc(output,allocatedSize);
return true;
}
else if (res!=BZ_OK)
{
Clear();
return false;
}
if (totalWritten==allocatedSize || read==0)
{
allocatedSize+=inputLength*4;
output=(char*)realloc(output, allocatedSize);
}
}
}
char *CompressorBase::GetOutput(void) const
{
return output;
}
unsigned MemoryCompressor::GetCompressedInputLength(void) const
{
return compressedInputLength;
}
unsigned CompressorBase::GetTotalOutputSize(void) const
{
return totalWritten;
}
unsigned CompressorBase::GetTotalInputSize(void) const
{
return totalRead;
}
void MemoryCompressor::Clear(void)
{
if (output)
{
free(output);
output=0;
}
if (streamInited)
BZ2_bzCompressEnd( &stream );
totalRead=totalWritten=compressedInputLength=0;
}
void MemoryDecompressor::Clear(void)
{
if (output)
{
free(output);
output=0;
}
if (streamInited)
BZ2_bzDecompressEnd( &stream );
}

View File

@ -0,0 +1,83 @@
/*
* Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*/
#ifndef _MEMORY_COMPRESSOR_H
#define _MEMORY_COMPRESSOR_H
#include "bzlib.h"
/// \internal
/// Do not use this class directly. Use MemoryCompressor and MemoryDecompressor.
class CompressorBase
{
public:
CompressorBase();
~CompressorBase();
/// Get the compressed data. The length currently written is returned from GetTotalOutputSize().
/// \return The compressed data
char *GetOutput(void) const;
/// \return The number of bytes outputted so far.
unsigned GetTotalOutputSize(void) const;
/// \return The number of bytes input by the user so far
unsigned GetTotalInputSize(void) const;
protected:
bz_stream stream;
char *output;
unsigned allocatedSize;
unsigned totalRead, totalWritten;
bool streamInited;
};
/// Compress one or more blocks of data
class MemoryCompressor : public CompressorBase
{
public:
MemoryCompressor();
~MemoryCompressor();
/// Compress a block of data. Pass true to finish if this is the last block in the series. If you don't know if it's the last block, you can call it again with 0 for inputLength
/// \note Data passed to input isn't necessarily immediately compressed to output. You can force a write by passing true to finish.
/// Multiple calls concatenate the written data.
/// \param[in] input A pointer to a block of data
/// \param[in] inputLength The length of input
/// \param[in] finish Write the last of the data.
bool Compress(char *input, const unsigned inputLength, bool finish);
/// Resets the compressor and all data.
void Clear(void);
// Number of bytes total passed to /a inputLength in the Compress() function
unsigned GetCompressedInputLength(void) const;
protected:
unsigned compressedInputLength;
};
class MemoryDecompressor : public CompressorBase
{
public:
~MemoryDecompressor();
/// Read \a inputLength bytes of compressed data from \a input
/// Writes the decompressed output to GetOutput(). Note that unlike the class MemoryCompressor, output data is updated immediately and not internally buffered
/// \param[in] input A pointer to a block of data
/// \param[in] inputLength The length of input
/// \param[in] ignoreStreamEnd Normally when Compress is called with finish==true stream end markers are placed. These are honored, such that the read will end early if a stream marker is hit. Pass true to ignore this and just output all the data.
bool Decompress(char *input, const unsigned inputLength, bool ignoreStreamEnd);
/// Resets the compressor and all data.
void Clear(void);
};
#endif

View File

@ -0,0 +1,81 @@
#
# This file was taken from RakNet 4.082.
# Please see licenses/RakNet license.txt for the underlying license and related copyright.
#
#
# Modified work: Copyright (c) 2019, SLikeSoft UG (haftungsbeschr<68>nkt)
#
# This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
# license found in the license.txt file in the root directory of this source tree.
#
cmake_minimum_required(VERSION 2.6)
option( RAKNET_ENABLE_EXTENSIONS "Enable extension projects that might need specific dependencies." TRUE )
option( RAKNET_EXTENSION_USEMYSQL "Enable extensions using MySQL" TRUE )
option( RAKNET_EXTENSION_USEPOSTGRESQL "Enable extensions using PostgreSQL" TRUE )
option( RAKNET_EXTENSION_USEBOOST "Enable extensions using Boost" TRUE )
option( RAKNET_EXTENSION_USESPEEX "Enable extensions using Speex" TRUE )
option( RAKNET_EXTENSION_USEIRRLICHT "Enable extensions using Irrlicht" TRUE )
option( RAKNET_EXTENSION_USEIRRKLANG "Enable extensions using Irkklang" TRUE )
option( RAKNET_EXTENSION_USEOGRE3D "Enable extensions using Ogre3D" TRUE )
option( RAKNET_EXTENSION_Autopatcher "Enable Autopatcher extension" TRUE )
add_subdirectory("bzip2-1.0.6")
add_subdirectory("XML")
if( RAKNET_ENABLE_EXTENSIONS )
IF(RAKNET_EXTENSION_USEMYSQL )
add_subdirectory(MySQLInterface)
ENDIF()
IF(RAKNET_EXTENSION_USEPOSTGRESQL)
add_subdirectory(PostgreSQLInterface)
ENDIF()
endif()
if( RAKNET_EXTENSION_Autopatcher )
add_subdirectory(Autopatcher)
endif()
IF (WIN32 AND NOT UNIX)
IF(NOT ${CMAKE_GENERATOR} STREQUAL "MSYS Makefiles")
add_subdirectory(portaudio_v18_1)
ENDIF(NOT ${CMAKE_GENERATOR} STREQUAL "MSYS Makefiles")
add_subdirectory(speex-1.1.12)
ENDIF(WIN32 AND NOT UNIX)
if( RAKNET_ENABLE_EXTENSIONS )
IF(RAKNET_EXTENSION_USEBOOST)
add_subdirectory(RPC3)
ENDIF()
endif()
IF(NOT WIN32 AND UNIX)
IF(RAKNET_EXTENSION_USESPEEX AND RAKNET_ENABLE_EXTENSIONS)
FINDSPEEX()
include_directories(${SLIKENET_HEADER_FILES} ${SPEEX_INCLUDE_DIRS})
add_library(LibRakVoice STATIC RakVoice.h RakVoice.cpp)
target_link_libraries(LibRakVoice ${SLIKENET_COMMON_LIBS} ${SPEEX_LIBRARIES})
ENDIF()
ENDIF()
if( RAKNET_ENABLE_EXTENSIONS )
IF( RAKNET_EXTENSION_USEIRRLICHT AND RAKNET_EXTENSION_USEIRRKLANG )
add_subdirectory(IrrlichtDemo)
ENDIF()
IF( RAKNET_EXTENSION_USEOGRE3D )
add_subdirectory(Ogre3DInterpDemo)
ENDIF()
endif()

View File

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DXTCompressor", "DXTCompressor.vcxproj", "{5CBD4DE3-AB31-4800-BAE2-4FD13AD1ECD0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5CBD4DE3-AB31-4800-BAE2-4FD13AD1ECD0}.Debug|Win32.ActiveCfg = Debug|Win32
{5CBD4DE3-AB31-4800-BAE2-4FD13AD1ECD0}.Debug|Win32.Build.0 = Debug|Win32
{5CBD4DE3-AB31-4800-BAE2-4FD13AD1ECD0}.Release|Win32.ActiveCfg = Release|Win32
{5CBD4DE3-AB31-4800-BAE2-4FD13AD1ECD0}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{5CBD4DE3-AB31-4800-BAE2-4FD13AD1ECD0}</ProjectGuid>
<RootNamespace>DXTCompressor</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>External\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(ProjectName).exe</OutputFile>
<AdditionalLibraryDirectories>External\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>External\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>External\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Src\DXTCompressor.cpp" />
<ClCompile Include="Src\main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Src\DXTCompressor.h" />
<ClInclude Include="Src\FrameBufferRenderBuffer.hpp" />
<ClInclude Include="Src\OpenGLWindow.hpp" />
<ClInclude Include="Src\ShaderSource.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Src\DXTCompressor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Src\main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Src\DXTCompressor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Src\FrameBufferRenderBuffer.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Src\OpenGLWindow.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Src\ShaderSource.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,758 @@
/*
*
* Copyright (c) 2002-2009, NVIDIA Corporation.
*
*
*
* NVIDIA Corporation("NVIDIA") supplies this software to you in consideration
* of your agreement to the following terms, and your use, installation,
* modification or redistribution of this NVIDIA software constitutes
* acceptance of these terms. If you do not agree with these terms, please do
* not use, install, modify or redistribute this NVIDIA software.
*
*
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, NVIDIA grants you a personal, non-exclusive license,
* under NVIDIA's copyrights in this original NVIDIA software (the "NVIDIA
* Software"), to use, reproduce, modify and redistribute the NVIDIA
* Software, with or without modifications, in source and/or binary forms;
* provided that if you redistribute the NVIDIA Software, you must retain the
* copyright notice of NVIDIA, this notice and the following text and
* disclaimers in all such redistributions of the NVIDIA Software. Neither the
* name, trademarks, service marks nor logos of NVIDIA Corporation may be used
* to endorse or promote products derived from the NVIDIA Software without
* specific prior written permission from NVIDIA. Except as expressly stated
* in this notice, no other rights or licenses express or implied, are granted
* by NVIDIA herein, including but not limited to any patent rights that may be
* infringed by your derivative works or by other works in which the NVIDIA
* Software may be incorporated. No hardware is licensed hereunder.
*
*
*
* THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
* WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR ITS USE AND OPERATION
* EITHER ALONE OR IN COMBINATION WITH OTHER PRODUCTS.
*
*
*
* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
* EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOST
* PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY OUT OF THE USE,
* REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE NVIDIA SOFTWARE,
* HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING
* NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF NVIDIA HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef _cg_h
#define _cg_h
/*************************************************************************/
/*** CG Run-Time Library API ***/
/*************************************************************************/
#define CG_VERSION_NUM 2200
#ifdef _WIN32
# ifndef APIENTRY /* From Win32's <windef.h> */
# define CG_APIENTRY_DEFINED
# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) || defined(__LCC__)
# define APIENTRY __stdcall
# else
# define APIENTRY
# endif
# endif
# ifndef WINGDIAPI /* From Win32's <wingdi.h> and <winnt.h> */
# define CG_WINGDIAPI_DEFINED
# define WINGDIAPI __declspec(dllimport)
# endif
#endif /* _WIN32 */
/* Set up CG_API for Win32 dllexport or gcc visibility */
#ifndef CG_API
# ifdef CG_EXPORTS
# ifdef _WIN32
# define CG_API __declspec(dllexport)
# elif defined(__GNUC__) && __GNUC__>=4
# define CG_API __attribute__ ((visibility("default")))
# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
# define CG_API __global
# else
# define CG_API
# endif
# else
# define CG_API
# endif
#endif
#ifndef CGENTRY
# ifdef _WIN32
# define CGENTRY __cdecl
# else
# define CGENTRY
# endif
#endif
/*************************************************************************/
/*** Data types and enumerants ***/
/*************************************************************************/
typedef int CGbool;
#define CG_FALSE ((CGbool)0)
#define CG_TRUE ((CGbool)1)
typedef struct _CGcontext *CGcontext;
typedef struct _CGprogram *CGprogram;
typedef struct _CGparameter *CGparameter;
typedef struct _CGobj *CGobj;
typedef struct _CGbuffer *CGbuffer;
typedef struct _CGeffect *CGeffect;
typedef struct _CGtechnique *CGtechnique;
typedef struct _CGpass *CGpass;
typedef struct _CGstate *CGstate;
typedef struct _CGstateassignment *CGstateassignment;
typedef struct _CGannotation *CGannotation;
typedef void *CGhandle;
/*!!! PREPROCESS BEGIN */
typedef enum
{
CG_UNKNOWN_TYPE,
CG_STRUCT,
CG_ARRAY,
CG_TYPELESS_STRUCT,
CG_TYPE_START_ENUM = 1024,
#define CG_DATATYPE_MACRO(name, compiler_name, enum_name, base_name, ncols, nrows, pc) \
enum_name ,
#include <Cg/cg_datatypes.h>
#undef CG_DATATYPE_MACRO
CG_TYPE_MAX
} CGtype;
typedef enum
{
# define CG_BINDLOCATION_MACRO(name,enum_name,compiler_name,\
enum_int,addressable,param_type) \
enum_name = enum_int,
#include <Cg/cg_bindlocations.h>
CG_UNDEFINED = 3256
} CGresource;
typedef enum
{
CG_PROFILE_START = 6144,
CG_PROFILE_UNKNOWN,
#define CG_PROFILE_MACRO(name, compiler_id, compiler_id_caps, compiler_opt,int_id,vertex_profile) \
CG_PROFILE_##compiler_id_caps = int_id,
#define CG_PROFILE_ALIAS(name, compiler_id, compiler_id_caps, compiler_opt,int_id,vertex_profile) \
CG_PROFILE_MACRO(name, compiler_id, compiler_id_caps, compiler_opt,int_id,vertex_profile)
#include <Cg/cg_profiles.h>
CG_PROFILE_MAX = 7100
} CGprofile;
typedef enum
{
#define CG_ERROR_MACRO(code, enum_name, message) \
enum_name = code,
#include <Cg/cg_errors.h>
CG_ERROR_MAX
} CGerror;
typedef enum
{
#define CG_ENUM_MACRO(enum_name, enum_val) \
enum_name = enum_val,
#include <Cg/cg_enums.h>
CG_ENUM_MAX
} CGenum;
/*!!! PREPROCESS END */
typedef enum
{
CG_PARAMETERCLASS_UNKNOWN = 0,
CG_PARAMETERCLASS_SCALAR,
CG_PARAMETERCLASS_VECTOR,
CG_PARAMETERCLASS_MATRIX,
CG_PARAMETERCLASS_STRUCT,
CG_PARAMETERCLASS_ARRAY,
CG_PARAMETERCLASS_SAMPLER,
CG_PARAMETERCLASS_OBJECT,
CG_PARAMETERCLASS_MAX
} CGparameterclass;
typedef enum
{
CG_UNKNOWN_DOMAIN = 0,
CG_FIRST_DOMAIN = 1,
CG_VERTEX_DOMAIN = 1,
CG_FRAGMENT_DOMAIN,
CG_GEOMETRY_DOMAIN,
CG_NUMBER_OF_DOMAINS,
CG_DOMAIN_MAX
} CGdomain;
typedef enum
{
CG_MAP_READ = 0,
CG_MAP_WRITE,
CG_MAP_READ_WRITE,
CG_MAP_WRITE_DISCARD,
CG_MAP_WRITE_NO_OVERWRITE,
CG_MAP_MAX
} CGbufferaccess;
typedef enum
{
CG_BUFFER_USAGE_STREAM_DRAW = 0,
CG_BUFFER_USAGE_STREAM_READ,
CG_BUFFER_USAGE_STREAM_COPY,
CG_BUFFER_USAGE_STATIC_DRAW,
CG_BUFFER_USAGE_STATIC_READ,
CG_BUFFER_USAGE_STATIC_COPY,
CG_BUFFER_USAGE_DYNAMIC_DRAW,
CG_BUFFER_USAGE_DYNAMIC_READ,
CG_BUFFER_USAGE_DYNAMIC_COPY,
CG_BUFFER_USAGE_MAX
} CGbufferusage;
#ifdef __cplusplus
extern "C" {
#endif
typedef CGbool (CGENTRY * CGstatecallback)(CGstateassignment);
typedef void (CGENTRY * CGerrorCallbackFunc)(void);
typedef void (CGENTRY * CGerrorHandlerFunc)(CGcontext ctx, CGerror err, void *data);
typedef void (CGENTRY * CGIncludeCallbackFunc)(CGcontext ctx, const char *filename);
/*************************************************************************/
/*** Functions ***/
/*************************************************************************/
#ifndef CG_EXPLICIT
/*** Library policy functions ***/
CG_API CGenum CGENTRY cgSetLockingPolicy(CGenum lockingPolicy);
CG_API CGenum CGENTRY cgGetLockingPolicy(void);
CG_API CGenum CGENTRY cgSetSemanticCasePolicy(CGenum casePolicy);
CG_API CGenum CGENTRY cgGetSemanticCasePolicy(void);
/*** Context functions ***/
CG_API CGcontext CGENTRY cgCreateContext(void);
CG_API void CGENTRY cgDestroyContext(CGcontext ctx);
CG_API CGbool CGENTRY cgIsContext(CGcontext ctx);
CG_API const char * CGENTRY cgGetLastListing(CGcontext ctx);
CG_API void CGENTRY cgSetLastListing(CGhandle handle, const char *listing);
CG_API void CGENTRY cgSetAutoCompile(CGcontext ctx, CGenum flag);
CG_API CGenum CGENTRY cgGetAutoCompile(CGcontext ctx);
CG_API void CGENTRY cgSetParameterSettingMode(CGcontext ctx, CGenum parameterSettingMode);
CG_API CGenum CGENTRY cgGetParameterSettingMode(CGcontext ctx);
/*** Inclusion ***/
CG_API void CGENTRY cgSetCompilerIncludeString(CGcontext ctx, const char *name, const char *source);
CG_API void CGENTRY cgSetCompilerIncludeFile(CGcontext ctx, const char *name, const char *filename);
CG_API void CGENTRY cgSetCompilerIncludeCallback(CGcontext ctx, CGIncludeCallbackFunc func);
CG_API CGIncludeCallbackFunc CGENTRY cgGetCompilerIncludeCallback(CGcontext ctx);
/*** Program functions ***/
CG_API CGprogram CGENTRY cgCreateProgram(CGcontext ctx,
CGenum program_type,
const char *program,
CGprofile profile,
const char *entry,
const char **args);
CG_API CGprogram CGENTRY cgCreateProgramFromFile(CGcontext ctx,
CGenum program_type,
const char *program_file,
CGprofile profile,
const char *entry,
const char **args);
CG_API CGprogram CGENTRY cgCopyProgram(CGprogram program);
CG_API void CGENTRY cgDestroyProgram(CGprogram program);
CG_API CGprogram CGENTRY cgGetFirstProgram(CGcontext ctx);
CG_API CGprogram CGENTRY cgGetNextProgram(CGprogram current);
CG_API CGcontext CGENTRY cgGetProgramContext(CGprogram prog);
CG_API CGbool CGENTRY cgIsProgram(CGprogram program);
CG_API void CGENTRY cgCompileProgram(CGprogram program);
CG_API CGbool CGENTRY cgIsProgramCompiled(CGprogram program);
CG_API const char * CGENTRY cgGetProgramString(CGprogram prog, CGenum pname);
CG_API CGprofile CGENTRY cgGetProgramProfile(CGprogram prog);
CG_API char const * const * CGENTRY cgGetProgramOptions(CGprogram prog);
CG_API void CGENTRY cgSetProgramProfile(CGprogram prog, CGprofile profile);
CG_API CGenum CGENTRY cgGetProgramInput(CGprogram program);
CG_API CGenum CGENTRY cgGetProgramOutput(CGprogram program);
CG_API void CGENTRY cgSetPassProgramParameters(CGprogram);
CG_API void CGENTRY cgUpdateProgramParameters(CGprogram program);
CG_API void CGENTRY cgUpdatePassParameters(CGpass pass);
/*** Parameter functions ***/
CG_API CGparameter CGENTRY cgCreateParameter(CGcontext ctx, CGtype type);
CG_API CGparameter CGENTRY cgCreateParameterArray(CGcontext ctx,
CGtype type,
int length);
CG_API CGparameter CGENTRY cgCreateParameterMultiDimArray(CGcontext ctx,
CGtype type,
int dim,
const int *lengths);
CG_API void CGENTRY cgDestroyParameter(CGparameter param);
CG_API void CGENTRY cgConnectParameter(CGparameter from, CGparameter to);
CG_API void CGENTRY cgDisconnectParameter(CGparameter param);
CG_API CGparameter CGENTRY cgGetConnectedParameter(CGparameter param);
CG_API int CGENTRY cgGetNumConnectedToParameters(CGparameter param);
CG_API CGparameter CGENTRY cgGetConnectedToParameter(CGparameter param, int index);
CG_API CGparameter CGENTRY cgGetNamedParameter(CGprogram prog, const char *name);
CG_API CGparameter CGENTRY cgGetNamedProgramParameter(CGprogram prog,
CGenum name_space,
const char *name);
CG_API CGparameter CGENTRY cgGetFirstParameter(CGprogram prog, CGenum name_space);
CG_API CGparameter CGENTRY cgGetNextParameter(CGparameter current);
CG_API CGparameter CGENTRY cgGetFirstLeafParameter(CGprogram prog, CGenum name_space);
CG_API CGparameter CGENTRY cgGetNextLeafParameter(CGparameter current);
CG_API CGparameter CGENTRY cgGetFirstStructParameter(CGparameter param);
CG_API CGparameter CGENTRY cgGetNamedStructParameter(CGparameter param,
const char *name);
CG_API CGparameter CGENTRY cgGetFirstDependentParameter(CGparameter param);
CG_API CGparameter CGENTRY cgGetArrayParameter(CGparameter aparam, int index);
CG_API int CGENTRY cgGetArrayDimension(CGparameter param);
CG_API CGtype CGENTRY cgGetArrayType(CGparameter param);
CG_API int CGENTRY cgGetArraySize(CGparameter param, int dimension);
CG_API int CGENTRY cgGetArrayTotalSize(CGparameter param);
CG_API void CGENTRY cgSetArraySize(CGparameter param, int size);
CG_API void CGENTRY cgSetMultiDimArraySize(CGparameter param, const int *sizes);
CG_API CGprogram CGENTRY cgGetParameterProgram(CGparameter param);
CG_API CGcontext CGENTRY cgGetParameterContext(CGparameter param);
CG_API CGbool CGENTRY cgIsParameter(CGparameter param);
CG_API const char * CGENTRY cgGetParameterName(CGparameter param);
CG_API CGtype CGENTRY cgGetParameterType(CGparameter param);
CG_API CGtype CGENTRY cgGetParameterBaseType(CGparameter param);
CG_API CGparameterclass CGENTRY cgGetParameterClass(CGparameter param);
CG_API int CGENTRY cgGetParameterRows(CGparameter param);
CG_API int CGENTRY cgGetParameterColumns(CGparameter param);
CG_API CGtype CGENTRY cgGetParameterNamedType(CGparameter param);
CG_API const char * CGENTRY cgGetParameterSemantic(CGparameter param);
CG_API CGresource CGENTRY cgGetParameterResource(CGparameter param);
CG_API CGresource CGENTRY cgGetParameterBaseResource(CGparameter param);
CG_API unsigned long CGENTRY cgGetParameterResourceIndex(CGparameter param);
CG_API CGenum CGENTRY cgGetParameterVariability(CGparameter param);
CG_API CGenum CGENTRY cgGetParameterDirection(CGparameter param);
CG_API CGbool CGENTRY cgIsParameterReferenced(CGparameter param);
CG_API CGbool CGENTRY cgIsParameterUsed(CGparameter param, CGhandle handle);
CG_API const double * CGENTRY cgGetParameterValues(CGparameter param,
CGenum value_type,
int *nvalues);
CG_API void CGENTRY cgSetParameterValuedr(CGparameter param, int n, const double *vals);
CG_API void CGENTRY cgSetParameterValuedc(CGparameter param, int n, const double *vals);
CG_API void CGENTRY cgSetParameterValuefr(CGparameter param, int n, const float *vals);
CG_API void CGENTRY cgSetParameterValuefc(CGparameter param, int n, const float *vals);
CG_API void CGENTRY cgSetParameterValueir(CGparameter param, int n, const int *vals);
CG_API void CGENTRY cgSetParameterValueic(CGparameter param, int n, const int *vals);
CG_API int CGENTRY cgGetParameterValuedr(CGparameter param, int n, double *vals);
CG_API int CGENTRY cgGetParameterValuedc(CGparameter param, int n, double *vals);
CG_API int CGENTRY cgGetParameterValuefr(CGparameter param, int n, float *vals);
CG_API int CGENTRY cgGetParameterValuefc(CGparameter param, int n, float *vals);
CG_API int CGENTRY cgGetParameterValueir(CGparameter param, int n, int *vals);
CG_API int CGENTRY cgGetParameterValueic(CGparameter param, int n, int *vals);
CG_API int CGENTRY cgGetParameterDefaultValuedr(CGparameter param, int n, double *vals);
CG_API int CGENTRY cgGetParameterDefaultValuedc(CGparameter param, int n, double *vals);
CG_API int CGENTRY cgGetParameterDefaultValuefr(CGparameter param, int n, float *vals);
CG_API int CGENTRY cgGetParameterDefaultValuefc(CGparameter param, int n, float *vals);
CG_API int CGENTRY cgGetParameterDefaultValueir(CGparameter param, int n, int *vals);
CG_API int CGENTRY cgGetParameterDefaultValueic(CGparameter param, int n, int *vals);
CG_API const char * CGENTRY cgGetStringParameterValue(CGparameter param);
CG_API void CGENTRY cgSetStringParameterValue(CGparameter param, const char *str);
CG_API int CGENTRY cgGetParameterOrdinalNumber(CGparameter param);
CG_API CGbool CGENTRY cgIsParameterGlobal(CGparameter param);
CG_API int CGENTRY cgGetParameterIndex(CGparameter param);
CG_API void CGENTRY cgSetParameterVariability(CGparameter param, CGenum vary);
CG_API void CGENTRY cgSetParameterSemantic(CGparameter param, const char *semantic);
CG_API void CGENTRY cgSetParameter1f(CGparameter param, float x);
CG_API void CGENTRY cgSetParameter2f(CGparameter param, float x, float y);
CG_API void CGENTRY cgSetParameter3f(CGparameter param, float x, float y, float z);
CG_API void CGENTRY cgSetParameter4f(CGparameter param,
float x,
float y,
float z,
float w);
CG_API void CGENTRY cgSetParameter1d(CGparameter param, double x);
CG_API void CGENTRY cgSetParameter2d(CGparameter param, double x, double y);
CG_API void CGENTRY cgSetParameter3d(CGparameter param,
double x,
double y,
double z);
CG_API void CGENTRY cgSetParameter4d(CGparameter param,
double x,
double y,
double z,
double w);
CG_API void CGENTRY cgSetParameter1i(CGparameter param, int x);
CG_API void CGENTRY cgSetParameter2i(CGparameter param, int x, int y);
CG_API void CGENTRY cgSetParameter3i(CGparameter param, int x, int y, int z);
CG_API void CGENTRY cgSetParameter4i(CGparameter param,
int x,
int y,
int z,
int w);
CG_API void CGENTRY cgSetParameter1iv(CGparameter param, const int *v);
CG_API void CGENTRY cgSetParameter2iv(CGparameter param, const int *v);
CG_API void CGENTRY cgSetParameter3iv(CGparameter param, const int *v);
CG_API void CGENTRY cgSetParameter4iv(CGparameter param, const int *v);
CG_API void CGENTRY cgSetParameter1fv(CGparameter param, const float *v);
CG_API void CGENTRY cgSetParameter2fv(CGparameter param, const float *v);
CG_API void CGENTRY cgSetParameter3fv(CGparameter param, const float *v);
CG_API void CGENTRY cgSetParameter4fv(CGparameter param, const float *v);
CG_API void CGENTRY cgSetParameter1dv(CGparameter param, const double *v);
CG_API void CGENTRY cgSetParameter2dv(CGparameter param, const double *v);
CG_API void CGENTRY cgSetParameter3dv(CGparameter param, const double *v);
CG_API void CGENTRY cgSetParameter4dv(CGparameter param, const double *v);
CG_API void CGENTRY cgSetMatrixParameterir(CGparameter param, const int *matrix);
CG_API void CGENTRY cgSetMatrixParameterdr(CGparameter param, const double *matrix);
CG_API void CGENTRY cgSetMatrixParameterfr(CGparameter param, const float *matrix);
CG_API void CGENTRY cgSetMatrixParameteric(CGparameter param, const int *matrix);
CG_API void CGENTRY cgSetMatrixParameterdc(CGparameter param, const double *matrix);
CG_API void CGENTRY cgSetMatrixParameterfc(CGparameter param, const float *matrix);
CG_API void CGENTRY cgGetMatrixParameterir(CGparameter param, int *matrix);
CG_API void CGENTRY cgGetMatrixParameterdr(CGparameter param, double *matrix);
CG_API void CGENTRY cgGetMatrixParameterfr(CGparameter param, float *matrix);
CG_API void CGENTRY cgGetMatrixParameteric(CGparameter param, int *matrix);
CG_API void CGENTRY cgGetMatrixParameterdc(CGparameter param, double *matrix);
CG_API void CGENTRY cgGetMatrixParameterfc(CGparameter param, float *matrix);
CG_API CGenum CGENTRY cgGetMatrixParameterOrder(CGparameter param);
CG_API CGparameter CGENTRY cgGetNamedSubParameter(CGparameter param, const char *name);
/*** Type Functions ***/
CG_API const char * CGENTRY cgGetTypeString(CGtype type);
CG_API CGtype CGENTRY cgGetType(const char *type_string);
CG_API CGtype CGENTRY cgGetNamedUserType(CGhandle handle, const char *name);
CG_API int CGENTRY cgGetNumUserTypes(CGhandle handle);
CG_API CGtype CGENTRY cgGetUserType(CGhandle handle, int index);
CG_API int CGENTRY cgGetNumParentTypes(CGtype type);
CG_API CGtype CGENTRY cgGetParentType(CGtype type, int index);
CG_API CGbool CGENTRY cgIsParentType(CGtype parent, CGtype child);
CG_API CGbool CGENTRY cgIsInterfaceType(CGtype type);
/*** Resource Functions ***/
CG_API const char * CGENTRY cgGetResourceString(CGresource resource);
CG_API CGresource CGENTRY cgGetResource(const char *resource_string);
/*** Enum Functions ***/
CG_API const char * CGENTRY cgGetEnumString(CGenum en);
CG_API CGenum CGENTRY cgGetEnum(const char *enum_string);
/*** Profile Functions ***/
CG_API const char * CGENTRY cgGetProfileString(CGprofile profile);
CG_API CGprofile CGENTRY cgGetProfile(const char *profile_string);
CG_API int CGENTRY cgGetNumSupportedProfiles(void);
CG_API CGprofile CGENTRY cgGetSupportedProfile(int index);
CG_API CGbool CGENTRY cgIsProfileSupported(CGprofile profile);
CG_API CGbool CGENTRY cgGetProfileProperty(CGprofile profile, CGenum query);
/*** ParameterClass Functions ***/
CG_API const char * CGENTRY cgGetParameterClassString(CGparameterclass pc);
CG_API CGparameterclass CGENTRY cgGetParameterClassEnum(const char * pString);
/*** Domain Functions ***/
CG_API const char * CGENTRY cgGetDomainString(CGdomain domain);
CG_API CGdomain CGENTRY cgGetDomain(const char *domain_string);
CG_API CGdomain CGENTRY cgGetProgramDomain(CGprogram program);
/*** Error Functions ***/
CG_API CGerror CGENTRY cgGetError(void);
CG_API CGerror CGENTRY cgGetFirstError(void);
CG_API const char * CGENTRY cgGetErrorString(CGerror error);
CG_API const char * CGENTRY cgGetLastErrorString(CGerror *error);
CG_API void CGENTRY cgSetErrorCallback(CGerrorCallbackFunc func);
CG_API CGerrorCallbackFunc CGENTRY cgGetErrorCallback(void);
CG_API void CGENTRY cgSetErrorHandler(CGerrorHandlerFunc func, void *data);
CG_API CGerrorHandlerFunc CGENTRY cgGetErrorHandler(void **data);
/*** Misc Functions ***/
CG_API const char * CGENTRY cgGetString(CGenum sname);
/*** CgFX Functions ***/
CG_API CGeffect CGENTRY cgCreateEffect(CGcontext, const char *code, const char **args);
CG_API CGeffect CGENTRY cgCreateEffectFromFile(CGcontext, const char *filename,
const char **args);
CG_API CGeffect CGENTRY cgCopyEffect(CGeffect effect);
CG_API void CGENTRY cgDestroyEffect(CGeffect);
CG_API CGcontext CGENTRY cgGetEffectContext(CGeffect);
CG_API CGbool CGENTRY cgIsEffect(CGeffect effect);
CG_API CGeffect CGENTRY cgGetFirstEffect(CGcontext);
CG_API CGeffect CGENTRY cgGetNextEffect(CGeffect);
CG_API CGprogram CGENTRY cgCreateProgramFromEffect(CGeffect effect,
CGprofile profile,
const char *entry,
const char **args);
CG_API CGtechnique CGENTRY cgGetFirstTechnique(CGeffect);
CG_API CGtechnique CGENTRY cgGetNextTechnique(CGtechnique);
CG_API CGtechnique CGENTRY cgGetNamedTechnique(CGeffect, const char *name);
CG_API const char * CGENTRY cgGetTechniqueName(CGtechnique);
CG_API CGbool CGENTRY cgIsTechnique(CGtechnique);
CG_API CGbool CGENTRY cgValidateTechnique(CGtechnique);
CG_API CGbool CGENTRY cgIsTechniqueValidated(CGtechnique);
CG_API CGeffect CGENTRY cgGetTechniqueEffect(CGtechnique);
CG_API CGpass CGENTRY cgGetFirstPass(CGtechnique);
CG_API CGpass CGENTRY cgGetNamedPass(CGtechnique, const char *name);
CG_API CGpass CGENTRY cgGetNextPass(CGpass);
CG_API CGbool CGENTRY cgIsPass(CGpass);
CG_API const char * CGENTRY cgGetPassName(CGpass);
CG_API CGtechnique CGENTRY cgGetPassTechnique(CGpass);
CG_API CGprogram CGENTRY cgGetPassProgram(CGpass pass, CGdomain domain);
CG_API void CGENTRY cgSetPassState(CGpass);
CG_API void CGENTRY cgResetPassState(CGpass);
CG_API CGstateassignment CGENTRY cgGetFirstStateAssignment(CGpass);
CG_API CGstateassignment CGENTRY cgGetNamedStateAssignment(CGpass, const char *name);
CG_API CGstateassignment CGENTRY cgGetNextStateAssignment(CGstateassignment);
CG_API CGbool CGENTRY cgIsStateAssignment(CGstateassignment);
CG_API CGbool CGENTRY cgCallStateSetCallback(CGstateassignment);
CG_API CGbool CGENTRY cgCallStateValidateCallback(CGstateassignment);
CG_API CGbool CGENTRY cgCallStateResetCallback(CGstateassignment);
CG_API CGpass CGENTRY cgGetStateAssignmentPass(CGstateassignment);
CG_API CGparameter CGENTRY cgGetSamplerStateAssignmentParameter(CGstateassignment);
CG_API const float * CGENTRY cgGetFloatStateAssignmentValues(CGstateassignment, int *nVals);
CG_API const int * CGENTRY cgGetIntStateAssignmentValues(CGstateassignment, int *nVals);
CG_API const CGbool * CGENTRY cgGetBoolStateAssignmentValues(CGstateassignment, int *nVals);
CG_API const char * CGENTRY cgGetStringStateAssignmentValue(CGstateassignment);
CG_API CGprogram CGENTRY cgGetProgramStateAssignmentValue(CGstateassignment);
CG_API CGparameter CGENTRY cgGetTextureStateAssignmentValue(CGstateassignment);
CG_API CGparameter CGENTRY cgGetSamplerStateAssignmentValue(CGstateassignment);
CG_API int CGENTRY cgGetStateAssignmentIndex(CGstateassignment);
CG_API int CGENTRY cgGetNumDependentStateAssignmentParameters(CGstateassignment);
CG_API CGparameter CGENTRY cgGetDependentStateAssignmentParameter(CGstateassignment, int index);
CG_API CGparameter CGENTRY cgGetConnectedStateAssignmentParameter(CGstateassignment);
CG_API CGstate CGENTRY cgGetStateAssignmentState(CGstateassignment);
CG_API CGstate CGENTRY cgGetSamplerStateAssignmentState(CGstateassignment);
CG_API CGstate CGENTRY cgCreateState(CGcontext, const char *name, CGtype);
CG_API CGstate CGENTRY cgCreateArrayState(CGcontext, const char *name, CGtype, int nelems);
CG_API void CGENTRY cgSetStateCallbacks(CGstate, CGstatecallback set, CGstatecallback reset,
CGstatecallback validate);
CG_API void CGENTRY cgSetStateLatestProfile(CGstate, CGprofile);
CG_API CGstatecallback CGENTRY cgGetStateSetCallback(CGstate);
CG_API CGstatecallback CGENTRY cgGetStateResetCallback(CGstate);
CG_API CGstatecallback CGENTRY cgGetStateValidateCallback(CGstate);
CG_API CGprofile CGENTRY cgGetStateLatestProfile(CGstate);
CG_API CGcontext CGENTRY cgGetStateContext(CGstate);
CG_API CGtype CGENTRY cgGetStateType(CGstate);
CG_API const char * CGENTRY cgGetStateName(CGstate);
CG_API CGstate CGENTRY cgGetNamedState(CGcontext, const char *name);
CG_API CGstate CGENTRY cgGetFirstState(CGcontext);
CG_API CGstate CGENTRY cgGetNextState(CGstate);
CG_API CGbool CGENTRY cgIsState(CGstate);
CG_API void CGENTRY cgAddStateEnumerant(CGstate, const char *name, int value);
CG_API CGstate CGENTRY cgCreateSamplerState(CGcontext, const char *name, CGtype);
CG_API CGstate CGENTRY cgCreateArraySamplerState(CGcontext, const char *name, CGtype, int nelems);
CG_API CGstate CGENTRY cgGetNamedSamplerState(CGcontext, const char *name);
CG_API CGstate CGENTRY cgGetFirstSamplerState(CGcontext);
CG_API CGstateassignment CGENTRY cgGetFirstSamplerStateAssignment(CGparameter);
CG_API CGstateassignment CGENTRY cgGetNamedSamplerStateAssignment(CGparameter, const char *);
CG_API void CGENTRY cgSetSamplerState(CGparameter);
CG_API CGparameter CGENTRY cgGetNamedEffectParameter(CGeffect, const char *);
CG_API CGparameter CGENTRY cgGetFirstLeafEffectParameter(CGeffect);
CG_API CGparameter CGENTRY cgGetFirstEffectParameter(CGeffect);
CG_API CGparameter CGENTRY cgGetEffectParameterBySemantic(CGeffect, const char *);
CG_API CGannotation CGENTRY cgGetFirstTechniqueAnnotation(CGtechnique);
CG_API CGannotation CGENTRY cgGetFirstPassAnnotation(CGpass);
CG_API CGannotation CGENTRY cgGetFirstParameterAnnotation(CGparameter);
CG_API CGannotation CGENTRY cgGetFirstProgramAnnotation(CGprogram);
CG_API CGannotation CGENTRY cgGetFirstEffectAnnotation(CGeffect);
CG_API CGannotation CGENTRY cgGetNextAnnotation(CGannotation);
CG_API CGannotation CGENTRY cgGetNamedTechniqueAnnotation(CGtechnique, const char *);
CG_API CGannotation CGENTRY cgGetNamedPassAnnotation(CGpass, const char *);
CG_API CGannotation CGENTRY cgGetNamedParameterAnnotation(CGparameter, const char *);
CG_API CGannotation CGENTRY cgGetNamedProgramAnnotation(CGprogram, const char *);
CG_API CGannotation CGENTRY cgGetNamedEffectAnnotation(CGeffect, const char *);
CG_API CGbool CGENTRY cgIsAnnotation(CGannotation);
CG_API const char * CGENTRY cgGetAnnotationName(CGannotation);
CG_API CGtype CGENTRY cgGetAnnotationType(CGannotation);
CG_API const float * CGENTRY cgGetFloatAnnotationValues(CGannotation, int *nvalues);
CG_API const int * CGENTRY cgGetIntAnnotationValues(CGannotation, int *nvalues);
CG_API const char * CGENTRY cgGetStringAnnotationValue(CGannotation);
CG_API const char * const * CGENTRY cgGetStringAnnotationValues(CGannotation, int *nvalues);
CG_API const CGbool * CGENTRY cgGetBoolAnnotationValues(CGannotation, int *nvalues);
CG_API const int * CGENTRY cgGetBooleanAnnotationValues(CGannotation, int *nvalues);
CG_API int CGENTRY cgGetNumDependentAnnotationParameters(CGannotation);
CG_API CGparameter CGENTRY cgGetDependentAnnotationParameter(CGannotation, int index);
CG_API void CGENTRY cgEvaluateProgram(CGprogram, float *, int ncomps, int nx, int ny, int nz);
/*** Cg 1.5 Additions ***/
CG_API CGbool CGENTRY cgSetEffectName(CGeffect, const char *name);
CG_API const char * CGENTRY cgGetEffectName(CGeffect);
CG_API CGeffect CGENTRY cgGetNamedEffect(CGcontext, const char *name);
CG_API CGparameter CGENTRY cgCreateEffectParameter(CGeffect, const char *name, CGtype);
CG_API CGtechnique CGENTRY cgCreateTechnique(CGeffect, const char *name);
CG_API CGparameter CGENTRY cgCreateEffectParameterArray(CGeffect, const char *name, CGtype type, int length);
CG_API CGparameter CGENTRY cgCreateEffectParameterMultiDimArray(CGeffect, const char *name, CGtype type, int dim, const int *lengths);
CG_API CGpass CGENTRY cgCreatePass(CGtechnique, const char *name);
CG_API CGstateassignment CGENTRY cgCreateStateAssignment(CGpass, CGstate);
CG_API CGstateassignment CGENTRY cgCreateStateAssignmentIndex(CGpass, CGstate, int index);
CG_API CGstateassignment CGENTRY cgCreateSamplerStateAssignment(CGparameter, CGstate);
CG_API CGbool CGENTRY cgSetFloatStateAssignment(CGstateassignment, float);
CG_API CGbool CGENTRY cgSetIntStateAssignment(CGstateassignment, int);
CG_API CGbool CGENTRY cgSetBoolStateAssignment(CGstateassignment, CGbool);
CG_API CGbool CGENTRY cgSetStringStateAssignment(CGstateassignment, const char *);
CG_API CGbool CGENTRY cgSetProgramStateAssignment(CGstateassignment, CGprogram);
CG_API CGbool CGENTRY cgSetSamplerStateAssignment(CGstateassignment, CGparameter);
CG_API CGbool CGENTRY cgSetTextureStateAssignment(CGstateassignment, CGparameter);
CG_API CGbool CGENTRY cgSetFloatArrayStateAssignment(CGstateassignment, const float *vals);
CG_API CGbool CGENTRY cgSetIntArrayStateAssignment(CGstateassignment, const int *vals);
CG_API CGbool CGENTRY cgSetBoolArrayStateAssignment(CGstateassignment, const CGbool *vals);
CG_API CGannotation CGENTRY cgCreateTechniqueAnnotation(CGtechnique, const char *name, CGtype);
CG_API CGannotation CGENTRY cgCreatePassAnnotation(CGpass, const char *name, CGtype);
CG_API CGannotation CGENTRY cgCreateParameterAnnotation(CGparameter, const char *name, CGtype);
CG_API CGannotation CGENTRY cgCreateProgramAnnotation(CGprogram, const char *name, CGtype);
CG_API CGannotation CGENTRY cgCreateEffectAnnotation(CGeffect, const char *name, CGtype);
CG_API CGbool CGENTRY cgSetIntAnnotation(CGannotation, int value);
CG_API CGbool CGENTRY cgSetFloatAnnotation(CGannotation, float value);
CG_API CGbool CGENTRY cgSetBoolAnnotation(CGannotation, CGbool value);
CG_API CGbool CGENTRY cgSetStringAnnotation(CGannotation, const char *value);
CG_API int CGENTRY cgGetNumStateEnumerants(CGstate);
CG_API const char * CGENTRY cgGetStateEnumerant(CGstate, int index, int* value);
CG_API const char * CGENTRY cgGetStateEnumerantName(CGstate, int value);
CG_API int CGENTRY cgGetStateEnumerantValue(CGstate, const char *name);
CG_API CGeffect CGENTRY cgGetParameterEffect(CGparameter param);
CG_API CGparameterclass CGENTRY cgGetTypeClass(CGtype type);
CG_API CGtype CGENTRY cgGetTypeBase(CGtype type);
CG_API CGbool CGENTRY cgGetTypeSizes(CGtype type, int *nrows, int *ncols);
CG_API void CGENTRY cgGetMatrixSize(CGtype type, int *nrows, int *ncols);
CG_API int CGENTRY cgGetNumProgramDomains( CGprogram program );
CG_API CGdomain CGENTRY cgGetProfileDomain( CGprofile profile );
CG_API CGprogram CGENTRY cgCombinePrograms( int n, const CGprogram *exeList );
CG_API CGprogram CGENTRY cgCombinePrograms2( const CGprogram exe1, const CGprogram exe2 );
CG_API CGprogram CGENTRY cgCombinePrograms3( const CGprogram exe1, const CGprogram exe2, const CGprogram exe3 );
CG_API CGprofile CGENTRY cgGetProgramDomainProfile(CGprogram program, int index);
CG_API CGprogram CGENTRY cgGetProgramDomainProgram(CGprogram program, int index);
/*** CGobj Functions ***/
CG_API CGobj CGENTRY cgCreateObj( CGcontext context, CGenum program_type, const char *source, CGprofile profile, const char **args );
CG_API CGobj CGENTRY cgCreateObjFromFile( CGcontext context, CGenum program_type, const char *source_file, CGprofile profile, const char **args );
CG_API void CGENTRY cgDestroyObj( CGobj obj );
CG_API long CGENTRY cgGetParameterResourceSize(CGparameter);
CG_API CGtype CGENTRY cgGetParameterResourceType(CGparameter);
CG_API const char* CGENTRY cgGetParameterResourceName(CGparameter param);
CG_API int CGENTRY cgGetParameterBufferIndex(CGparameter);
CG_API int CGENTRY cgGetParameterBufferOffset(CGparameter);
CG_API CGbuffer CGENTRY cgCreateBuffer(CGcontext, int size, const void *data, CGbufferusage bufferUsage);
CG_API void CGENTRY cgSetBufferData(CGbuffer, int size, const void *data);
CG_API void CGENTRY cgSetBufferSubData(CGbuffer, int offset, int size, const void *data);
CG_API void CGENTRY cgSetProgramBuffer(CGprogram program, int bufferIndex, CGbuffer buffer);
CG_API void * CGENTRY cgMapBuffer(CGbuffer buffer, CGbufferaccess access);
CG_API void CGENTRY cgUnmapBuffer(CGbuffer buffer);
CG_API void CGENTRY cgDestroyBuffer(CGbuffer buffer);
CG_API CGbuffer CGENTRY cgGetProgramBuffer(CGprogram, int bufferIndex);
CG_API int CGENTRY cgGetBufferSize(CGbuffer);
CG_API int CGENTRY cgGetProgramBufferMaxSize(CGprofile profile);
CG_API int CGENTRY cgGetProgramBufferMaxIndex(CGprofile profile);
#endif
#ifdef __cplusplus
}
#endif
#ifdef CG_APIENTRY_DEFINED
# undef CG_APIENTRY_DEFINED
# undef APIENTRY
#endif
#ifdef CG_WINGDIAPI_DEFINED
# undef CG_WINGDIAPI_DEFINED
# undef WINGDIAPI
#endif
#endif

View File

@ -0,0 +1,238 @@
/*
*
* Copyright (c) 2008-2009, NVIDIA Corporation.
*
*
*
* NVIDIA Corporation("NVIDIA") supplies this software to you in consideration
* of your agreement to the following terms, and your use, installation,
* modification or redistribution of this NVIDIA software constitutes
* acceptance of these terms. If you do not agree with these terms, please do
* not use, install, modify or redistribute this NVIDIA software.
*
*
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, NVIDIA grants you a personal, non-exclusive license,
* under NVIDIA's copyrights in this original NVIDIA software (the "NVIDIA
* Software"), to use, reproduce, modify and redistribute the NVIDIA
* Software, with or without modifications, in source and/or binary forms;
* provided that if you redistribute the NVIDIA Software, you must retain the
* copyright notice of NVIDIA, this notice and the following text and
* disclaimers in all such redistributions of the NVIDIA Software. Neither the
* name, trademarks, service marks nor logos of NVIDIA Corporation may be used
* to endorse or promote products derived from the NVIDIA Software without
* specific prior written permission from NVIDIA. Except as expressly stated
* in this notice, no other rights or licenses express or implied, are granted
* by NVIDIA herein, including but not limited to any patent rights that may be
* infringed by your derivative works or by other works in which the NVIDIA
* Software may be incorporated. No hardware is licensed hereunder.
*
*
*
* THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
* WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR ITS USE AND OPERATION
* EITHER ALONE OR IN COMBINATION WITH OTHER PRODUCTS.
*
*
*
* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
* EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOST
* PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY OUT OF THE USE,
* REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE NVIDIA SOFTWARE,
* HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING
* NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF NVIDIA HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __CGD3D10_H__
#define __CGD3D10_H__
#ifdef _WIN32
#pragma once
#include <windows.h>
#include <d3d10.h>
#include "Cg/cg.h"
// Set up for either Win32 import/export/lib.
#ifdef CGD3D10DLL_EXPORTS
#define CGD3D10DLL_API __declspec(dllexport)
#elif defined (CG_LIB)
#define CGD3D10DLL_API
#else
#define CGD3D10DLL_API __declspec(dllimport)
#endif
#ifndef CGD3D10ENTRY
# ifdef _WIN32
# define CGD3D10ENTRY __cdecl
# else
# define CGD3D10ENTRY
# endif
#endif
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef CGD3D10_EXPLICIT
/* ----- D3D Device Control ----- */
CGD3D10DLL_API ID3D10Device * CGD3D10ENTRY
cgD3D10GetDevice(
CGcontext Context
);
CGD3D10DLL_API HRESULT CGD3D10ENTRY
cgD3D10SetDevice(
CGcontext Context,
ID3D10Device * pDevice
);
/* ----- Texture Functions ----- */
CGD3D10DLL_API void CGD3D10ENTRY
cgD3D10SetTextureParameter(
CGparameter Parameter,
ID3D10Resource * pTexture
);
CGD3D10DLL_API void CGD3D10ENTRY
cgD3D10SetSamplerStateParameter(
CGparameter Parameter,
ID3D10SamplerState * pSamplerState
);
CGD3D10DLL_API void CGD3D10ENTRY
cgD3D10SetTextureSamplerStateParameter(
CGparameter Parameter,
ID3D10Resource * pTexture,
ID3D10SamplerState * pSamplerState
);
/* ----- Shader Management ----- */
CGD3D10DLL_API HRESULT CGD3D10ENTRY
cgD3D10LoadProgram(
CGprogram Program,
UINT Flags
);
CGD3D10DLL_API ID3D10Blob * CGD3D10ENTRY
cgD3D10GetCompiledProgram(
CGprogram Program
);
CGD3D10DLL_API ID3D10Blob * CGD3D10ENTRY
cgD3D10GetProgramErrors(
CGprogram Program
);
CGD3D10DLL_API CGbool CGD3D10ENTRY
cgD3D10IsProgramLoaded(
CGprogram Program
);
CGD3D10DLL_API HRESULT CGD3D10ENTRY
cgD3D10BindProgram(
CGprogram Program
);
CGD3D10DLL_API void CGD3D10ENTRY
cgD3D10UnloadProgram(
CGprogram Program
);
/* ----- Buffer Management ----- */
CGD3D10DLL_API ID3D10Buffer * CGD3D10ENTRY
cgD3D10GetBufferByIndex(
CGprogram Program,
UINT Index
);
/* ----- CgFX ----- */
CGD3D10DLL_API void CGD3D10ENTRY
cgD3D10RegisterStates(
CGcontext Context
);
CGD3D10DLL_API void CGD3D10ENTRY
cgD3D10SetManageTextureParameters(
CGcontext Context,
CGbool Flag
);
CGD3D10DLL_API CGbool CGD3D10ENTRY
cgD3D10GetManageTextureParameters(
CGcontext Context
);
CGD3D10DLL_API ID3D10Blob * CGD3D10ENTRY
cgD3D10GetIASignatureByPass(
CGpass Pass
);
/* ----- Profile Options ----- */
CGD3D10DLL_API CGprofile CGD3D10ENTRY
cgD3D10GetLatestVertexProfile();
CGD3D10DLL_API CGprofile CGD3D10ENTRY
cgD3D10GetLatestGeometryProfile();
CGD3D10DLL_API CGprofile CGD3D10ENTRY
cgD3D10GetLatestPixelProfile();
CGD3D10DLL_API CGbool CGD3D10ENTRY
cgD3D10IsProfileSupported(
CGprofile Profile
);
/* ----- Utility Functions ----- */
CGD3D10DLL_API DWORD CGD3D10ENTRY
cgD3D10TypeToSize(
CGtype Type
);
CGD3D10DLL_API HRESULT CGD3D10ENTRY
cgD3D10GetLastError();
CGD3D10DLL_API const char ** CGD3D10ENTRY
cgD3D10GetOptimalOptions(
CGprofile Profile
);
CGD3D10DLL_API const char * CGD3D10ENTRY
cgD3D10TranslateCGerror(
CGerror Error
);
CGD3D10DLL_API const char * CGD3D10ENTRY
cgD3D10TranslateHRESULT(
HRESULT hr
);
#endif // #ifndef CGD3D10_EXPLICIT
#ifdef __cplusplus
}; // extern "C"
#endif
#endif // #ifdef _WIN32
#endif // #ifndef __CGD3D10_H__

View File

@ -0,0 +1,279 @@
/*
*
* Copyright (c) 2002-2009, NVIDIA Corporation.
*
*
*
* NVIDIA Corporation("NVIDIA") supplies this software to you in consideration
* of your agreement to the following terms, and your use, installation,
* modification or redistribution of this NVIDIA software constitutes
* acceptance of these terms. If you do not agree with these terms, please do
* not use, install, modify or redistribute this NVIDIA software.
*
*
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, NVIDIA grants you a personal, non-exclusive license,
* under NVIDIA's copyrights in this original NVIDIA software (the "NVIDIA
* Software"), to use, reproduce, modify and redistribute the NVIDIA
* Software, with or without modifications, in source and/or binary forms;
* provided that if you redistribute the NVIDIA Software, you must retain the
* copyright notice of NVIDIA, this notice and the following text and
* disclaimers in all such redistributions of the NVIDIA Software. Neither the
* name, trademarks, service marks nor logos of NVIDIA Corporation may be used
* to endorse or promote products derived from the NVIDIA Software without
* specific prior written permission from NVIDIA. Except as expressly stated
* in this notice, no other rights or licenses express or implied, are granted
* by NVIDIA herein, including but not limited to any patent rights that may be
* infringed by your derivative works or by other works in which the NVIDIA
* Software may be incorporated. No hardware is licensed hereunder.
*
*
*
* THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
* WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR ITS USE AND OPERATION
* EITHER ALONE OR IN COMBINATION WITH OTHER PRODUCTS.
*
*
*
* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
* EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOST
* PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY OUT OF THE USE,
* REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE NVIDIA SOFTWARE,
* HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING
* NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF NVIDIA HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef CGD3D8_INCLUDED
#define CGD3D8_INCLUDED
#ifdef _WIN32
#pragma once
#include "cg.h"
#include <d3d8.h>
#include <d3dx8.h>
// Set up for either Win32 import/export/lib.
#include <windows.h>
#ifdef CGD3D8DLL_EXPORTS
#define CGD3D8DLL_API __declspec(dllexport)
#elif defined (CG_LIB)
#define CGD3D8DLL_API
#else
#define CGD3D8DLL_API __declspec(dllimport)
#endif
#ifndef CGD3D8ENTRY
# ifdef _WIN32
# define CGD3D8ENTRY __cdecl
# else
# define CGD3D8ENTRY
# endif
#endif
/*---------------------------------------------------------------------------
// CGerrors that will be fed to cgSetError
// Use cgD3D8TranslateCGerror() to translate these errors into strings.
---------------------------------------------------------------------------*/
enum cgD3D8Errors
{
cgD3D8Failed = 1000,
cgD3D8DebugTrace = 1001,
};
/*---------------------------------------------------------------------------
// HRESULTs specific to cgD3D8. When the CGerror is set to cgD3D8Failed
// cgD3D8GetLastError will return an HRESULT that could be one these.
// Use cgD3D8TranslateHRESULT() to translate these errors into strings.
---------------------------------------------------------------------------*/
static const HRESULT CGD3D8ERR_NOTLOADED = MAKE_HRESULT(1, 0x877, 1);
static const HRESULT CGD3D8ERR_NODEVICE = MAKE_HRESULT(1, 0x877, 2);
static const HRESULT CGD3D8ERR_NOTSAMPLER = MAKE_HRESULT(1, 0x877, 3);
static const HRESULT CGD3D8ERR_INVALIDPROFILE = MAKE_HRESULT(1, 0x877, 4);
static const HRESULT CGD3D8ERR_NULLVALUE = MAKE_HRESULT(1, 0x877, 5);
static const HRESULT CGD3D8ERR_OUTOFRANGE = MAKE_HRESULT(1, 0x877, 6);
static const HRESULT CGD3D8ERR_NOTUNIFORM = MAKE_HRESULT(1, 0x877, 7);
static const HRESULT CGD3D8ERR_NOTMATRIX = MAKE_HRESULT(1, 0x877, 8);
static const HRESULT CGD3D8ERR_INVALIDPARAM = MAKE_HRESULT(1, 0x877, 9);
static const HRESULT CGD3D8ERR_INVALIDSAMPLERSTATE = MAKE_HRESULT(1, 0x877, 100);
static const HRESULT CGD3D8ERR_INVALIDVEREXDECL = MAKE_HRESULT(1, 0x877, 101);
/*---------------------------------------------------------------------------
// Other error return values
---------------------------------------------------------------------------*/
static const DWORD CGD3D8_INVALID_REG = 0xFFFFFFFF;
#ifdef __cplusplus
extern "C"
{
#endif
/*---------------------------------------------------------------------------
// Minimal Interface
---------------------------------------------------------------------------*/
CGD3D8DLL_API DWORD CGD3D8ENTRY
cgD3D8TypeToSize(
CGtype type
);
CGD3D8DLL_API DWORD CGD3D8ENTRY
cgD3D8ResourceToInputRegister(
CGresource resource
);
CGD3D8DLL_API CGbool CGD3D8ENTRY
cgD3D8GetVertexDeclaration(
CGprogram prog,
DWORD decl[MAX_FVF_DECL_SIZE]
);
CGD3D8DLL_API CGbool CGD3D8ENTRY
cgD3D8ValidateVertexDeclaration(
CGprogram prog,
const DWORD* decl
);
/*---------------------------------------------------------------------------
// Expanded Interface
---------------------------------------------------------------------------*/
/* ----- D3D Device Control ----------- */
CGD3D8DLL_API IDirect3DDevice8 * CGD3D8ENTRY
cgD3D8GetDevice();
CGD3D8DLL_API HRESULT CGD3D8ENTRY
cgD3D8SetDevice(
IDirect3DDevice8* pDevice
);
/* ----- Shader Management ----------- */
CGD3D8DLL_API HRESULT CGD3D8ENTRY
cgD3D8LoadProgram(
CGprogram prog,
CGbool paramShadowing,
DWORD assemFlags,
DWORD vshaderUsage,
const DWORD* vertexDecl
);
CGD3D8DLL_API HRESULT CGD3D8ENTRY
cgD3D8UnloadProgram(
CGprogram prog
);
CGD3D8DLL_API CGbool CGD3D8ENTRY
cgD3D8IsProgramLoaded(
CGprogram prog
);
CGD3D8DLL_API HRESULT CGD3D8ENTRY
cgD3D8BindProgram(
CGprogram prog
);
/* ----- Parameter Management ----------- */
CGD3D8DLL_API HRESULT CGD3D8ENTRY
cgD3D8SetUniform(
CGparameter param,
const void* floats
);
CGD3D8DLL_API HRESULT CGD3D8ENTRY
cgD3D8SetUniformArray(
CGparameter param,
DWORD offset,
DWORD numItems,
const void* values
);
CGD3D8DLL_API HRESULT CGD3D8ENTRY
cgD3D8SetUniformMatrix(
CGparameter param,
const D3DMATRIX* matrix
);
CGD3D8DLL_API HRESULT CGD3D8ENTRY
cgD3D8SetUniformMatrixArray(
CGparameter param,
DWORD offset,
DWORD numItems,
const D3DMATRIX* matrices
);
CGD3D8DLL_API HRESULT CGD3D8ENTRY
cgD3D8SetTexture(
CGparameter param,
IDirect3DBaseTexture8* tex
);
CGD3D8DLL_API HRESULT CGD3D8ENTRY
cgD3D8SetTextureStageState(
CGparameter param,
D3DTEXTURESTAGESTATETYPE type,
DWORD value
);
CGD3D8DLL_API HRESULT CGD3D8ENTRY
cgD3D8SetTextureWrapMode(
CGparameter param,
DWORD value
);
/* ----- Parameter Management (Shadowing) ----------- */
CGD3D8DLL_API HRESULT CGD3D8ENTRY
cgD3D8EnableParameterShadowing(
CGprogram prog,
CGbool enable
);
CGD3D8DLL_API CGbool CGD3D8ENTRY
cgD3D8IsParameterShadowingEnabled(
CGprogram prog
);
/* --------- Profile Options ----------------- */
CGD3D8DLL_API CGprofile CGD3D8ENTRY
cgD3D8GetLatestVertexProfile();
CGD3D8DLL_API CGprofile CGD3D8ENTRY
cgD3D8GetLatestPixelProfile();
CGD3D8DLL_API const char * CGD3D8ENTRY
cgD3D8GetOptimalOptions(
CGprofile profile
);
/* --------- Error reporting ----------------- */
CGD3D8DLL_API HRESULT CGD3D8ENTRY
cgD3D8GetLastError();
CGD3D8DLL_API const char * CGD3D8ENTRY
cgD3D8TranslateCGerror(
CGerror error
);
CGD3D8DLL_API const char * CGD3D8ENTRY
cgD3D8TranslateHRESULT(
HRESULT hr
);
CGD3D8DLL_API void CGD3D8ENTRY
cgD3D8EnableDebugTracing(
CGbool enable
);
#ifdef __cplusplus
};
#endif
#endif // _WIN32
#endif

View File

@ -0,0 +1,317 @@
/*
*
* Copyright (c) 2002-2009, NVIDIA Corporation.
*
*
*
* NVIDIA Corporation("NVIDIA") supplies this software to you in consideration
* of your agreement to the following terms, and your use, installation,
* modification or redistribution of this NVIDIA software constitutes
* acceptance of these terms. If you do not agree with these terms, please do
* not use, install, modify or redistribute this NVIDIA software.
*
*
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, NVIDIA grants you a personal, non-exclusive license,
* under NVIDIA's copyrights in this original NVIDIA software (the "NVIDIA
* Software"), to use, reproduce, modify and redistribute the NVIDIA
* Software, with or without modifications, in source and/or binary forms;
* provided that if you redistribute the NVIDIA Software, you must retain the
* copyright notice of NVIDIA, this notice and the following text and
* disclaimers in all such redistributions of the NVIDIA Software. Neither the
* name, trademarks, service marks nor logos of NVIDIA Corporation may be used
* to endorse or promote products derived from the NVIDIA Software without
* specific prior written permission from NVIDIA. Except as expressly stated
* in this notice, no other rights or licenses express or implied, are granted
* by NVIDIA herein, including but not limited to any patent rights that may be
* infringed by your derivative works or by other works in which the NVIDIA
* Software may be incorporated. No hardware is licensed hereunder.
*
*
*
* THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
* WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR ITS USE AND OPERATION
* EITHER ALONE OR IN COMBINATION WITH OTHER PRODUCTS.
*
*
*
* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
* EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOST
* PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY OUT OF THE USE,
* REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE NVIDIA SOFTWARE,
* HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING
* NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF NVIDIA HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef CGD3D9_INCLUDED
#define CGD3D9_INCLUDED
#ifdef _WIN32
#pragma once
#include "cg.h"
#include <d3d9.h>
#include <d3dx9.h>
// Set up for either Win32 import/export/lib.
#include <windows.h>
#ifdef CGD3D9DLL_EXPORTS
#define CGD3D9DLL_API __declspec(dllexport)
#elif defined (CG_LIB)
#define CGD3D9DLL_API
#else
#define CGD3D9DLL_API __declspec(dllimport)
#endif
#ifndef CGD3D9ENTRY
# ifdef _WIN32
# define CGD3D9ENTRY __cdecl
# else
# define CGD3D9ENTRY
# endif
#endif
/*---------------------------------------------------------------------------
// CGerrors that will be fed to cgSetError
// Use cgD3D9TranslateCGerror() to translate these errors into strings.
---------------------------------------------------------------------------*/
enum cgD3D9Errors
{
cgD3D9Failed = 1000,
cgD3D9DebugTrace = 1001,
};
/*---------------------------------------------------------------------------
// HRESULTs specific to cgD3D9. When the CGerror is set to cgD3D9Failed
// cgD3D9GetLastError will return an HRESULT that could be one these.
// Use cgD3D9TranslateHRESULT() to translate these errors into strings.
---------------------------------------------------------------------------*/
static const HRESULT CGD3D9ERR_NOTLOADED = MAKE_HRESULT(1, 0x877, 1);
static const HRESULT CGD3D9ERR_NODEVICE = MAKE_HRESULT(1, 0x877, 2);
static const HRESULT CGD3D9ERR_NOTSAMPLER = MAKE_HRESULT(1, 0x877, 3);
static const HRESULT CGD3D9ERR_INVALIDPROFILE = MAKE_HRESULT(1, 0x877, 4);
static const HRESULT CGD3D9ERR_NULLVALUE = MAKE_HRESULT(1, 0x877, 5);
static const HRESULT CGD3D9ERR_OUTOFRANGE = MAKE_HRESULT(1, 0x877, 6);
static const HRESULT CGD3D9ERR_NOTUNIFORM = MAKE_HRESULT(1, 0x877, 7);
static const HRESULT CGD3D9ERR_NOTMATRIX = MAKE_HRESULT(1, 0x877, 8);
static const HRESULT CGD3D9ERR_INVALIDPARAM = MAKE_HRESULT(1, 0x877, 9);
/*---------------------------------------------------------------------------
// Other error return values
---------------------------------------------------------------------------*/
static const DWORD CGD3D9_INVALID_USAGE = 0xFF;
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef CGD3D9_EXPLICIT
/*---------------------------------------------------------------------------
// Minimal Interface
---------------------------------------------------------------------------*/
CGD3D9DLL_API DWORD CGD3D9ENTRY
cgD3D9TypeToSize(
CGtype type
);
CGD3D9DLL_API BYTE CGD3D9ENTRY
cgD3D9ResourceToDeclUsage(
CGresource resource
);
CGD3D9DLL_API CGbool CGD3D9ENTRY
cgD3D9GetVertexDeclaration(
CGprogram prog,
D3DVERTEXELEMENT9 decl[MAXD3DDECLLENGTH]
);
CGD3D9DLL_API CGbool CGD3D9ENTRY
cgD3D9ValidateVertexDeclaration(
CGprogram prog,
const D3DVERTEXELEMENT9* decl
);
/*---------------------------------------------------------------------------
// Expanded Interface
---------------------------------------------------------------------------*/
/* ----- D3D Device Control ----------- */
CGD3D9DLL_API IDirect3DDevice9 * CGD3D9ENTRY
cgD3D9GetDevice();
CGD3D9DLL_API HRESULT CGD3D9ENTRY
cgD3D9SetDevice(
IDirect3DDevice9* pDevice
);
/* ----- Shader Management ----------- */
CGD3D9DLL_API HRESULT CGD3D9ENTRY
cgD3D9LoadProgram(
CGprogram prog,
CGbool paramShadowing,
DWORD assemFlags
);
CGD3D9DLL_API HRESULT CGD3D9ENTRY
cgD3D9UnloadProgram(
CGprogram prog
);
CGD3D9DLL_API CGbool CGD3D9ENTRY
cgD3D9IsProgramLoaded(
CGprogram prog
);
CGD3D9DLL_API HRESULT CGD3D9ENTRY
cgD3D9BindProgram(
CGprogram prog
);
/* ----- Parameter Management ----------- */
CGD3D9DLL_API HRESULT CGD3D9ENTRY
cgD3D9SetUniform(
CGparameter param,
const void* floats
);
CGD3D9DLL_API HRESULT CGD3D9ENTRY
cgD3D9SetUniformArray(
CGparameter param,
DWORD offset,
DWORD numItems,
const void* values
);
CGD3D9DLL_API HRESULT CGD3D9ENTRY
cgD3D9SetUniformMatrix(
CGparameter param,
const D3DMATRIX* matrix
);
CGD3D9DLL_API HRESULT CGD3D9ENTRY
cgD3D9SetUniformMatrixArray(
CGparameter param,
DWORD offset,
DWORD numItems,
const D3DMATRIX* matrices
);
CGD3D9DLL_API HRESULT CGD3D9ENTRY
cgD3D9SetTexture(
CGparameter param,
IDirect3DBaseTexture9* tex
);
CGD3D9DLL_API HRESULT CGD3D9ENTRY
cgD3D9SetSamplerState(
CGparameter param,
D3DSAMPLERSTATETYPE type,
DWORD value
);
CGD3D9DLL_API HRESULT CGD3D9ENTRY
cgD3D9SetTextureWrapMode(
CGparameter param,
DWORD value
);
/* ----- Parameter Management (Shadowing) ----------- */
CGD3D9DLL_API HRESULT CGD3D9ENTRY
cgD3D9EnableParameterShadowing(
CGprogram prog,
CGbool enable
);
CGD3D9DLL_API CGbool CGD3D9ENTRY
cgD3D9IsParameterShadowingEnabled(
CGprogram prog
);
/* --------- Profile Options ----------------- */
CGD3D9DLL_API CGprofile CGD3D9ENTRY
cgD3D9GetLatestVertexProfile();
CGD3D9DLL_API CGprofile CGD3D9ENTRY
cgD3D9GetLatestPixelProfile();
CGD3D9DLL_API const char * * CGD3D9ENTRY
cgD3D9GetOptimalOptions(
CGprofile profile
);
CGD3D9DLL_API CGbool CGD3D9ENTRY
cgD3D9IsProfileSupported(
CGprofile profile
);
/* --------- Error reporting ----------------- */
CGD3D9DLL_API HRESULT CGD3D9ENTRY
cgD3D9GetLastError();
CGD3D9DLL_API const char * CGD3D9ENTRY
cgD3D9TranslateCGerror(
CGerror error
);
CGD3D9DLL_API const char * CGD3D9ENTRY
cgD3D9TranslateHRESULT(
HRESULT hr
);
CGD3D9DLL_API void CGD3D9ENTRY
cgD3D9EnableDebugTracing(
CGbool enable
);
/* --------- CgFX support -------------------- */
CGD3D9DLL_API void CGD3D9ENTRY
cgD3D9RegisterStates(
CGcontext ctx
);
CGD3D9DLL_API void CGD3D9ENTRY
cgD3D9SetManageTextureParameters(
CGcontext ctx,
CGbool flag
);
CGD3D9DLL_API CGbool CGD3D9ENTRY
cgD3D9GetManageTextureParameters(
CGcontext ctx
);
CGD3D9DLL_API IDirect3DBaseTexture9 * CGD3D9ENTRY
cgD3D9GetTextureParameter(
CGparameter param
);
CGD3D9DLL_API void CGD3D9ENTRY
cgD3D9SetTextureParameter(
CGparameter param,
IDirect3DBaseTexture9 *tex
);
CGD3D9DLL_API void CGD3D9ENTRY
cgD3D9UnloadAllPrograms( void );
#endif
#ifdef __cplusplus
};
#endif
#endif // _WIN32
#endif

View File

@ -0,0 +1,427 @@
/*
*
* Copyright (c) 2002-2009, NVIDIA Corporation.
*
*
*
* NVIDIA Corporation("NVIDIA") supplies this software to you in consideration
* of your agreement to the following terms, and your use, installation,
* modification or redistribution of this NVIDIA software constitutes
* acceptance of these terms. If you do not agree with these terms, please do
* not use, install, modify or redistribute this NVIDIA software.
*
*
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, NVIDIA grants you a personal, non-exclusive license,
* under NVIDIA's copyrights in this original NVIDIA software (the "NVIDIA
* Software"), to use, reproduce, modify and redistribute the NVIDIA
* Software, with or without modifications, in source and/or binary forms;
* provided that if you redistribute the NVIDIA Software, you must retain the
* copyright notice of NVIDIA, this notice and the following text and
* disclaimers in all such redistributions of the NVIDIA Software. Neither the
* name, trademarks, service marks nor logos of NVIDIA Corporation may be used
* to endorse or promote products derived from the NVIDIA Software without
* specific prior written permission from NVIDIA. Except as expressly stated
* in this notice, no other rights or licenses express or implied, are granted
* by NVIDIA herein, including but not limited to any patent rights that may be
* infringed by your derivative works or by other works in which the NVIDIA
* Software may be incorporated. No hardware is licensed hereunder.
*
*
*
* THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
* WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR ITS USE AND OPERATION
* EITHER ALONE OR IN COMBINATION WITH OTHER PRODUCTS.
*
*
*
* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
* EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOST
* PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY OUT OF THE USE,
* REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE NVIDIA SOFTWARE,
* HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING
* NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF NVIDIA HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef _cggl_h
#define _cggl_h
#include <Cg/cg.h>
#ifdef _WIN32
# ifndef APIENTRY /* From Win32's <windef.h> */
# define CGGL_APIENTRY_DEFINED
# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) || defined(__LCC__)
# define APIENTRY __stdcall
# else
# define APIENTRY
# endif
# endif
# ifndef WINGDIAPI /* From Win32's <wingdi.h> and <winnt.h> */
# define CGGL_WINGDIAPI_DEFINED
# define WINGDIAPI __declspec(dllimport)
# endif
#endif /* _WIN32 */
/* Set up for either Win32 import/export/lib. */
#ifndef CGGL_API
# ifdef CGGL_EXPORTS
# ifdef _WIN32
# define CGGL_API __declspec(dllexport)
# elif defined(__GNUC__) && __GNUC__>=4
# define CGGL_API __attribute__ ((visibility("default")))
# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
# define CGGL_API __global
# else
# define CGGL_API
# endif
# else
# define CGGL_API
# endif
#endif
#ifndef CGGLENTRY
# ifdef _WIN32
# define CGGLENTRY __cdecl
# else
# define CGGLENTRY
# endif
#endif
#ifdef __APPLE__
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*****************************************************************************/
/*** cgGL Type Definitions ***/
/*****************************************************************************/
typedef enum
{
CG_GL_MATRIX_IDENTITY = 0,
CG_GL_MATRIX_TRANSPOSE = 1,
CG_GL_MATRIX_INVERSE = 2,
CG_GL_MATRIX_INVERSE_TRANSPOSE = 3,
CG_GL_MODELVIEW_MATRIX,
CG_GL_PROJECTION_MATRIX,
CG_GL_TEXTURE_MATRIX,
CG_GL_MODELVIEW_PROJECTION_MATRIX,
CG_GL_VERTEX,
CG_GL_FRAGMENT,
CG_GL_GEOMETRY
} CGGLenum;
#ifndef CGGL_EXPLICIT
/******************************************************************************
*** Profile Functions
*****************************************************************************/
CGGL_API CGbool CGGLENTRY cgGLIsProfileSupported(CGprofile profile);
CGGL_API void CGGLENTRY cgGLEnableProfile(CGprofile profile);
CGGL_API void CGGLENTRY cgGLDisableProfile(CGprofile profile);
CGGL_API CGprofile CGGLENTRY cgGLGetLatestProfile(CGGLenum profile_type);
CGGL_API void CGGLENTRY cgGLSetOptimalOptions(CGprofile profile);
CGGL_API char const ** CGGLENTRY cgGLGetOptimalOptions(CGprofile profile);
/******************************************************************************
*** Program Managment Functions
*****************************************************************************/
CGGL_API void CGGLENTRY cgGLLoadProgram(CGprogram program);
CGGL_API void CGGLENTRY cgGLUnloadProgram(CGprogram program);
CGGL_API CGbool CGGLENTRY cgGLIsProgramLoaded(CGprogram program);
CGGL_API void CGGLENTRY cgGLBindProgram(CGprogram program);
CGGL_API void CGGLENTRY cgGLUnbindProgram(CGprofile profile);
CGGL_API GLuint CGGLENTRY cgGLGetProgramID(CGprogram program);
/******************************************************************************
*** Parameter Managment Functions
*****************************************************************************/
CGGL_API void CGGLENTRY cgGLSetParameter1f(CGparameter param,
float x);
CGGL_API void CGGLENTRY cgGLSetParameter2f(CGparameter param,
float x,
float y);
CGGL_API void CGGLENTRY cgGLSetParameter3f(CGparameter param,
float x,
float y,
float z);
CGGL_API void CGGLENTRY cgGLSetParameter4f(CGparameter param,
float x,
float y,
float z,
float w);
CGGL_API void CGGLENTRY cgGLSetParameter1fv(CGparameter param, const float *v);
CGGL_API void CGGLENTRY cgGLSetParameter2fv(CGparameter param, const float *v);
CGGL_API void CGGLENTRY cgGLSetParameter3fv(CGparameter param, const float *v);
CGGL_API void CGGLENTRY cgGLSetParameter4fv(CGparameter param, const float *v);
CGGL_API void CGGLENTRY cgGLSetParameter1d(CGparameter param,
double x);
CGGL_API void CGGLENTRY cgGLSetParameter2d(CGparameter param,
double x,
double y);
CGGL_API void CGGLENTRY cgGLSetParameter3d(CGparameter param,
double x,
double y,
double z);
CGGL_API void CGGLENTRY cgGLSetParameter4d(CGparameter param,
double x,
double y,
double z,
double w);
CGGL_API void CGGLENTRY cgGLSetParameter1dv(CGparameter param, const double *v);
CGGL_API void CGGLENTRY cgGLSetParameter2dv(CGparameter param, const double *v);
CGGL_API void CGGLENTRY cgGLSetParameter3dv(CGparameter param, const double *v);
CGGL_API void CGGLENTRY cgGLSetParameter4dv(CGparameter param, const double *v);
CGGL_API void CGGLENTRY cgGLGetParameter1f(CGparameter param, float *v);
CGGL_API void CGGLENTRY cgGLGetParameter2f(CGparameter param, float *v);
CGGL_API void CGGLENTRY cgGLGetParameter3f(CGparameter param, float *v);
CGGL_API void CGGLENTRY cgGLGetParameter4f(CGparameter param, float *v);
CGGL_API void CGGLENTRY cgGLGetParameter1d(CGparameter param, double *v);
CGGL_API void CGGLENTRY cgGLGetParameter2d(CGparameter param, double *v);
CGGL_API void CGGLENTRY cgGLGetParameter3d(CGparameter param, double *v);
CGGL_API void CGGLENTRY cgGLGetParameter4d(CGparameter param, double *v);
CGGL_API void CGGLENTRY cgGLSetParameterArray1f(CGparameter param,
long offset,
long nelements,
const float *v);
CGGL_API void CGGLENTRY cgGLSetParameterArray2f(CGparameter param,
long offset,
long nelements,
const float *v);
CGGL_API void CGGLENTRY cgGLSetParameterArray3f(CGparameter param,
long offset,
long nelements,
const float *v);
CGGL_API void CGGLENTRY cgGLSetParameterArray4f(CGparameter param,
long offset,
long nelements,
const float *v);
CGGL_API void CGGLENTRY cgGLSetParameterArray1d(CGparameter param,
long offset,
long nelements,
const double *v);
CGGL_API void CGGLENTRY cgGLSetParameterArray2d(CGparameter param,
long offset,
long nelements,
const double *v);
CGGL_API void CGGLENTRY cgGLSetParameterArray3d(CGparameter param,
long offset,
long nelements,
const double *v);
CGGL_API void CGGLENTRY cgGLSetParameterArray4d(CGparameter param,
long offset,
long nelements,
const double *v);
CGGL_API void CGGLENTRY cgGLGetParameterArray1f(CGparameter param,
long offset,
long nelements,
float *v);
CGGL_API void CGGLENTRY cgGLGetParameterArray2f(CGparameter param,
long offset,
long nelements,
float *v);
CGGL_API void CGGLENTRY cgGLGetParameterArray3f(CGparameter param,
long offset,
long nelements,
float *v);
CGGL_API void CGGLENTRY cgGLGetParameterArray4f(CGparameter param,
long offset,
long nelements,
float *v);
CGGL_API void CGGLENTRY cgGLGetParameterArray1d(CGparameter param,
long offset,
long nelements,
double *v);
CGGL_API void CGGLENTRY cgGLGetParameterArray2d(CGparameter param,
long offset,
long nelements,
double *v);
CGGL_API void CGGLENTRY cgGLGetParameterArray3d(CGparameter param,
long offset,
long nelements,
double *v);
CGGL_API void CGGLENTRY cgGLGetParameterArray4d(CGparameter param,
long offset,
long nelements,
double *v);
CGGL_API void CGGLENTRY cgGLSetParameterPointer(CGparameter param,
GLint fsize,
GLenum type,
GLsizei stride,
const GLvoid *pointer);
CGGL_API void CGGLENTRY cgGLEnableClientState(CGparameter param);
CGGL_API void CGGLENTRY cgGLDisableClientState(CGparameter param);
/******************************************************************************
*** Matrix Parameter Managment Functions
*****************************************************************************/
CGGL_API void CGGLENTRY cgGLSetMatrixParameterdr(CGparameter param,
const double *matrix);
CGGL_API void CGGLENTRY cgGLSetMatrixParameterfr(CGparameter param,
const float *matrix);
CGGL_API void CGGLENTRY cgGLSetMatrixParameterdc(CGparameter param,
const double *matrix);
CGGL_API void CGGLENTRY cgGLSetMatrixParameterfc(CGparameter param,
const float *matrix);
CGGL_API void CGGLENTRY cgGLGetMatrixParameterdr(CGparameter param, double *matrix);
CGGL_API void CGGLENTRY cgGLGetMatrixParameterfr(CGparameter param, float *matrix);
CGGL_API void CGGLENTRY cgGLGetMatrixParameterdc(CGparameter param, double *matrix);
CGGL_API void CGGLENTRY cgGLGetMatrixParameterfc(CGparameter param, float *matrix);
CGGL_API void CGGLENTRY cgGLSetStateMatrixParameter(CGparameter param,
CGGLenum matrix,
CGGLenum transform);
CGGL_API void CGGLENTRY cgGLSetMatrixParameterArrayfc(CGparameter param,
long offset,
long nelements,
const float *matrices);
CGGL_API void CGGLENTRY cgGLSetMatrixParameterArrayfr(CGparameter param,
long offset,
long nelements,
const float *matrices);
CGGL_API void CGGLENTRY cgGLSetMatrixParameterArraydc(CGparameter param,
long offset,
long nelements,
const double *matrices);
CGGL_API void CGGLENTRY cgGLSetMatrixParameterArraydr(CGparameter param,
long offset,
long nelements,
const double *matrices);
CGGL_API void CGGLENTRY cgGLGetMatrixParameterArrayfc(CGparameter param,
long offset,
long nelements,
float *matrices);
CGGL_API void CGGLENTRY cgGLGetMatrixParameterArrayfr(CGparameter param,
long offset,
long nelements,
float *matrices);
CGGL_API void CGGLENTRY cgGLGetMatrixParameterArraydc(CGparameter param,
long offset,
long nelements,
double *matrices);
CGGL_API void CGGLENTRY cgGLGetMatrixParameterArraydr(CGparameter param,
long offset,
long nelements,
double *matrices);
/******************************************************************************
*** Texture Parameter Managment Functions
*****************************************************************************/
CGGL_API void CGGLENTRY cgGLSetTextureParameter(CGparameter param, GLuint texobj);
CGGL_API GLuint CGGLENTRY cgGLGetTextureParameter(CGparameter param);
CGGL_API void CGGLENTRY cgGLEnableTextureParameter(CGparameter param);
CGGL_API void CGGLENTRY cgGLDisableTextureParameter(CGparameter param);
CGGL_API GLenum CGGLENTRY cgGLGetTextureEnum(CGparameter param);
CGGL_API void CGGLENTRY cgGLSetManageTextureParameters(CGcontext ctx, CGbool flag);
CGGL_API CGbool CGGLENTRY cgGLGetManageTextureParameters(CGcontext ctx);
CGGL_API void CGGLENTRY cgGLSetupSampler(CGparameter param, GLuint texobj);
CGGL_API void CGGLENTRY cgGLRegisterStates(CGcontext);
CGGL_API void CGGLENTRY cgGLEnableProgramProfiles( CGprogram program );
CGGL_API void CGGLENTRY cgGLDisableProgramProfiles( CGprogram program );
/******************************************************************************
*** Misc Functions
*****************************************************************************/
CGGL_API void CGGLENTRY cgGLSetDebugMode( CGbool debug );
/******************************************************************************
*** Buffer Functions
*****************************************************************************/
CGGL_API CGbuffer CGGLENTRY cgGLCreateBuffer(CGcontext context, int size, const void *data, GLenum bufferUsage);
CGGL_API GLuint CGGLENTRY cgGLGetBufferObject(CGbuffer buffer);
#endif
#ifdef __cplusplus
}
#endif
#ifdef CGGL_APIENTRY_DEFINED
# undef CGGL_APIENTRY_DEFINED
# undef APIENTRY
#endif
#ifdef CGGL_WINGDIAPI_DEFINED
# undef CGGL_WINGDIAPI_DEFINED
# undef WINGDIAPI
#endif
#endif

View File

@ -0,0 +1,75 @@
/*
*
* Copyright (c) 2002-2009, NVIDIA Corporation.
*
*
*
* NVIDIA Corporation("NVIDIA") supplies this software to you in consideration
* of your agreement to the following terms, and your use, installation,
* modification or redistribution of this NVIDIA software constitutes
* acceptance of these terms. If you do not agree with these terms, please do
* not use, install, modify or redistribute this NVIDIA software.
*
*
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, NVIDIA grants you a personal, non-exclusive license,
* under NVIDIA's copyrights in this original NVIDIA software (the "NVIDIA
* Software"), to use, reproduce, modify and redistribute the NVIDIA
* Software, with or without modifications, in source and/or binary forms;
* provided that if you redistribute the NVIDIA Software, you must retain the
* copyright notice of NVIDIA, this notice and the following text and
* disclaimers in all such redistributions of the NVIDIA Software. Neither the
* name, trademarks, service marks nor logos of NVIDIA Corporation may be used
* to endorse or promote products derived from the NVIDIA Software without
* specific prior written permission from NVIDIA. Except as expressly stated
* in this notice, no other rights or licenses express or implied, are granted
* by NVIDIA herein, including but not limited to any patent rights that may be
* infringed by your derivative works or by other works in which the NVIDIA
* Software may be incorporated. No hardware is licensed hereunder.
*
*
*
* THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
* WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR ITS USE AND OPERATION
* EITHER ALONE OR IN COMBINATION WITH OTHER PRODUCTS.
*
*
*
* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
* EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOST
* PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY OUT OF THE USE,
* REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE NVIDIA SOFTWARE,
* HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING
* NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF NVIDIA HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
CG_PROFILE_MACRO(Vertex,vp20,VP20,"vp20",6146,1)
CG_PROFILE_MACRO(Fragment20,fp20,FP20,"fp20",6147,0)
CG_PROFILE_MACRO(Vertex30,vp30,VP30,"vp30",6148,1)
CG_PROFILE_MACRO(Fragment,fp30,FP30,"fp30",6149,0)
CG_PROFILE_MACRO(ARBVertex,arbvp1,ARBVP1,"arbvp1",6150,1)
CG_PROFILE_MACRO(Fragment40,fp40,FP40,"fp40",6151,0)
CG_PROFILE_MACRO(ARBFragment,arbfp1,ARBFP1,"arbfp1",7000,0)
CG_PROFILE_MACRO(Vertex40,vp40,VP40,"vp40",7001,1)
CG_PROFILE_MACRO(GLSLVertex,glslv,GLSLV,"glslv",7007,1)
CG_PROFILE_MACRO(GLSLFragment,glslf,GLSLF,"glslf",7008,0)
CG_PROFILE_MACRO(GLSLGeometry,glslg,GLSLG,"glslg",7016,0)
CG_PROFILE_MACRO(GLSLCombined, glslc, GLSLC, "glslc", 7009, 0)
CG_PROFILE_MACRO(GPUFragment,gpu_fp,GPU_FP,"gp4fp",7010,0)
CG_PROFILE_MACRO(GPUVertex,gpu_vp,GPU_VP,"gp4vp",7011,1)
CG_PROFILE_MACRO(GPUGeometry,gpu_gp,GPU_GP,"gp4gp",7012,0)
CG_PROFILE_ALIAS(GPUFragment,gp4fp,GP4FP,"gp4fp",7010,0)
CG_PROFILE_ALIAS(GPUVertex,gp4vp,GP4VP,"gp4vp",7011,1)
CG_PROFILE_ALIAS(GPUGeometry,gp4gp,GP4GP,"gp4gp",7012,0)
#ifndef CG_IN_PROFILES_INCLUDE
# undef CG_PROFILE_MACRO
#endif

View File

@ -0,0 +1,382 @@
/*
*
* Copyright (c) 2002-2009, NVIDIA Corporation.
*
*
*
* NVIDIA Corporation("NVIDIA") supplies this software to you in consideration
* of your agreement to the following terms, and your use, installation,
* modification or redistribution of this NVIDIA software constitutes
* acceptance of these terms. If you do not agree with these terms, please do
* not use, install, modify or redistribute this NVIDIA software.
*
*
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, NVIDIA grants you a personal, non-exclusive license,
* under NVIDIA's copyrights in this original NVIDIA software (the "NVIDIA
* Software"), to use, reproduce, modify and redistribute the NVIDIA
* Software, with or without modifications, in source and/or binary forms;
* provided that if you redistribute the NVIDIA Software, you must retain the
* copyright notice of NVIDIA, this notice and the following text and
* disclaimers in all such redistributions of the NVIDIA Software. Neither the
* name, trademarks, service marks nor logos of NVIDIA Corporation may be used
* to endorse or promote products derived from the NVIDIA Software without
* specific prior written permission from NVIDIA. Except as expressly stated
* in this notice, no other rights or licenses express or implied, are granted
* by NVIDIA herein, including but not limited to any patent rights that may be
* infringed by your derivative works or by other works in which the NVIDIA
* Software may be incorporated. No hardware is licensed hereunder.
*
*
*
* THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
* WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR ITS USE AND OPERATION
* EITHER ALONE OR IN COMBINATION WITH OTHER PRODUCTS.
*
*
*
* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
* EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOST
* PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY OUT OF THE USE,
* REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE NVIDIA SOFTWARE,
* HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING
* NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF NVIDIA HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* The following macro invocations define the supported CG basic hardware
* bind locations.
*
* The macros have the form :
*
* CG_BINDLOCATION_MACRO(name, compiler_name, enum_int)
*
* name : The name of the location.
* enum_name : The C enumerant.
* compiler_name : The name of the location within the compiler syntax.
* int_id : Integer enumerant associated with this bind location.
* (3256 is reservered for CG_UNDEFINED)
* addressable : The bind location must have an integer address
* associated with it.
* ParamType : the cgParamType of this register.
*
*/
CG_BINDLOCATION_MACRO(TexUnit0,CG_TEXUNIT0,"texunit 0",2048,0,CG_TEXOBJ_PARAM)
CG_BINDLOCATION_MACRO(TexUnit1,CG_TEXUNIT1,"texunit 1",2049,0,CG_TEXOBJ_PARAM)
CG_BINDLOCATION_MACRO(TexUnit2,CG_TEXUNIT2,"texunit 2",2050,0,CG_TEXOBJ_PARAM)
CG_BINDLOCATION_MACRO(TexUnit3,CG_TEXUNIT3,"texunit 3",2051,0,CG_TEXOBJ_PARAM)
CG_BINDLOCATION_MACRO(TexUnit4,CG_TEXUNIT4,"texunit 4",2052,0,CG_TEXOBJ_PARAM)
CG_BINDLOCATION_MACRO(TexUnit5,CG_TEXUNIT5,"texunit 5",2053,0,CG_TEXOBJ_PARAM)
CG_BINDLOCATION_MACRO(TexUnit6,CG_TEXUNIT6,"texunit 6",2054,0,CG_TEXOBJ_PARAM)
CG_BINDLOCATION_MACRO(TexUnit7,CG_TEXUNIT7,"texunit 7",2055,0,CG_TEXOBJ_PARAM)
CG_BINDLOCATION_MACRO(TexUnit8,CG_TEXUNIT8,"texunit 8",2056,0,CG_TEXOBJ_PARAM)
CG_BINDLOCATION_MACRO(TexUnit9,CG_TEXUNIT9,"texunit 9",2057,0,CG_TEXOBJ_PARAM)
CG_BINDLOCATION_MACRO(TexUnit10,CG_TEXUNIT10,"texunit 10",2058,0,CG_TEXOBJ_PARAM)
CG_BINDLOCATION_MACRO(TexUnit11,CG_TEXUNIT11,"texunit 11",2059,0,CG_TEXOBJ_PARAM)
CG_BINDLOCATION_MACRO(TexUnit12,CG_TEXUNIT12,"texunit 12",2060,0,CG_TEXOBJ_PARAM)
CG_BINDLOCATION_MACRO(TexUnit13,CG_TEXUNIT13,"texunit 13",2061,0,CG_TEXOBJ_PARAM)
CG_BINDLOCATION_MACRO(TexUnit14,CG_TEXUNIT14,"texunit 14",2062,0,CG_TEXOBJ_PARAM)
CG_BINDLOCATION_MACRO(TexUnit15,CG_TEXUNIT15,"texunit 15",2063,0,CG_TEXOBJ_PARAM)
CG_BINDLOCATION_MACRO(Buffer0, CG_BUFFER0, "buffer[0]", 2064, 1, CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(Buffer1, CG_BUFFER1, "buffer[1]", 2065, 1, CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(Buffer2, CG_BUFFER2, "buffer[2]", 2066, 1, CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(Buffer3, CG_BUFFER3, "buffer[3]", 2067, 1, CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(Buffer4, CG_BUFFER4, "buffer[4]", 2068, 1, CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(Buffer5, CG_BUFFER5, "buffer[5]", 2069, 1, CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(Buffer6, CG_BUFFER6, "buffer[6]", 2070, 1, CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(Buffer7, CG_BUFFER7, "buffer[7]", 2071, 1, CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(Buffer8, CG_BUFFER8, "buffer[8]", 2072, 1, CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(Buffer9, CG_BUFFER9, "buffer[9]", 2073, 1, CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(Buffer10, CG_BUFFER10, "buffer[10]", 2074, 1, CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(Buffer11, CG_BUFFER11, "buffer[11]", 2075, 1, CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(Attr0,CG_ATTR0,"ATTR0",2113,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Attr1,CG_ATTR1,"ATTR1",2114,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Attr2,CG_ATTR2,"ATTR2",2115,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Attr3,CG_ATTR3,"ATTR3",2116,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Attr4,CG_ATTR4,"ATTR4",2117,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Attr5,CG_ATTR5,"ATTR5",2118,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Attr6,CG_ATTR6,"ATTR6",2119,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Attr7,CG_ATTR7,"ATTR7",2120,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Attr8,CG_ATTR8,"ATTR8",2121,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Attr9,CG_ATTR9,"ATTR9",2122,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Attr10,CG_ATTR10,"ATTR10",2123,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Attr11,CG_ATTR11,"ATTR11",2124,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Attr12,CG_ATTR12,"ATTR12",2125,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Attr13,CG_ATTR13,"ATTR13",2126,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Attr14,CG_ATTR14,"ATTR14",2127,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Attr15,CG_ATTR15,"ATTR15",2128,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(VertUniform,CG_C,"c",2178,1,CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(Tex0,CG_TEX0,"TEX0",2179,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tex1,CG_TEX1,"TEX1",2180,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tex2,CG_TEX2,"TEX2",2181,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tex3,CG_TEX3,"TEX3",2192,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tex4,CG_TEX4,"TEX4",2193,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tex5,CG_TEX5,"TEX5",2194,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tex6,CG_TEX6,"TEX6",2195,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tex7,CG_TEX7,"TEX7",2196,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(HPos,CG_HPOS,"HPOS",2243,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Col0,CG_COL0,"COL0",2245,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Col1,CG_COL1,"COL1",2246,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Col2,CG_COL2,"COL2",2247,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Col3,CG_COL3,"COL3",2248,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PSiz,CG_PSIZ,"PSIZ",2309,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Clp0,CG_CLP0,"CLP0",2310,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Clp1,CG_CLP1,"CLP1",2311,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Clp2,CG_CLP2,"CLP2",2312,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Clp3,CG_CLP3,"CLP3",2313,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Clp4,CG_CLP4,"CLP4",2314,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Clp5,CG_CLP5,"CLP5",2315,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(WPos,CG_WPOS,"WPOS",2373,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PointCoord,CG_POINTCOORD,"POINTCOORD",2374,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Position0,CG_POSITION0,"POSITION0",2437,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Position1,CG_POSITION1,"POSITION1",2438,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Position2,CG_POSITION2,"POSITION2",2439,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Position3,CG_POSITION3,"POSITION3",2440,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Position4,CG_POSITION4,"POSITION4",2441,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Position5,CG_POSITION5,"POSITION5",2442,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Position6,CG_POSITION6,"POSITION6",2443,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Position7,CG_POSITION7,"POSITION7",2444,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Position8,CG_POSITION8,"POSITION8",2445,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Position9,CG_POSITION9,"POSITION9",2446,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Position10,CG_POSITION10,"POSITION10",2447,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Position11,CG_POSITION11,"POSITION11",2448,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Position12,CG_POSITION12,"POSITION12",2449,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Position13,CG_POSITION13,"POSITION13",2450,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Position14,CG_POSITION14,"POSITION14",2451,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Position15,CG_POSITION15,"POSITION15",2452,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Diffuse0,CG_DIFFUSE0,"DIFFUSE0",2501,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tangent0,CG_TANGENT0,"TANGENT0",2565,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tangent1,CG_TANGENT1,"TANGENT1",2566,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tangent2,CG_TANGENT2,"TANGENT2",2567,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tangent3,CG_TANGENT3,"TANGENT3",2568,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tangent4,CG_TANGENT4,"TANGENT4",2569,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tangent5,CG_TANGENT5,"TANGENT5",2570,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tangent6,CG_TANGENT6,"TANGENT6",2571,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tangent7,CG_TANGENT7,"TANGENT7",2572,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tangent8,CG_TANGENT8,"TANGENT8",2573,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tangent9,CG_TANGENT9,"TANGENT9",2574,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tangent10,CG_TANGENT10,"TANGENT10",2575,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tangent11,CG_TANGENT11,"TANGENT11",2576,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tangent12,CG_TANGENT12,"TANGENT12",2577,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tangent13,CG_TANGENT13,"TANGENT13",2578,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tangent14,CG_TANGENT14,"TANGENT14",2579,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Tangent15,CG_TANGENT15,"TANGENT15",2580,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Specular0,CG_SPECULAR0,"SPECULAR0",2629,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendIndices0,CG_BLENDINDICES0,"BLENDINDICES0",2693,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendIndices1,CG_BLENDINDICES1,"BLENDINDICES1",2694,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendIndices2,CG_BLENDINDICES2,"BLENDINDICES2",2695,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendIndices3,CG_BLENDINDICES3,"BLENDINDICES3",2696,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendIndices4,CG_BLENDINDICES4,"BLENDINDICES4",2697,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendIndices5,CG_BLENDINDICES5,"BLENDINDICES5",2698,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendIndices6,CG_BLENDINDICES6,"BLENDINDICES6",2699,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendIndices7,CG_BLENDINDICES7,"BLENDINDICES7",2700,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendIndices8,CG_BLENDINDICES8,"BLENDINDICES8",2701,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendIndices9,CG_BLENDINDICES9,"BLENDINDICES9",2702,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendIndices10,CG_BLENDINDICES10,"BLENDINDICES10",2703,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendIndices11,CG_BLENDINDICES11,"BLENDINDICES11",2704,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendIndices12,CG_BLENDINDICES12,"BLENDINDICES12",2705,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendIndices13,CG_BLENDINDICES13,"BLENDINDICES13",2706,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendIndices14,CG_BLENDINDICES14,"BLENDINDICES14",2707,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendIndices15,CG_BLENDINDICES15,"BLENDINDICES15",2708,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Color0,CG_COLOR0,"COLOR0",2757,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Color1,CG_COLOR1,"COLOR1",2758,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Color2,CG_COLOR2,"COLOR2",2759,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Color3,CG_COLOR3,"COLOR3",2760,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Color4,CG_COLOR4,"COLOR4",2761,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Color5,CG_COLOR5,"COLOR5",2762,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Color6,CG_COLOR6,"COLOR6",2763,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Color7,CG_COLOR7,"COLOR7",2764,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Color8,CG_COLOR8,"COLOR8",2765,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Color9,CG_COLOR9,"COLOR9",2766,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Color10,CG_COLOR10,"COLOR10",2767,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Color11,CG_COLOR11,"COLOR11",2768,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Color12,CG_COLOR12,"COLOR12",2769,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Color13,CG_COLOR13,"COLOR13",2770,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Color14,CG_COLOR14,"COLOR14",2771,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Color15,CG_COLOR15,"COLOR15",2772,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PSize0,CG_PSIZE0,"PSIZE0",2821,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PSize1,CG_PSIZE1,"PSIZE1",2822,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PSize2,CG_PSIZE2,"PSIZE2",2823,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PSize3,CG_PSIZE3,"PSIZE3",2824,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PSize4,CG_PSIZE4,"PSIZE4",2825,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PSize5,CG_PSIZE5,"PSIZE5",2826,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PSize6,CG_PSIZE6,"PSIZE6",2827,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PSize7,CG_PSIZE7,"PSIZE7",2828,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PSize8,CG_PSIZE8,"PSIZE8",2829,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PSize9,CG_PSIZE9,"PSIZE9",2830,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PSize10,CG_PSIZE10,"PSIZE10",2831,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PSize11,CG_PSIZE11,"PSIZE11",2832,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PSize12,CG_PSIZE12,"PSIZE12",2833,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PSize13,CG_PSIZE13,"PSIZE13",2834,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PSize14,CG_PSIZE14,"PSIZE14",2835,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PSize15,CG_PSIZE15,"PSIZE15",2836,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BiNormal0,CG_BINORMAL0,"BINORMAL0",2885,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BiNormal1,CG_BINORMAL1,"BINORMAL1",2886,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BiNormal2,CG_BINORMAL2,"BINORMAL2",2887,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BiNormal3,CG_BINORMAL3,"BINORMAL3",2888,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BiNormal4,CG_BINORMAL4,"BINORMAL4",2889,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BiNormal5,CG_BINORMAL5,"BINORMAL5",2890,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BiNormal6,CG_BINORMAL6,"BINORMAL6",2891,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BiNormal7,CG_BINORMAL7,"BINORMAL7",2892,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BiNormal8,CG_BINORMAL8,"BINORMAL8",2893,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BiNormal9,CG_BINORMAL9,"BINORMAL9",2894,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BiNormal10,CG_BINORMAL10,"BINORMAL10",2895,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BiNormal11,CG_BINORMAL11,"BINORMAL11",2896,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BiNormal12,CG_BINORMAL12,"BINORMAL12",2897,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BiNormal13,CG_BINORMAL13,"BINORMAL13",2898,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BiNormal14,CG_BINORMAL14,"BINORMAL14",2899,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BiNormal15,CG_BINORMAL15,"BINORMAL15",2900,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(FOG0,CG_FOG0,"FOG0",2917,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(FOG1,CG_FOG1,"FOG1",2918,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(FOG2,CG_FOG2,"FOG2",2919,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(FOG3,CG_FOG3,"FOG3",2920,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(FOG4,CG_FOG4,"FOG4",2921,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(FOG5,CG_FOG5,"FOG5",2922,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(FOG6,CG_FOG6,"FOG6",2923,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(FOG7,CG_FOG7,"FOG7",2924,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(FOG8,CG_FOG8,"FOG8",2925,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(FOG9,CG_FOG9,"FOG9",2926,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(FOG10,CG_FOG10,"FOG10",2927,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(FOG11,CG_FOG11,"FOG11",2928,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(FOG12,CG_FOG12,"FOG12",2929,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(FOG13,CG_FOG13,"FOG13",2930,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(FOG14,CG_FOG14,"FOG14",2931,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(FOG15,CG_FOG15,"FOG15",2932,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(DEPTH0,CG_DEPTH0,"DEPTH0",2933,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(DEPTH1,CG_DEPTH1,"DEPTH1",2934,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(DEPTH2,CG_DEPTH2,"DEPTH2",2935,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(DEPTH3,CG_DEPTH3,"DEPTH3",2936,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(DEPTH4,CG_DEPTH4,"DEPTH4",2937,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(DEPTH5,CG_DEPTH5,"DEPTH5",2938,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(DEPTH6,CG_DEPTH6,"DEPTH6",2939,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(DEPTH7,CG_DEPTH7,"DEPTH7",2940,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(DEPTH8,CG_DEPTH8,"DEPTH8",2941,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(DEPTH9,CG_DEPTH9,"DEPTH9",2942,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(DEPTH10,CG_DEPTH10,"DEPTH10",2943,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(DEPTH11,CG_DEPTH11,"DEPTH11",2944,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(DEPTH12,CG_DEPTH12,"DEPTH12",2945,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(DEPTH13,CG_DEPTH13,"DEPTH13",2946,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(DEPTH14,CG_DEPTH14,"DEPTH14",2947,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(DEPTH15,CG_DEPTH15,"DEPTH15",2948,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SAMPLE0,CG_SAMPLE0,"SAMPLE0",2949,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SAMPLE1,CG_SAMPLE1,"SAMPLE1",2950,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SAMPLE2,CG_SAMPLE2,"SAMPLE2",2951,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SAMPLE3,CG_SAMPLE3,"SAMPLE3",2952,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SAMPLE4,CG_SAMPLE4,"SAMPLE4",2953,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SAMPLE5,CG_SAMPLE5,"SAMPLE5",2954,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SAMPLE6,CG_SAMPLE6,"SAMPLE6",2955,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SAMPLE7,CG_SAMPLE7,"SAMPLE7",2956,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SAMPLE8,CG_SAMPLE8,"SAMPLE8",2957,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SAMPLE9,CG_SAMPLE9,"SAMPLE9",2958,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SAMPLE10,CG_SAMPLE10,"SAMPLE10",2959,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SAMPLE11,CG_SAMPLE11,"SAMPLE11",2960,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SAMPLE12,CG_SAMPLE12,"SAMPLE12",2961,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SAMPLE13,CG_SAMPLE13,"SAMPLE13",2962,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SAMPLE14,CG_SAMPLE14,"SAMPLE14",2963,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SAMPLE15,CG_SAMPLE15,"SAMPLE15",2964,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendWeight0,CG_BLENDWEIGHT0,"BLENDWEIGHT0",3028,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendWeight1,CG_BLENDWEIGHT1,"BLENDWEIGHT1",3029,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendWeight2,CG_BLENDWEIGHT2,"BLENDWEIGHT2",3030,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendWeight3,CG_BLENDWEIGHT3,"BLENDWEIGHT3",3031,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendWeight4,CG_BLENDWEIGHT4,"BLENDWEIGHT4",3032,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendWeight5,CG_BLENDWEIGHT5,"BLENDWEIGHT5",3033,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendWeight6,CG_BLENDWEIGHT6,"BLENDWEIGHT6",3034,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendWeight7,CG_BLENDWEIGHT7,"BLENDWEIGHT7",3035,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendWeight8,CG_BLENDWEIGHT8,"BLENDWEIGHT8",3036,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendWeight9,CG_BLENDWEIGHT9,"BLENDWEIGHT9",3037,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendWeight10,CG_BLENDWEIGHT10,"BLENDWEIGHT10",3038,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendWeight11,CG_BLENDWEIGHT11,"BLENDWEIGHT11",3039,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendWeight12,CG_BLENDWEIGHT12,"BLENDWEIGHT12",3040,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendWeight13,CG_BLENDWEIGHT13,"BLENDWEIGHT13",3041,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendWeight14,CG_BLENDWEIGHT14,"BLENDWEIGHT14",3042,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(BlendWeight15,CG_BLENDWEIGHT15,"BLENDWEIGHT15",3043,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Normal0,CG_NORMAL0,"NORMAL0",3092,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Normal1,CG_NORMAL1,"NORMAL1",3093,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Normal2,CG_NORMAL2,"NORMAL2",3094,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Normal3,CG_NORMAL3,"NORMAL3",3095,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Normal4,CG_NORMAL4,"NORMAL4",3096,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Normal5,CG_NORMAL5,"NORMAL5",3097,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Normal6,CG_NORMAL6,"NORMAL6",3098,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Normal7,CG_NORMAL7,"NORMAL7",3099,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Normal8,CG_NORMAL8,"NORMAL8",3100,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Normal9,CG_NORMAL9,"NORMAL9",3101,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Normal10,CG_NORMAL10,"NORMAL10",3102,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Normal11,CG_NORMAL11,"NORMAL11",3103,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Normal12,CG_NORMAL12,"NORMAL12",3104,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Normal13,CG_NORMAL13,"NORMAL13",3105,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Normal14,CG_NORMAL14,"NORMAL14",3106,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Normal15,CG_NORMAL15,"NORMAL15",3107,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(FogCoord,CG_FOGCOORD,"FOGCOORD",3156,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(TexCoord0,CG_TEXCOORD0,"TEXCOORD0",3220,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(TexCoord1,CG_TEXCOORD1,"TEXCOORD1",3221,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(TexCoord2,CG_TEXCOORD2,"TEXCOORD2",3222,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(TexCoord3,CG_TEXCOORD3,"TEXCOORD3",3223,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(TexCoord4,CG_TEXCOORD4,"TEXCOORD4",3224,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(TexCoord5,CG_TEXCOORD5,"TEXCOORD5",3225,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(TexCoord6,CG_TEXCOORD6,"TEXCOORD6",3226,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(TexCoord7,CG_TEXCOORD7,"TEXCOORD7",3227,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(TexCoord8,CG_TEXCOORD8,"TEXCOORD8",3228,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(TexCoord9,CG_TEXCOORD9,"TEXCOORD9",3229,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(TexCoord10,CG_TEXCOORD10,"TEXCOORD10",3230,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(TexCoord11,CG_TEXCOORD11,"TEXCOORD11",3231,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(TexCoord12,CG_TEXCOORD12,"TEXCOORD12",3232,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(TexCoord13,CG_TEXCOORD13,"TEXCOORD13",3233,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(TexCoord14,CG_TEXCOORD14,"TEXCOORD14",3234,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(TexCoord15,CG_TEXCOORD15,"TEXCOORD15",3235,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(CombinerConst0,CG_COMBINER_CONST0,"COMBINER_CONST0",3284,0,CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(CombinerConst1,CG_COMBINER_CONST1,"COMBINER_CONST1",3285,0,CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(CombinerStageConst0,CG_COMBINER_STAGE_CONST0,"COMBINER_STAGE_CONST0",3286,1,CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(CombinerStageConst1,CG_COMBINER_STAGE_CONST1,"COMBINER_STAGE_CONST1",3287,1,CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(OffsetTextureMatrix,CG_OFFSET_TEXTURE_MATRIX,"OFFSET_TEXTURE_MATRIX",3288,0,CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(OffsetTextureScale,CG_OFFSET_TEXTURE_SCALE,"OFFSET_TEXTURE_SCALE",3289,0,CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(OffsetTextureBias,CG_OFFSET_TEXTURE_BIAS,"OFFSET_TEXTURE_BIAS",3290,0,CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(ConstEye,CG_CONST_EYE,"CONST_EYE",3291,0,CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(Coverage, CG_COVERAGE, "COVERAGE", 3292, 0, CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(TessFactor,CG_TESSFACTOR,"TESSFACTOR",3255,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(GLSLUniform,CG_GLSL_UNIFORM,"glsl_uniform",3300,1,CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(GLSLAttrib,CG_GLSL_ATTRIB,"glsl_attrib",3301,1,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Env,CG_ENV,"ENV",3302,1,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(HLSLUniform,CG_HLSL_UNIFORM,"hlsl_uniform",3559,1,CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(HLSLAttrib,CG_HLSL_VARYING,"hlsl_attrib",3560,1,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SamplerResource,CG_SAMPLER_RES, "SAMPLER_RES", 3561, 1, CGI_UNIFORM_PARAM)
CG_BINDLOCATION_MACRO(LastColor0, CG_LASTCOL0, "LASTCOL0", 4400, 0, CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(LastColor1, CG_LASTCOL1, "LASTCOL1", 4401, 0, CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(LastColor2, CG_LASTCOL2, "LASTCOL2", 4402, 0, CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(LastColor3, CG_LASTCOL3, "LASTCOL3", 4403, 0, CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(LastColor4, CG_LASTCOL4, "LASTCOL4", 4404, 0, CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(LastColor5, CG_LASTCOL5, "LASTCOL5", 4405, 0, CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(LastColor6, CG_LASTCOL6, "LASTCOL6", 4406, 0, CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(LastColor7, CG_LASTCOL7, "LASTCOL7", 4407, 0, CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Face,CG_FACE,"FACE",4410,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(PrimitiveId,CG_PRIMITIVEID,"PRIMITIVEID",4411,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(InstanceId,CG_INSTANCEID,"INSTANCEID",4412,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SampleId,CG_SAMPLEID,"SAMPLEID",4413,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(VertexId,CG_VERTEXID,"VERTEXID",4414,0,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(Layer,CG_LAYER,"LAYER",4415,1,CG_VARYING_PARAM)
CG_BINDLOCATION_MACRO(SampleMask,CG_SAMPLEMASK,"SAMPLEMASK",4416,0,CG_VARYING_PARAM)
#undef CG_BINDLOCATION_MACRO

View File

@ -0,0 +1,196 @@
/*
*
* Copyright (c) 2002-2009, NVIDIA Corporation.
*
*
*
* NVIDIA Corporation("NVIDIA") supplies this software to you in consideration
* of your agreement to the following terms, and your use, installation,
* modification or redistribution of this NVIDIA software constitutes
* acceptance of these terms. If you do not agree with these terms, please do
* not use, install, modify or redistribute this NVIDIA software.
*
*
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, NVIDIA grants you a personal, non-exclusive license,
* under NVIDIA's copyrights in this original NVIDIA software (the "NVIDIA
* Software"), to use, reproduce, modify and redistribute the NVIDIA
* Software, with or without modifications, in source and/or binary forms;
* provided that if you redistribute the NVIDIA Software, you must retain the
* copyright notice of NVIDIA, this notice and the following text and
* disclaimers in all such redistributions of the NVIDIA Software. Neither the
* name, trademarks, service marks nor logos of NVIDIA Corporation may be used
* to endorse or promote products derived from the NVIDIA Software without
* specific prior written permission from NVIDIA. Except as expressly stated
* in this notice, no other rights or licenses express or implied, are granted
* by NVIDIA herein, including but not limited to any patent rights that may be
* infringed by your derivative works or by other works in which the NVIDIA
* Software may be incorporated. No hardware is licensed hereunder.
*
*
*
* THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
* WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR ITS USE AND OPERATION
* EITHER ALONE OR IN COMBINATION WITH OTHER PRODUCTS.
*
*
*
* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
* EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOST
* PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY OUT OF THE USE,
* REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE NVIDIA SOFTWARE,
* HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING
* NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF NVIDIA HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* The following macro invocations define the supported CG basic data types.
*
* The macros have the form :
*
* CG_DATATYPE_MACRO(name, compiler_name, enum_name, base_name, nrows, ncols, pc_name)
*
* name : The name of the data type.
* compiler_name : The name of the data type within the compiler syntax.
* enum_name : The C enumerant.
* base_name : The C enumerant of the base type.
* nrows : Number of rows for matrix types. Should be 0 other-wise.
* ncols : Number of columns for scalar, vector, and matrix types.
* pc_name : The C enumerant of the parameter class.
*
*/
/*
* ADD NEW DATA TYPES TO THE END OF THIS MACRO LIST!
*
*/
CG_DATATYPE_MACRO(Half,half,CG_HALF,CG_HALF,0,1,CG_PARAMETERCLASS_SCALAR)
CG_DATATYPE_MACRO(Half2,half2,CG_HALF2,CG_HALF,0,2,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Half3,half3,CG_HALF3,CG_HALF,0,3,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Half4,half4,CG_HALF4,CG_HALF,0,4,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Half1x1,half1x1,CG_HALF1x1,CG_HALF,1,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Half1x2,half1x2,CG_HALF1x2,CG_HALF,1,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Half1x3,half1x3,CG_HALF1x3,CG_HALF,1,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Half1x4,half1x4,CG_HALF1x4,CG_HALF,1,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Half2x1,half2x1,CG_HALF2x1,CG_HALF,2,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Half2x2,half2x2,CG_HALF2x2,CG_HALF,2,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Half2x3,half2x3,CG_HALF2x3,CG_HALF,2,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Half2x4,half2x4,CG_HALF2x4,CG_HALF,2,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Half3x1,half3x1,CG_HALF3x1,CG_HALF,3,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Half3x2,half3x2,CG_HALF3x2,CG_HALF,3,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Half3x3,half3x3,CG_HALF3x3,CG_HALF,3,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Half3x4,half3x4,CG_HALF3x4,CG_HALF,3,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Half4x1,half4x1,CG_HALF4x1,CG_HALF,4,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Half4x2,half4x2,CG_HALF4x2,CG_HALF,4,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Half4x3,half4x3,CG_HALF4x3,CG_HALF,4,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Half4x4,half4x4,CG_HALF4x4,CG_HALF,4,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Float,float,CG_FLOAT,CG_FLOAT,0,1,CG_PARAMETERCLASS_SCALAR)
CG_DATATYPE_MACRO(Float2,float2,CG_FLOAT2,CG_FLOAT,0,2,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Float3,float3,CG_FLOAT3,CG_FLOAT,0,3,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Float4,float4,CG_FLOAT4,CG_FLOAT,0,4,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Float1x1,float1x1,CG_FLOAT1x1,CG_FLOAT,1,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Float1x2,float1x2,CG_FLOAT1x2,CG_FLOAT,1,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Float1x3,float1x3,CG_FLOAT1x3,CG_FLOAT,1,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Float1x4,float1x4,CG_FLOAT1x4,CG_FLOAT,1,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Float2x1,float2x1,CG_FLOAT2x1,CG_FLOAT,2,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Float2x2,float2x2,CG_FLOAT2x2,CG_FLOAT,2,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Float2x3,float2x3,CG_FLOAT2x3,CG_FLOAT,2,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Float2x4,float2x4,CG_FLOAT2x4,CG_FLOAT,2,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Float3x1,float3x1,CG_FLOAT3x1,CG_FLOAT,3,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Float3x2,float3x2,CG_FLOAT3x2,CG_FLOAT,3,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Float3x3,float3x3,CG_FLOAT3x3,CG_FLOAT,3,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Float3x4,float3x4,CG_FLOAT3x4,CG_FLOAT,3,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Float4x1,float4x1,CG_FLOAT4x1,CG_FLOAT,4,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Float4x2,float4x2,CG_FLOAT4x2,CG_FLOAT,4,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Float4x3,float4x3,CG_FLOAT4x3,CG_FLOAT,4,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Float4x4,float4x4,CG_FLOAT4x4,CG_FLOAT,4,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Sampler1D,sampler1D,CG_SAMPLER1D,CG_SAMPLER1D,0,0,CG_PARAMETERCLASS_SAMPLER)
CG_DATATYPE_MACRO(Sampler2D,sampler2D,CG_SAMPLER2D,CG_SAMPLER2D,0,0,CG_PARAMETERCLASS_SAMPLER)
CG_DATATYPE_MACRO(Sampler3D,sampler3D,CG_SAMPLER3D,CG_SAMPLER3D,0,0,CG_PARAMETERCLASS_SAMPLER)
CG_DATATYPE_MACRO(SamplerRECT,samplerRECT,CG_SAMPLERRECT,CG_SAMPLERRECT,0,0,CG_PARAMETERCLASS_SAMPLER)
CG_DATATYPE_MACRO(SamplerCUBE,samplerCUBE,CG_SAMPLERCUBE,CG_SAMPLERCUBE,0,0,CG_PARAMETERCLASS_SAMPLER)
CG_DATATYPE_MACRO(Fixed,fixed,CG_FIXED,CG_FIXED,0,1,CG_PARAMETERCLASS_SCALAR)
CG_DATATYPE_MACRO(Fixed2,fixed2,CG_FIXED2,CG_FIXED,0,2,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Fixed3,fixed3,CG_FIXED3,CG_FIXED,0,3,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Fixed4,fixed4,CG_FIXED4,CG_FIXED,0,4,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Fixed1x1,fixed1x1,CG_FIXED1x1,CG_FIXED,1,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Fixed1x2,fixed1x2,CG_FIXED1x2,CG_FIXED,1,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Fixed1x3,fixed1x3,CG_FIXED1x3,CG_FIXED,1,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Fixed1x4,fixed1x4,CG_FIXED1x4,CG_FIXED,1,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Fixed2x1,fixed2x1,CG_FIXED2x1,CG_FIXED,2,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Fixed2x2,fixed2x2,CG_FIXED2x2,CG_FIXED,2,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Fixed2x3,fixed2x3,CG_FIXED2x3,CG_FIXED,2,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Fixed2x4,fixed2x4,CG_FIXED2x4,CG_FIXED,2,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Fixed3x1,fixed3x1,CG_FIXED3x1,CG_FIXED,3,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Fixed3x2,fixed3x2,CG_FIXED3x2,CG_FIXED,3,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Fixed3x3,fixed3x3,CG_FIXED3x3,CG_FIXED,3,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Fixed3x4,fixed3x4,CG_FIXED3x4,CG_FIXED,3,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Fixed4x1,fixed4x1,CG_FIXED4x1,CG_FIXED,4,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Fixed4x2,fixed4x2,CG_FIXED4x2,CG_FIXED,4,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Fixed4x3,fixed4x3,CG_FIXED4x3,CG_FIXED,4,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Fixed4x4,fixed4x4,CG_FIXED4x4,CG_FIXED,4,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Half1,half1,CG_HALF1,CG_HALF,0,1,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Float1,float1,CG_FLOAT1,CG_FLOAT,0,1,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Fixed1,fixed1,CG_FIXED1,CG_FIXED,0,1,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Int,int,CG_INT,CG_INT,0,1,CG_PARAMETERCLASS_SCALAR)
CG_DATATYPE_MACRO(Int1,int1,CG_INT1,CG_INT,0,1,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Int2,int2,CG_INT2,CG_INT,0,2,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Int3,int3,CG_INT3,CG_INT,0,3,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Int4,int4,CG_INT4,CG_INT,0,4,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Int1x1,int1x1,CG_INT1x1,CG_INT,1,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Int1x2,int1x2,CG_INT1x2,CG_INT,1,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Int1x3,int1x3,CG_INT1x3,CG_INT,1,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Int1x4,int1x4,CG_INT1x4,CG_INT,1,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Int2x1,int2x1,CG_INT2x1,CG_INT,2,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Int2x2,int2x2,CG_INT2x2,CG_INT,2,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Int2x3,int2x3,CG_INT2x3,CG_INT,2,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Int2x4,int2x4,CG_INT2x4,CG_INT,2,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Int3x1,int3x1,CG_INT3x1,CG_INT,3,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Int3x2,int3x2,CG_INT3x2,CG_INT,3,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Int3x3,int3x3,CG_INT3x3,CG_INT,3,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Int3x4,int3x4,CG_INT3x4,CG_INT,3,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Int4x1,int4x1,CG_INT4x1,CG_INT,4,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Int4x2,int4x2,CG_INT4x2,CG_INT,4,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Int4x3,int4x3,CG_INT4x3,CG_INT,4,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Int4x4,int4x4,CG_INT4x4,CG_INT,4,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Bool,bool,CG_BOOL,CG_BOOL,0,1,CG_PARAMETERCLASS_SCALAR)
CG_DATATYPE_MACRO(Bool1,bool1,CG_BOOL1,CG_BOOL,0,1,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Bool2,bool2,CG_BOOL2,CG_BOOL,0,2,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Bool3,bool3,CG_BOOL3,CG_BOOL,0,3,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Bool4,bool4,CG_BOOL4,CG_BOOL,0,4,CG_PARAMETERCLASS_VECTOR)
CG_DATATYPE_MACRO(Bool1x1,bool1x1,CG_BOOL1x1,CG_BOOL,1,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Bool1x2,bool1x2,CG_BOOL1x2,CG_BOOL,1,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Bool1x3,bool1x3,CG_BOOL1x3,CG_BOOL,1,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Bool1x4,bool1x4,CG_BOOL1x4,CG_BOOL,1,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Bool2x1,bool2x1,CG_BOOL2x1,CG_BOOL,2,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Bool2x2,bool2x2,CG_BOOL2x2,CG_BOOL,2,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Bool2x3,bool2x3,CG_BOOL2x3,CG_BOOL,2,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Bool2x4,bool2x4,CG_BOOL2x4,CG_BOOL,2,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Bool3x1,bool3x1,CG_BOOL3x1,CG_BOOL,3,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Bool3x2,bool3x2,CG_BOOL3x2,CG_BOOL,3,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Bool3x3,bool3x3,CG_BOOL3x3,CG_BOOL,3,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Bool3x4,bool3x4,CG_BOOL3x4,CG_BOOL,3,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Bool4x1,bool4x1,CG_BOOL4x1,CG_BOOL,4,1,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Bool4x2,bool4x2,CG_BOOL4x2,CG_BOOL,4,2,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Bool4x3,bool4x3,CG_BOOL4x3,CG_BOOL,4,3,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(Bool4x4,bool4x4,CG_BOOL4x4,CG_BOOL,4,4,CG_PARAMETERCLASS_MATRIX)
CG_DATATYPE_MACRO(String,string,CG_STRING,CG_STRING,0,1,CG_PARAMETERCLASS_OBJECT)
CG_DATATYPE_MACRO(Program,program,CG_PROGRAM_TYPE,CG_PROGRAM_TYPE,0,0,CG_PARAMETERCLASS_OBJECT)
CG_DATATYPE_MACRO(Texture,texture,CG_TEXTURE,CG_TEXTURE,0,0,CG_PARAMETERCLASS_OBJECT)
CG_DATATYPE_MACRO(Sampler1DARRAY,sampler1DARRAY,CG_SAMPLER1DARRAY,CG_SAMPLER1DARRAY,0,0,CG_PARAMETERCLASS_SAMPLER)
CG_DATATYPE_MACRO(Sampler2DARRAY,sampler2DARRAY,CG_SAMPLER2DARRAY,CG_SAMPLER2DARRAY,0,0,CG_PARAMETERCLASS_SAMPLER)
CG_DATATYPE_MACRO(SamplerCUBEARRAY,samplerCUBEARRAY,CG_SAMPLERCUBEARRAY,CG_SAMPLERCUBEARRAY,0,0,CG_PARAMETERCLASS_SAMPLER)
CG_DATATYPE_MACRO(VertexShader, vertexshader, CG_VERTEXSHADER_TYPE, CG_VERTEXSHADER_TYPE, 0, 0, CG_PARAMETERCLASS_OBJECT)
CG_DATATYPE_MACRO(PixelShader, pixelshader, CG_PIXELSHADER_TYPE, CG_PIXELSHADER_TYPE, 0, 0, CG_PARAMETERCLASS_OBJECT)
CG_DATATYPE_MACRO(Sampler, sampler, CG_SAMPLER, CG_SAMPLER, 0, 0, CG_PARAMETERCLASS_SAMPLER)
CG_DATATYPE_MACRO(SamplerBUF,samplerBUF,CG_SAMPLERBUF,CG_SAMPLERBUF,0,0,CG_PARAMETERCLASS_SAMPLER)
#undef CG_DATATYPE_MACRO

View File

@ -0,0 +1,128 @@
/*
*
* Copyright (c) 2002-2009, NVIDIA Corporation.
*
*
*
* NVIDIA Corporation("NVIDIA") supplies this software to you in consideration
* of your agreement to the following terms, and your use, installation,
* modification or redistribution of this NVIDIA software constitutes
* acceptance of these terms. If you do not agree with these terms, please do
* not use, install, modify or redistribute this NVIDIA software.
*
*
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, NVIDIA grants you a personal, non-exclusive license,
* under NVIDIA's copyrights in this original NVIDIA software (the "NVIDIA
* Software"), to use, reproduce, modify and redistribute the NVIDIA
* Software, with or without modifications, in source and/or binary forms;
* provided that if you redistribute the NVIDIA Software, you must retain the
* copyright notice of NVIDIA, this notice and the following text and
* disclaimers in all such redistributions of the NVIDIA Software. Neither the
* name, trademarks, service marks nor logos of NVIDIA Corporation may be used
* to endorse or promote products derived from the NVIDIA Software without
* specific prior written permission from NVIDIA. Except as expressly stated
* in this notice, no other rights or licenses express or implied, are granted
* by NVIDIA herein, including but not limited to any patent rights that may be
* infringed by your derivative works or by other works in which the NVIDIA
* Software may be incorporated. No hardware is licensed hereunder.
*
*
*
* THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
* WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR ITS USE AND OPERATION
* EITHER ALONE OR IN COMBINATION WITH OTHER PRODUCTS.
*
*
*
* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
* EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOST
* PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY OUT OF THE USE,
* REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE NVIDIA SOFTWARE,
* HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING
* NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF NVIDIA HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* The following macro invocations define the supported CG basic data types.
*
* The macros have the form :
*
* CG_ENUM_MACRO(enum_name, enum_val)
*
* enum_name : The C enumerant name.
* enum_val : The enumerant value.
*
*/
CG_ENUM_MACRO(CG_UNKNOWN, 4096)
CG_ENUM_MACRO(CG_IN, 4097)
CG_ENUM_MACRO(CG_OUT, 4098)
CG_ENUM_MACRO(CG_INOUT, 4099)
CG_ENUM_MACRO(CG_MIXED, 4100)
CG_ENUM_MACRO(CG_VARYING, 4101)
CG_ENUM_MACRO(CG_UNIFORM, 4102)
CG_ENUM_MACRO(CG_CONSTANT, 4103)
CG_ENUM_MACRO(CG_PROGRAM_SOURCE, 4104)
CG_ENUM_MACRO(CG_PROGRAM_ENTRY, 4105)
CG_ENUM_MACRO(CG_COMPILED_PROGRAM, 4106)
CG_ENUM_MACRO(CG_PROGRAM_PROFILE, 4107)
CG_ENUM_MACRO(CG_GLOBAL, 4108)
CG_ENUM_MACRO(CG_PROGRAM, 4109)
CG_ENUM_MACRO(CG_DEFAULT, 4110)
CG_ENUM_MACRO(CG_ERROR, 4111)
CG_ENUM_MACRO(CG_SOURCE, 4112)
CG_ENUM_MACRO(CG_OBJECT, 4113)
CG_ENUM_MACRO(CG_COMPILE_MANUAL, 4114)
CG_ENUM_MACRO(CG_COMPILE_IMMEDIATE, 4115)
CG_ENUM_MACRO(CG_COMPILE_LAZY, 4116)
CG_ENUM_MACRO(CG_CURRENT, 4117)
CG_ENUM_MACRO(CG_LITERAL, 4118)
CG_ENUM_MACRO(CG_VERSION, 4119)
CG_ENUM_MACRO(CG_ROW_MAJOR, 4120)
CG_ENUM_MACRO(CG_COLUMN_MAJOR, 4121)
CG_ENUM_MACRO(CG_FRAGMENT, 4122)
CG_ENUM_MACRO(CG_VERTEX, 4123)
CG_ENUM_MACRO(CG_POINT, 4124)
CG_ENUM_MACRO(CG_LINE, 4125)
CG_ENUM_MACRO(CG_LINE_ADJ, 4126)
CG_ENUM_MACRO(CG_TRIANGLE, 4127)
CG_ENUM_MACRO(CG_TRIANGLE_ADJ, 4128)
CG_ENUM_MACRO(CG_POINT_OUT, 4129)
CG_ENUM_MACRO(CG_LINE_OUT, 4130)
CG_ENUM_MACRO(CG_TRIANGLE_OUT, 4131)
CG_ENUM_MACRO(CG_IMMEDIATE_PARAMETER_SETTING, 4132)
CG_ENUM_MACRO(CG_DEFERRED_PARAMETER_SETTING, 4133)
CG_ENUM_MACRO(CG_NO_LOCKS_POLICY, 4134)
CG_ENUM_MACRO(CG_THREAD_SAFE_POLICY, 4135)
CG_ENUM_MACRO(CG_FORCE_UPPER_CASE_POLICY, 4136)
CG_ENUM_MACRO(CG_UNCHANGED_CASE_POLICY, 4137)
CG_ENUM_MACRO(CG_IS_OPENGL_PROFILE, 4138)
CG_ENUM_MACRO(CG_IS_DIRECT3D_PROFILE, 4139)
CG_ENUM_MACRO(CG_IS_DIRECT3D_8_PROFILE, 4140)
CG_ENUM_MACRO(CG_IS_DIRECT3D_9_PROFILE, 4141)
CG_ENUM_MACRO(CG_IS_DIRECT3D_10_PROFILE, 4142)
CG_ENUM_MACRO(CG_IS_VERTEX_PROFILE, 4143)
CG_ENUM_MACRO(CG_IS_FRAGMENT_PROFILE, 4144)
CG_ENUM_MACRO(CG_IS_GEOMETRY_PROFILE, 4145)
CG_ENUM_MACRO(CG_IS_TRANSLATION_PROFILE, 4146)
CG_ENUM_MACRO(CG_IS_HLSL_PROFILE, 4147)
CG_ENUM_MACRO(CG_IS_GLSL_PROFILE, 4148)
/*
if you add any enums here, you must also change
the last enum value in the definition of cgiEnumStringMap
(currently found in common/cg_enum.cpp)
*/
#undef CG_ENUM_MACRO

View File

@ -0,0 +1,325 @@
/*
*
* Copyright (c) 2002-2009, NVIDIA Corporation.
*
*
*
* NVIDIA Corporation("NVIDIA") supplies this software to you in consideration
* of your agreement to the following terms, and your use, installation,
* modification or redistribution of this NVIDIA software constitutes
* acceptance of these terms. If you do not agree with these terms, please do
* not use, install, modify or redistribute this NVIDIA software.
*
*
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, NVIDIA grants you a personal, non-exclusive license,
* under NVIDIA's copyrights in this original NVIDIA software (the "NVIDIA
* Software"), to use, reproduce, modify and redistribute the NVIDIA
* Software, with or without modifications, in source and/or binary forms;
* provided that if you redistribute the NVIDIA Software, you must retain the
* copyright notice of NVIDIA, this notice and the following text and
* disclaimers in all such redistributions of the NVIDIA Software. Neither the
* name, trademarks, service marks nor logos of NVIDIA Corporation may be used
* to endorse or promote products derived from the NVIDIA Software without
* specific prior written permission from NVIDIA. Except as expressly stated
* in this notice, no other rights or licenses express or implied, are granted
* by NVIDIA herein, including but not limited to any patent rights that may be
* infringed by your derivative works or by other works in which the NVIDIA
* Software may be incorporated. No hardware is licensed hereunder.
*
*
*
* THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
* WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR ITS USE AND OPERATION
* EITHER ALONE OR IN COMBINATION WITH OTHER PRODUCTS.
*
*
*
* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
* EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOST
* PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY OUT OF THE USE,
* REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE NVIDIA SOFTWARE,
* HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING
* NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF NVIDIA HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* The following macro invocations define error codes returned by various cg
* API functions.
*
* The macros have the form :
*
* CG_ERROR_MACRO(code, enum_name, message)
*
* code : The integer error code associated with the error.
* enum_name : The name of enumerant of the error code in the API.
* message : A description string associated with the error.
*
*/
CG_ERROR_MACRO(0,
CG_NO_ERROR,
"No error has occurred.")
CG_ERROR_MACRO(1,
CG_COMPILER_ERROR,
"The compile returned an error.")
CG_ERROR_MACRO(2,
CG_INVALID_PARAMETER_ERROR,
"The parameter used is invalid.")
CG_ERROR_MACRO(3,
CG_INVALID_PROFILE_ERROR,
"The profile is not supported.")
CG_ERROR_MACRO(4,
CG_PROGRAM_LOAD_ERROR,
"The program could not load.")
CG_ERROR_MACRO(5,
CG_PROGRAM_BIND_ERROR,
"The program could not bind.")
CG_ERROR_MACRO(6,
CG_PROGRAM_NOT_LOADED_ERROR,
"The program must be loaded before this operation may be used.")
CG_ERROR_MACRO(7,
CG_UNSUPPORTED_GL_EXTENSION_ERROR,
"An unsupported GL extension was required to perform this operation.")
CG_ERROR_MACRO(8,
CG_INVALID_VALUE_TYPE_ERROR,
"An unknown value type was assigned to a parameter.")
CG_ERROR_MACRO(9,
CG_NOT_MATRIX_PARAM_ERROR,
"The parameter is not of matrix type.")
CG_ERROR_MACRO(10,
CG_INVALID_ENUMERANT_ERROR,
"The enumerant parameter has an invalid value.")
CG_ERROR_MACRO(11,
CG_NOT_4x4_MATRIX_ERROR,
"The parameter must be a 4x4 matrix type.")
CG_ERROR_MACRO(12,
CG_FILE_READ_ERROR,
"The file could not be read.")
CG_ERROR_MACRO(13,
CG_FILE_WRITE_ERROR,
"The file could not be written.")
CG_ERROR_MACRO(14,
CG_NVPARSE_ERROR,
"nvparse could not successfully parse the output from the Cg "
"compiler backend.")
CG_ERROR_MACRO(15,
CG_MEMORY_ALLOC_ERROR,
"Memory allocation failed.")
CG_ERROR_MACRO(16,
CG_INVALID_CONTEXT_HANDLE_ERROR,
"Invalid context handle.")
CG_ERROR_MACRO(17,
CG_INVALID_PROGRAM_HANDLE_ERROR,
"Invalid program handle.")
CG_ERROR_MACRO(18,
CG_INVALID_PARAM_HANDLE_ERROR,
"Invalid parameter handle.")
CG_ERROR_MACRO(19,
CG_UNKNOWN_PROFILE_ERROR,
"The specified profile is unknown.")
CG_ERROR_MACRO(20,
CG_VAR_ARG_ERROR,
"The variable arguments were specified incorrectly.")
CG_ERROR_MACRO(21,
CG_INVALID_DIMENSION_ERROR,
"The dimension value is invalid.")
CG_ERROR_MACRO(22,
CG_ARRAY_PARAM_ERROR,
"The parameter must be an array.")
CG_ERROR_MACRO(23,
CG_OUT_OF_ARRAY_BOUNDS_ERROR,
"Index into the array is out of bounds.")
CG_ERROR_MACRO(24,
CG_CONFLICTING_TYPES_ERROR,
"A type being added to the context conflicts with an "
"existing type.")
CG_ERROR_MACRO(25,
CG_CONFLICTING_PARAMETER_TYPES_ERROR,
"The parameters being bound have conflicting types.")
CG_ERROR_MACRO(26,
CG_PARAMETER_IS_NOT_SHARED_ERROR,
"The parameter must be global.")
CG_ERROR_MACRO(27,
CG_INVALID_PARAMETER_VARIABILITY_ERROR,
"The parameter could not be changed to the given variability.")
CG_ERROR_MACRO(28,
CG_CANNOT_DESTROY_PARAMETER_ERROR,
"Cannot destroy the parameter. It is bound to other parameters "
"or is not a root parameter.")
CG_ERROR_MACRO(29,
CG_NOT_ROOT_PARAMETER_ERROR,
"The parameter is not a root parameter.")
CG_ERROR_MACRO(30,
CG_PARAMETERS_DO_NOT_MATCH_ERROR,
"The two parameters being bound do not match.")
CG_ERROR_MACRO(31,
CG_IS_NOT_PROGRAM_PARAMETER_ERROR,
"The parameter is not a program parameter.")
CG_ERROR_MACRO(32,
CG_INVALID_PARAMETER_TYPE_ERROR,
"The type of the parameter is invalid.")
CG_ERROR_MACRO(33,
CG_PARAMETER_IS_NOT_RESIZABLE_ARRAY_ERROR,
"The parameter must be a resizable array.")
CG_ERROR_MACRO(34,
CG_INVALID_SIZE_ERROR,
"The size value is invalid.")
CG_ERROR_MACRO(35,
CG_BIND_CREATES_CYCLE_ERROR,
"Cannot bind the given parameters. Binding will form a cycle.")
CG_ERROR_MACRO(36,
CG_ARRAY_TYPES_DO_NOT_MATCH_ERROR,
"Cannot bind the given parameters. Array types do not match.")
CG_ERROR_MACRO(37,
CG_ARRAY_DIMENSIONS_DO_NOT_MATCH_ERROR,
"Cannot bind the given parameters. "
"Array dimensions do not match.")
CG_ERROR_MACRO(38,
CG_ARRAY_HAS_WRONG_DIMENSION_ERROR,
"The array has the wrong dimension.")
CG_ERROR_MACRO(39,
CG_TYPE_IS_NOT_DEFINED_IN_PROGRAM_ERROR,
"Connecting the parameters failed because The type of the "
"source parameter is not defined within the given program "
"or does not match the type with the same name in the program.")
CG_ERROR_MACRO(40,
CG_INVALID_EFFECT_HANDLE_ERROR,
"Invalid effect handle.")
CG_ERROR_MACRO(41,
CG_INVALID_STATE_HANDLE_ERROR,
"Invalid state handle.")
CG_ERROR_MACRO(42,
CG_INVALID_STATE_ASSIGNMENT_HANDLE_ERROR,
"Invalid stateassignment handle.")
CG_ERROR_MACRO(43,
CG_INVALID_PASS_HANDLE_ERROR,
"Invalid pass handle.")
CG_ERROR_MACRO(44,
CG_INVALID_ANNOTATION_HANDLE_ERROR,
"Invalid annotation handle.")
CG_ERROR_MACRO(45,
CG_INVALID_TECHNIQUE_HANDLE_ERROR,
"Invalid technique handle.")
/* Do not use this! Use CG_INVALID_PARAM_HANDLE_ERROR instead. */
CG_ERROR_MACRO(46,
CG_INVALID_PARAMETER_HANDLE_ERROR,
"Invalid parameter handle.")
CG_ERROR_MACRO(47,
CG_STATE_ASSIGNMENT_TYPE_MISMATCH_ERROR,
"Operation is not valid for this type of stateassignment.")
CG_ERROR_MACRO(48,
CG_INVALID_FUNCTION_HANDLE_ERROR,
"Invalid function handle.")
CG_ERROR_MACRO(49,
CG_INVALID_TECHNIQUE_ERROR,
"Technique did not pass validation.")
CG_ERROR_MACRO(50,
CG_INVALID_POINTER_ERROR,
"The supplied pointer is NULL.")
CG_ERROR_MACRO(51,
CG_NOT_ENOUGH_DATA_ERROR,
"Not enough data was provided.")
CG_ERROR_MACRO(52,
CG_NON_NUMERIC_PARAMETER_ERROR,
"The parameter is not of a numeric type.")
CG_ERROR_MACRO(53,
CG_ARRAY_SIZE_MISMATCH_ERROR,
"The specified array sizes are not compatible with the given array.")
CG_ERROR_MACRO(54,
CG_CANNOT_SET_NON_UNIFORM_PARAMETER_ERROR,
"Cannot set the value of a non-uniform parameter.")
CG_ERROR_MACRO(55,
CG_DUPLICATE_NAME_ERROR,
"This name is already in use.")
CG_ERROR_MACRO(56,
CG_INVALID_OBJ_HANDLE_ERROR,
"Invalid object handle.")
CG_ERROR_MACRO(57,
CG_INVALID_BUFFER_HANDLE_ERROR,
"Invalid buffer handle.")
CG_ERROR_MACRO(58,
CG_BUFFER_INDEX_OUT_OF_RANGE_ERROR,
"Buffer index is out of bounds.")
CG_ERROR_MACRO(59,
CG_BUFFER_ALREADY_MAPPED_ERROR,
"The buffer is already mapped.")
CG_ERROR_MACRO(60,
CG_BUFFER_UPDATE_NOT_ALLOWED_ERROR,
"The buffer cannot be updated.")
CG_ERROR_MACRO(61,
CG_GLSLG_UNCOMBINED_LOAD_ERROR,
"The GLSL geometry program can not load without being combined with a vertex program.")
#undef CG_ERROR_MACRO

View File

@ -0,0 +1,105 @@
/*
*
* Copyright (c) 2002-2009, NVIDIA Corporation.
*
*
*
* NVIDIA Corporation("NVIDIA") supplies this software to you in consideration
* of your agreement to the following terms, and your use, installation,
* modification or redistribution of this NVIDIA software constitutes
* acceptance of these terms. If you do not agree with these terms, please do
* not use, install, modify or redistribute this NVIDIA software.
*
*
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, NVIDIA grants you a personal, non-exclusive license,
* under NVIDIA's copyrights in this original NVIDIA software (the "NVIDIA
* Software"), to use, reproduce, modify and redistribute the NVIDIA
* Software, with or without modifications, in source and/or binary forms;
* provided that if you redistribute the NVIDIA Software, you must retain the
* copyright notice of NVIDIA, this notice and the following text and
* disclaimers in all such redistributions of the NVIDIA Software. Neither the
* name, trademarks, service marks nor logos of NVIDIA Corporation may be used
* to endorse or promote products derived from the NVIDIA Software without
* specific prior written permission from NVIDIA. Except as expressly stated
* in this notice, no other rights or licenses express or implied, are granted
* by NVIDIA herein, including but not limited to any patent rights that may be
* infringed by your derivative works or by other works in which the NVIDIA
* Software may be incorporated. No hardware is licensed hereunder.
*
*
*
* THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
* WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR ITS USE AND OPERATION
* EITHER ALONE OR IN COMBINATION WITH OTHER PRODUCTS.
*
*
*
* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
* EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOST
* PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY OUT OF THE USE,
* REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE NVIDIA SOFTWARE,
* HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING
* NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF NVIDIA HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* The following macro invocations define the supported CG profiles.
*
* The macros have the form :
*
* CG_PROFILE_MACRO(name, compiler_id, compiler_id_caps, compiler_opt, int_id, vertex_profile)
*
* name : The name of the profile. Used consistently with the API.
* compiler_id : The identifier string for the profile used by the compiler.
* compiler_id_caps : compiler_id in caps.
* compiler_opt : The command-line switch used to force compilation into
* the profile.
* int_id : Integer enumerant associated with this bind location.
* vertex_profile : Non-zero if this is a vertex profile, otherwise it
* is considered to be a fragment profile.
*
*
*/
#define CG_IN_PROFILES_INCLUDE
/* Used for profile enumeration aliases */
#ifndef CG_PROFILE_ALIAS
#define CG_PROFILE_ALIAS(name, compiler_id, compiler_id_caps, compiler_opt, int_id, vertex_profile) /*nothing*/
#endif
#include <Cg/cgGL_profiles.h>
CG_PROFILE_MACRO(DX9Vertex11,vs_1_1,VS_1_1,"vs_1_1",6153,1)
CG_PROFILE_MACRO(DX9Vertex20,vs_2_0,VS_2_0,"vs_2_0",6154,1)
CG_PROFILE_MACRO(DX9Vertex2x,vs_2_x,VS_2_X,"vs_2_x",6155,1)
CG_PROFILE_MACRO(DX9Vertex2sw,vs_2_sw,VS_2_SW,"vs_2_sw",6156,1)
CG_PROFILE_MACRO(DX9Vertex30,vs_3_0,VS_3_0,"vs_3_0",6157,1)
CG_PROFILE_MACRO(DX9VertexHLSL,hlslv, HLSLV,"hlslv",6158,1)
CG_PROFILE_MACRO(DX9Pixel11,ps_1_1,PS_1_1,"ps_1_1",6159,0)
CG_PROFILE_MACRO(DX9Pixel12,ps_1_2,PS_1_2,"ps_1_2",6160,0)
CG_PROFILE_MACRO(DX9Pixel13,ps_1_3,PS_1_3,"ps_1_3",6161,0)
CG_PROFILE_MACRO(DX9Pixel20,ps_2_0,PS_2_0,"ps_2_0",6162,0)
CG_PROFILE_MACRO(DX9Pixel2x,ps_2_x,PS_2_X,"ps_2_x",6163,0)
CG_PROFILE_MACRO(DX9Pixel2sw,ps_2_sw,PS_2_SW,"ps_2_sw",6164,0)
CG_PROFILE_MACRO(DX9Pixel30,ps_3_0,PS_3_0,"ps_3_0",6165,0)
CG_PROFILE_MACRO(DX9PixelHLSL,hlslf,HLSLF,"hlslf",6166,0)
CG_PROFILE_MACRO(DX10Vertex40,vs_4_0,VS_4_0,"vs_4_0",6167,1)
CG_PROFILE_MACRO(DX10Pixel40,ps_4_0,PS_4_0,"ps_4_0",6168,0)
CG_PROFILE_MACRO(DX10Geometry40,gs_4_0,GS_4_0,"gs_4_0",6169,0)
CG_PROFILE_MACRO(Generic, generic, GENERIC, "generic", 7002,0)
#undef CG_PROFILE_MACRO
#undef CG_PROFILE_ALIAS
#undef CG_IN_PROFILES_INCLUDE

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,797 @@
#ifndef __glut_h__
#define __glut_h__
/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998, 2000, 2006. */
/* This program is freely distributable without licensing fees and is
provided without guarantee or warrantee expressed or implied. This
program is -not- in the public domain. */
#if defined(_WIN32) || defined(__CYGWIN__)
/* GLUT 3.7 now tries to avoid including <windows.h>
to avoid name space pollution, but Win32's <GL/gl.h>
needs APIENTRY and WINGDIAPI defined properly. */
# if 0
/* This would put tons of macros and crap in our clean name space. */
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# else
/* XXX This is from Win32's <windef.h> */
# ifndef APIENTRY
# define GLUT_APIENTRY_DEFINED
/* Cygwin and MingW32 are two free GNU-based Open Source compilation
environments for Win32. Note that __CYGWIN32__ is deprecated
in favor of simply __CYGWIN__. */
# if defined(__MINGW32__) || defined(__CYGWIN32__) || defined(__CYGWIN__)
# if defined(__CYGWIN__)
# define APIENTRY __stdcall
# else
# ifdef i386
# define APIENTRY __attribute__((stdcall))
# else
# define APIENTRY
# endif
# endif
# else
# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
# define APIENTRY __stdcall
# else
# define APIENTRY
# endif
# endif
# endif
/* XXX This is from Win32's <winnt.h> */
# ifndef CALLBACK
# if defined(__MINGW32__) || defined(__CYGWIN32__) || defined(__CYGWIN__)
# ifndef __stdcall
# define __stdcall __attribute__((stdcall))
# endif
# define CALLBACK __stdcall
# else
# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
# define CALLBACK __stdcall
# else
# define CALLBACK
# endif
# endif
# endif
/* XXX This is from Win32's <wingdi.h> and <winnt.h> */
# ifndef WINGDIAPI
# define GLUT_WINGDIAPI_DEFINED
# if defined(__MINGW32__) || defined(__CYGWIN32__) || defined(__CYGWIN__)
# define WINGDIAPI
# else
# define WINGDIAPI __declspec(dllimport)
# endif
# endif
# if defined(__MINGW32__) || defined(__CYGWIN32__) || defined(__CYGWIN__)
/* Rely on Cygwin32/MingW32 <stddef.h> to set wchar_t. */
/* XXX Warning. The Cygwin32/MingW32 definition for wchar_t
is an "int" instead of the "short" used by Windows. */
# include <stddef.h>
# else
/* XXX This is from Win32's <ctype.h> */
# ifndef _WCHAR_T_DEFINED
typedef unsigned short wchar_t;
# define _WCHAR_T_DEFINED
# endif
# endif
# endif
/* To disable automatic library usage for GLUT, define GLUT_NO_LIB_PRAGMA
in your compile preprocessor options (Microsoft Visual C only). */
# if !defined(GLUT_BUILDING_LIB) && !defined(GLUT_NO_LIB_PRAGMA) && defined(_MSC_VER)
# pragma comment (lib, "winmm.lib") /* link with Windows MultiMedia lib */
# pragma comment (lib, "user32.lib") /* link with Windows User lib */
# pragma comment (lib, "gdi32.lib") /* link with Windows GDI lib */
/* To enable automatic SGI OpenGL for Windows library usage for GLUT,
define GLUT_USE_SGI_OPENGL in your compile preprocessor options. */
# ifdef GLUT_USE_SGI_OPENGL
# pragma comment (lib, "opengl.lib") /* link with SGI OpenGL for Windows lib */
# pragma comment (lib, "glu.lib") /* link with SGI OpenGL Utility lib */
# if defined(GLUT_STATIC_LIB)
# pragma comment (lib, "glutstatic.lib") /* link with static Win32 GLUT lib */
# else
# pragma comment (lib, "glut.lib") /* link with Win32 GLUT lib */
# endif
# else
# pragma comment (lib, "opengl32.lib") /* link with Microsoft OpenGL lib */
# pragma comment (lib, "glu32.lib") /* link with Microsoft OpenGL Utility lib */
# if defined(GLUT_STATIC_LIB)
# pragma comment (lib, "glutstatic.lib") /* link with static Win32 GLUT lib */
# else
# pragma comment (lib, "glut32.lib") /* link with Win32 GLUT lib */
# endif
# endif
# endif
/* To disable supression of annoying warnings about floats being promoted
to doubles, define GLUT_NO_WARNING_DISABLE in your compile preprocessor
options. */
# if defined(_MSC_VER) && !defined(GLUT_NO_WARNING_DISABLE)
# pragma warning (disable:4244) /* Disable bogus VC++ 4.2 conversion warnings. */
# pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */
# endif
/* Win32 has an annoying issue where there are multiple C run-time
libraries (CRTs). If the executable is linked with a different CRT
from the GLUT DLL, the GLUT DLL will not share the same CRT static
data seen by the executable. In particular, atexit callbacks registered
in the executable will not be called if GLUT calls its (different)
exit routine). GLUT is typically built with the
"/MD" option (the CRT with multithreading DLL support), but the Visual
C++ linker default is "/ML" (the single threaded CRT).
One workaround to this issue is requiring users to always link with
the same CRT as GLUT is compiled with. That requires users supply a
non-standard option. GLUT 3.7 has its own built-in workaround where
the executable's "exit" function pointer is covertly passed to GLUT.
GLUT then calls the executable's exit function pointer to ensure that
any "atexit" calls registered by the application are called if GLUT
needs to exit.
Note that the __glut*WithExit routines should NEVER be called directly.
To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */
/* XXX This is from Win32's <process.h> */
# if !defined(_MSC_VER) && !defined(__cdecl)
/* Define __cdecl for non-Microsoft compilers. */
# define __cdecl
# define GLUT_DEFINED___CDECL
# endif
# ifndef _CRTIMP
# ifdef _NTSDK
/* Definition compatible with NT SDK */
# define _CRTIMP
# else
/* Current definition */
# ifdef _DLL
# define _CRTIMP __declspec(dllimport)
# else
# define _CRTIMP
# endif
# endif
# define GLUT_DEFINED__CRTIMP
# endif
/* GLUT API entry point declarations for Win32. */
# ifdef GLUT_BUILDING_LIB
/* MSDN article 835326 says "When you build a DLL by using the 64-bit
version of the Microsoft Visual C++ Compiler and Linker, you may
receive Linker error number LNK4197 if a function has been declared
for export more than one time." GLUT builds with glut.def that
declares GLUT's EXPORTS list so do not use __declspec(dllexport)
to keep 64-bit compiler happy. */
# define GLUTAPI /*__declspec(dllexport)*/
# else
# ifdef _DLL
# define GLUTAPI __declspec(dllimport)
# else
# define GLUTAPI extern
# endif
# endif
/* GLUT callback calling convention for Win32. */
# define GLUTCALLBACK __cdecl
# if (_MSC_VER >= 800) || defined(__MINGW32__) || defined(_STDCALL_SUPPORTED) || defined(__CYGWIN32__)
# define GLUTAPIENTRY __stdcall
# else
# define GLUTAPIENTRY
# endif
#endif /* _WIN32 */
#include <GL/gl.h>
#include <GL/glu.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(_WIN32) || defined(__CYGWIN__)
# ifndef GLUT_BUILDING_LIB
# if __BORLANDC__
# if defined(_BUILDRTLDLL)
void __cdecl __export exit(int __status);
# else
void __cdecl exit(int __status);
# endif
# else
# if _MSC_VER >= 1200
extern _CRTIMP __declspec(noreturn) void __cdecl exit(int);
# else
extern _CRTIMP void __cdecl exit(int);
# endif
# endif
# endif
#else
/* non-Win32 case. */
/* Define APIENTRY and CALLBACK to nothing if we aren't on Win32. */
# define APIENTRY
# define GLUT_APIENTRY_DEFINED
# define CALLBACK
/* Define GLUTAPI and GLUTCALLBACK as below if we aren't on Win32. */
# define GLUTAPI extern
# define GLUTAPIENTRY
# define GLUTCALLBACK
/* Prototype exit for the non-Win32 case (see above). */
# ifdef __GNUC__
extern void exit(int __status) __attribute__((__noreturn__));
# else
extern void exit(int);
# endif
#endif
/**
GLUT API revision history:
GLUT_API_VERSION is updated to reflect incompatible GLUT
API changes (interface changes, semantic changes, deletions,
or additions).
GLUT_API_VERSION=1 First public release of GLUT. 11/29/94
GLUT_API_VERSION=2 Added support for OpenGL/GLX multisampling,
extension. Supports new input devices like tablet, dial and button
box, and Spaceball. Easy to query OpenGL extensions.
GLUT_API_VERSION=3 glutMenuStatus added.
GLUT_API_VERSION=4 glutInitDisplayString, glutWarpPointer,
glutBitmapLength, glutStrokeLength, glutWindowStatusFunc, dynamic
video resize subAPI, glutPostWindowRedisplay, glutKeyboardUpFunc,
glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat,
glutJoystickFunc, glutForceJoystickFunc, glutStrokeWidthf,
glutStrokeLengthf (NOT FINALIZED!).
**/
#ifndef GLUT_API_VERSION /* allow this to be overriden */
#define GLUT_API_VERSION 3
#endif
/**
GLUT implementation revision history:
GLUT_XLIB_IMPLEMENTATION is updated to reflect both GLUT
API revisions and implementation revisions (ie, bug fixes).
GLUT_XLIB_IMPLEMENTATION=1 mjk's first public release of
GLUT Xlib-based implementation. 11/29/94
GLUT_XLIB_IMPLEMENTATION=2 mjk's second public release of
GLUT Xlib-based implementation providing GLUT version 2
interfaces.
GLUT_XLIB_IMPLEMENTATION=3 mjk's GLUT 2.2 images. 4/17/95
GLUT_XLIB_IMPLEMENTATION=4 mjk's GLUT 2.3 images. 6/?/95
GLUT_XLIB_IMPLEMENTATION=5 mjk's GLUT 3.0 images. 10/?/95
GLUT_XLIB_IMPLEMENTATION=7 mjk's GLUT 3.1+ with glutWarpPoitner. 7/24/96
GLUT_XLIB_IMPLEMENTATION=8 mjk's GLUT 3.1+ with glutWarpPoitner
and video resize. 1/3/97
GLUT_XLIB_IMPLEMENTATION=9 mjk's GLUT 3.4 release with early GLUT 4 routines.
GLUT_XLIB_IMPLEMENTATION=11 Mesa 2.5's GLUT 3.6 release.
GLUT_XLIB_IMPLEMENTATION=12 mjk's GLUT 3.6 release with early GLUT 4 routines + signal handling.
GLUT_XLIB_IMPLEMENTATION=13 mjk's GLUT 3.7 beta with GameGLUT support.
GLUT_XLIB_IMPLEMENTATION=14 mjk's GLUT 3.7 beta with f90gl friend interface.
GLUT_XLIB_IMPLEMENTATION=15 mjk's GLUT 3.7 beta sync'ed with Mesa <GL/glut.h>
GLUT_XLIB_IMPLEMENTATION=16 mjk's early GLUT 3.8
GLUT_XLIB_IMPLEMENTATION=17 mjk's GLUT 3.8 with glutStrokeWidthf and glutStrokeLengthf
**/
#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overriden. */
#define GLUT_XLIB_IMPLEMENTATION 17
#endif
/* Display mode bit masks. */
#define GLUT_RGB 0
#define GLUT_RGBA GLUT_RGB
#define GLUT_INDEX 1
#define GLUT_SINGLE 0
#define GLUT_DOUBLE 2
#define GLUT_ACCUM 4
#define GLUT_ALPHA 8
#define GLUT_DEPTH 16
#define GLUT_STENCIL 32
#if (GLUT_API_VERSION >= 2)
#define GLUT_MULTISAMPLE 128
#define GLUT_STEREO 256
#endif
#if (GLUT_API_VERSION >= 3)
#define GLUT_LUMINANCE 512
#endif
/* Mouse buttons. */
#define GLUT_LEFT_BUTTON 0
#define GLUT_MIDDLE_BUTTON 1
#define GLUT_RIGHT_BUTTON 2
/* Mouse button state. */
#define GLUT_DOWN 0
#define GLUT_UP 1
#if (GLUT_API_VERSION >= 2)
/* function keys */
#define GLUT_KEY_F1 1
#define GLUT_KEY_F2 2
#define GLUT_KEY_F3 3
#define GLUT_KEY_F4 4
#define GLUT_KEY_F5 5
#define GLUT_KEY_F6 6
#define GLUT_KEY_F7 7
#define GLUT_KEY_F8 8
#define GLUT_KEY_F9 9
#define GLUT_KEY_F10 10
#define GLUT_KEY_F11 11
#define GLUT_KEY_F12 12
/* directional keys */
#define GLUT_KEY_LEFT 100
#define GLUT_KEY_UP 101
#define GLUT_KEY_RIGHT 102
#define GLUT_KEY_DOWN 103
#define GLUT_KEY_PAGE_UP 104
#define GLUT_KEY_PAGE_DOWN 105
#define GLUT_KEY_HOME 106
#define GLUT_KEY_END 107
#define GLUT_KEY_INSERT 108
#endif
/* Entry/exit state. */
#define GLUT_LEFT 0
#define GLUT_ENTERED 1
/* Menu usage state. */
#define GLUT_MENU_NOT_IN_USE 0
#define GLUT_MENU_IN_USE 1
/* Visibility state. */
#define GLUT_NOT_VISIBLE 0
#define GLUT_VISIBLE 1
/* Window status state. */
#define GLUT_HIDDEN 0
#define GLUT_FULLY_RETAINED 1
#define GLUT_PARTIALLY_RETAINED 2
#define GLUT_FULLY_COVERED 3
/* Color index component selection values. */
#define GLUT_RED 0
#define GLUT_GREEN 1
#define GLUT_BLUE 2
#ifdef _WIN32
/* Stroke font constants (use these in GLUT program). */
#define GLUT_STROKE_ROMAN ((void*)0)
#define GLUT_STROKE_MONO_ROMAN ((void*)1)
/* Bitmap font constants (use these in GLUT program). */
#define GLUT_BITMAP_9_BY_15 ((void*)2)
#define GLUT_BITMAP_8_BY_13 ((void*)3)
#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4)
#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5)
#if (GLUT_API_VERSION >= 3)
#define GLUT_BITMAP_HELVETICA_10 ((void*)6)
#define GLUT_BITMAP_HELVETICA_12 ((void*)7)
#define GLUT_BITMAP_HELVETICA_18 ((void*)8)
#endif
#else
/* Stroke font opaque addresses (use constants instead in source code). */
GLUTAPI void *glutStrokeRoman;
GLUTAPI void *glutStrokeMonoRoman;
/* Stroke font constants (use these in GLUT program). */
#define GLUT_STROKE_ROMAN (&glutStrokeRoman)
#define GLUT_STROKE_MONO_ROMAN (&glutStrokeMonoRoman)
/* Bitmap font opaque addresses (use constants instead in source code). */
GLUTAPI void *glutBitmap9By15;
GLUTAPI void *glutBitmap8By13;
GLUTAPI void *glutBitmapTimesRoman10;
GLUTAPI void *glutBitmapTimesRoman24;
GLUTAPI void *glutBitmapHelvetica10;
GLUTAPI void *glutBitmapHelvetica12;
GLUTAPI void *glutBitmapHelvetica18;
/* Bitmap font constants (use these in GLUT program). */
#define GLUT_BITMAP_9_BY_15 (&glutBitmap9By15)
#define GLUT_BITMAP_8_BY_13 (&glutBitmap8By13)
#define GLUT_BITMAP_TIMES_ROMAN_10 (&glutBitmapTimesRoman10)
#define GLUT_BITMAP_TIMES_ROMAN_24 (&glutBitmapTimesRoman24)
#if (GLUT_API_VERSION >= 3)
#define GLUT_BITMAP_HELVETICA_10 (&glutBitmapHelvetica10)
#define GLUT_BITMAP_HELVETICA_12 (&glutBitmapHelvetica12)
#define GLUT_BITMAP_HELVETICA_18 (&glutBitmapHelvetica18)
#endif
#endif
/* glutGet parameters. */
#define GLUT_WINDOW_X ((GLenum) 100)
#define GLUT_WINDOW_Y ((GLenum) 101)
#define GLUT_WINDOW_WIDTH ((GLenum) 102)
#define GLUT_WINDOW_HEIGHT ((GLenum) 103)
#define GLUT_WINDOW_BUFFER_SIZE ((GLenum) 104)
#define GLUT_WINDOW_STENCIL_SIZE ((GLenum) 105)
#define GLUT_WINDOW_DEPTH_SIZE ((GLenum) 106)
#define GLUT_WINDOW_RED_SIZE ((GLenum) 107)
#define GLUT_WINDOW_GREEN_SIZE ((GLenum) 108)
#define GLUT_WINDOW_BLUE_SIZE ((GLenum) 109)
#define GLUT_WINDOW_ALPHA_SIZE ((GLenum) 110)
#define GLUT_WINDOW_ACCUM_RED_SIZE ((GLenum) 111)
#define GLUT_WINDOW_ACCUM_GREEN_SIZE ((GLenum) 112)
#define GLUT_WINDOW_ACCUM_BLUE_SIZE ((GLenum) 113)
#define GLUT_WINDOW_ACCUM_ALPHA_SIZE ((GLenum) 114)
#define GLUT_WINDOW_DOUBLEBUFFER ((GLenum) 115)
#define GLUT_WINDOW_RGBA ((GLenum) 116)
#define GLUT_WINDOW_PARENT ((GLenum) 117)
#define GLUT_WINDOW_NUM_CHILDREN ((GLenum) 118)
#define GLUT_WINDOW_COLORMAP_SIZE ((GLenum) 119)
#if (GLUT_API_VERSION >= 2)
#define GLUT_WINDOW_NUM_SAMPLES ((GLenum) 120)
#define GLUT_WINDOW_STEREO ((GLenum) 121)
#endif
#if (GLUT_API_VERSION >= 3)
#define GLUT_WINDOW_CURSOR ((GLenum) 122)
#endif
#define GLUT_SCREEN_WIDTH ((GLenum) 200)
#define GLUT_SCREEN_HEIGHT ((GLenum) 201)
#define GLUT_SCREEN_WIDTH_MM ((GLenum) 202)
#define GLUT_SCREEN_HEIGHT_MM ((GLenum) 203)
#define GLUT_MENU_NUM_ITEMS ((GLenum) 300)
#define GLUT_DISPLAY_MODE_POSSIBLE ((GLenum) 400)
#define GLUT_INIT_WINDOW_X ((GLenum) 500)
#define GLUT_INIT_WINDOW_Y ((GLenum) 501)
#define GLUT_INIT_WINDOW_WIDTH ((GLenum) 502)
#define GLUT_INIT_WINDOW_HEIGHT ((GLenum) 503)
#define GLUT_INIT_DISPLAY_MODE ((GLenum) 504)
#if (GLUT_API_VERSION >= 2)
#define GLUT_ELAPSED_TIME ((GLenum) 700)
#endif
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
#define GLUT_WINDOW_FORMAT_ID ((GLenum) 123)
#endif
#if (GLUT_API_VERSION >= 2)
/* glutDeviceGet parameters. */
#define GLUT_HAS_KEYBOARD ((GLenum) 600)
#define GLUT_HAS_MOUSE ((GLenum) 601)
#define GLUT_HAS_SPACEBALL ((GLenum) 602)
#define GLUT_HAS_DIAL_AND_BUTTON_BOX ((GLenum) 603)
#define GLUT_HAS_TABLET ((GLenum) 604)
#define GLUT_NUM_MOUSE_BUTTONS ((GLenum) 605)
#define GLUT_NUM_SPACEBALL_BUTTONS ((GLenum) 606)
#define GLUT_NUM_BUTTON_BOX_BUTTONS ((GLenum) 607)
#define GLUT_NUM_DIALS ((GLenum) 608)
#define GLUT_NUM_TABLET_BUTTONS ((GLenum) 609)
#endif
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
#define GLUT_DEVICE_IGNORE_KEY_REPEAT ((GLenum) 610)
#define GLUT_DEVICE_KEY_REPEAT ((GLenum) 611)
#define GLUT_HAS_JOYSTICK ((GLenum) 612)
#define GLUT_OWNS_JOYSTICK ((GLenum) 613)
#define GLUT_JOYSTICK_BUTTONS ((GLenum) 614)
#define GLUT_JOYSTICK_AXES ((GLenum) 615)
#define GLUT_JOYSTICK_POLL_RATE ((GLenum) 616)
#endif
#if (GLUT_API_VERSION >= 3)
/* glutLayerGet parameters. */
#define GLUT_OVERLAY_POSSIBLE ((GLenum) 800)
#define GLUT_LAYER_IN_USE ((GLenum) 801)
#define GLUT_HAS_OVERLAY ((GLenum) 802)
#define GLUT_TRANSPARENT_INDEX ((GLenum) 803)
#define GLUT_NORMAL_DAMAGED ((GLenum) 804)
#define GLUT_OVERLAY_DAMAGED ((GLenum) 805)
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
/* glutVideoResizeGet parameters. */
#define GLUT_VIDEO_RESIZE_POSSIBLE ((GLenum) 900)
#define GLUT_VIDEO_RESIZE_IN_USE ((GLenum) 901)
#define GLUT_VIDEO_RESIZE_X_DELTA ((GLenum) 902)
#define GLUT_VIDEO_RESIZE_Y_DELTA ((GLenum) 903)
#define GLUT_VIDEO_RESIZE_WIDTH_DELTA ((GLenum) 904)
#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA ((GLenum) 905)
#define GLUT_VIDEO_RESIZE_X ((GLenum) 906)
#define GLUT_VIDEO_RESIZE_Y ((GLenum) 907)
#define GLUT_VIDEO_RESIZE_WIDTH ((GLenum) 908)
#define GLUT_VIDEO_RESIZE_HEIGHT ((GLenum) 909)
#endif
/* glutUseLayer parameters. */
#define GLUT_NORMAL ((GLenum) 0)
#define GLUT_OVERLAY ((GLenum) 1)
/* glutGetModifiers return mask. */
#define GLUT_ACTIVE_SHIFT 1
#define GLUT_ACTIVE_CTRL 2
#define GLUT_ACTIVE_ALT 4
/* glutSetCursor parameters. */
/* Basic arrows. */
#define GLUT_CURSOR_RIGHT_ARROW 0
#define GLUT_CURSOR_LEFT_ARROW 1
/* Symbolic cursor shapes. */
#define GLUT_CURSOR_INFO 2
#define GLUT_CURSOR_DESTROY 3
#define GLUT_CURSOR_HELP 4
#define GLUT_CURSOR_CYCLE 5
#define GLUT_CURSOR_SPRAY 6
#define GLUT_CURSOR_WAIT 7
#define GLUT_CURSOR_TEXT 8
#define GLUT_CURSOR_CROSSHAIR 9
/* Directional cursors. */
#define GLUT_CURSOR_UP_DOWN 10
#define GLUT_CURSOR_LEFT_RIGHT 11
/* Sizing cursors. */
#define GLUT_CURSOR_TOP_SIDE 12
#define GLUT_CURSOR_BOTTOM_SIDE 13
#define GLUT_CURSOR_LEFT_SIDE 14
#define GLUT_CURSOR_RIGHT_SIDE 15
#define GLUT_CURSOR_TOP_LEFT_CORNER 16
#define GLUT_CURSOR_TOP_RIGHT_CORNER 17
#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 18
#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 19
/* Inherit from parent window. */
#define GLUT_CURSOR_INHERIT 100
/* Blank cursor. */
#define GLUT_CURSOR_NONE 101
/* Fullscreen crosshair (if available). */
#define GLUT_CURSOR_FULL_CROSSHAIR 102
#endif
/* GLUT initialization sub-API. */
GLUTAPI void GLUTAPIENTRY glutInit(int *argcp, char **argv);
#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
GLUTAPI void GLUTAPIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int));
#ifndef GLUT_BUILDING_LIB
static void GLUTAPIENTRY glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); }
#define glutInit glutInit_ATEXIT_HACK
#endif
#endif
GLUTAPI void GLUTAPIENTRY glutInitDisplayMode(unsigned int mode);
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
GLUTAPI void GLUTAPIENTRY glutInitDisplayString(const char *string);
#endif
GLUTAPI void GLUTAPIENTRY glutInitWindowPosition(int x, int y);
GLUTAPI void GLUTAPIENTRY glutInitWindowSize(int width, int height);
GLUTAPI void GLUTAPIENTRY glutMainLoop(void);
/* GLUT window sub-API. */
GLUTAPI int GLUTAPIENTRY glutCreateWindow(const char *title);
#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
GLUTAPI int GLUTAPIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int));
#ifndef GLUT_BUILDING_LIB
static int GLUTAPIENTRY glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); }
#define glutCreateWindow glutCreateWindow_ATEXIT_HACK
#endif
#endif
GLUTAPI int GLUTAPIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height);
GLUTAPI void GLUTAPIENTRY glutDestroyWindow(int win);
GLUTAPI void GLUTAPIENTRY glutPostRedisplay(void);
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11)
GLUTAPI void GLUTAPIENTRY glutPostWindowRedisplay(int win);
#endif
GLUTAPI void GLUTAPIENTRY glutSwapBuffers(void);
GLUTAPI int GLUTAPIENTRY glutGetWindow(void);
GLUTAPI void GLUTAPIENTRY glutSetWindow(int win);
GLUTAPI void GLUTAPIENTRY glutSetWindowTitle(const char *title);
GLUTAPI void GLUTAPIENTRY glutSetIconTitle(const char *title);
GLUTAPI void GLUTAPIENTRY glutPositionWindow(int x, int y);
GLUTAPI void GLUTAPIENTRY glutReshapeWindow(int width, int height);
GLUTAPI void GLUTAPIENTRY glutPopWindow(void);
GLUTAPI void GLUTAPIENTRY glutPushWindow(void);
GLUTAPI void GLUTAPIENTRY glutIconifyWindow(void);
GLUTAPI void GLUTAPIENTRY glutShowWindow(void);
GLUTAPI void GLUTAPIENTRY glutHideWindow(void);
#if (GLUT_API_VERSION >= 3)
GLUTAPI void GLUTAPIENTRY glutFullScreen(void);
GLUTAPI void GLUTAPIENTRY glutSetCursor(int cursor);
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
GLUTAPI void GLUTAPIENTRY glutWarpPointer(int x, int y);
#endif
/* GLUT overlay sub-API. */
GLUTAPI void GLUTAPIENTRY glutEstablishOverlay(void);
GLUTAPI void GLUTAPIENTRY glutRemoveOverlay(void);
GLUTAPI void GLUTAPIENTRY glutUseLayer(GLenum layer);
GLUTAPI void GLUTAPIENTRY glutPostOverlayRedisplay(void);
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11)
GLUTAPI void GLUTAPIENTRY glutPostWindowOverlayRedisplay(int win);
#endif
GLUTAPI void GLUTAPIENTRY glutShowOverlay(void);
GLUTAPI void GLUTAPIENTRY glutHideOverlay(void);
#endif
/* GLUT menu sub-API. */
GLUTAPI int GLUTAPIENTRY glutCreateMenu(void (GLUTCALLBACK *func)(int));
#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
GLUTAPI int GLUTAPIENTRY __glutCreateMenuWithExit(void (GLUTCALLBACK *func)(int), void (__cdecl *exitfunc)(int));
#ifndef GLUT_BUILDING_LIB
static int GLUTAPIENTRY glutCreateMenu_ATEXIT_HACK(void (GLUTCALLBACK *func)(int)) { return __glutCreateMenuWithExit(func, exit); }
#define glutCreateMenu glutCreateMenu_ATEXIT_HACK
#endif
#endif
GLUTAPI void GLUTAPIENTRY glutDestroyMenu(int menu);
GLUTAPI int GLUTAPIENTRY glutGetMenu(void);
GLUTAPI void GLUTAPIENTRY glutSetMenu(int menu);
GLUTAPI void GLUTAPIENTRY glutAddMenuEntry(const char *label, int value);
GLUTAPI void GLUTAPIENTRY glutAddSubMenu(const char *label, int submenu);
GLUTAPI void GLUTAPIENTRY glutChangeToMenuEntry(int item, const char *label, int value);
GLUTAPI void GLUTAPIENTRY glutChangeToSubMenu(int item, const char *label, int submenu);
GLUTAPI void GLUTAPIENTRY glutRemoveMenuItem(int item);
GLUTAPI void GLUTAPIENTRY glutAttachMenu(int button);
GLUTAPI void GLUTAPIENTRY glutDetachMenu(int button);
/* GLUT window callback sub-API. */
GLUTAPI void GLUTAPIENTRY glutDisplayFunc(void (GLUTCALLBACK *func)(void));
GLUTAPI void GLUTAPIENTRY glutReshapeFunc(void (GLUTCALLBACK *func)(int width, int height));
GLUTAPI void GLUTAPIENTRY glutKeyboardFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y));
GLUTAPI void GLUTAPIENTRY glutMouseFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y));
GLUTAPI void GLUTAPIENTRY glutMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
GLUTAPI void GLUTAPIENTRY glutPassiveMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
GLUTAPI void GLUTAPIENTRY glutEntryFunc(void (GLUTCALLBACK *func)(int state));
GLUTAPI void GLUTAPIENTRY glutVisibilityFunc(void (GLUTCALLBACK *func)(int state));
GLUTAPI void GLUTAPIENTRY glutIdleFunc(void (GLUTCALLBACK *func)(void));
GLUTAPI void GLUTAPIENTRY glutTimerFunc(unsigned int millis, void (GLUTCALLBACK *func)(int value), int value);
GLUTAPI void GLUTAPIENTRY glutMenuStateFunc(void (GLUTCALLBACK *func)(int state));
#if (GLUT_API_VERSION >= 2)
GLUTAPI void GLUTAPIENTRY glutSpecialFunc(void (GLUTCALLBACK *func)(int key, int x, int y));
GLUTAPI void GLUTAPIENTRY glutSpaceballMotionFunc(void (GLUTCALLBACK *func)(int x, int y, int z));
GLUTAPI void GLUTAPIENTRY glutSpaceballRotateFunc(void (GLUTCALLBACK *func)(int x, int y, int z));
GLUTAPI void GLUTAPIENTRY glutSpaceballButtonFunc(void (GLUTCALLBACK *func)(int button, int state));
GLUTAPI void GLUTAPIENTRY glutButtonBoxFunc(void (GLUTCALLBACK *func)(int button, int state));
GLUTAPI void GLUTAPIENTRY glutDialsFunc(void (GLUTCALLBACK *func)(int dial, int value));
GLUTAPI void GLUTAPIENTRY glutTabletMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
GLUTAPI void GLUTAPIENTRY glutTabletButtonFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y));
#if (GLUT_API_VERSION >= 3)
GLUTAPI void GLUTAPIENTRY glutMenuStatusFunc(void (GLUTCALLBACK *func)(int status, int x, int y));
GLUTAPI void GLUTAPIENTRY glutOverlayDisplayFunc(void (GLUTCALLBACK *func)(void));
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
GLUTAPI void GLUTAPIENTRY glutWindowStatusFunc(void (GLUTCALLBACK *func)(int state));
#endif
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
GLUTAPI void GLUTAPIENTRY glutKeyboardUpFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y));
GLUTAPI void GLUTAPIENTRY glutSpecialUpFunc(void (GLUTCALLBACK *func)(int key, int x, int y));
GLUTAPI void GLUTAPIENTRY glutJoystickFunc(void (GLUTCALLBACK *func)(unsigned int buttonMask, int x, int y, int z), int pollInterval);
#endif
#endif
#endif
/* GLUT color index sub-API. */
GLUTAPI void GLUTAPIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue);
GLUTAPI GLfloat GLUTAPIENTRY glutGetColor(int ndx, int component);
GLUTAPI void GLUTAPIENTRY glutCopyColormap(int win);
/* GLUT state retrieval sub-API. */
GLUTAPI int GLUTAPIENTRY glutGet(GLenum type);
GLUTAPI int GLUTAPIENTRY glutDeviceGet(GLenum type);
#if (GLUT_API_VERSION >= 2)
/* GLUT extension support sub-API */
GLUTAPI int GLUTAPIENTRY glutExtensionSupported(const char *name);
#endif
#if (GLUT_API_VERSION >= 3)
GLUTAPI int GLUTAPIENTRY glutGetModifiers(void);
GLUTAPI int GLUTAPIENTRY glutLayerGet(GLenum type);
#endif
/* GLUT font sub-API */
GLUTAPI void GLUTAPIENTRY glutBitmapCharacter(void *font, int character);
GLUTAPI int GLUTAPIENTRY glutBitmapWidth(void *font, int character);
GLUTAPI void GLUTAPIENTRY glutStrokeCharacter(void *font, int character);
GLUTAPI int GLUTAPIENTRY glutStrokeWidth(void *font, int character);
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
GLUTAPI int GLUTAPIENTRY glutBitmapLength(void *font, const unsigned char *string);
GLUTAPI int GLUTAPIENTRY glutStrokeLength(void *font, const unsigned char *string);
#endif
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 17)
GLUTAPI float GLUTAPIENTRY glutStrokeWidthf(void *font, int character);
GLUTAPI float GLUTAPIENTRY glutStrokeLengthf(void *font, const unsigned char *string);
#endif
/* GLUT pre-built models sub-API */
GLUTAPI void GLUTAPIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks);
GLUTAPI void GLUTAPIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks);
GLUTAPI void GLUTAPIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
GLUTAPI void GLUTAPIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
GLUTAPI void GLUTAPIENTRY glutWireCube(GLdouble size);
GLUTAPI void GLUTAPIENTRY glutSolidCube(GLdouble size);
GLUTAPI void GLUTAPIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
GLUTAPI void GLUTAPIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
GLUTAPI void GLUTAPIENTRY glutWireDodecahedron(void);
GLUTAPI void GLUTAPIENTRY glutSolidDodecahedron(void);
GLUTAPI void GLUTAPIENTRY glutWireTeapot(GLdouble size);
GLUTAPI void GLUTAPIENTRY glutSolidTeapot(GLdouble size);
GLUTAPI void GLUTAPIENTRY glutWireOctahedron(void);
GLUTAPI void GLUTAPIENTRY glutSolidOctahedron(void);
GLUTAPI void GLUTAPIENTRY glutWireTetrahedron(void);
GLUTAPI void GLUTAPIENTRY glutSolidTetrahedron(void);
GLUTAPI void GLUTAPIENTRY glutWireIcosahedron(void);
GLUTAPI void GLUTAPIENTRY glutSolidIcosahedron(void);
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
/* GLUT video resize sub-API. */
GLUTAPI int GLUTAPIENTRY glutVideoResizeGet(GLenum param);
GLUTAPI void GLUTAPIENTRY glutSetupVideoResizing(void);
GLUTAPI void GLUTAPIENTRY glutStopVideoResizing(void);
GLUTAPI void GLUTAPIENTRY glutVideoResize(int x, int y, int width, int height);
GLUTAPI void GLUTAPIENTRY glutVideoPan(int x, int y, int width, int height);
/* GLUT debugging sub-API. */
GLUTAPI void GLUTAPIENTRY glutReportErrors(void);
#endif
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
/* GLUT device control sub-API. */
/* glutSetKeyRepeat modes. */
#define GLUT_KEY_REPEAT_OFF 0
#define GLUT_KEY_REPEAT_ON 1
#define GLUT_KEY_REPEAT_DEFAULT 2
/* Joystick button masks. */
#define GLUT_JOYSTICK_BUTTON_A 1
#define GLUT_JOYSTICK_BUTTON_B 2
#define GLUT_JOYSTICK_BUTTON_C 4
#define GLUT_JOYSTICK_BUTTON_D 8
GLUTAPI void GLUTAPIENTRY glutIgnoreKeyRepeat(int ignore);
GLUTAPI void GLUTAPIENTRY glutSetKeyRepeat(int repeatMode);
GLUTAPI void GLUTAPIENTRY glutForceJoystickFunc(void);
/* GLUT game mode sub-API. */
/* glutGameModeGet. */
#define GLUT_GAME_MODE_ACTIVE ((GLenum) 0)
#define GLUT_GAME_MODE_POSSIBLE ((GLenum) 1)
#define GLUT_GAME_MODE_WIDTH ((GLenum) 2)
#define GLUT_GAME_MODE_HEIGHT ((GLenum) 3)
#define GLUT_GAME_MODE_PIXEL_DEPTH ((GLenum) 4)
#define GLUT_GAME_MODE_REFRESH_RATE ((GLenum) 5)
#define GLUT_GAME_MODE_DISPLAY_CHANGED ((GLenum) 6)
GLUTAPI void GLUTAPIENTRY glutGameModeString(const char *string);
GLUTAPI int GLUTAPIENTRY glutEnterGameMode(void);
GLUTAPI void GLUTAPIENTRY glutLeaveGameMode(void);
GLUTAPI int GLUTAPIENTRY glutGameModeGet(GLenum mode);
#endif
#ifdef __cplusplus
}
#endif
#ifdef GLUT_APIENTRY_DEFINED
# undef GLUT_APIENTRY_DEFINED
# if defined(__CYGWIN__)
/* Leave APIENTRY defined when __CYGWIN__ is defined since OpenGL.org's
offical glext.h logic does not define APIENTY when __CYGWIN__
is defined. */
# else
# undef APIENTRY
# endif
#endif
#ifdef GLUT_WINGDIAPI_DEFINED
# undef GLUT_WINGDIAPI_DEFINED
# undef WINGDIAPI
#endif
#ifdef GLUT_DEFINED___CDECL
# undef GLUT_DEFINED___CDECL
# undef __cdecl
#endif
#ifdef GLUT_DEFINED__CRTIMP
# undef GLUT_DEFINED__CRTIMP
# undef _CRTIMP
#endif
#endif /* __glut_h__ */

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,145 @@
/*
* This file was taken from RakNet 4.082 without any modifications.
* Please see licenses/RakNet license.txt for the underlying license and related copyright.
*/
#ifndef __DDS_HEADER_H__
#define __DDS_HEADER_H__
// little-endian, of course
#define DDS_MAGIC 0x20534444
// DDS_header.dwFlags
#define DDSD_CAPS 0x00000001
#define DDSD_HEIGHT 0x00000002
#define DDSD_WIDTH 0x00000004
#define DDSD_PITCH 0x00000008
#define DDSD_PIXELFORMAT 0x00001000
#define DDSD_MIPMAPCOUNT 0x00020000
#define DDSD_LINEARSIZE 0x00080000
#define DDSD_DEPTH 0x00800000
// DDS_header.sPixelFormat.dwFlags
#define DDPF_ALPHAPIXELS 0x00000001
#define DDPF_FOURCC 0x00000004
#define DDPF_INDEXED 0x00000020
#define DDPF_RGB 0x00000040
// DDS_header.sCaps.dwCaps1
#define DDSCAPS_COMPLEX 0x00000008
#define DDSCAPS_TEXTURE 0x00001000
#define DDSCAPS_MIPMAP 0x00400000
// DDS_header.sCaps.dwCaps2
#define DDSCAPS2_CUBEMAP 0x00000200
#define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400
#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800
#define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000
#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
#define DDSCAPS2_VOLUME 0x00200000
#define D3DFMT_DXT1 '1TXD' // DXT1 compression texture format
#define D3DFMT_DXT2 '2TXD' // DXT2 compression texture format
#define D3DFMT_DXT3 '3TXD' // DXT3 compression texture format
#define D3DFMT_DXT4 '4TXD' // DXT4 compression texture format
#define D3DFMT_DXT5 '5TXD' // DXT5 compression texture format
#define PF_IS_DXT1(pf) \
((pf.dwFlags & DDPF_FOURCC) && \
(pf.dwFourCC == D3DFMT_DXT1))
#define PF_IS_DXT3(pf) \
((pf.dwFlags & DDPF_FOURCC) && \
(pf.dwFourCC == D3DFMT_DXT3))
#define PF_IS_DXT5(pf) \
((pf.dwFlags & DDPF_FOURCC) && \
(pf.dwFourCC == D3DFMT_DXT5))
#define PF_IS_BGRA8(pf) \
((pf.dwFlags & DDPF_RGB) && \
(pf.dwFlags & DDPF_ALPHAPIXELS) && \
(pf.dwRGBBitCount == 32) && \
(pf.dwRBitMask == 0xff0000) && \
(pf.dwGBitMask == 0xff00) && \
(pf.dwBBitMask == 0xff) && \
(pf.dwAlphaBitMask == 0xff000000U))
#define PF_IS_BGR8(pf) \
((pf.dwFlags & DDPF_ALPHAPIXELS) && \
!(pf.dwFlags & DDPF_ALPHAPIXELS) && \
(pf.dwRGBBitCount == 24) && \
(pf.dwRBitMask == 0xff0000) && \
(pf.dwGBitMask == 0xff00) && \
(pf.dwBBitMask == 0xff))
#define PF_IS_BGR5A1(pf) \
((pf.dwFlags & DDPF_RGB) && \
(pf.dwFlags & DDPF_ALPHAPIXELS) && \
(pf.dwRGBBitCount == 16) && \
(pf.dwRBitMask == 0x00007c00) && \
(pf.dwGBitMask == 0x000003e0) && \
(pf.dwBBitMask == 0x0000001f) && \
(pf.dwAlphaBitMask == 0x00008000))
#define PF_IS_BGR565(pf) \
((pf.dwFlags & DDPF_RGB) && \
!(pf.dwFlags & DDPF_ALPHAPIXELS) && \
(pf.dwRGBBitCount == 16) && \
(pf.dwRBitMask == 0x0000f800) && \
(pf.dwGBitMask == 0x000007e0) && \
(pf.dwBBitMask == 0x0000001f))
#define PF_IS_INDEX8(pf) \
((pf.dwFlags & DDPF_INDEXED) && \
(pf.dwRGBBitCount == 8))
union DDS_header
{
struct
{
unsigned int dwMagic;
unsigned int dwSize;
unsigned int dwFlags;
unsigned int dwHeight;
unsigned int dwWidth;
unsigned int dwPitchOrLinearSize;
unsigned int dwDepth;
unsigned int dwMipMapCount;
unsigned int dwReserved1[ 11 ];
// DDPIXELFORMAT
struct
{
unsigned int dwSize;
unsigned int dwFlags;
unsigned int dwFourCC;
unsigned int dwRGBBitCount;
unsigned int dwRBitMask;
unsigned int dwGBitMask;
unsigned int dwBBitMask;
unsigned int dwAlphaBitMask;
} sPixelFormat;
// DDCAPS2
struct
{
unsigned int dwCaps1;
unsigned int dwCaps2;
unsigned int dwDDSX;
unsigned int dwReserved;
} sCaps;
unsigned int dwReserved2;
};
char data[ 128 ];
};
#endif // mydds_h

View File

@ -0,0 +1,813 @@
/* ------------------------------------------------------------------------------------------------------------------------------------ */
// Portions of this file have been written by using the "Compress YCOCgDXT" sample as a reference.
// Please refer to http://developer.download.nvidia.com/SDK/10/opengl/samples.html#compress_YCoCgDXT for more information.
/* ------------------------------------------------------------------------------------------------------------------------------------ */
/*
* This file was taken from RakNet 4.082.
* Please see licenses/RakNet license.txt for the underlying license and related copyright.
*
* Modified work: Copyright (c) 2020, SLikeSoft UG (haftungsbeschr<68>nkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
/* ------------------------------------------------------------------------------------------------------------------------------------ */
// Includes
#include <windows.h>
#include <assert.h>
#include "DXTCompressor.h"
#include "FrameBufferRenderBuffer.hpp"
#include "ShaderSource.h"
#include "OpenGLWindow.hpp"
#include <map>
/* ------------------------------------------------------------------------------------------------------------------------------------ */
// Enable performance timing
// #define DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
/* ------------------------------------------------------------------------------------------------------------------------------------ */
// Link with these libraries
#pragma comment(lib, "glutstatic")
#pragma comment(lib, "glew32")
#pragma comment(lib, "cg")
#pragma comment(lib, "cgGL")
/* ------------------------------------------------------------------------------------------------------------------------------------ */
// Defines
#define DXTCOMPRESSOR_WINDOW_WIDTH 640
#define DXTCOMPRESSOR_WINDOW_HEIGHT 480
/* ------------------------------------------------------------------------------------------------------------------------------------ */
// Static class data
int DXTCompressor::m_initRefCount = 0;
CGcontext DXTCompressor::m_cgContext;
CGprofile DXTCompressor::m_cgVProfile;
CGprofile DXTCompressor::m_cgFProfile;
CGprogram DXTCompressor::m_compressVProg;
CGprogram DXTCompressor::m_compressDXT1RGBAFProg;
CGprogram DXTCompressor::m_compressDXT5RGBAFProg;
CGprogram DXTCompressor::m_compressDXT1BGRAFProg;
CGprogram DXTCompressor::m_compressDXT5BGRAFProg;
int DXTCompressor::m_numIterations = 0;
int DXTCompressor::m_currentImageWidth = 0;
int DXTCompressor::m_currentImageHeight = 0;
float DXTCompressor::m_lastCompressionTime = 0;
float DXTCompressor::m_accumulatedTime = 0;
float DXTCompressor::m_timeRunningCompressionShader = 0;
float DXTCompressor::m_timeCopyingPixelDataToCPU = 0;
/* ------------------------------------------------------------------------------------------------------------------------------------ */
// Hash table to store framebuffer objects
struct FramebufferObjectKeyCompare
{
bool operator()(int s1, int s2) const
{
return s1 < s2;
}
};
typedef int FramebufferObjectKey;
typedef class map< FramebufferObjectKey, FramebufferObject*, FramebufferObjectKeyCompare > FramebufferObjectHashtable;
// The hashtable
FramebufferObjectHashtable s_frameBuffersHash;
// Hashkey generation
FramebufferObjectKey GetHashKey( CompressionType compressionType, int width, int height )
{
return (int(compressionType) + width + (width*height));
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
#ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
// Typedef ticks
typedef __int64 Ticks;
inline Ticks GetTicks()
{
Ticks ticks;
QueryPerformanceCounter( (LARGE_INTEGER*) &ticks);
return ticks;
}
inline float TicksToMilliseconds( Ticks ticks )
{
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
return float(float(ticks) * 1000.0f / float(freq.QuadPart));
}
const int TIMER_STACK_SIZE = 256;
static int g_currentStackId = 0;
static Ticks g_startTrack[ TIMER_STACK_SIZE ];
static Ticks g_endTrack[ TIMER_STACK_SIZE ];
// Used for tracking time
inline void StartTracking()
{
g_startTrack[ g_currentStackId++ ] = GetTicks();
}
inline void EndTracking()
{
g_endTrack[ --g_currentStackId ] = GetTicks();
}
inline float GetDeltaTimeInSeconds()
{
Ticks delta = g_endTrack[ g_currentStackId ] - g_startTrack[ g_currentStackId ];
return TicksToMilliseconds( delta ) / 1000.0f;
}
inline float GetDeltaTimeInMilliseconds()
{
Ticks delta = g_endTrack[ g_currentStackId ] - g_startTrack[ g_currentStackId ];
return TicksToMilliseconds( delta );
}
#endif // #ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
/* ------------------------------------------------------------------------------------------------------------------------------------ */
DXTCompressor::DXTCompressor()
{
m_imageWidth = 0;
m_imageHeight = 0;
m_compressionType = DXT1;
m_pCompressFbo = 0;
m_compressFboTex = 0;
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
void DXTCompressor::cgErrorCallback()
{
CGerror lastError = cgGetError();
if( lastError )
{
printf( "%s\n", cgGetErrorString( lastError ) );
printf( "%s\n", cgGetLastListing( m_cgContext ) );
assert( false );
}
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
bool DXTCompressor::Initialize()
{
if( m_initRefCount == 0 )
{
if( !InitOpenGL() )
return false;
if( !InitCG() )
return false;
}
m_initRefCount++;
return true;
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
void DXTCompressor::Shutdown()
{
if( m_initRefCount > 0 )
m_initRefCount--;
if( m_initRefCount == 0 )
{
// Deallocate buffers
DeallocateBuffers();
// Shutdown cg stuff
cgGLDisableProfile(m_cgVProfile);
cgGLDisableProfile(m_cgFProfile);
cgGLUnloadProgram( m_compressVProg );
cgGLUnloadProgram( m_compressDXT1RGBAFProg );
cgGLUnloadProgram( m_compressDXT5RGBAFProg );
cgGLUnloadProgram( m_compressDXT1BGRAFProg );
cgGLUnloadProgram( m_compressDXT5BGRAFProg );
cgDestroyContext(m_cgContext);
// Kill the OpenGL window
KillGLWindow();
}
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
bool DXTCompressor::InitOpenGL()
{
bool bFullscreen = false;
#if 1
// Compute desktop window width and height
HWND desktopHwnd = GetDesktopWindow();
RECT windowRect;
GetWindowRect( desktopHwnd, &windowRect );
int windowWidth = windowRect.right - windowRect.left;
int windowHeight = windowRect.bottom - windowRect.top;
bFullscreen = true;
#else
int windowWidth = 640;
int windowHeight = 480;
#endif
// Create the window; this is needed in order to invoke OpenGL commands
BOOL windowCreateSuccess = CreateGLWindow( "Testing", windowWidth, windowHeight, 32, bFullscreen, true );
if( !windowCreateSuccess )
return false;
// Int GLEW
glewInit();
// Make sure these extensions are supported
if (!glewIsSupported(
"GL_VERSION_2_0 "
"GL_ARB_vertex_program "
"GL_ARB_fragment_program "
"GL_NV_gpu_program4 "
"GL_ARB_pixel_buffer_object "
"GL_EXT_framebuffer_object "
"GL_ARB_texture_compression "
"GL_EXT_texture_compression_s3tc "
"GL_EXT_texture_integer "
))
{
printf("Unable to load required OpenGL extension!\n");
return false;
}
// Enable depth testing
glEnable(GL_DEPTH_TEST);
glClearColor(0.2, 0.2, 0.2, 1.0);
// Report any errors to the console screen
glutReportErrors();
// Success
return true;
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
bool DXTCompressor::InitCG()
{
// Create Cg Context
m_cgContext = cgCreateContext();
cgSetErrorCallback( cgErrorCallback );
// Load Cg programs
m_cgVProfile = cgGLGetLatestProfile( CG_GL_VERTEX );
m_cgFProfile = cgGLGetLatestProfile( CG_GL_FRAGMENT );
// Shader compile options...
const char *args[] =
{
"-unroll", "all",
0,
};
m_compressVProg = cgCreateProgram( m_cgContext, CG_SOURCE, pDXTCompressorShaderSource, m_cgVProfile, "compress_vp", args );
cgGLLoadProgram( m_compressVProg );
m_compressDXT1RGBAFProg = cgCreateProgram( m_cgContext, CG_SOURCE, pDXTCompressorShaderSource, m_cgFProfile, "compress_DXT1_RGBA_fp", args );
cgGLLoadProgram( m_compressDXT1RGBAFProg );
m_compressDXT1BGRAFProg = cgCreateProgram( m_cgContext, CG_SOURCE, pDXTCompressorShaderSource, m_cgFProfile, "compress_DXT1_BGRA_fp", args );
cgGLLoadProgram( m_compressDXT1BGRAFProg );
m_compressDXT5RGBAFProg = cgCreateProgram( m_cgContext, CG_SOURCE, pDXTCompressorShaderSource, m_cgFProfile, "compress_YCoCgDXT5_RGBA_fp", args );
cgGLLoadProgram( m_compressDXT5RGBAFProg );
m_compressDXT5BGRAFProg = cgCreateProgram( m_cgContext, CG_SOURCE, pDXTCompressorShaderSource, m_cgFProfile, "compress_YCoCgDXT5_BGRA_fp", args );
cgGLLoadProgram( m_compressDXT5BGRAFProg );
return true;
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
bool DXTCompressor::IsInitialized()
{
return (m_initRefCount != 0);
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
static GLuint CreateTexture( GLenum target, GLint internalformat, GLenum format, GLenum type, int w, int h )
{
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(target, tex);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(target, 0, internalformat, w, h, 0, format, type, 0);
return tex;
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
FramebufferObject* DXTCompressor::RequestFBO( CompressionType compressionType, int width, int height )
{
// Get hash key
FramebufferObjectKey hashKey = GetHashKey( compressionType, width, height );
// See if we have it in the hash
if( s_frameBuffersHash.find( hashKey ) != s_frameBuffersHash.end() )
{
return s_frameBuffersHash[ hashKey ];
}
// Create the texture
GLuint newTextureID = 0;
FramebufferObject* pNewFrameBufferObject = new FramebufferObject();
if( compressionType == DXT1 )
{
newTextureID = CreateTexture(GL_TEXTURE_2D, GL_LUMINANCE_ALPHA32UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_INT, width/4, height/4);
}
else if( compressionType == DXT5_YCOCG )
{
newTextureID = CreateTexture(GL_TEXTURE_2D, GL_RGBA32UI_EXT, GL_RGBA_INTEGER_EXT, GL_INT, width/4, height/4);
}
// Attach texture to framebuffer object
pNewFrameBufferObject->Bind();
pNewFrameBufferObject->AttachTexture(GL_TEXTURE_2D, newTextureID, GL_COLOR_ATTACHMENT0_EXT);
pNewFrameBufferObject->IsValid();
FramebufferObject::Disable();
// Add to hash
s_frameBuffersHash[ hashKey ] = pNewFrameBufferObject;
// Return
return pNewFrameBufferObject;
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
void DXTCompressor::DeallocateBuffers()
{
FramebufferObjectHashtable::iterator iter = s_frameBuffersHash.begin();
while( iter != s_frameBuffersHash.end() )
{
// Delete object
FramebufferObject* pFrameBufferObject = iter->second;
GLuint textureID = pFrameBufferObject->GetAttachedTextureID();
glDeleteTextures(1, &textureID);
delete pFrameBufferObject;
// Bump
++iter;
}
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
static inline void SetParameter( CGprogram prog, char *name, float x, float y=0.0, float z=0.0, float w=0.0 )
{
CGparameter param = cgGetNamedParameter( prog, name );
if( param )
{
cgGLSetParameter4f( param, x, y, z, w );
}
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
void DXTCompressor::SetShaderConstants()
{
SetParameter( m_compressDXT1RGBAFProg, "imageSize", m_imageWidth, m_imageHeight );
SetParameter( m_compressDXT5RGBAFProg, "imageSize", m_imageWidth, m_imageHeight );
SetParameter( m_compressDXT1BGRAFProg, "imageSize", m_imageWidth, m_imageHeight );
SetParameter( m_compressDXT5BGRAFProg, "imageSize", m_imageWidth, m_imageHeight );
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
static inline void DrawQuad()
{
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0);
glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0);
glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0);
glEnd();
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
void DXTCompressor::CompressInternal(bool sourceFormatIsBGRA)
{
#ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
StartTracking();
#endif
glViewport(0, 0, m_imageWidth/4, m_imageHeight/4);
glDisable(GL_DEPTH_TEST);
cgGLBindProgram(m_compressVProg);
cgGLEnableProfile(m_cgVProfile);
if( m_compressionType == DXT5_YCOCG )
{
if (sourceFormatIsBGRA==false)
cgGLBindProgram(m_compressDXT5RGBAFProg);
else
cgGLBindProgram(m_compressDXT5BGRAFProg);
}
else if( m_compressionType == DXT1 )
{
if (sourceFormatIsBGRA==false)
cgGLBindProgram(m_compressDXT1RGBAFProg);
else
cgGLBindProgram(m_compressDXT1BGRAFProg);
}
else
{
assert(false );
}
cgGLEnableProfile(m_cgFProfile);
glBindTexture(GL_TEXTURE_2D, m_imageTexId);
SetShaderConstants();
DrawQuad();
cgGLDisableProfile(m_cgVProfile);
cgGLDisableProfile(m_cgFProfile);
#ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
glFinish();
EndTracking();
m_timeRunningCompressionShader += GetDeltaTimeInMilliseconds();
#endif
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
int DXTCompressor::GetBufferSize( CompressionType compressionType, int inputWidth, int inputHeight )
{
if( compressionType == DXT5_YCOCG )
{
int size = (inputWidth/4)*(inputHeight/4)*8;
return sizeof(GLushort)*size;
}
else
{
int size = (inputWidth/4)*(inputHeight/4)*4;
return sizeof(GLushort)*size;
}
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
void DXTCompressor::DoCompression( void* ppOutputData, bool sourceFormatIsBGRA )
{
if( m_compressionType == DXT5_YCOCG )
{
// Render to integer fbo
m_pCompressFbo->Bind();
CompressInternal(sourceFormatIsBGRA);
// Readback data to host
int size = (m_imageWidth/4)*(m_imageHeight/4)*8;
GLushort *data = (GLushort *) ppOutputData;
// Copy pixel data
#ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
StartTracking();
#endif
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadPixels(0, 0, m_imageWidth/4, m_imageHeight/4, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_INT, data);
FramebufferObject::Disable();
#ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
EndTracking();
m_timeCopyingPixelDataToCPU += GetDeltaTimeInMilliseconds();
#endif
}
else if( m_compressionType == DXT1 )
{
// Render to integer fbo
m_pCompressFbo->Bind();
CompressInternal(sourceFormatIsBGRA);
// Readback data to host
int size = (m_imageWidth/4)*(m_imageHeight/4)*4;
GLushort *data = (GLushort *) ppOutputData;
// Copy pixel data
#ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
StartTracking();
#endif
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadPixels(0, 0, m_imageWidth/4, m_imageHeight/4, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_UNSIGNED_INT, data);
FramebufferObject::Disable();
#ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
EndTracking();
m_timeCopyingPixelDataToCPU += GetDeltaTimeInMilliseconds();
#endif
}
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
bool DXTCompressor::CompressImageData( CompressionType compressionType, const void *inputRGBA, int inputWidth, int inputHeight, void *outputData, bool bDisplayResults, bool sourceFormatIsBGRA )
{
// Make sure we're initialized
if( !IsInitialized() )
{
printf( "You need to initialize DXTCompressor before calling compress!\n " );
return false;
}
// Make sure the source width and height are divisible by 4
// This is a requirement by the DXT compression algorithm
if( !( (inputWidth%4)==0 && (inputHeight%4)==0 ) )
{
printf( "Error! Input image width and height must be multiple of 4, as required by DXT compression rules. You have passed in an image of %dx%d", inputWidth, inputHeight );
return false;
}
// Accumulate width and heights
m_numIterations++;
m_currentImageWidth = inputWidth;
m_currentImageHeight = inputHeight;
// Instantiate the compressor
DXTCompressor compressor;
compressor.m_imageWidth = inputWidth;
compressor.m_imageHeight = inputHeight;
compressor.m_compressionType = compressionType;
// Make a copy of the source data and flip the Y. OpenGL rendering has Y going down
/*
char* pFlippedData = new char[ inputWidth*inputHeight*4 ];
{
const int rowSize = inputWidth*4;
char* pRunnerDest = pFlippedData + (rowSize*(inputHeight-1));
const char* pRunnerSrc = (const char*)inputRGBA;
for( int row = inputHeight-1; row >=0; row-- )
{
memcpy( pRunnerDest, pRunnerSrc, rowSize );
pRunnerSrc += rowSize;
pRunnerDest -= rowSize;
}
}
*/
// Generate a texture and bind it to the input source data
glGenTextures(1, &compressor.m_imageTexId);
glBindTexture(GL_TEXTURE_2D, compressor.m_imageTexId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, inputWidth, inputHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)pFlippedData );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, inputWidth, inputHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)inputRGBA );
// Request FBO
compressor.m_pCompressFbo = RequestFBO( compressionType, inputWidth, inputHeight );
compressor.m_compressFboTex = compressor.m_pCompressFbo->GetAttachedTextureID();
#ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
// Start the clock
StartTracking();
#endif
// Do the compression
compressor.DoCompression( outputData, sourceFormatIsBGRA );
#ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
// Stop the clock
EndTracking();
m_lastCompressionTime = GetDeltaTimeInMilliseconds();
m_accumulatedTime += m_lastCompressionTime;
printf( "Compression time: %f ms\n", m_lastCompressionTime );
#endif
// Display texture? Only DXT1 supported here.
if( bDisplayResults && compressionType == DXT1 )
{
// Create empty dxt1 compressed texture
GLuint tempDisplayTexture;
int dxt1Size = (inputWidth/4)*(inputHeight/4)*8;
GLubyte * tempPadData = new GLubyte [dxt1Size];
memset(tempPadData, 0, dxt1Size);
glGenTextures(1, &tempDisplayTexture);
glBindTexture(GL_TEXTURE_2D, tempDisplayTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, inputWidth, inputHeight, 0, dxt1Size, tempPadData);
delete [] tempPadData;
// Re-upload the texture to VRAM for display
int size = (inputWidth/4)*(inputHeight/4);
glBindTexture(GL_TEXTURE_2D, tempDisplayTexture);
glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, inputWidth, inputHeight, 0, size*8, outputData);
// Display the texture
DisplayTexture( tempDisplayTexture, inputWidth, inputHeight );
// Get rid of the texture
glDeleteTextures(1, &tempDisplayTexture);
}
// Clean up
// delete [] pFlippedData;
// pFlippedData = nullptr;
glDeleteTextures( 1, &compressor.m_imageTexId );
// Done
return true;
}
#include <stdlib.h>
#include "DDSHeader.h"
/* ------------------------------------------------------------------------------------------------------------------------------------ */
int DXTCompressor::GetDDSHeaderSize(void)
{
return sizeof(DDS_header);
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
void DXTCompressor::WriteDDSHeader( CompressionType compressionType, int width, int height, int compresedDataLength, void *outputData )
{
DDS_header* pHdr = (DDS_header*)outputData;
memset( pHdr, 0, sizeof(DDS_header) );
pHdr->dwMagic = DDS_MAGIC;
pHdr->dwSize = 124;
pHdr->dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
pHdr->dwWidth = width;
pHdr->dwHeight = height;
pHdr->sCaps.dwCaps1 = DDSCAPS_TEXTURE | DDSD_CAPS;
pHdr->sPixelFormat.dwSize = 32;
pHdr->sPixelFormat.dwFlags = DDPF_FOURCC;
if( compressionType == DXT1 )
pHdr->sPixelFormat.dwFourCC = D3DFMT_DXT1;
else if( compressionType == DXT5_YCOCG )
pHdr->sPixelFormat.dwFourCC = D3DFMT_DXT5;
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
void DXTCompressor::WriteDDSMemoryFile( CompressionType compressionType, int width, int height, const void* pCompressedData, int compresedDataLength, void **outputData, int *outputLength )
{
// Allocate the header + data
int totalSize = sizeof(DDS_header) + compresedDataLength;
void* pMemFile = new char[ totalSize ];
// Write the header
WriteDDSHeader(compressionType, width, height, compresedDataLength, pMemFile );
// Write the data
void* pData = ((char*)pMemFile + sizeof(DDS_header));
memcpy( pData, pCompressedData, compresedDataLength );
// Return data to user
*outputData = pMemFile;
*outputLength = totalSize;
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
void DXTCompressor::PrintPerformanceLog()
{
#ifdef DXTCOMPRESSOR_ENABLE_PERFORMANCE_TIMING
// Compute
float mPixelsPerSec = (m_currentImageWidth*m_currentImageHeight*m_numIterations) / (m_accumulatedTime*1e6/1000.0f);
printf( "For %dx%d image, compression took %f ms, Average of %f mPixelsPerSec (mPixels/sec)\n", m_currentImageWidth, m_currentImageHeight, m_accumulatedTime/m_numIterations, mPixelsPerSec );
printf( "%f ms was spent in running compression shader, %f ms was spent copying pixel data to main memory for the cpu\n", m_timeRunningCompressionShader/m_numIterations, m_timeCopyingPixelDataToCPU/m_numIterations );
// Reset stats
m_currentImageWidth = 0;
m_currentImageHeight = 0;
m_numIterations = 0;
m_accumulatedTime = 0;
m_timeCopyingPixelDataToCPU = 0;
m_timeRunningCompressionShader = 0;
#endif
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
static void glutPrint(float x, float y, const char *s, void *font)
{
int i, len;
glRasterPos2f(x, y);
len = (int) strlen(s);
for (i = 0; i < len; i++) {
glutBitmapCharacter(font, s[i]);
}
}
static bool DrawTexture( GLuint textureID )
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0,0,windowWidth,windowHeight);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glColor3f(1.0, 1.0, 1.0);
DrawQuad();
glDisable(GL_TEXTURE_2D);
glLoadIdentity();
glutPrint(-0.95, -0.95, "DXT1 compressed (push ESC to close)", GLUT_BITMAP_9_BY_15);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
return true;
}
void ClientResize(HWND hWnd, int nWidth, int nHeight)
{
RECT rcClient, rcWindow;
POINT ptDiff;
GetClientRect(hWnd, &rcClient);
GetWindowRect(hWnd, &rcWindow);
ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right;
ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
MoveWindow(hWnd,rcWindow.left, rcWindow.top, nWidth + ptDiff.x, nHeight + ptDiff.y, TRUE);
}
void DXTCompressor::DisplayTexture( GLuint textureID, int texW, int texH )
{
// Show the window
ShowWindow(hWnd,SW_SHOW);
// Resize the window to match the size of the texture
ClientResize( hWnd, texW, texH );
// Windows message pump
MSG msg;
BOOL done=FALSE;
while(!done)
{
if (PeekMessage(&msg, nullptr,0,0,PM_REMOVE))
{
if (msg.message==WM_QUIT)
{
done=TRUE;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
if ((active && !DrawTexture( textureID )) || keys[VK_ESCAPE])
{
keys[VK_ESCAPE] = FALSE;
done=TRUE;
}
else
{
SwapBuffers(hDC);
}
}
}
// Hide the window
ShowWindow(hWnd,SW_HIDE);
}

View File

@ -0,0 +1,98 @@
/*
* This file was taken from RakNet 4.082 without any modifications.
* Please see licenses/RakNet license.txt for the underlying license and related copyright.
*/
#ifndef __DXT_COMPRESSOR_H__
#define __DXT_COMPRESSOR_H__
/* ------------------------------------------------------------------------------------------------------------------------------------ */
// Includes
#include <GL/glew.h>
#include <GL/glut.h>
#include <Cg/cg.h>
#include <Cg/cgGL.h>
/* ------------------------------------------------------------------------------------------------------------------------------------ */
// Forward decls.
class FramebufferObject;
class Renderbuffer;
/* ------------------------------------------------------------------------------------------------------------------------------------ */
enum CompressionType
{
DXT1,
DXT5_YCOCG,
};
/* ------------------------------------------------------------------------------------------------------------------------------------ */
class DXTCompressor
{
public:
DXTCompressor();
public:
// These need to be called before using the compressor, and shutdown after using the compressor
static bool Initialize();
static void Shutdown();
// Compresses input data into the desired compressed format.
// The input data is assumed to be 32-bit RGBA (1 byte per channel).
// outputData should be allocated to at least GetBufferSize()
// This will return true if the compression is successful.
static bool CompressImageData( CompressionType compressionType, const void *inputRGBA, int inputWidth, int inputHeight, void *outputData, bool bDisplayResults, bool sourceFormatIsBGRA );
static int GetBufferSize(CompressionType compressionType, int inputWidth, int inputHeight );
// Saves the compressed data into a Microsoft DDS file.
static int GetDDSHeaderSize(void);
static void WriteDDSHeader( CompressionType compressionType, int width, int height, int compresedDataLength, void *outputData );
static void WriteDDSMemoryFile( CompressionType compressionType, int width, int height, const void* pCompressedData, int compresedDataLength, void **outputData, int *outputLength );
// Prints out the accumulated performance of the compressor
static void PrintPerformanceLog();
private:
void SetShaderConstants();
void CompressInternal( bool sourceFormatIsBGRA);
void DoCompression( void* ppOutputData, bool sourceFormatIsBGRA );
static bool InitOpenGL();
static bool InitCG();
static void cgErrorCallback();
static bool IsInitialized();
static void DisplayTexture( GLuint textureID, int texW, int texH );
static FramebufferObject* RequestFBO( CompressionType compressionType, int width, int height );
static void DeallocateBuffers();
private:
// Image related data
int m_imageWidth;
int m_imageHeight;
CompressionType m_compressionType;
GLuint m_imageTexId;
FramebufferObject* m_pCompressFbo;
GLuint m_compressFboTex;
// CG related data
static int m_initRefCount;
static CGcontext m_cgContext;
static CGprofile m_cgVProfile, m_cgFProfile;
static CGprogram m_compressVProg, m_compressDXT1RGBAFProg, m_compressDXT5RGBAFProg, m_compressDXT1BGRAFProg, m_compressDXT5BGRAFProg;
// Used to collect stats
static int m_numIterations;
static int m_currentImageWidth, m_currentImageHeight;
static float m_lastCompressionTime;
static float m_accumulatedTime;
static float m_timeRunningCompressionShader;
static float m_timeCopyingPixelDataToCPU;
};
#endif // __DXT_COMPRESSOR_H__

View File

@ -0,0 +1,639 @@
/*
Copyright (c) 2005,
Aaron Lefohn (lefohn@cs.ucdavis.edu)
Adam Moerschell (atmoerschell@ucdavis.edu)
All rights reserved.
This software is licensed under the BSD open-source license. See
http://www.opensource.org/licenses/bsd-license.php for more detail.
*************************************************************
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.
Neither the name of the University of Californa, Davis nor the names of
the contributors 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.
*/
#ifndef __FRAMEBUFFERRENDERBUFFER_HPP__
#define __FRAMEBUFFERRENDERBUFFER_HPP__
#include <GL/glew.h>
#include <iostream>
/*!
FramebufferObject Class. This class encapsulates the FramebufferObject
(FBO) OpenGL spec. See the official spec at:
http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txt
for details.
A framebuffer object (FBO) is conceptually a structure containing pointers
to GPU memory. The memory pointed to is either an OpenGL texture or an
OpenGL RenderBuffer. FBOs can be used to render to one or more textures,
share depth buffers between multiple sets of color buffers/textures and
are a complete replacement for pbuffers.
Performance Notes:
1) It is more efficient (but not required) to call Bind()
on an FBO before making multiple method calls. For example:
FramebufferObject fbo;
fbo.Bind();
fbo.AttachTexture(GL_TEXTURE_2D, texId0, GL_COLOR_ATTACHMENT0_EXT);
fbo.AttachTexture(GL_TEXTURE_2D, texId1, GL_COLOR_ATTACHMENT1_EXT);
fbo.IsValid();
To provide a complete encapsulation, the following usage
pattern works correctly but is less efficient:
FramebufferObject fbo;
// NOTE : No Bind() call
fbo.AttachTexture(GL_TEXTURE_2D, texId0, GL_COLOR_ATTACHMENT0_EXT);
fbo.AttachTexture(GL_TEXTURE_2D, texId1, GL_COLOR_ATTACHMENT1_EXT);
fbo.IsValid();
The first usage pattern binds the FBO only once, whereas
the second usage binds/unbinds the FBO for each method call.
2) Use FramebufferObject::Disable() sparingly. We have intentionally
left out an "Unbind()" method because it is largely unnecessary
and encourages rendundant Bind/Unbind coding. Binding an FBO is
usually much faster than enabling/disabling a pbuffer, but is
still a costly operation. When switching between multiple FBOs
and a visible OpenGL framebuffer, the following usage pattern
is recommended:
FramebufferObject fbo1, fbo2;
fbo1.Bind();
... Render ...
// NOTE : No Unbind/Disable here...
fbo2.Bind();
... Render ...
// Disable FBO rendering and return to visible window
// OpenGL framebuffer.
FramebufferObject::Disable();
*/
class FramebufferObject
{
public:
/// Ctor/Dtor
FramebufferObject();
virtual ~FramebufferObject();
/// Bind this FBO as current render target
void Bind();
/// Bind a texture to the "attachment" point of this FBO
virtual void AttachTexture( GLenum texTarget,
GLuint texId,
GLenum attachment = GL_COLOR_ATTACHMENT0_EXT,
int mipLevel = 0,
int zSlice = 0 );
/// Bind an array of textures to multiple "attachment" points of this FBO
/// - By default, the first 'numTextures' attachments are used,
/// starting with GL_COLOR_ATTACHMENT0_EXT
virtual void AttachTextures( int numTextures,
GLenum texTarget[],
GLuint texId[],
GLenum attachment[] = NULL,
int mipLevel[] = NULL,
int zSlice[] = NULL );
/// Bind a render buffer to the "attachment" point of this FBO
virtual void AttachRenderBuffer( GLuint buffId,
GLenum attachment = GL_COLOR_ATTACHMENT0_EXT );
/// Bind an array of render buffers to corresponding "attachment" points
/// of this FBO.
/// - By default, the first 'numBuffers' attachments are used,
/// starting with GL_COLOR_ATTACHMENT0_EXT
virtual void AttachRenderBuffers( int numBuffers, GLuint buffId[],
GLenum attachment[] = NULL );
/// Free any resource bound to the "attachment" point of this FBO
void Unattach( GLenum attachment );
/// Free any resources bound to any attachment points of this FBO
void UnattachAll();
/// Is this FBO currently a valid render target?
/// - Sends output to std::cerr by default but can
/// be a user-defined C++ stream
///
/// NOTE : This function works correctly in debug build
/// mode but always returns "true" if NDEBUG is
/// is defined (optimized builds)
#ifndef NDEBUG
bool IsValid( std::ostream& ostr = std::cerr );
#else
bool IsValid( std::ostream& ostr = std::cerr ) {
return true;
}
#endif
/// BEGIN : Accessors
/// Is attached type GL_RENDERBUFFER_EXT or GL_TEXTURE?
GLenum GetAttachedType( GLenum attachment );
/// What is the Id of Renderbuffer/texture currently
/// attached to "attachement?"
GLuint GetAttachedId( GLenum attachment );
/// Which mipmap level is currently attached to "attachement?"
GLint GetAttachedMipLevel( GLenum attachment );
/// Which cube face is currently attached to "attachment?"
GLint GetAttachedCubeFace( GLenum attachment );
/// Which z-slice is currently attached to "attachment?"
GLint GetAttachedZSlice( GLenum attachment );
/// END : Accessors
GLuint GetAttachedTextureID() const { return m_attachedTexture; }
/// BEGIN : Static methods global to all FBOs
/// Return number of color attachments permitted
static int GetMaxColorAttachments();
/// Disable all FBO rendering and return to traditional,
/// windowing-system controlled framebuffer
/// NOTE:
/// This is NOT an "unbind" for this specific FBO, but rather
/// disables all FBO rendering. This call is intentionally "static"
/// and named "Disable" instead of "Unbind" for this reason. The
/// motivation for this strange semantic is performance. Providing
/// "Unbind" would likely lead to a large number of unnecessary
/// FBO enablings/disabling.
static void Disable();
/// END : Static methods global to all FBOs
protected:
void _GuardedBind();
void _GuardedUnbind();
void _FramebufferTextureND( GLenum attachment, GLenum texTarget,
GLuint texId, int mipLevel, int zSlice );
static GLuint _GenerateFboId();
private:
GLuint m_fboId;
GLint m_savedFboId;
GLuint m_attachedTexture;
};
#include <iostream>
using namespace std;
FramebufferObject::FramebufferObject()
: m_fboId(_GenerateFboId()),
m_savedFboId(0)
{
// Bind this FBO so that it actually gets created now
_GuardedBind();
_GuardedUnbind();
}
FramebufferObject::~FramebufferObject()
{
glDeleteFramebuffersEXT(1, &m_fboId);
}
void FramebufferObject::Bind()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fboId);
}
void FramebufferObject::Disable()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
void
FramebufferObject::AttachTexture( GLenum texTarget, GLuint texId,
GLenum attachment, int mipLevel, int zSlice )
{
_GuardedBind();
/*
#ifndef NDEBUG
if( GetAttachedId(attachment) != texId ) {
#endif
*/
_FramebufferTextureND( attachment, texTarget,
texId, mipLevel, zSlice );
m_attachedTexture = texId;
/*
#ifndef NDEBUG
}
else {
cerr << "FramebufferObject::AttachTexture PERFORMANCE WARNING:\n"
<< "\tRedundant bind of texture (id = " << texId << ").\n"
<< "\tHINT : Compile with -DNDEBUG to remove this warning.\n";
}
#endif
*/
_GuardedUnbind();
}
void
FramebufferObject::AttachTextures( int numTextures, GLenum texTarget[], GLuint texId[],
GLenum attachment[], int mipLevel[], int zSlice[] )
{
for(int i = 0; i < numTextures; ++i) {
AttachTexture( texTarget[i], texId[i],
attachment ? attachment[i] : (GL_COLOR_ATTACHMENT0_EXT + i),
mipLevel ? mipLevel[i] : 0,
zSlice ? zSlice[i] : 0 );
}
}
void
FramebufferObject::AttachRenderBuffer( GLuint buffId, GLenum attachment )
{
_GuardedBind();
#ifndef NDEBUG
if( GetAttachedId(attachment) != buffId ) {
#endif
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachment,
GL_RENDERBUFFER_EXT, buffId);
#ifndef NDEBUG
}
else {
cerr << "FramebufferObject::AttachRenderBuffer PERFORMANCE WARNING:\n"
<< "\tRedundant bind of Renderbuffer (id = " << buffId << ")\n"
<< "\tHINT : Compile with -DNDEBUG to remove this warning.\n";
}
#endif
_GuardedUnbind();
}
void
FramebufferObject::AttachRenderBuffers( int numBuffers, GLuint buffId[], GLenum attachment[] )
{
for(int i = 0; i < numBuffers; ++i) {
AttachRenderBuffer( buffId[i],
attachment ? attachment[i] : (GL_COLOR_ATTACHMENT0_EXT + i) );
}
}
void
FramebufferObject::Unattach( GLenum attachment )
{
_GuardedBind();
GLenum type = GetAttachedType(attachment);
switch(type) {
case GL_NONE:
break;
case GL_RENDERBUFFER_EXT:
AttachRenderBuffer( 0, attachment );
break;
case GL_TEXTURE:
AttachTexture( GL_TEXTURE_2D, 0, attachment );
break;
default:
cerr << "FramebufferObject::unbind_attachment ERROR: Unknown attached resource type\n";
}
_GuardedUnbind();
}
void
FramebufferObject::UnattachAll()
{
int numAttachments = GetMaxColorAttachments();
for(int i = 0; i < numAttachments; ++i) {
Unattach( GL_COLOR_ATTACHMENT0_EXT + i );
}
}
GLint FramebufferObject::GetMaxColorAttachments()
{
GLint maxAttach = 0;
glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS_EXT, &maxAttach );
return maxAttach;
}
GLuint FramebufferObject::_GenerateFboId()
{
GLuint id = 0;
glGenFramebuffersEXT(1, &id);
return id;
}
void FramebufferObject::_GuardedBind()
{
// Only binds if m_fboId is different than the currently bound FBO
glGetIntegerv( GL_FRAMEBUFFER_BINDING_EXT, &m_savedFboId );
if (m_fboId != (GLuint)m_savedFboId) {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fboId);
}
}
void FramebufferObject::_GuardedUnbind()
{
// Returns FBO binding to the previously enabled FBO
if (m_fboId != (GLuint)m_savedFboId) {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, (GLuint)m_savedFboId);
}
}
void
FramebufferObject::_FramebufferTextureND( GLenum attachment, GLenum texTarget,
GLuint texId, int mipLevel,
int zSlice )
{
if (texTarget == GL_TEXTURE_1D) {
glFramebufferTexture1DEXT( GL_FRAMEBUFFER_EXT, attachment,
GL_TEXTURE_1D, texId, mipLevel );
}
else if (texTarget == GL_TEXTURE_3D) {
glFramebufferTexture3DEXT( GL_FRAMEBUFFER_EXT, attachment,
GL_TEXTURE_3D, texId, mipLevel, zSlice );
}
else {
// Default is GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_ARB, or cube faces
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, attachment,
texTarget, texId, mipLevel );
}
}
#ifndef NDEBUG
bool FramebufferObject::IsValid( ostream& ostr )
{
_GuardedBind();
bool isOK = false;
GLenum status;
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
switch(status) {
case GL_FRAMEBUFFER_COMPLETE_EXT: // Everything's OK
isOK = true;
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
ostr << "glift::CheckFramebufferStatus() ERROR:\n\t"
<< "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\n";
isOK = false;
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
ostr << "glift::CheckFramebufferStatus() ERROR:\n\t"
<< "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\n";
isOK = false;
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
ostr << "glift::CheckFramebufferStatus() ERROR:\n\t"
<< "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\n";
isOK = false;
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
ostr << "glift::CheckFramebufferStatus() ERROR:\n\t"
<< "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\n";
isOK = false;
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
ostr << "glift::CheckFramebufferStatus() ERROR:\n\t"
<< "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n";
isOK = false;
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
ostr << "glift::CheckFramebufferStatus() ERROR:\n\t"
<< "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\n";
isOK = false;
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
ostr << "glift::CheckFramebufferStatus() ERROR:\n\t"
<< "GL_FRAMEBUFFER_UNSUPPORTED_EXT\n";
isOK = false;
break;
default:
ostr << "glift::CheckFramebufferStatus() ERROR:\n\t"
<< "Unknown ERROR\n";
isOK = false;
}
_GuardedUnbind();
return isOK;
}
#endif // NDEBUG
/// Accessors
GLenum FramebufferObject::GetAttachedType( GLenum attachment )
{
// Returns GL_RENDERBUFFER_EXT or GL_TEXTURE
_GuardedBind();
GLint type = 0;
glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,
&type);
_GuardedUnbind();
return GLenum(type);
}
GLuint FramebufferObject::GetAttachedId( GLenum attachment )
{
_GuardedBind();
GLint id = 0;
glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
&id);
_GuardedUnbind();
return GLuint(id);
}
GLint FramebufferObject::GetAttachedMipLevel( GLenum attachment )
{
_GuardedBind();
GLint level = 0;
glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT,
&level);
_GuardedUnbind();
return level;
}
GLint FramebufferObject::GetAttachedCubeFace( GLenum attachment )
{
_GuardedBind();
GLint level = 0;
glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT,
&level);
_GuardedUnbind();
return level;
}
GLint FramebufferObject::GetAttachedZSlice( GLenum attachment )
{
_GuardedBind();
GLint slice = 0;
glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT,
&slice);
_GuardedUnbind();
return slice;
}
/*!
Renderbuffer Class. This class encapsulates the Renderbuffer OpenGL
object described in the FramebufferObject (FBO) OpenGL spec.
See the official spec at:
http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txt
for complete details.
A "Renderbuffer" is a chunk of GPU memory used by FramebufferObjects to
represent "traditional" framebuffer memory (depth, stencil, and color buffers).
By "traditional," we mean that the memory cannot be bound as a texture.
With respect to GPU shaders, Renderbuffer memory is "write-only." Framebuffer
operations such as alpha blending, depth test, alpha test, stencil test, etc.
read from this memory in post-fragement-shader (ROP) operations.
The most common use of Renderbuffers is to create depth and stencil buffers.
Note that as of 7/1/05, NVIDIA drivers to do not support stencil Renderbuffers.
Usage Notes:
1) "internalFormat" can be any of the following:
Valid OpenGL internal formats beginning with:
RGB, RGBA, DEPTH_COMPONENT
or a stencil buffer format (not currently supported
in NVIDIA drivers as of 7/1/05).
STENCIL_INDEX1_EXT
STENCIL_INDEX4_EXT
STENCIL_INDEX8_EXT
STENCIL_INDEX16_EXT
*/
class Renderbuffer
{
public:
/// Ctors/Dtors
Renderbuffer();
Renderbuffer(GLenum internalFormat, int width, int height);
~Renderbuffer();
void Bind();
void Unbind();
void Set(GLenum internalFormat, int width, int height);
GLuint GetId() const;
static GLint GetMaxSize();
private:
GLuint m_bufId;
static GLuint _CreateBufferId();
};
#include <iostream>
using namespace std;
Renderbuffer::Renderbuffer()
: m_bufId(_CreateBufferId())
{}
Renderbuffer::Renderbuffer(GLenum internalFormat, int width, int height)
: m_bufId(_CreateBufferId())
{
Set(internalFormat, width, height);
}
Renderbuffer::~Renderbuffer()
{
glDeleteRenderbuffersEXT(1, &m_bufId);
}
void Renderbuffer::Bind()
{
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_bufId);
}
void Renderbuffer::Unbind()
{
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
}
void Renderbuffer::Set(GLenum internalFormat, int width, int height)
{
int maxSize = Renderbuffer::GetMaxSize();
if (width > maxSize || height > maxSize ) {
cerr << "Renderbuffer::Renderbuffer() ERROR:\n\t"
<< "Size too big (" << width << ", " << height << ")\n";
return;
}
// Guarded bind
GLint savedId = 0;
glGetIntegerv( GL_RENDERBUFFER_BINDING_EXT, &savedId );
if (savedId != (GLint)m_bufId) {
Bind();
}
// Allocate memory for renderBuffer
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalFormat, width, height );
// Guarded unbind
if (savedId != (GLint)m_bufId) {
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, savedId);
}
}
GLuint Renderbuffer::GetId() const
{
return m_bufId;
}
GLint Renderbuffer::GetMaxSize()
{
GLint maxAttach = 0;
glGetIntegerv( GL_MAX_RENDERBUFFER_SIZE_EXT, &maxAttach );
return maxAttach;
}
GLuint Renderbuffer::_CreateBufferId()
{
GLuint id = 0;
glGenRenderbuffersEXT(1, &id);
return id;
}
#endif // __FRAMEBUFFERRENDERBUFFER_HPP__

View File

@ -0,0 +1,358 @@
/*
* This Code Was Created By Jeff Molofee 2000
* A HUGE Thanks To Fredric Echols For Cleaning Up
* And Optimizing This Code, Making It More Flexible!
* If You've Found This Code Useful, Please Let Me Know.
* Visit My Site At nehe.gamedev.net
*/
/*
* This file was taken from RakNet 4.082.
* Please see licenses/RakNet license.txt for the underlying license and related copyright.
*
* Modified work: Copyright (c) 2015-2020, SLikeSoft UG (haftungsbeschr<68>nkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include <windows.h> // Header File For Windows
#include <tchar.h> // Header File For Unicode conversion support
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
HDC hDC= nullptr; // Private GDI Device Context
HGLRC hRC= nullptr; // Permanent Rendering Context
HWND hWnd= nullptr; // Holds Our Window Handle
HINSTANCE hInstance; // Holds The Instance Of The Application
int windowWidth = 0, windowHeight = 0;
bool keys[256]; // Array Used For The Keyboard Routine
bool active=TRUE; // Window Active Flag Set To TRUE By Default
bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default
static void MessageBoxPrivate( HWND hWnd, const char* pMessage, const char* pTitle, int flags )
{
printf( "%s: %s\n", pTitle, pMessage );
}
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window
{
if (height==0) // Prevent A Divide By Zero By
{
height=1; // Making Height Equal One
}
glViewport(0,0,width,height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
int InitGL(GLvoid) // All Setup For OpenGL Goes Here
{
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
return TRUE; // Initialization Went OK
}
int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
return TRUE; // Everything Went OK
}
GLvoid KillGLWindow(GLvoid) // Properly Kill The Window
{
if (fullscreen) // Are We In Fullscreen Mode?
{
ChangeDisplaySettings(nullptr,0); // If So Switch Back To The Desktop
ShowCursor(TRUE); // Show Mouse Pointer
}
if (hRC) // Do We Have A Rendering Context?
{
if (!wglMakeCurrent(nullptr, nullptr)) // Are We Able To Release The DC And RC Contexts?
{
MessageBoxPrivate(nullptr,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC?
{
MessageBoxPrivate(nullptr,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
hRC= nullptr; // Set RC To nullptr
}
if (hDC && !ReleaseDC(hWnd,hDC)) // Are We Able To Release The DC
{
MessageBoxPrivate(nullptr,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hDC= nullptr; // Set DC To nullptr
}
if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window?
{
MessageBoxPrivate(nullptr,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hWnd= nullptr; // Set hWnd To nullptr
}
if (!UnregisterClass(_T("OpenGL"),hInstance)) // Are We Able To Unregister Class
{
MessageBoxPrivate(nullptr,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hInstance= nullptr; // Set hInstance To nullptr
}
}
/* This Code Creates Our OpenGL Window. Parameters Are: *
* title - Title To Appear At The Top Of The Window *
* width - Width Of The GL Window Or Fullscreen Mode *
* height - Height Of The GL Window Or Fullscreen Mode *
* bits - Number Of Bits To Use For Color (8/16/24/32) *
* fullscreenflag - Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE) */
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag, bool hideWindow=true)
{
GLuint PixelFormat; // Holds The Results After Searching For A Match
WNDCLASS wc; // Windows Class Structure
DWORD dwExStyle; // Window Extended Style
DWORD dwStyle; // Window Style
RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values
WindowRect.left=(long)0; // Set Left Value To 0
WindowRect.right=(long)width; // Set Right Value To Requested Width
WindowRect.top=(long)0; // Set Top Value To 0
WindowRect.bottom=(long)height; // Set Bottom Value To Requested Height
fullscreen=fullscreenflag; // Set The Global Fullscreen Flag
hInstance = GetModuleHandle(nullptr); // Grab An Instance For Our Window
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Size, And Own DC For Window.
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc Handles Messages
wc.cbClsExtra = 0; // No Extra Window Data
wc.cbWndExtra = 0; // No Extra Window Data
wc.hInstance = hInstance; // Set The Instance
wc.hIcon = LoadIcon(nullptr, IDI_WINLOGO); // Load The Default Icon
wc.hCursor = LoadCursor(nullptr, IDC_ARROW); // Load The Arrow Pointer
wc.hbrBackground = nullptr; // No Background Required For GL
wc.lpszMenuName = nullptr; // We Don't Want A Menu
wc.lpszClassName = _T("OpenGL"); // Set The Class Name
if (!RegisterClass(&wc)) // Attempt To Register The Window Class
{
MessageBoxPrivate(nullptr,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if (fullscreen) // Attempt Fullscreen Mode?
{
DEVMODE dmScreenSettings; // Device Mode
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared
dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure
dmScreenSettings.dmPelsWidth = width; // Selected Screen Width
dmScreenSettings.dmPelsHeight = height; // Selected Screen Height
dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
{
/*
// If The Mode Fails, Offer Two Options. Quit Or Use Windowed Mode.
if (MessageBoxPrivate(nullptr,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
{
fullscreen=FALSE; // Windowed Mode Selected. Fullscreen = FALSE
}
else
{
// Pop Up A Message Box Letting User Know The Program Is Closing.
MessageBoxPrivate(nullptr,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);
return FALSE; // Return FALSE
}
*/
fullscreen=FALSE;
}
}
if (fullscreen) // Are We Still In Fullscreen Mode?
{
dwExStyle=WS_EX_APPWINDOW; // Window Extended Style
dwStyle=WS_POPUP; // Windows Style
ShowCursor(FALSE); // Hide Mouse Pointer
}
else
{
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
dwStyle=WS_OVERLAPPEDWINDOW; // Windows Style
}
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size
// Create The Window
if (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window
_T("OpenGL"), // Class Name
_T("DXTCompress"), // Window Title
dwStyle | // Defined Window Style
WS_CLIPSIBLINGS | // Required Window Style
WS_CLIPCHILDREN, // Required Window Style
0, 0, // Window Position
WindowRect.right-WindowRect.left, // Calculate Window Width
WindowRect.bottom-WindowRect.top, // Calculate Window Height
nullptr, // No Parent Window
nullptr, // No Menu
hInstance, // Instance
nullptr))) // Dont Pass Anything To WM_CREATE
{
KillGLWindow(); // Reset The Display
MessageBoxPrivate(nullptr,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
static_cast<BYTE>(bits), // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
16, // 16Bit Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
if (!(hDC=GetDC(hWnd))) // Did We Get A Device Context?
{
KillGLWindow(); // Reset The Display
MessageBoxPrivate(nullptr,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) // Did Windows Find A Matching Pixel Format?
{
KillGLWindow(); // Reset The Display
MessageBoxPrivate(nullptr,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are We Able To Set The Pixel Format?
{
KillGLWindow(); // Reset The Display
MessageBoxPrivate(nullptr,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if (!(hRC=wglCreateContext(hDC))) // Are We Able To Get A Rendering Context?
{
KillGLWindow(); // Reset The Display
MessageBoxPrivate(nullptr,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if(!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context
{
KillGLWindow(); // Reset The Display
MessageBoxPrivate(nullptr,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if( hideWindow )
ShowWindow(hWnd,SW_HIDE); // Show The Window
else
ShowWindow(hWnd,SW_SHOW); // Show The Window
SetForegroundWindow(hWnd); // Slightly Higher Priority
SetFocus(hWnd); // Sets Keyboard Focus To The Window
ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen
if (!InitGL()) // Initialize Our Newly Created GL Window
{
KillGLWindow(); // Reset The Display
MessageBoxPrivate(nullptr,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
return TRUE; // Success
}
LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window
UINT uMsg, // Message For This Window
WPARAM wParam, // Additional Message Information
LPARAM lParam) // Additional Message Information
{
switch (uMsg) // Check For Windows Messages
{
case WM_ACTIVATE: // Watch For Window Activate Message
{
if (!HIWORD(wParam)) // Check Minimization State
{
active=TRUE; // Program Is Active
}
else
{
active=FALSE; // Program Is No Longer Active
}
return 0; // Return To The Message Loop
}
case WM_SYSCOMMAND: // Intercept System Commands
{
switch (wParam) // Check System Calls
{
case SC_SCREENSAVE: // Screensaver Trying To Start?
case SC_MONITORPOWER: // Monitor Trying To Enter Powersave?
return 0; // Prevent From Happening
}
break; // Exit
}
case WM_CLOSE: // Did We Receive A Close Message?
{
PostQuitMessage(0); // Send A Quit Message
return 0; // Jump Back
}
case WM_KEYDOWN: // Is A Key Being Held Down?
{
keys[wParam] = TRUE; // If So, Mark It As TRUE
return 0; // Jump Back
}
case WM_KEYUP: // Has A Key Been Released?
{
keys[wParam] = FALSE; // If So, Mark It As FALSE
return 0; // Jump Back
}
case WM_SIZE: // Resize The OpenGL Window
{
windowWidth = LOWORD(lParam);
windowHeight = HIWORD(lParam);
ReSizeGLScene(windowWidth, windowHeight); // LoWord=Width, HiWord=Height
return 0; // Jump Back
}
}
// Pass All Unhandled Messages To DefWindowProc
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

View File

@ -0,0 +1,571 @@
/*
Real-time DXT1 & YCoCg DXT5 compression (Cg 2.0)
Copyright (c) NVIDIA Corporation.
Written by: Ignacio Castano <icastano@nvidia.com>
Thanks to JMP van Waveren, Simon Green, Eric Werness, Simon Brown
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 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 SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
const char* pDXTCompressorShaderSource =
" \n"
"// vertex program \n"
"void compress_vp(float4 pos : POSITION, \n"
" float2 texcoord : TEXCOORD0, \n"
" out float4 hpos : POSITION, \n"
" out float2 o_texcoord : TEXCOORD0 \n"
" ) \n"
"{ \n"
" o_texcoord = texcoord; \n"
" hpos = pos; \n"
"} \n"
" \n"
"typedef unsigned int uint; \n"
"typedef unsigned int2 uint2; \n"
"typedef unsigned int3 uint3; \n"
"typedef unsigned int4 uint4; \n"
" \n"
"const float offset = 128.0 / 255.0; \n"
" \n"
"// Use dot product to minimize RMS instead absolute distance like in the CPU compressor. \n"
"float colorDistance(float3 c0, float3 c1) \n"
"{ \n"
" return dot(c0-c1, c0-c1); \n"
"} \n"
"float colorDistance(float2 c0, float2 c1) \n"
"{ \n"
" return dot(c0-c1, c0-c1); \n"
"} \n"
" \n"
" \n"
"void ExtractColorBlockRGB(out float3 col[16], sampler2D image, float2 texcoord, float2 imageSize) \n"
"{ \n"
" // use TXF instruction (integer coordinates with offset) \n"
" // note offsets must be constant \n"
" //int4 base = int4(wpos*4-2, 0, 0); \n"
" int4 base = int4(texcoord * imageSize - 1.5, 0, 0); \n"
" col[0] = tex2Dfetch(image, base, int2(0, 0)).rgb; \n"
" col[1] = tex2Dfetch(image, base, int2(1, 0)).rgb; \n"
" col[2] = tex2Dfetch(image, base, int2(2, 0)).rgb; \n"
" col[3] = tex2Dfetch(image, base, int2(3, 0)).rgb; \n"
" col[4] = tex2Dfetch(image, base, int2(0, 1)).rgb; \n"
" col[5] = tex2Dfetch(image, base, int2(1, 1)).rgb; \n"
" col[6] = tex2Dfetch(image, base, int2(2, 1)).rgb; \n"
" col[7] = tex2Dfetch(image, base, int2(3, 1)).rgb; \n"
" col[8] = tex2Dfetch(image, base, int2(0, 2)).rgb; \n"
" col[9] = tex2Dfetch(image, base, int2(1, 2)).rgb; \n"
" col[10] = tex2Dfetch(image, base, int2(2, 2)).rgb; \n"
" col[11] = tex2Dfetch(image, base, int2(3, 2)).rgb; \n"
" col[12] = tex2Dfetch(image, base, int2(0, 3)).rgb; \n"
" col[13] = tex2Dfetch(image, base, int2(1, 3)).rgb; \n"
" col[14] = tex2Dfetch(image, base, int2(2, 3)).rgb; \n"
" col[15] = tex2Dfetch(image, base, int2(3, 3)).rgb; \n"
"} \n"
" \n"
"void ExtractColorBlockBGR(out float3 col[16], sampler2D image, float2 texcoord, float2 imageSize) \n"
"{ \n"
" // use TXF instruction (integer coordinates with offset) \n"
" // note offsets must be constant \n"
" //int4 base = int4(wpos*4-2, 0, 0); \n"
" int4 base = int4(texcoord * imageSize - 1.5, 0, 0); \n"
" col[0] = tex2Dfetch(image, base, int2(0, 0)).bgr; \n"
" col[1] = tex2Dfetch(image, base, int2(1, 0)).bgr; \n"
" col[2] = tex2Dfetch(image, base, int2(2, 0)).bgr; \n"
" col[3] = tex2Dfetch(image, base, int2(3, 0)).bgr; \n"
" col[4] = tex2Dfetch(image, base, int2(0, 1)).bgr; \n"
" col[5] = tex2Dfetch(image, base, int2(1, 1)).bgr; \n"
" col[6] = tex2Dfetch(image, base, int2(2, 1)).bgr; \n"
" col[7] = tex2Dfetch(image, base, int2(3, 1)).bgr; \n"
" col[8] = tex2Dfetch(image, base, int2(0, 2)).bgr; \n"
" col[9] = tex2Dfetch(image, base, int2(1, 2)).bgr; \n"
" col[10] = tex2Dfetch(image, base, int2(2, 2)).bgr; \n"
" col[11] = tex2Dfetch(image, base, int2(3, 2)).bgr; \n"
" col[12] = tex2Dfetch(image, base, int2(0, 3)).bgr; \n"
" col[13] = tex2Dfetch(image, base, int2(1, 3)).bgr; \n"
" col[14] = tex2Dfetch(image, base, int2(2, 3)).bgr; \n"
" col[15] = tex2Dfetch(image, base, int2(3, 3)).bgr; \n"
"} \n"
" \n"
"float3 toYCoCg(float3 c) \n"
"{ \n"
" float Y = (c.r + 2 * c.g + c.b) * 0.25; \n"
" float Co = ( ( 2 * c.r - 2 * c.b ) * 0.25 + offset ); \n"
" float Cg = ( ( -c.r + 2 * c.g - c.b) * 0.25 + offset ); \n"
" \n"
" return float3(Y, Co, Cg); \n"
"} \n"
" \n"
"void ExtractColorBlockYCoCg_RGB(out float3 col[16], sampler2D image, float2 texcoord, float2 imageSize) \n"
"{ \n"
" // use TXF instruction (integer coordinates with offset) \n"
" // note offsets must be constant \n"
" //int4 base = int4(wpos*4-2, 0, 0); \n"
" int4 base = int4(texcoord * imageSize - 1.5, 0, 0); \n"
" col[0] = toYCoCg(tex2Dfetch(image, base, int2(0, 0)).rgb); \n"
" col[1] = toYCoCg(tex2Dfetch(image, base, int2(1, 0)).rgb); \n"
" col[2] = toYCoCg(tex2Dfetch(image, base, int2(2, 0)).rgb); \n"
" col[3] = toYCoCg(tex2Dfetch(image, base, int2(3, 0)).rgb); \n"
" col[4] = toYCoCg(tex2Dfetch(image, base, int2(0, 1)).rgb); \n"
" col[5] = toYCoCg(tex2Dfetch(image, base, int2(1, 1)).rgb); \n"
" col[6] = toYCoCg(tex2Dfetch(image, base, int2(2, 1)).rgb); \n"
" col[7] = toYCoCg(tex2Dfetch(image, base, int2(3, 1)).rgb); \n"
" col[8] = toYCoCg(tex2Dfetch(image, base, int2(0, 2)).rgb); \n"
" col[9] = toYCoCg(tex2Dfetch(image, base, int2(1, 2)).rgb); \n"
" col[10] = toYCoCg(tex2Dfetch(image, base, int2(2, 2)).rgb); \n"
" col[11] = toYCoCg(tex2Dfetch(image, base, int2(3, 2)).rgb); \n"
" col[12] = toYCoCg(tex2Dfetch(image, base, int2(0, 3)).rgb); \n"
" col[13] = toYCoCg(tex2Dfetch(image, base, int2(1, 3)).rgb); \n"
" col[14] = toYCoCg(tex2Dfetch(image, base, int2(2, 3)).rgb); \n"
" col[15] = toYCoCg(tex2Dfetch(image, base, int2(3, 3)).rgb); \n"
"} \n"
" \n"
"void ExtractColorBlockYCoCg_BGR(out float3 col[16], sampler2D image, float2 texcoord, float2 imageSize) \n"
"{ \n"
" // use TXF instruction (integer coordinates with offset) \n"
" // note offsets must be constant \n"
" //int4 base = int4(wpos*4-2, 0, 0); \n"
" int4 base = int4(texcoord * imageSize - 1.5, 0, 0); \n"
" col[0] = toYCoCg(tex2Dfetch(image, base, int2(0, 0)).bgr); \n"
" col[1] = toYCoCg(tex2Dfetch(image, base, int2(1, 0)).bgr); \n"
" col[2] = toYCoCg(tex2Dfetch(image, base, int2(2, 0)).bgr); \n"
" col[3] = toYCoCg(tex2Dfetch(image, base, int2(3, 0)).bgr); \n"
" col[4] = toYCoCg(tex2Dfetch(image, base, int2(0, 1)).bgr); \n"
" col[5] = toYCoCg(tex2Dfetch(image, base, int2(1, 1)).bgr); \n"
" col[6] = toYCoCg(tex2Dfetch(image, base, int2(2, 1)).bgr); \n"
" col[7] = toYCoCg(tex2Dfetch(image, base, int2(3, 1)).bgr); \n"
" col[8] = toYCoCg(tex2Dfetch(image, base, int2(0, 2)).bgr); \n"
" col[9] = toYCoCg(tex2Dfetch(image, base, int2(1, 2)).bgr); \n"
" col[10] = toYCoCg(tex2Dfetch(image, base, int2(2, 2)).bgr); \n"
" col[11] = toYCoCg(tex2Dfetch(image, base, int2(3, 2)).bgr); \n"
" col[12] = toYCoCg(tex2Dfetch(image, base, int2(0, 3)).bgr); \n"
" col[13] = toYCoCg(tex2Dfetch(image, base, int2(1, 3)).bgr); \n"
" col[14] = toYCoCg(tex2Dfetch(image, base, int2(2, 3)).bgr); \n"
" col[15] = toYCoCg(tex2Dfetch(image, base, int2(3, 3)).bgr); \n"
"} \n"
" \n"
"// find minimum and maximum colors based on bounding box in color space \n"
"void FindMinMaxColorsBox(float3 block[16], out float3 mincol, out float3 maxcol) \n"
"{ \n"
" mincol = block[0]; \n"
" maxcol = block[0]; \n"
" \n"
" for (int i = 1; i < 16; i++) { \n"
" mincol = min(mincol, block[i]); \n"
" maxcol = max(maxcol, block[i]); \n"
" } \n"
"} \n"
" \n"
"void InsetBBox(in out float3 mincol, in out float3 maxcol) \n"
"{ \n"
" float3 inset = (maxcol - mincol) / 16.0 - (8.0 / 255.0) / 16; \n"
" mincol = saturate(mincol + inset); \n"
" maxcol = saturate(maxcol - inset); \n"
"} \n"
"void InsetYBBox(in out float mincol, in out float maxcol) \n"
"{ \n"
" float inset = (maxcol - mincol) / 32.0 - (16.0 / 255.0) / 32.0; \n"
" mincol = saturate(mincol + inset); \n"
" maxcol = saturate(maxcol - inset); \n"
"} \n"
"void InsetCoCgBBox(in out float2 mincol, in out float2 maxcol) \n"
"{ \n"
" float2 inset = (maxcol - mincol) / 16.0 - (8.0 / 255.0) / 16; \n"
" mincol = saturate(mincol + inset); \n"
" maxcol = saturate(maxcol - inset); \n"
"} \n"
" \n"
"void SelectDiagonal(float3 block[16], in out float3 mincol, in out float3 maxcol) \n"
"{ \n"
" float3 center = (mincol + maxcol) * 0.5; \n"
" \n"
" float2 cov = 0; \n"
" for (int i = 0; i < 16; i++) \n"
" { \n"
" float3 t = block[i] - center; \n"
" cov.x += t.x * t.z; \n"
" cov.y += t.y * t.z; \n"
" } \n"
" \n"
" if (cov.x < 0) { \n"
" float temp = maxcol.x; \n"
" maxcol.x = mincol.x; \n"
" mincol.x = temp; \n"
" } \n"
" if (cov.y < 0) { \n"
" float temp = maxcol.y; \n"
" maxcol.y = mincol.y; \n"
" mincol.y = temp; \n"
" } \n"
"} \n"
" \n"
"float3 RoundAndExpand(float3 v, out uint w) \n"
"{ \n"
" int3 c = round(v * float3(31, 63, 31)); \n"
" w = (c.r << 11) | (c.g << 5) | c.b; \n"
" \n"
" c.rb = (c.rb << 3) | (c.rb >> 2); \n"
" c.g = (c.g << 2) | (c.g >> 4); \n"
" \n"
" return (float3)c * (1.0 / 255.0); \n"
"} \n"
" \n"
"uint EmitEndPointsDXT1(in out float3 mincol, in out float3 maxcol) \n"
"{ \n"
" uint2 output; \n"
" maxcol = RoundAndExpand(maxcol, output.x); \n"
" mincol = RoundAndExpand(mincol, output.y); \n"
" \n"
" // We have to do this in case we select an alternate diagonal. \n"
" if (output.x < output.y) \n"
" { \n"
" float3 tmp = mincol; \n"
" mincol = maxcol; \n"
" maxcol = tmp; \n"
" return output.y | (output.x << 16); \n"
" } \n"
" \n"
" return output.x | (output.y << 16); \n"
"} \n"
" \n"
"uint EmitIndicesDXT1(float3 block[16], float3 mincol, float3 maxcol) \n"
"{ \n"
" const float RGB_RANGE = 3; \n"
" \n"
" float3 dir = (maxcol - mincol); \n"
" float3 origin = maxcol + dir / (2.0 * RGB_RANGE); \n"
" dir /= dot(dir, dir); \n"
" \n"
" // Compute indices \n"
" uint indices = 0; \n"
" for (int i = 0; i < 16; i++) \n"
" { \n"
" uint index = saturate(dot(origin - block[i], dir)) * RGB_RANGE; \n"
" indices |= index << (i * 2); \n"
" } \n"
" \n"
" uint i0 = (indices & 0x55555555); \n"
" uint i1 = (indices & 0xAAAAAAAA) >> 1; \n"
" indices = ((i0 ^ i1) << 1) | i1; \n"
" \n"
" // Output indices \n"
" return indices; \n"
"} \n"
" \n"
"int ScaleYCoCg(float2 minColor, float2 maxColor) \n"
"{ \n"
" float2 m0 = abs(minColor - offset); \n"
" float2 m1 = abs(maxColor - offset); \n"
" \n"
" float m = max(max(m0.x, m0.y), max(m1.x, m1.y)); \n"
" \n"
" const float s0 = 64.0 / 255.0; \n"
" const float s1 = 32.0 / 255.0; \n"
" \n"
" int scale = 1; \n"
" if (m < s0) scale = 2; \n"
" if (m < s1) scale = 4; \n"
" \n"
" return scale; \n"
"} \n"
" \n"
"void SelectYCoCgDiagonal(const float3 block[16], in out float2 minColor, in out float2 maxColor) \n"
"{ \n"
" float2 mid = (maxColor + minColor) * 0.5; \n"
" \n"
" float cov = 0; \n"
" for (int i = 0; i < 16; i++) \n"
" { \n"
" float2 t = block[i].yz - mid; \n"
" cov += t.x * t.y; \n"
" } \n"
" if (cov < 0) { \n"
" float tmp = maxColor.y; \n"
" maxColor.y = minColor.y; \n"
" minColor.y = tmp; \n"
" } \n"
"} \n"
" \n"
" \n"
"uint EmitEndPointsYCoCgDXT5(in out float2 mincol, in out float2 maxcol, int scale) \n"
"{ \n"
" maxcol = (maxcol - offset) * scale + offset; \n"
" mincol = (mincol - offset) * scale + offset; \n"
" \n"
" InsetCoCgBBox(mincol, maxcol); \n"
" \n"
" maxcol = round(maxcol * float2(31, 63)); \n"
" mincol = round(mincol * float2(31, 63)); \n"
" \n"
" int2 imaxcol = maxcol; \n"
" int2 imincol = mincol; \n"
" \n"
" uint2 output; \n"
" output.x = (imaxcol.r << 11) | (imaxcol.g << 5) | (scale - 1); \n"
" output.y = (imincol.r << 11) | (imincol.g << 5) | (scale - 1); \n"
" \n"
" imaxcol.r = (imaxcol.r << 3) | (imaxcol.r >> 2); \n"
" imaxcol.g = (imaxcol.g << 2) | (imaxcol.g >> 4); \n"
" imincol.r = (imincol.r << 3) | (imincol.r >> 2); \n"
" imincol.g = (imincol.g << 2) | (imincol.g >> 4); \n"
" \n"
" maxcol = (float2)imaxcol * (1.0 / 255.0); \n"
" mincol = (float2)imincol * (1.0 / 255.0); \n"
" \n"
" // Undo rescale. \n"
" maxcol = (maxcol - offset) / scale + offset; \n"
" mincol = (mincol - offset) / scale + offset; \n"
" \n"
" return output.x | (output.y << 16); \n"
"} \n"
" \n"
"uint EmitIndicesYCoCgDXT5(float3 block[16], float2 mincol, float2 maxcol) \n"
"{ \n"
" const float COCG_RANGE = 3; \n"
" \n"
" float2 dir = (maxcol - mincol); \n"
" float2 origin = maxcol + dir / (2.0 * COCG_RANGE); \n"
" dir /= dot(dir, dir); \n"
" \n"
" // Compute indices \n"
" uint indices = 0; \n"
" for (int i = 0; i < 16; i++) \n"
" { \n"
" uint index = saturate(dot(origin - block[i].yz, dir)) * COCG_RANGE; \n"
" indices |= index << (i * 2); \n"
" } \n"
" \n"
" uint i0 = (indices & 0x55555555); \n"
" uint i1 = (indices & 0xAAAAAAAA) >> 1; \n"
" indices = ((i0 ^ i1) << 1) | i1; \n"
" \n"
" // Output indices \n"
" return indices; \n"
"} \n"
" \n"
"uint EmitAlphaEndPointsYCoCgDXT5(float mincol, float maxcol) \n"
"{ \n"
" uint c0 = round(mincol * 255); \n"
" uint c1 = round(maxcol * 255); \n"
" \n"
" return (c0 << 8) | c1; \n"
"} \n"
" \n"
"// Optimized index selection. \n"
"uint2 EmitAlphaIndicesYCoCgDXT5(float3 block[16], float minAlpha, float maxAlpha) \n"
"{ \n"
" const int ALPHA_RANGE = 7; \n"
" \n"
" float bias = maxAlpha + (maxAlpha - minAlpha) / (2.0 * ALPHA_RANGE); \n"
" float scale = 1.0f / (maxAlpha - minAlpha); \n"
" \n"
" uint2 indices = 0; \n"
" \n"
" for (int i = 0; i < 6; i++) \n"
" { \n"
" uint index = saturate((bias - block[i].x) * scale) * ALPHA_RANGE; \n"
" indices.x |= index << (3 * i); \n"
" } \n"
" \n"
" for (int i = 6; i < 16; i++) \n"
" { \n"
" uint index = saturate((bias - block[i].x) * scale) * ALPHA_RANGE; \n"
" indices.y |= index << (3 * i - 18); \n"
" } \n"
" \n"
" uint2 i0 = (indices >> 0) & 0x09249249; \n"
" uint2 i1 = (indices >> 1) & 0x09249249; \n"
" uint2 i2 = (indices >> 2) & 0x09249249; \n"
" \n"
" i2 ^= i0 & i1; \n"
" i1 ^= i0; \n"
" i0 ^= (i1 | i2); \n"
" \n"
" indices.x = (i2.x << 2) | (i1.x << 1) | i0.x; \n"
" indices.y = (((i2.y << 2) | (i1.y << 1) | i0.y) << 2) | (indices.x >> 16); \n"
" indices.x <<= 16; \n"
" \n"
" return indices; \n"
"} \n"
" \n"
"// compress a 4x4 block to DXT1 format \n"
"// integer version, renders to 2 x int32 buffer \n"
"uint4 compress_DXT1_RGBA_fp(float2 texcoord : TEXCOORD0, \n"
" uniform sampler2D image, \n"
" uniform float2 imageSize = { 512.0, 512.0 } \n"
" ) : COLOR \n"
"{ \n"
" // read block \n"
" float3 block[16]; \n"
" ExtractColorBlockRGB(block, image, texcoord, imageSize); \n"
" \n"
" // find min and max colors \n"
" float3 mincol, maxcol; \n"
" FindMinMaxColorsBox(block, mincol, maxcol); \n"
" \n"
" SelectDiagonal(block, mincol, maxcol); \n"
" \n"
" InsetBBox(mincol, maxcol); \n"
" \n"
" uint4 output; \n"
" output.x = EmitEndPointsDXT1(mincol, maxcol); \n"
" output.w = EmitIndicesDXT1(block, mincol, maxcol); \n"
" \n"
" return output; \n"
"} \n"
" \n"
"uint4 compress_DXT1_BGRA_fp(float2 texcoord : TEXCOORD0, \n"
" uniform sampler2D image, \n"
" uniform float2 imageSize = { 512.0, 512.0 } \n"
" ) : COLOR \n"
"{ \n"
" // read block \n"
" float3 block[16]; \n"
" ExtractColorBlockBGR(block, image, texcoord, imageSize); \n"
" \n"
" // find min and max colors \n"
" float3 mincol, maxcol; \n"
" FindMinMaxColorsBox(block, mincol, maxcol); \n"
" \n"
" SelectDiagonal(block, mincol, maxcol); \n"
" \n"
" InsetBBox(mincol, maxcol); \n"
" \n"
" uint4 output; \n"
" output.x = EmitEndPointsDXT1(mincol, maxcol); \n"
" output.w = EmitIndicesDXT1(block, mincol, maxcol); \n"
" \n"
" return output; \n"
"} \n"
" \n"
" \n"
"// compress a 4x4 block to YCoCg DXT5 format \n"
"// integer version, renders to 4 x int32 buffer \n"
"uint4 compress_YCoCgDXT5_RGBA_fp(float2 texcoord : TEXCOORD0, \n"
" uniform sampler2D image, \n"
" uniform float2 imageSize = { 512.0, 512.0 } \n"
" ) : COLOR \n"
"{ \n"
" //imageSize = tex2Dsize(image, texcoord); \n"
" \n"
" // read block \n"
" float3 block[16]; \n"
" ExtractColorBlockYCoCg_RGB(block, image, texcoord, imageSize); \n"
" \n"
" // find min and max colors \n"
" float3 mincol, maxcol; \n"
" FindMinMaxColorsBox(block, mincol, maxcol); \n"
" \n"
" SelectYCoCgDiagonal(block, mincol.yz, maxcol.yz); \n"
" \n"
" int scale = ScaleYCoCg(mincol.yz, maxcol.yz); \n"
" \n"
" // Output CoCg in DXT1 block. \n"
" uint4 output; \n"
" output.z = EmitEndPointsYCoCgDXT5(mincol.yz, maxcol.yz, scale); \n"
" output.w = EmitIndicesYCoCgDXT5(block, mincol.yz, maxcol.yz); \n"
" \n"
" InsetYBBox(mincol.x, maxcol.x); \n"
" \n"
" // Output Y in DXT5 alpha block. \n"
" output.x = EmitAlphaEndPointsYCoCgDXT5(mincol.x, maxcol.x); \n"
" \n"
" uint2 indices = EmitAlphaIndicesYCoCgDXT5(block, mincol.x, maxcol.x); \n"
" output.x |= indices.x; \n"
" output.y = indices.y; \n"
" \n"
" return output; \n"
"} \n"
" \n"
"uint4 compress_YCoCgDXT5_BGRA_fp(float2 texcoord : TEXCOORD0, \n"
" uniform sampler2D image, \n"
" uniform float2 imageSize = { 512.0, 512.0 } \n"
" ) : COLOR \n"
"{ \n"
" //imageSize = tex2Dsize(image, texcoord); \n"
" \n"
" // read block \n"
" float3 block[16]; \n"
" ExtractColorBlockYCoCg_BGR(block, image, texcoord, imageSize); \n"
" \n"
" // find min and max colors \n"
" float3 mincol, maxcol; \n"
" FindMinMaxColorsBox(block, mincol, maxcol); \n"
" \n"
" SelectYCoCgDiagonal(block, mincol.yz, maxcol.yz); \n"
" \n"
" int scale = ScaleYCoCg(mincol.yz, maxcol.yz); \n"
" \n"
" // Output CoCg in DXT1 block. \n"
" uint4 output; \n"
" output.z = EmitEndPointsYCoCgDXT5(mincol.yz, maxcol.yz, scale); \n"
" output.w = EmitIndicesYCoCgDXT5(block, mincol.yz, maxcol.yz); \n"
" \n"
" InsetYBBox(mincol.x, maxcol.x); \n"
" \n"
" // Output Y in DXT5 alpha block. \n"
" output.x = EmitAlphaEndPointsYCoCgDXT5(mincol.x, maxcol.x); \n"
" \n"
" uint2 indices = EmitAlphaIndicesYCoCgDXT5(block, mincol.x, maxcol.x); \n"
" output.x |= indices.x; \n"
" output.y = indices.y; \n"
" \n"
" return output; \n"
"} \n"
" \n"
"uniform bool reconstructColor = false; \n"
"uniform bool displayError = false; \n"
"uniform float errorScale = 4.0f; \n"
" \n"
"uniform sampler2D image : TEXUNIT0; \n"
"uniform sampler2D originalImage : TEXUNIT1; \n"
" \n"
"float4 display_fp(float2 texcoord : TEXCOORD0) : COLOR \n"
"{ \n"
" float4 rgba = tex2D(image, texcoord); \n"
" \n"
" if (reconstructColor) \n"
" { \n"
" float Y = rgba.a; \n"
" float scale = 1.0 / ((255.0 / 8.0) * rgba.b + 1); \n"
" float Co = (rgba.r - offset) * scale; \n"
" float Cg = (rgba.g - offset) * scale; \n"
" \n"
" float R = Y + Co - Cg; \n"
" float G = Y + Cg; \n"
" float B = Y - Co - Cg; \n"
" \n"
" rgba = float4(R, G, B, 1); \n"
" } \n"
" \n"
" if (displayError) \n"
" { \n"
" float3 originalColor = tex2D(originalImage, texcoord).rgb; \n"
" float3 diff = abs(rgba.rgb - originalColor) * errorScale; \n"
" return float4(diff, 1); \n"
" } \n"
" else \n"
" { \n"
" return rgba; \n"
" } \n"
"} \n"
" \n";

View File

@ -0,0 +1,194 @@
/*
* This file was taken from RakNet 4.082 without any modifications.
* Please see licenses/RakNet license.txt for the underlying license and related copyright.
*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "DXTCompressor.h"
/* ------------------------------------------------------------------------------------------------------------------------------------ */
bool LoadTGAFromFile( const char* pFilename, void **image, int* width, int* height )
{
typedef struct
{
char identsize;
char colourmaptype;
char imagetype;
unsigned short colourmapstart;
unsigned short colourmaplength;
char colourmapbits;
unsigned short xstart;
unsigned short ystart;
unsigned short width;
unsigned short height;
char bits;
char descriptor;
} TGA_HEADER;
// Open the file
FILE* pic;
if((pic=fopen( pFilename, "rb"))==NULL )
{
return false;
}
// Zero out the header
TGA_HEADER TGAheader;
memset(&TGAheader,0,sizeof(TGA_HEADER));
// Read the header
fread(&TGAheader.identsize,sizeof(char),1,pic);
fread(&TGAheader.colourmaptype,sizeof(char),1,pic);
fread(&TGAheader.imagetype,sizeof(char),1,pic);
fread(&TGAheader.colourmapstart,sizeof(unsigned short),1,pic);
fread(&TGAheader.colourmaplength,sizeof(unsigned short),1,pic);
fread(&TGAheader.colourmapbits,sizeof(char),1,pic);
fread(&TGAheader.xstart,sizeof(unsigned short),1,pic);
fread(&TGAheader.ystart,sizeof(unsigned short),1,pic);
fread(&TGAheader.width,sizeof(unsigned short),1,pic);
fread(&TGAheader.height,sizeof(unsigned short),1,pic);
fread(&TGAheader.bits,sizeof(char),1,pic);
fread(&TGAheader.descriptor,sizeof(char),1,pic);
*width = TGAheader.width;
*height = TGAheader.height;
int DataSize = TGAheader.width*TGAheader.height*4;
// Read the pixels
*image = new char[DataSize];
if ((TGAheader.descriptor>>5) & 1)
{
// Right side up
fread(*image, sizeof(char),DataSize, pic);
}
else
{
//Upside down
for (int row=TGAheader.height-1; row >=0; row--)
{
fread(((char*) (*image))+row*TGAheader.width*TGAheader.bits/8, TGAheader.bits/8, TGAheader.width, pic);
}
}
// Close the file
fclose(pic);
// TGA is stored on disk BGRA
// Endian swap bits so that the image is actually in RGBA format
if( TGAheader.bits == 32 )
{
unsigned char* pRunner = (unsigned char*)*image;
for( int i = 0; i < DataSize; i+=4 )
{
char color[4] =
{
pRunner[ 0 ],
pRunner[ 1 ],
pRunner[ 2 ],
pRunner[ 3 ],
};
pRunner[ 0 ] = color[ 2 ];
pRunner[ 1 ] = color[ 1 ];
pRunner[ 2 ] = color[ 0 ];
pRunner[ 3 ] = color[ 3 ];
pRunner += 4;
}
}
return true;
}
/* ------------------------------------------------------------------------------------------------------------------------------------ */
int main( int argc, const char* argv[] )
{
// Initialize the compressor
DXTCompressor::Initialize();
// Load sample .tga
void* pSourceData;
int w, h;
//bool bFileLoaded = LoadTGAFromFile( "1600x1200.tga", &pSourceData, &w, &h );
bool bFileLoaded = LoadTGAFromFile( "320x200.tga", &pSourceData, &w, &h );
if( bFileLoaded )
{
// Test performance
// const int numIterations = 100;
// for( int i = 0; i < numIterations; i++ )
// {
// // Compress the data
// void* pOutputData;
// int outputLength;
// bool bCompressSuccess = DXTCompressor::CompressRGBAImageData( DXT1, pSourceData, w, h, &pOutputData, &outputLength, false );
//
// // Clean up
// delete [] pOutputData;
// pOutputData = NULL;
// }
// Print total stats
// printf( "\n\n****Total stats on %d iterations****\n", numIterations );
// DXTCompressor::PrintPerformanceLog();
// Now test saving to DDS memory file
{
// Compress the data
// void* pCompressedOutput;
// int compressedOutputLength;
// bool bCompressSuccess = DXTCompressor::CompressRGBAImageData( DXT1, pSourceData, w, h, &pCompressedOutput, &compressedOutputLength, false );
char *outputData;
int bufferSize = DXTCompressor::GetBufferSize(DXT1,
w,
h);
int ddsHeaderSize = DXTCompressor::GetDDSHeaderSize();
outputData = (char*) malloc(bufferSize + ddsHeaderSize );
bool bCompressSuccess = DXTCompressor::CompressRGBAImageData(
DXT1,
pSourceData,
w,
h,
outputData+ddsHeaderSize, false );
if( bCompressSuccess )
{
// Save DDS file
// void* pOutputDDSFile;
// int outputDDSFileLength;
// DXTCompressor::WriteDDSMemoryFile( DXT1, w, h, pCompressedOutput, compressedOutputLength, &pOutputDDSFile, &outputDDSFileLength );
// Clean up
// delete [] pCompressedOutput;
// pCompressedOutput = NULL;
// delete [] pOutputDDSFile;
// pOutputDDSFile = NULL;
DXTCompressor::WriteDDSHeader(DXT1,
w,
h,
bufferSize,
outputData);
FILE *fp = fopen("DXTCompressorTGAtoDDS.dds", "wb");
fwrite(outputData,1,bufferSize + ddsHeaderSize,fp);
fclose(fp);
free(outputData);
}
}
}
// Shutdown the compressor
DXTCompressor::Shutdown();
return 0;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,128 @@
/**********************************************************************
Filename : FxGameDelegate.cpp
Content : Communication logic for CLIK GameDelegate
Created :
Authors : Prasad Silva
Copyright : (c) 2005-2009 Scaleform Corp. All Rights Reserved.
This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR ANY PURPOSE.
**********************************************************************/
#include "FxGameDelegate.h"
//
// Visitor to register callbacks
//
class AddCallbackVisitor : public FxDelegateHandler::CallbackProcessor
{
public:
AddCallbackVisitor(FxDelegateHandler* pthis, FxDelegate::CallbackHash* phash)
: pThis(pthis), pHash(phash) {}
void Process(const GString& methodName, FxDelegateHandler::CallbackFn method)
{
FxDelegate::CallbackDefn cbt;
cbt.pThis = pThis;
cbt.pCallback = method;
pHash->Add(methodName, cbt);
}
private:
FxDelegateHandler* pThis;
FxDelegate::CallbackHash* pHash;
};
//
// Visitor to unregister callbacks
//
class RemoveCallbackVisitor : public FxDelegateHandler::CallbackProcessor
{
public:
RemoveCallbackVisitor(FxDelegateHandler* pthis, FxDelegate::CallbackHash* phash)
: pThis(pthis), pHash(phash) {}
void Process(const GString& methodName, FxDelegateHandler::CallbackFn method)
{
GUNUSED(method);
pHash->Remove(methodName);
}
private:
FxDelegateHandler* pThis;
FxDelegate::CallbackHash* pHash;
};
//////////////////////////////////////////////////////////////////////////
FxDelegate::FxDelegate()
{
}
void FxDelegate::RegisterHandler(FxDelegateHandler* callback)
{
AddCallbackVisitor reg(callback, &Callbacks);
callback->Accept(&reg);
}
void FxDelegate::UnregisterHandler(FxDelegateHandler* callback)
{
RemoveCallbackVisitor reg(callback, &Callbacks);
callback->Accept(&reg);
}
void FxDelegate::Invoke(GFxMovieView* pmovieView, const char* methodName,
FxResponseArgsBase& args)
{
GFxValue* pv = NULL;
UInt nv = args.GetValues(&pv);
pv[0] = methodName;
pmovieView->Invoke("call", pv, nv);
}
void FxDelegate::Invoke2(GFxMovieView* pmovieView, const char* methodName,
FxResponseArgsBase& args)
{
GFxValue* pv = NULL;
UInt nv = args.GetValues(&pv);
pmovieView->Invoke(methodName, NULL, pv+1, nv-1);
}
void FxDelegate::Callback(GFxMovieView* pmovieView, const char* methodName, const GFxValue* args, UInt argCount)
{
// KevinJ: With calling ExternalInterface from flash, this is apparently obsolete now
// GASSERT(argCount > 0); // Must at least have a uid parameter
CallbackDefn* pcb = Callbacks.GetAlt(methodName);
if (pcb != NULL)
{
// KevinJ: With calling ExternalInterface from flash, this is apparently obsolete now
// FxDelegateArgs params(args[0],
// pcb->pThis,
// pmovieView,
// &args[1],
// argCount - 1);
FxDelegateArgs params(GFxValue(),
pcb->pThis,
pmovieView,
argCount>=1 ? &args[0] : NULL,
argCount);
pcb->pCallback(params);
}
}
//////////////////////////////////////////////////////////////////////////
void FxDelegateArgs::Respond(FxResponseArgsBase& params) const
{
GFxValue* pv = NULL;
UInt nv = params.GetValues(&pv);
pv[0] = ResponseID;
pMovieView->Invoke("respond", pv, nv);
}

View File

@ -0,0 +1,212 @@
/**********************************************************************
Filename : FxGameDelegate.h
Content : Communication logic for CLIK GameDelegate
Created :
Authors : Prasad Silva
Copyright : (c) 2005-2009 Scaleform Corp. All Rights Reserved.
This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR ANY PURPOSE.
**********************************************************************/
#ifndef INC_FxGameDelegateHandler_H
#define INC_FxGameDelegateHandler_H
#include "GFxPlayer.h"
#include "GMemory.h"
class FxDelegate;
class FxDelegateArgs;
//
// Interface implemented by all callback handlers. These handlers register
// callbacks with the FxGameDelegate.
//
class FxDelegateHandler : public GRefCountBase<FxDelegateHandler, GStat_Default_Mem>
{
public:
virtual ~FxDelegateHandler() {}
//
// All callback methods must have the following signature. To produce a response
// to the callback, push parameters to the game delegate.
//
typedef void (*CallbackFn)(const FxDelegateArgs& params);
//
// Interface implemented by callback registrars. The handler should
// pass the appropriate parameters to the Visit method.
//
class CallbackProcessor
{
public:
virtual ~CallbackProcessor() {}
virtual void Process(const GString& methodName, CallbackFn method) = 0;
};
//
// Callback registrar visitor method
// Implementations are expected to call the registrar's Process method
// for all callbacks.
//
virtual void Accept(CallbackProcessor* cbreg) = 0;
};
//////////////////////////////////////////////////////////////////////////
//
// Callback response parameters
// The
//
class FxResponseArgsBase
{
public:
virtual ~FxResponseArgsBase() {}
virtual UInt GetValues(GFxValue** pparams) = 0;
};
//
// Callback response that uses stack based storage
//
template <int N>
class FxResponseArgs : public FxResponseArgsBase
{
public:
FxResponseArgs() : Index(1) {}
void Add(const GFxValue& v)
{
if (Index > N)
{
GFC_DEBUG_WARNING(1, "Adding parameter out of bounds!");
return;
}
Values[Index++] = v;
}
UInt GetValues(GFxValue** pparams) { *pparams = Values; return Index; }
private:
GFxValue Values[N+1]; // Space for response data
UInt Index;
};
//
// Callback response that uses dynamically allocated storage
//
class FxResponseArgsList : public FxResponseArgsBase
{
public:
FxResponseArgsList() { Args.PushBack(GFxValue::VT_Null); } // Space for response data
void Add(const GFxValue& v) { Args.PushBack(v); }
UInt GetValues(GFxValue** pparams) { *pparams = &Args[0]; return (UInt)Args.GetSize(); }
private:
GArray<GFxValue> Args;
};
//////////////////////////////////////////////////////////////////////////
//
// Parameters passed to the callback handler
//
class FxDelegateArgs
{
public:
FxDelegateArgs(GFxValue responseid, FxDelegateHandler* pthis, GFxMovieView* pmovie,
const GFxValue* vals, UInt nargs) : ResponseID(responseid), pThis(pthis),
pMovieView(pmovie), Args(vals), NArgs(nargs) {}
void Respond(FxResponseArgsBase& params) const;
FxDelegateHandler* GetHandler() const { return pThis; }
GFxMovieView* GetMovie() const { return pMovieView; }
const GFxValue& operator[](UPInt i) const
{
GASSERT(i >= 0 && i < NArgs);
return Args[i];
}
UInt GetArgCount() const { return NArgs; }
private:
GFxValue ResponseID;
FxDelegateHandler* pThis;
GFxMovieView* pMovieView;
const GFxValue* Args;
UInt NArgs;
};
//////////////////////////////////////////////////////////////////////////
//
// Callback manager that marshals calls from ActionScript
//
class FxDelegate : public GFxExternalInterface
{
public:
//
// Callback target
//
struct CallbackDefn
{
GPtr<FxDelegateHandler> pThis;
FxDelegateHandler::CallbackFn pCallback;
};
//
// Callback hash
//
struct CallbackHashFunctor
{
UPInt operator()(const char* data) const
{
UPInt size = G_strlen(data);
return GString::BernsteinHashFunction(data, size);
}
};
typedef GHash<GString, CallbackDefn, CallbackHashFunctor> CallbackHash;
FxDelegate();
//
// Install and uninstall callbacks
//
void RegisterHandler(FxDelegateHandler* callback);
void UnregisterHandler(FxDelegateHandler* callback);
//
// Call a method registered with the AS2 GameDelegate instance
//
static void Invoke(GFxMovieView* pmovieView, const char* methodName,
FxResponseArgsBase& args);
// KevinJ: Workaround interface changes
static void Invoke2(GFxMovieView* pmovieView, const char* methodName,
FxResponseArgsBase& args);
//
// ExternalInterface callback entry point
//
void Callback(GFxMovieView* pmovieView, const char* methodName,
const GFxValue* args, UInt argCount);
private:
//
// Callbacks installed with the game delegate
//
CallbackHash Callbacks;
};
#endif // INC_FxGameDelegateHandler_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,183 @@
// This is a Demo of the Irrlicht Engine (c) 2006 by N.Gebhardt.
// This file is not documented.
/*
* This file was taken from RakNet 4.082.
* Please see licenses/RakNet license.txt for the underlying license and related copyright.
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
* Alternatively you are permitted to license the modifications under the zlib/libpng license.
*/
#ifndef __C_DEMO_H_INCLUDED__
#define __C_DEMO_H_INCLUDED__
#define USE_IRRKLANG
//#define USE_SDL_MIXER
// For windows 1.6 must be used for this demo unless you recompile the dlls and replace them,
// however it is untested on windows with later versions
// Include path in windows project by defaults assumes C:\irrlicht-1.6
// 1.6 or higher may be used in linux
// Get Irrlicht from http://irrlicht.sourceforge.net/ , it's a great engine
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4100) // unreferenced formal parameter
#pragma warning(disable:4127) // conditional expression is constant
#pragma warning(disable:4244) // type-conversion with possible loss of data
#pragma warning(disable:4458) // declaration of 'identifier' hides class member
#endif
#include <irrlicht.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#define IRRLICHT_MEDIA_PATH "IrrlichtMedia/"
#ifdef _WIN32__
#include "slikenet/WindowsIncludes.h" // Prevent 'fd_set' : 'struct' type redefinition
#include <windows.h>
#endif
using namespace irr;
// audio support
// Included in RakNet download with permission by Nikolaus Gebhardt
#ifdef USE_IRRKLANG
#if defined(_WIN32__) || defined(WIN32) || defined(_WIN32)
#include <irrKlang-1.1.3/irrKlang.h>
#else
#include "irrKlang.h"
#endif
#ifdef _IRR_WINDOWS_
#pragma comment (lib, "irrKlang-1.1.3/irrKlang.lib")
#endif
#endif
#ifdef USE_SDL_MIXER
# include <SDL/SDL.h>
# include <SDL/SDL_mixer.h>
#endif
const int CAMERA_COUNT = 7;
const float CAMERA_HEIGHT=50.0f;
const float SHOT_SPEED=.6f;
const float BALL_DIAMETER=25.0f;
// SLikeNet
#include "slikenetstuff.h"
#include "slikenet/DS_Multilist.h"
#include "slikenet/string.h"
#include "slikenet/time.h"
class CDemo : public IEventReceiver
{
public:
CDemo(bool fullscreen, bool music, bool shadows, bool additive, bool vsync, bool aa, video::E_DRIVER_TYPE driver, core::stringw &_playerName);
~CDemo();
void run();
virtual bool OnEvent(const SEvent& event);
IrrlichtDevice * GetDevice(void) const {return device;}
scene::ISceneManager* GetSceneManager(void) const {return device->getSceneManager();}
// RakNet: Control what animation is playing by what key is pressed on the remote system
bool IsKeyDown(EKEY_CODE keyCode) const;
bool IsMovementKeyDown(void) const;
// RakNet: Decouple the origin of the shot from the camera, so the network code can use this same graphical effect
SLNet::TimeMS shootFromOrigin(core::vector3df camPosition, core::vector3df camAt);
const core::aabbox3df& GetSyndeyBoundingBox(void) const;
void PlayDeathSound(core::vector3df position);
void EnableInput(bool enabled);
private:
void createLoadingScreen();
void loadSceneData();
void switchToNextScene();
void shoot();
void createParticleImpacts();
bool fullscreen;
bool music;
bool shadows;
bool additive;
bool vsync;
bool aa;
video::E_DRIVER_TYPE driverType;
core::stringw playerName;
IrrlichtDevice *device;
#ifdef USE_IRRKLANG
void startIrrKlang();
irrklang::ISoundEngine* irrKlang;
irrklang::ISoundSource* ballSound;
irrklang::ISoundSource* deathSound;
irrklang::ISoundSource* impactSound;
#endif
#ifdef USE_SDL_MIXER
void startSound();
void playSound(Mix_Chunk *);
void pollSound();
Mix_Music *stream;
Mix_Chunk *ballSound;
Mix_Chunk *impactSound;
#endif
struct SParticleImpact
{
u32 when;
core::vector3df pos;
core::vector3df outVector;
};
int currentScene;
video::SColor backColor;
gui::IGUIStaticText* statusText;
gui::IGUIInOutFader* inOutFader;
scene::IQ3LevelMesh* quakeLevelMesh;
scene::ISceneNode* quakeLevelNode;
scene::ISceneNode* skyboxNode;
scene::IAnimatedMeshSceneNode* model1;
scene::IAnimatedMeshSceneNode* model2;
scene::IParticleSystemSceneNode* campFire;
scene::IMetaTriangleSelector* metaSelector;
scene::ITriangleSelector* mapSelector;
s32 sceneStartTime;
s32 timeForThisScene;
core::array<SParticleImpact> Impacts;
// Per-tick game update for RakNet
void UpdateRakNet(void);
// Holds output messages
DataStructures::Multilist<ML_QUEUE, SLNet::RakString> outputMessages;
SLNet::TimeMS whenOutputMessageStarted;
void PushMessage(SLNet::RakString rs);
const char *GetCurrentMessage(void);
// We use this array to store the current state of each key
bool KeyIsDown[KEY_KEY_CODES_COUNT];
// Bounding box of syndney.md2, extended by BALL_DIAMETER/2 for collision against shots
core::aabbox3df syndeyBoundingBox;
void CalculateSyndeyBoundingBox(void);
bool isConnectedToNATPunchthroughServer;
};
#endif

View File

@ -0,0 +1,454 @@
// This is a Demo of the Irrlicht Engine (c) 2005-2008 by N.Gebhardt.
// This file is not documented.
/*
* This file was taken from RakNet 4.082.
* Please see licenses/RakNet license.txt for the underlying license and related copyright.
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschr<68>nkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "CMainMenu.h"
//! we want the lights follow the model when it's moving
class CSceneNodeAnimatorFollowBoundingBox : public irr::scene::ISceneNodeAnimator
{
public:
//! constructor
CSceneNodeAnimatorFollowBoundingBox(irr::scene::ISceneNode* tofollow,
const core::vector3df &offset, u32 frequency, s32 phase)
: Offset(offset), ToFollow(tofollow), Frequency(frequency), Phase(phase)
{
if (ToFollow)
ToFollow->grab();
}
//! destructor
virtual ~CSceneNodeAnimatorFollowBoundingBox()
{
if (ToFollow)
ToFollow->drop();
}
//! animates a scene node
virtual void animateNode(irr::scene::ISceneNode* node, u32 timeMs)
{
if (0 == node || node->getType() != irr::scene::ESNT_LIGHT)
return;
irr::scene::ILightSceneNode* l = (irr::scene::ILightSceneNode*) node;
if (ToFollow)
{
core::vector3df now = l->getPosition();
now += ToFollow->getBoundingBox().getCenter();
now += Offset;
l->setPosition(now);
}
irr::video::SColorHSL color;
irr::video::SColorf rgb(0);
color.Hue = ( (timeMs + Phase) % Frequency ) * ( 2.f * irr::core::PI / Frequency );
color.Saturation = 1.f;
color.Luminance = 0.5f;
color.toRGB(rgb);
video::SLight light = l->getLightData();
light.DiffuseColor = rgb;
l->setLightData(light);
}
virtual scene::ISceneNodeAnimator* createClone(scene::ISceneNode* node, scene::ISceneManager* newManager=0)
{
// unused parameter
(void)node;
(void)newManager;
return 0;
}
private:
core::vector3df Offset;
irr::scene::ISceneNode* ToFollow;
s32 Frequency;
s32 Phase;
};
CMainMenu::CMainMenu()
: startButton(0), MenuDevice(0), selected(2), start(false),
shadows(false), additive(false), transparent(true), vsync(false), aa(false),
#ifdef _DEBUG
fullscreen(false), music(false)
#else
fullscreen(true), music(true)
#endif
{
}
bool CMainMenu::run(bool& outFullscreen, bool& outMusic, bool& outShadows,
bool& outAdditive, bool& outVSync, bool& outAA,
video::E_DRIVER_TYPE& outDriver, core::stringw &playerName)
{
//video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;
//video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
video::E_DRIVER_TYPE driverType = video::EDT_BURNINGSVIDEO;
//video::E_DRIVER_TYPE driverType = video::EDT_SOFTWARE;
MenuDevice = createDevice(driverType,
core::dimension2d<u32>(512, 384), 16, false, false, false, this);
if (MenuDevice->getFileSystem()->existFile("irrlicht.dat"))
MenuDevice->getFileSystem()->addFileArchive("irrlicht.dat", true, true, io::EFAT_ZIP);
else
MenuDevice->getFileSystem()->addFileArchive("../../media/irrlicht.dat", true, true, io::EFAT_ZIP);
video::IVideoDriver* driver = MenuDevice->getVideoDriver();
scene::ISceneManager* smgr = MenuDevice->getSceneManager();
gui::IGUIEnvironment* guienv = MenuDevice->getGUIEnvironment();
core::stringw str = "Irrlicht Engine Demo v";
str += MenuDevice->getVersion();
MenuDevice->setWindowCaption(str.c_str());
// set new Skin
gui::IGUISkin* newskin = guienv->createSkin(gui::EGST_BURNING_SKIN);
guienv->setSkin(newskin);
newskin->drop();
// load font
gui::IGUIFont* font = guienv->getFont("../../media/fonthaettenschweiler.bmp");
if (font)
guienv->getSkin()->setFont(font);
// add images
const s32 leftX = 260;
// add tab control
gui::IGUITabControl* tabctrl = guienv->addTabControl(core::rect<int>(leftX,10,512-10,384-10),
0, true, true);
gui::IGUITab* optTab = tabctrl->addTab(L"Demo");
gui::IGUITab* aboutTab = tabctrl->addTab(L"About");
// add list box
gui::IGUIListBox* box = guienv->addListBox(core::rect<int>(10,10,220,120), optTab, 1);
box->addItem(L"OpenGL 1.5");
box->addItem(L"Direct3D 8.1");
box->addItem(L"Direct3D 9.0c");
box->addItem(L"Burning's Video 0.39");
box->addItem(L"Irrlicht Software Renderer 1.0");
box->setSelected(selected);
// add button
startButton = guienv->addButton(core::rect<int>(30,295,200,324), optTab, 2, L"Start Demo");
// add checkbox
const s32 d = 50;
guienv->addCheckBox(fullscreen, core::rect<int>(20,85+d,130,110+d),
optTab, 3, L"Fullscreen");
guienv->addCheckBox(music, core::rect<int>(135,85+d,245,110+d),
optTab, 4, L"Music & Sfx");
guienv->addCheckBox(shadows, core::rect<int>(20,110+d,135,135+d),
optTab, 5, L"Realtime shadows");
guienv->addCheckBox(additive, core::rect<int>(20,135+d,230,160+d),
optTab, 6, L"Old HW compatible blending");
guienv->addCheckBox(vsync, core::rect<int>(20,160+d,230,185+d),
optTab, 7, L"Vertical synchronisation");
guienv->addCheckBox(aa, core::rect<int>(135,110+d,245,135+d),
optTab, 8, L"Antialiasing");
// RakNet: Add edit box
nameEditBox=guienv->addEditBox(L"Your name here", core::rect<int>(20,185+d,230,210+d), true, optTab, 9);
// add about text
wchar_t* text2 = L"This is the tech demo of the Irrlicht engine. To start, "\
L"select a video driver which works best with your hardware and press 'Start Demo'.\n"\
L"What you currently see is displayed using the Burning Software Renderer (Thomas Alten).\n"\
L"The Irrlicht Engine was written by me, Nikolaus Gebhardt. The models, "\
L"maps and textures were placed at my disposal by B.Collins, M.Cook and J.Marton. The music was created by "\
L"M.Rohde and is played back by irrKlang.\n"\
L"For more informations, please visit the homepage of the Irrlicht engine:\nhttp://irrlicht.sourceforge.net\n"\
L"\n*** MULTIPLAYER UPDATE ***\n"\
L"Peer to peer multiplayer added in two days using RakNet.\n"\
L"For a description of the networking design, see included readme.txt .\n";
guienv->addStaticText(text2, core::rect<int>(10, 10, 230, 320),
true, true, aboutTab);
// add md2 model
scene::IAnimatedMesh* mesh = smgr->getMesh("../../media/faerie.md2");
scene::IAnimatedMeshSceneNode* modelNode = smgr->addAnimatedMeshSceneNode(mesh);
if (modelNode)
{
modelNode->setPosition( core::vector3df(0.f, 0.f, -5.f) );
modelNode->setMaterialTexture(0, driver->getTexture("../../media/faerie2.bmp"));
modelNode->setMaterialFlag(video::EMF_LIGHTING, true);
modelNode->getMaterial(0).Shininess = 28.f;
modelNode->getMaterial(0).NormalizeNormals = true;
modelNode->setMD2Animation(scene::EMAT_STAND);
}
// set ambient light (no sun light in the catacombs)
smgr->setAmbientLight( video::SColorf(0.f, 0.f, 0.f) );
scene::ISceneNodeAnimator* anim;
scene::ISceneNode* bill;
// add light 1 (sunset orange)
scene::ILightSceneNode* light1 =
smgr->addLightSceneNode(0, core::vector3df(10.f,10.f,0),
video::SColorf(0.86f, 0.38f, 0.05f), 200.0f);
// add fly circle animator to light 1
anim = smgr->createFlyCircleAnimator(core::vector3df(0,0,0),30.0f, -0.004f, core::vector3df(0.41f, 0.4f, 0.0f));
light1->addAnimator(anim);
anim->drop();
// let the lights follow the model...
anim = new CSceneNodeAnimatorFollowBoundingBox(modelNode, core::vector3df(0,16,0), 4000, 0);
//light1->addAnimator(anim);
anim->drop();
// attach billboard to the light
bill = smgr->addBillboardSceneNode(light1, core::dimension2d<f32>(10, 10));
bill->setMaterialFlag(video::EMF_LIGHTING, false);
bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
bill->setMaterialTexture(0, driver->getTexture("../../media/particlered.bmp"));
#if 1
// add light 2 (nearly red)
scene::ILightSceneNode* light2 =
smgr->addLightSceneNode(0, core::vector3df(0,1,0),
video::SColorf(0.9f, 1.0f, 0.f, 0.0f), 200.0f);
// add fly circle animator to light 1
anim = smgr->createFlyCircleAnimator(core::vector3df(0,0,0),30.0f, 0.004f, core::vector3df(0.41f, 0.4f, 0.0f));
light2->addAnimator(anim);
anim->drop();
// let the lights follow the model...
anim = new CSceneNodeAnimatorFollowBoundingBox( modelNode, core::vector3df(0,-8,0), 2000, 0 );
//light2->addAnimator(anim);
anim->drop();
// attach billboard to the light
bill = smgr->addBillboardSceneNode(light2, core::dimension2d<f32>(10, 10));
bill->setMaterialFlag(video::EMF_LIGHTING, false);
bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
bill->setMaterialTexture(0, driver->getTexture("../../media/particlered.bmp"));
// add light 3 (nearly blue)
scene::ILightSceneNode* light3 =
smgr->addLightSceneNode(0, core::vector3df(0,-1,0),
video::SColorf(0.f, 0.0f, 0.9f, 0.0f), 40.0f);
// add fly circle animator to light 2
anim = smgr->createFlyCircleAnimator(core::vector3df(0,0,0),40.0f, 0.004f, core::vector3df(-0.41f, -0.4f, 0.0f));
light3->addAnimator(anim);
anim->drop();
// let the lights follow the model...
anim = new CSceneNodeAnimatorFollowBoundingBox(modelNode, core::vector3df(0,8,0), 8000, 0);
//light3->addAnimator(anim);
anim->drop();
// attach billboard to the light
bill = smgr->addBillboardSceneNode(light3, core::dimension2d<f32>(10, 10));
if (bill)
{
bill->setMaterialFlag(video::EMF_LIGHTING, false);
bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
bill->setMaterialTexture(0, driver->getTexture("../../media/portal1.bmp"));
}
#endif
// create a fixed camera
smgr->addCameraSceneNode(0, core::vector3df(45,0,0), core::vector3df(0,0,10));
// irrlicht logo and background
// add irrlicht logo
bool oldMipMapState = driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
guienv->addImage(driver->getTexture("../../media/irrlichtlogo2.png"),
core::position2d<s32>(5,5));
video::ITexture* irrlichtBack = driver->getTexture("../../media/demoback.jpg");
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState);
// query original skin color
getOriginalSkinColor();
// set transparency
setTransparency();
// draw all
while(MenuDevice->run())
{
if (MenuDevice->isWindowActive())
{
driver->beginScene(false, true, video::SColor(0,0,0,0));
if (irrlichtBack)
driver->draw2DImage(irrlichtBack,
core::position2d<int>(0,0));
smgr->drawAll();
guienv->drawAll();
driver->endScene();
}
}
playerName=nameEditBox->getText();
MenuDevice->drop();
outFullscreen = fullscreen;
outMusic = music;
outShadows = shadows;
outAdditive = additive;
outVSync = vsync;
outAA = aa;
switch(selected)
{
case 0: outDriver = video::EDT_OPENGL; break;
case 1: outDriver = video::EDT_DIRECT3D8; break;
case 2: outDriver = video::EDT_DIRECT3D9; break;
case 3: outDriver = video::EDT_BURNINGSVIDEO; break;
case 4: outDriver = video::EDT_SOFTWARE; break;
}
return start;
}
bool CMainMenu::OnEvent(const SEvent& event)
{
if (event.EventType == EET_KEY_INPUT_EVENT &&
event.KeyInput.Key == KEY_F9 &&
event.KeyInput.PressedDown == false)
{
video::IImage* image = MenuDevice->getVideoDriver()->createScreenShot();
if (image)
{
MenuDevice->getVideoDriver()->writeImageToFile(image, "screenshot_main.jpg");
image->drop();
}
}
else
if (event.EventType == irr::EET_MOUSE_INPUT_EVENT &&
event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP )
{
core::rect<s32> r(event.MouseInput.X, event.MouseInput.Y, 0, 0);
gui::IGUIContextMenu* menu = MenuDevice->getGUIEnvironment()->addContextMenu(r, 0, 45);
menu->addItem(L"transparent menus", 666, transparent == false);
menu->addItem(L"solid menus", 666, transparent == true);
menu->addSeparator();
menu->addItem(L"Cancel");
}
else
if (event.EventType == EET_GUI_EVENT)
{
s32 id = event.GUIEvent.Caller->getID();
switch(id)
{
case 45: // context menu
if (event.GUIEvent.EventType == gui::EGET_MENU_ITEM_SELECTED)
{
s32 s = ((gui::IGUIContextMenu*)event.GUIEvent.Caller)->getSelectedItem();
if (s == 0 || s == 1)
{
transparent = !transparent;
setTransparency();
}
}
break;
case 1:
if (event.GUIEvent.EventType == gui::EGET_LISTBOX_CHANGED ||
event.GUIEvent.EventType == gui::EGET_LISTBOX_SELECTED_AGAIN)
{
selected = ((gui::IGUIListBox*)event.GUIEvent.Caller)->getSelected();
//startButton->setEnabled(selected != 4);
startButton->setEnabled(true);
}
break;
case 2:
if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED )
{
MenuDevice->closeDevice();
start = true;
}
case 3:
if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )
fullscreen = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();
break;
case 4:
if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )
music = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();
break;
case 5:
if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )
shadows = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();
break;
case 6:
if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )
additive = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();
break;
case 7:
if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )
vsync = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();
break;
case 8:
if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )
aa = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();
break;
}
}
return false;
}
void CMainMenu::getOriginalSkinColor()
{
irr::gui::IGUISkin * skin = MenuDevice->getGUIEnvironment()->getSkin();
for (s32 i=0; i<gui::EGDC_COUNT ; ++i)
{
SkinColor[i] = skin->getColor( (gui::EGUI_DEFAULT_COLOR)i );
}
}
void CMainMenu::setTransparency()
{
irr::gui::IGUISkin * skin = MenuDevice->getGUIEnvironment()->getSkin();
for (u32 i=0; i<gui::EGDC_COUNT ; ++i)
{
video::SColor col = SkinColor[i];
if (false == transparent)
col.setAlpha(255);
skin->setColor((gui::EGUI_DEFAULT_COLOR)i, col);
}
}

View File

@ -0,0 +1,79 @@
// This is a Demo of the Irrlicht Engine (c) 2005 by N.Gebhardt.
// This file is not documentated.
/*
* This file was taken from RakNet 4.082.
*
* Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
* Alternatively you are permitted to license the modifications under the zlib/libpng license.
*/
#ifndef __C_MAIN_MENU_H_INCLUDED__
#define __C_MAIN_MENU_H_INCLUDED__
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4100) // unreferenced formal parameter
#pragma warning(disable:4127) // conditional expression is constant
#pragma warning(disable:4244) // type-conversion with possible loss of data
#pragma warning(disable:4458) // declaration of 'identifier' hides class member
#endif
#include <irrlicht.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#ifdef _WIN32__
#include "slikenet/WindowsIncludes.h" // Prevent 'fd_set' : 'struct' type redefinition
#endif
#include "IGUIEditBox.h"
using namespace irr;
class CMainMenu : public IEventReceiver
{
public:
CMainMenu();
bool run(bool& outFullscreen, bool& outMusic, bool& outShadows,
bool& outAdditive, bool &outVSync, bool& outAA,
video::E_DRIVER_TYPE& outDriver,
core::stringw &playerName);
virtual bool OnEvent(const SEvent& event);
private:
void setTransparency();
gui::IGUIButton* startButton;
IrrlichtDevice *MenuDevice;
s32 selected;
bool start;
bool fullscreen;
bool music;
bool shadows;
bool additive;
bool transparent;
bool vsync;
bool aa;
scene::IAnimatedMesh* quakeLevel;
scene::ISceneNode* lightMapNode;
scene::ISceneNode* dynamicNode;
video::SColor SkinColor [ gui::EGDC_COUNT ];
void getOriginalSkinColor();
// RakNet: Store the edit box pointer so we can get the text later
irr::gui::IGUIEditBox* nameEditBox;
};
#endif

View File

@ -0,0 +1,40 @@
#
# This file was taken from RakNet 4.082.
# Please see licenses/RakNet license.txt for the underlying license and related copyright.
#
#
# Modified work: Copyright (c) 2017-2019, SLikeSoft UG (haftungsbeschränkt)
#
# This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
# license found in the license.txt file in the root directory of this source tree.
#
cmake_minimum_required(VERSION 2.6)
GETCURRENTFOLDER()
FINDIRRLICHT()
IF(WIN32 AND NOT UNIX)
project(${current_folder})
FILE(GLOB ALL_CPP_SRCS *.cpp "${SLikeNet_SOURCE_DIR}/Samples/PHPDirectoryServer2/PHPDirectoryServer2.cpp")
FILE(GLOB ALL_HEADER_SRCS *.h "${SLikeNet_SOURCE_DIR}/Samples/PHPDirectoryServer2/PHPDirectoryServer2.h")
FIXCOMPILEOPTIONS()
include_directories(${SLIKENET_HEADER_FILES} ./ ${IRRLICHT_INCLUDE_DIR})
add_executable(${current_folder} WIN32 ${ALL_CPP_SRCS} ${ALL_HEADER_SRCS})
target_link_libraries(${current_folder} ${SLIKENET_COMMON_LIBS})
set_target_properties(${current_folder} PROPERTIES PROJECT_GROUP "Samples/3D Demos")
ELSE(WIN32 AND NOT UNIX)
project(${current_folder})
FINDIRRKLANG()
FILE(GLOB ALL_CPP_SRCS *.cpp "${SLikeNet_SOURCE_DIR}/Samples/PHPDirectoryServer2/PHPDirectoryServer2.cpp")
FILE(GLOB ALL_HEADER_SRCS *.h "${SLikeNet_SOURCE_DIR}/Samples/PHPDirectoryServer2/PHPDirectoryServer2.h")
FIXCOMPILEOPTIONS()
include_directories(${SLIKENET_HEADER_FILES} ./ ${IRRLICHT_INCLUDE_DIR} ${IRRKLANG_INCLUDE_DIR})
add_executable(${current_folder} WIN32 ${ALL_CPP_SRCS} ${ALL_HEADER_SRCS})
target_link_libraries(${current_folder} ${SLIKENET_COMMON_LIBS} ${IRRLICHT_LIBRARIES} ${IRRKLANG_LIBRARIES})
ENDIF(WIN32 AND NOT UNIX)

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,326 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug - Unicode|Win32">
<Configuration>Debug - Unicode</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release - Unicode|Win32">
<Configuration>Release - Unicode</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Retail - Unicode|Win32">
<Configuration>Retail - Unicode</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Retail|Win32">
<Configuration>Retail</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>IrrlichtDemo</ProjectName>
<ProjectGuid>{DEDB9D76-00E6-4230-8612-0B5AC0F3D5E8}</ProjectGuid>
<RootNamespace>IrrlichtDemo</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Retail|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Retail - Unicode|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Retail|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Retail - Unicode|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'">$(ProjectDir)$(Configuration)\</OutDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Retail|Win32'">$(ProjectDir)$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'">$(ProjectDir)$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Retail - Unicode|Win32'">$(ProjectDir)$(Configuration)\</OutDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Retail|Win32'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Retail - Unicode|Win32'">false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>./;./../../Source/include;C:\irrlicht-1.8\include;./../../DependentExtensions/miniupnpc-1.5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINSOCK_DEPRECATED_NO_WARNINGS;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;IPHlpApi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX86</TargetMachine>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
</Link>
<PostBuildEvent>
<Command>copy C:\irrlicht-1.8\bin\Win32-VisualStudio\Irrlicht.dll .\</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>./;./../../Source/include;C:\irrlicht-1.8\include;./../../DependentExtensions/miniupnpc-1.5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINSOCK_DEPRECATED_NO_WARNINGS;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;IPHlpApi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX86</TargetMachine>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
</Link>
<PostBuildEvent>
<Command>copy C:\irrlicht-1.8\bin\Win32-VisualStudio\Irrlicht.dll .\</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>./;./../../Source/include;C:\irrlicht-1.8\include;./../../DependentExtensions/miniupnpc-1.5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINSOCK_DEPRECATED_NO_WARNINGS;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<MinimalRebuild>true</MinimalRebuild>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;IPHlpApi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
</Link>
<PostBuildEvent>
<Command>copy C:\irrlicht-1.8\bin\Win32-VisualStudio\Irrlicht.dll .\</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Retail|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>./;./../../Source/include;C:\irrlicht-1.8\include;./../../DependentExtensions/miniupnpc-1.5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINSOCK_DEPRECATED_NO_WARNINGS;_RETAIL;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<MinimalRebuild>true</MinimalRebuild>
<BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;IPHlpApi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
</Link>
<PostBuildEvent>
<Command>copy C:\irrlicht-1.8\bin\Win32-VisualStudio\Irrlicht.dll .\</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>./;./../../Source/include;C:\irrlicht-1.8\include;./../../DependentExtensions/miniupnpc-1.5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINSOCK_DEPRECATED_NO_WARNINGS;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<MinimalRebuild>true</MinimalRebuild>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;IPHlpApi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
</Link>
<PostBuildEvent>
<Command>copy C:\irrlicht-1.8\bin\Win32-VisualStudio\Irrlicht.dll .\</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Retail - Unicode|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>./;./../../Source/include;C:\irrlicht-1.8\include;./../../DependentExtensions/miniupnpc-1.5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINSOCK_DEPRECATED_NO_WARNINGS;_RETAIL;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<MinimalRebuild>true</MinimalRebuild>
<BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;IPHlpApi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
</Link>
<PostBuildEvent>
<Command>copy C:\irrlicht-1.8\bin\Win32-VisualStudio\Irrlicht.dll .\</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\miniupnpc-1.5\connecthostport.c" />
<ClCompile Include="..\miniupnpc-1.5\igd_desc_parse.c" />
<ClCompile Include="..\miniupnpc-1.5\minisoap.c" />
<ClCompile Include="..\miniupnpc-1.5\miniupnpc.c">
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4100;4389;4456;4706</DisableSpecificWarnings>
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'">4100;4389;4456;4706</DisableSpecificWarnings>
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'">4100;4389;4456;4706</DisableSpecificWarnings>
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Retail|Win32'">4100;4389;4456;4706</DisableSpecificWarnings>
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">4100;4389;4456;4706</DisableSpecificWarnings>
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Retail - Unicode|Win32'">4100;4389;4456;4706</DisableSpecificWarnings>
</ClCompile>
<ClCompile Include="..\miniupnpc-1.5\miniwget.c">
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4100</DisableSpecificWarnings>
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'">4100</DisableSpecificWarnings>
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'">4100</DisableSpecificWarnings>
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Retail|Win32'">4100</DisableSpecificWarnings>
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">4100</DisableSpecificWarnings>
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Retail - Unicode|Win32'">4100</DisableSpecificWarnings>
</ClCompile>
<ClCompile Include="..\miniupnpc-1.5\minixml.c" />
<ClCompile Include="..\miniupnpc-1.5\upnpcommands.c">
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4245</DisableSpecificWarnings>
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Debug - Unicode|Win32'">4245</DisableSpecificWarnings>
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Release - Unicode|Win32'">4245</DisableSpecificWarnings>
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Retail|Win32'">4245</DisableSpecificWarnings>
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">4245</DisableSpecificWarnings>
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Retail - Unicode|Win32'">4245</DisableSpecificWarnings>
</ClCompile>
<ClCompile Include="..\miniupnpc-1.5\upnperrors.c" />
<ClCompile Include="..\miniupnpc-1.5\upnpreplyparse.c" />
<ClCompile Include="CDemo.cpp" />
<ClCompile Include="CMainMenu.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="slikenetstuff.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\miniupnpc-1.5\connecthostport.h" />
<ClInclude Include="..\miniupnpc-1.5\igd_desc_parse.h" />
<ClInclude Include="..\miniupnpc-1.5\minisoap.h" />
<ClInclude Include="..\miniupnpc-1.5\miniupnpc.h" />
<ClInclude Include="..\miniupnpc-1.5\miniwget.h" />
<ClInclude Include="..\miniupnpc-1.5\minixml.h" />
<ClInclude Include="..\miniupnpc-1.5\upnpcommands.h" />
<ClInclude Include="..\miniupnpc-1.5\upnperrors.h" />
<ClInclude Include="..\miniupnpc-1.5\upnpreplyparse.h" />
<ClInclude Include="CDemo.h" />
<ClInclude Include="CMainMenu.h" />
<ClInclude Include="slikenetstuff.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Lib\LibStatic\LibStatic.vcxproj">
<Project>{6533bdae-0f0c-45e4-8fe7-add0f37fe063}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="miniupnpc-1.5">
<UniqueIdentifier>{3104a32d-ac4c-4587-9569-369d9223dbd2}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\miniupnpc-1.5\connecthostport.c">
<Filter>miniupnpc-1.5</Filter>
</ClCompile>
<ClCompile Include="..\miniupnpc-1.5\igd_desc_parse.c">
<Filter>miniupnpc-1.5</Filter>
</ClCompile>
<ClCompile Include="..\miniupnpc-1.5\minisoap.c">
<Filter>miniupnpc-1.5</Filter>
</ClCompile>
<ClCompile Include="..\miniupnpc-1.5\miniupnpc.c">
<Filter>miniupnpc-1.5</Filter>
</ClCompile>
<ClCompile Include="..\miniupnpc-1.5\miniwget.c">
<Filter>miniupnpc-1.5</Filter>
</ClCompile>
<ClCompile Include="..\miniupnpc-1.5\minixml.c">
<Filter>miniupnpc-1.5</Filter>
</ClCompile>
<ClCompile Include="..\miniupnpc-1.5\upnpcommands.c">
<Filter>miniupnpc-1.5</Filter>
</ClCompile>
<ClCompile Include="..\miniupnpc-1.5\upnperrors.c">
<Filter>miniupnpc-1.5</Filter>
</ClCompile>
<ClCompile Include="..\miniupnpc-1.5\upnpreplyparse.c">
<Filter>miniupnpc-1.5</Filter>
</ClCompile>
<ClCompile Include="CDemo.cpp" />
<ClCompile Include="CMainMenu.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="slikenetstuff.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\miniupnpc-1.5\connecthostport.h">
<Filter>miniupnpc-1.5</Filter>
</ClInclude>
<ClInclude Include="..\miniupnpc-1.5\igd_desc_parse.h">
<Filter>miniupnpc-1.5</Filter>
</ClInclude>
<ClInclude Include="..\miniupnpc-1.5\minisoap.h">
<Filter>miniupnpc-1.5</Filter>
</ClInclude>
<ClInclude Include="..\miniupnpc-1.5\miniupnpc.h">
<Filter>miniupnpc-1.5</Filter>
</ClInclude>
<ClInclude Include="..\miniupnpc-1.5\miniwget.h">
<Filter>miniupnpc-1.5</Filter>
</ClInclude>
<ClInclude Include="..\miniupnpc-1.5\minixml.h">
<Filter>miniupnpc-1.5</Filter>
</ClInclude>
<ClInclude Include="..\miniupnpc-1.5\upnpcommands.h">
<Filter>miniupnpc-1.5</Filter>
</ClInclude>
<ClInclude Include="..\miniupnpc-1.5\upnperrors.h">
<Filter>miniupnpc-1.5</Filter>
</ClInclude>
<ClInclude Include="..\miniupnpc-1.5\upnpreplyparse.h">
<Filter>miniupnpc-1.5</Filter>
</ClInclude>
<ClInclude Include="CDemo.h" />
<ClInclude Include="CMainMenu.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="slikenetstuff.h" />
</ItemGroup>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_layout_file>
<ActiveTarget name="" />
</CodeBlocks_layout_file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,74 @@
// This is a Demo of the Irrlicht Engine (c) 2005-2008 by N.Gebhardt.
// This file is not documented.
/*
* This file was taken from RakNet 4.082.
* Please see licenses/RakNet license.txt for the underlying license and related copyright.
*
* Modified work: Copyright (c) 2017-2018, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
* Alternatively you are permitted to license the modifications under the zlib/libpng license.
*/
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4100) // unreferenced formal parameter
#pragma warning(disable:4127) // conditional expression is constant
#pragma warning(disable:4244) // type-conversion with possible loss of data
#pragma warning(disable:4458) // declaration of 'identifier' hides class member
#endif
#include <irrlicht.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#ifdef _WIN32__
#include "slikenet/WindowsIncludes.h" // Prevent 'fd_set' : 'struct' type redefinition
#include <windows.h>
#endif
#include <stdio.h>
#include "CMainMenu.h"
#include "CDemo.h"
using namespace irr;
#ifdef _WIN32
#pragma comment(lib, "Irrlicht.lib")
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, INT )
#else
int main(int, char*[])
#endif
{
bool fullscreen = false;
bool music = true;
bool shadows = false;
bool additive = false;
bool vsync = false;
bool aa = false;
core::stringw playerName;
#ifndef _IRR_WINDOWS_
video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
#else
video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;
#endif
CMainMenu menu;
//#ifndef _DEBUG
if (menu.run(fullscreen, music, shadows, additive, vsync, aa, driverType, playerName))
//#endif
{
CDemo demo(fullscreen, music, shadows, additive, vsync, aa, driverType, playerName);
demo.run();
}
return 0;
}

View File

@ -0,0 +1,16 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by resscript.rc
//
#define IDI_ICON1 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -0,0 +1,72 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Deutsch (<28>sterreich) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEA)
#ifdef _WIN32
LANGUAGE LANG_GERMAN, SUBLANG_GERMAN_AUSTRIAN
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON DISCARDABLE "icon.ico"
#endif // Deutsch (<28>sterreich) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -0,0 +1,528 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2016-2020, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "slikenetstuff.h"
#include "slikenet/NetworkIDManager.h"
#include "CDemo.h"
#include "slikenet/time.h"
#include "slikenet/GetTime.h"
#include "slikenet/SocketLayer.h"
#include "slikenet/linux_adapter.h"
#include "slikenet/osx_adapter.h"
using namespace SLNet;
RakPeerInterface *rakPeer;
NetworkIDManager *networkIDManager;
ReplicaManager3Irrlicht *irrlichtReplicaManager3;
NatPunchthroughClient *natPunchthroughClient;
CloudClient *cloudClient;
SLNet::FullyConnectedMesh2 *fullyConnectedMesh2;
PlayerReplica *playerReplica;
/*
class DebugBoxSceneNode : public scene::ISceneNode
{
public:
DebugBoxSceneNode(scene::ISceneNode* parent,
scene::ISceneManager* mgr,
s32 id = -1);
virtual const core::aabbox3d<f32>& getBoundingBox() const;
virtual void OnRegisterSceneNode();
virtual void render();
CDemo *demo;
};
DebugBoxSceneNode::DebugBoxSceneNode(
scene::ISceneNode* parent,
scene::ISceneManager* mgr,
s32 id)
: scene::ISceneNode(parent, mgr, id)
{
#ifdef _DEBUG
setDebugName("DebugBoxSceneNode");
#endif
setAutomaticCulling(scene::EAC_OFF);
}
const core::aabbox3d<f32>& DebugBoxSceneNode::getBoundingBox() const
{
return demo->GetSyndeyBoundingBox();
}
void DebugBoxSceneNode::OnRegisterSceneNode()
{
if (IsVisible)
demo->GetSceneManager()->registerNodeForRendering(this, scene::ESNRP_SOLID);
}
void DebugBoxSceneNode::render()
{
if (DebugDataVisible)
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
video::SMaterial m;
m.Lighting = false;
demo->GetDevice()->getVideoDriver()->setMaterial(m);
demo->GetDevice()->getVideoDriver()->draw3DBox(demo->GetSyndeyBoundingBox());
}
}
*/
DataStructures::List<PlayerReplica*> PlayerReplica::playerList;
// Take this many milliseconds to move the visible position to the real position
static const float INTERP_TIME_MS=100.0f;
void InstantiateRakNetClasses(void)
{
static const int MAX_PLAYERS=32;
static const unsigned short TCP_PORT=0;
static const SLNet::TimeMS UDP_SLEEP_TIMER=30;
// Basis of all UDP communications
rakPeer= SLNet::RakPeerInterface::GetInstance();
// Using fixed port so we can use AdvertiseSystem and connect on the LAN if the server is not available.
SLNet::SocketDescriptor sd(1234,0);
sd.socketFamily=AF_INET; // Only IPV4 supports broadcast on 255.255.255.255
while (IRNS2_Berkley::IsPortInUse(sd.port, sd.hostAddress, sd.socketFamily, SOCK_DGRAM)==true)
sd.port++;
// +1 is for the connection to the NAT punchthrough server
SLNET_VERIFY(rakPeer->Startup(MAX_PLAYERS+1,&sd,1) == SLNet::RAKNET_STARTED);
rakPeer->SetMaximumIncomingConnections(MAX_PLAYERS);
// Fast disconnect for easier testing of host migration
rakPeer->SetTimeoutTime(5000,UNASSIGNED_SYSTEM_ADDRESS);
// ReplicaManager3 replies on NetworkIDManager. It assigns numbers to objects so they can be looked up over the network
// It's a class in case you wanted to have multiple worlds, then you could have multiple instances of NetworkIDManager
networkIDManager=new NetworkIDManager;
// Automatically sends around new / deleted / changed game objects
irrlichtReplicaManager3=new ReplicaManager3Irrlicht;
irrlichtReplicaManager3->SetNetworkIDManager(networkIDManager);
rakPeer->AttachPlugin(irrlichtReplicaManager3);
// Automatically destroy connections, but don't create them so we have more control over when a system is considered ready to play
irrlichtReplicaManager3->SetAutoManageConnections(false,true);
// Create and register the network object that represents the player
playerReplica = new PlayerReplica;
irrlichtReplicaManager3->Reference(playerReplica);
// Lets you connect through routers
natPunchthroughClient=new NatPunchthroughClient;
rakPeer->AttachPlugin(natPunchthroughClient);
// Uploads game instance, basically client half of a directory server
// Server code is in NATCompleteServer sample
cloudClient=new CloudClient;
rakPeer->AttachPlugin(cloudClient);
fullyConnectedMesh2=new FullyConnectedMesh2;
fullyConnectedMesh2->SetAutoparticipateConnections(false);
fullyConnectedMesh2->SetConnectOnNewRemoteConnection(false, "");
rakPeer->AttachPlugin(fullyConnectedMesh2);
// Connect to the NAT punchthrough server
SLNET_VERIFY(rakPeer->Connect(DEFAULT_NAT_PUNCHTHROUGH_FACILITATOR_IP, DEFAULT_NAT_PUNCHTHROUGH_FACILITATOR_PORT,0,0) == CONNECTION_ATTEMPT_STARTED);
// Advertise ourselves on the lAN if the NAT punchthrough server is not available
//for (int i=0; i < 8; i++)
// rakPeer->AdvertiseSystem("255.255.255.255", 1234+i, 0,0,0);
}
void DeinitializeRakNetClasses(void)
{
// Shutdown so the server knows we stopped
rakPeer->Shutdown(100,0);
SLNet::RakPeerInterface::DestroyInstance(rakPeer);
delete networkIDManager;
delete irrlichtReplicaManager3;
delete natPunchthroughClient;
delete cloudClient;
delete fullyConnectedMesh2;
// ReplicaManager3 deletes all referenced objects, including this one
//playerReplica->PreDestruction(0);
//delete playerReplica;
}
BaseIrrlichtReplica::BaseIrrlichtReplica()
{
}
BaseIrrlichtReplica::~BaseIrrlichtReplica()
{
}
void BaseIrrlichtReplica::SerializeConstruction(SLNet::BitStream *constructionBitstream, SLNet::Connection_RM3 *destinationConnection)
{
// unused parameters
(void)destinationConnection;
constructionBitstream->Write(position);
}
bool BaseIrrlichtReplica::DeserializeConstruction(SLNet::BitStream *constructionBitstream, SLNet::Connection_RM3 *sourceConnection)
{
// unused parameters
(void)sourceConnection;
constructionBitstream->Read(position);
return true;
}
RM3SerializationResult BaseIrrlichtReplica::Serialize(SLNet::SerializeParameters *serializeParameters)
{
// unused parameters
(void)serializeParameters;
return RM3SR_BROADCAST_IDENTICALLY;
}
void BaseIrrlichtReplica::Deserialize(SLNet::DeserializeParameters *deserializeParameters)
{
// unused parameters
(void)deserializeParameters;
}
void BaseIrrlichtReplica::Update(SLNet::TimeMS curTime)
{
// unused parameters
(void)curTime;
}
PlayerReplica::PlayerReplica()
{
model=0;
rotationDeltaPerMS=0.0f;
isMoving=false;
deathTimeout=0;
lastUpdate= SLNet::GetTimeMS();
playerList.Push(this,_FILE_AND_LINE_);
}
PlayerReplica::~PlayerReplica()
{
unsigned int index = playerList.GetIndexOf(this);
if (index != (unsigned int) -1)
playerList.RemoveAtIndexFast(index);
}
void PlayerReplica::WriteAllocationID(SLNet::Connection_RM3 *destinationConnection, SLNet::BitStream *allocationIdBitstream) const
{
// unused parameters
(void)destinationConnection;
allocationIdBitstream->Write(SLNet::RakString("PlayerReplica"));
}
void PlayerReplica::SerializeConstruction(SLNet::BitStream *constructionBitstream, SLNet::Connection_RM3 *destinationConnection)
{
BaseIrrlichtReplica::SerializeConstruction(constructionBitstream, destinationConnection);
constructionBitstream->Write(rotationAroundYAxis);
constructionBitstream->Write(playerName);
constructionBitstream->Write(IsDead());
}
bool PlayerReplica::DeserializeConstruction(SLNet::BitStream *constructionBitstream, SLNet::Connection_RM3 *sourceConnection)
{
if (!BaseIrrlichtReplica::DeserializeConstruction(constructionBitstream, sourceConnection))
return false;
constructionBitstream->Read(rotationAroundYAxis);
constructionBitstream->Read(playerName);
constructionBitstream->Read(isDead);
return true;
}
void PlayerReplica::PostDeserializeConstruction(SLNet::BitStream *constructionBitstream, SLNet::Connection_RM3 *destinationConnection)
{
// unused parameters
(void)constructionBitstream;
(void)destinationConnection;
// Object was remotely created and all data loaded. Now we can make the object visible
scene::IAnimatedMesh* mesh = 0;
scene::ISceneManager *sm = demo->GetSceneManager();
mesh = sm->getMesh(IRRLICHT_MEDIA_PATH "sydney.md2");
model = sm->addAnimatedMeshSceneNode(mesh, 0);
// DebugBoxSceneNode * debugBox = new DebugBoxSceneNode(model,sm);
// debugBox->demo=demo;
// debugBox->setDebugDataVisible(true);
model->setPosition(position);
model->setRotation(core::vector3df(0, rotationAroundYAxis, 0));
model->setScale(core::vector3df(2,2,2));
model->setMD2Animation(scene::EMAT_STAND);
curAnim=scene::EMAT_STAND;
model->setMaterialTexture(0, demo->GetDevice()->getVideoDriver()->getTexture(IRRLICHT_MEDIA_PATH "sydney.bmp"));
model->setMaterialFlag(video::EMF_LIGHTING, true);
model->addShadowVolumeSceneNode();
model->setAutomaticCulling ( scene::EAC_BOX );
model->setVisible(true);
model->setAnimationEndCallback(this);
wchar_t playerNameWChar[1024];
mbstowcs_s(nullptr, playerNameWChar, playerName.C_String(), 1023);
scene::IBillboardSceneNode *bb = sm->addBillboardTextSceneNode(0, playerNameWChar, model);
bb->setSize(core::dimension2df(40,20));
bb->setPosition(core::vector3df(0,model->getBoundingBox().MaxEdge.Y+bb->getBoundingBox().MaxEdge.Y-bb->getBoundingBox().MinEdge.Y+5.0f,0));
bb->setColor(video::SColor(255,255,128,128), video::SColor(255,255,128,128));
}
void PlayerReplica::PreDestruction(SLNet::Connection_RM3 *sourceConnection)
{
// unused parameters
(void)sourceConnection;
if (model)
model->remove();
}
RM3SerializationResult PlayerReplica::Serialize(SLNet::SerializeParameters *serializeParameters)
{
BaseIrrlichtReplica::Serialize(serializeParameters);
serializeParameters->outputBitstream[0].Write(position);
serializeParameters->outputBitstream[0].Write(rotationAroundYAxis);
serializeParameters->outputBitstream[0].Write(isMoving);
serializeParameters->outputBitstream[0].Write(IsDead());
return RM3SR_BROADCAST_IDENTICALLY;
}
void PlayerReplica::Deserialize(SLNet::DeserializeParameters *deserializeParameters)
{
BaseIrrlichtReplica::Deserialize(deserializeParameters);
deserializeParameters->serializationBitstream[0].Read(position);
deserializeParameters->serializationBitstream[0].Read(rotationAroundYAxis);
deserializeParameters->serializationBitstream[0].Read(isMoving);
bool wasDead=isDead;
deserializeParameters->serializationBitstream[0].Read(isDead);
if (isDead==true && wasDead==false)
{
demo->PlayDeathSound(position);
}
core::vector3df positionOffset;
positionOffset=position-model->getPosition();
positionDeltaPerMS = positionOffset / INTERP_TIME_MS;
float rotationOffset;
rotationOffset=GetRotationDifference(rotationAroundYAxis,model->getRotation().Y);
rotationDeltaPerMS = rotationOffset / INTERP_TIME_MS;
interpEndTime = SLNet::GetTimeMS() + (SLNet::TimeMS) INTERP_TIME_MS;
}
void PlayerReplica::Update(SLNet::TimeMS curTime)
{
// Is a locally created object?
if (creatingSystemGUID==rakPeer->GetGuidFromSystemAddress(SLNet::UNASSIGNED_SYSTEM_ADDRESS))
{
// Local player has no mesh to interpolate
// Input our camera position as our player position
playerReplica->position=demo->GetSceneManager()->getActiveCamera()->getPosition()-irr::core::vector3df(0,CAMERA_HEIGHT,0);
playerReplica->rotationAroundYAxis=demo->GetSceneManager()->getActiveCamera()->getRotation().Y-90.0f;
isMoving=demo->IsMovementKeyDown();
// Ack, makes the screen messed up and the mouse move off the window
// Find another way to keep the dead player from moving
// demo->EnableInput(IsDead()==false);
return;
}
// Update interpolation
SLNet::TimeMS elapsed = curTime-lastUpdate;
if (elapsed<=1)
return;
if (elapsed>100)
elapsed=100;
lastUpdate=curTime;
irr::core::vector3df curPositionDelta = position-model->getPosition();
irr::core::vector3df interpThisTick = positionDeltaPerMS*(float) elapsed;
if (curTime < interpEndTime && interpThisTick.getLengthSQ() < curPositionDelta.getLengthSQ())
{
model->setPosition(model->getPosition()+positionDeltaPerMS*(float) elapsed);
}
else
{
model->setPosition(position);
}
float curRotationDelta = GetRotationDifference(rotationAroundYAxis,model->getRotation().Y);
float interpThisTickRotation = rotationDeltaPerMS*(float)elapsed;
if (curTime < interpEndTime && fabs(interpThisTickRotation) < fabs(curRotationDelta))
{
model->setRotation(model->getRotation()+core::vector3df(0,interpThisTickRotation,0));
}
else
{
model->setRotation(core::vector3df(0,rotationAroundYAxis,0));
}
if (isDead)
{
UpdateAnimation(scene::EMAT_DEATH_FALLBACK);
model->setLoopMode(false);
}
else if (curAnim!=scene::EMAT_ATTACK)
{
if (isMoving)
{
UpdateAnimation(scene::EMAT_RUN);
model->setLoopMode(true);
}
else
{
UpdateAnimation(scene::EMAT_STAND);
model->setLoopMode(true);
}
}
}
void PlayerReplica::UpdateAnimation(irr::scene::EMD2_ANIMATION_TYPE anim)
{
if (anim!=curAnim)
model->setMD2Animation(anim);
curAnim=anim;
}
float PlayerReplica::GetRotationDifference(float r1, float r2)
{
float diff = r1-r2;
while (diff>180.0f)
diff-=360.0f;
while (diff<-180.0f)
diff+=360.0f;
return diff;
}
void PlayerReplica::OnAnimationEnd(scene::IAnimatedMeshSceneNode* node)
{
// unused parameters
(void)node;
if (curAnim==scene::EMAT_ATTACK)
{
if (isMoving)
{
UpdateAnimation(scene::EMAT_RUN);
model->setLoopMode(true);
}
else
{
UpdateAnimation(scene::EMAT_STAND);
model->setLoopMode(true);
}
}
}
void PlayerReplica::PlayAttackAnimation(void)
{
if (isDead==false)
{
UpdateAnimation(scene::EMAT_ATTACK);
model->setLoopMode(false);
}
}
bool PlayerReplica::IsDead(void) const
{
return deathTimeout > SLNet::GetTimeMS();
}
BallReplica::BallReplica()
{
creationTime= SLNet::GetTimeMS();
}
BallReplica::~BallReplica()
{
}
void BallReplica::WriteAllocationID(SLNet::Connection_RM3 *destinationConnection, SLNet::BitStream *allocationIdBitstream) const
{
// unused parameters
(void)destinationConnection;
allocationIdBitstream->Write(SLNet::RakString("BallReplica"));
}
void BallReplica::SerializeConstruction(SLNet::BitStream *constructionBitstream, SLNet::Connection_RM3 *destinationConnection)
{
BaseIrrlichtReplica::SerializeConstruction(constructionBitstream, destinationConnection);
constructionBitstream->Write(shotDirection);
}
bool BallReplica::DeserializeConstruction(SLNet::BitStream *constructionBitstream, SLNet::Connection_RM3 *sourceConnection)
{
if (!BaseIrrlichtReplica::DeserializeConstruction(constructionBitstream, sourceConnection))
return false;
constructionBitstream->Read(shotDirection);
return true;
}
void BallReplica::PostDeserializeConstruction(SLNet::BitStream *constructionBitstream, SLNet::Connection_RM3 *destinationConnection)
{
// unused parameters
(void)constructionBitstream;
(void)destinationConnection;
// Shot visible effect and BallReplica classes are not linked, but they update the same way, such that
// they are in the same spot all the time
demo->shootFromOrigin(position, shotDirection);
// Find the owner of this ball, and make them play the attack animation
unsigned int idx;
for (idx=0; idx < PlayerReplica::playerList.Size(); idx++)
{
if (PlayerReplica::playerList[idx]->creatingSystemGUID==creatingSystemGUID)
{
PlayerReplica::playerList[idx]->PlayAttackAnimation();
break;
}
}
}
void BallReplica::PreDestruction(SLNet::Connection_RM3 *sourceConnection)
{
// unused parameters
(void)sourceConnection;
// The system that shot this ball destroyed it, or disconnected
// Technically we should clear out the node visible effect too, but it's not important for now
}
RM3SerializationResult BallReplica::Serialize(SLNet::SerializeParameters *serializeParameters)
{
BaseIrrlichtReplica::Serialize(serializeParameters);
return RM3SR_BROADCAST_IDENTICALLY;
}
void BallReplica::Deserialize(SLNet::DeserializeParameters *deserializeParameters)
{
BaseIrrlichtReplica::Deserialize(deserializeParameters);
}
void BallReplica::Update(SLNet::TimeMS curTime)
{
// Is a locally created object?
if (creatingSystemGUID==rakPeer->GetGuidFromSystemAddress(SLNet::UNASSIGNED_SYSTEM_ADDRESS))
{
// Destroy if shot expired
if (curTime > shotLifetime)
{
// Destroy on network
BroadcastDestruction();
delete this;
return;
}
}
// Keep at the same position as the visible effect
// Deterministic, so no need to actually transmit position
// The variable position is the origin that the ball was created at. For the player, it is their actual position
SLNet::TimeMS elapsedTime;
// Due to ping variances and timestamp miscalculations, it's possible with very low pings to get a slightly negative time, so we have to check
if (curTime>=creationTime)
elapsedTime = curTime - creationTime;
else
elapsedTime=0;
irr::core::vector3df updatedPosition = position + shotDirection * (float) elapsedTime * SHOT_SPEED;
// See if the bullet hit us
if (creatingSystemGUID!=rakPeer->GetGuidFromSystemAddress(SLNet::UNASSIGNED_SYSTEM_ADDRESS))
{
if (playerReplica->IsDead()==false)
{
//float playerHalfHeight=demo->GetSyndeyBoundingBox().getExtent().Y/2;
irr::core::vector3df positionRelativeToCharacter = updatedPosition-playerReplica->position;//+core::vector3df(0,playerHalfHeight,0);
if (demo->GetSyndeyBoundingBox().isPointInside(positionRelativeToCharacter))
//if ((playerReplica->position+core::vector3df(0,playerHalfHeight,0)-updatedPosition).getLengthSQ() < BALL_DIAMETER*BALL_DIAMETER/4.0f)
{
// We're dead for 3 seconds
playerReplica->deathTimeout=curTime+3000;
}
}
}
}
SLNet::Replica3 *Connection_RM3Irrlicht::AllocReplica(SLNet::BitStream *allocationId, ReplicaManager3 *replicaManager3)
{
// unused parameters
(void)replicaManager3;
SLNet::RakString typeName; allocationId->Read(typeName);
if (typeName=="PlayerReplica") {BaseIrrlichtReplica *r = new PlayerReplica; r->demo=demo; return r;}
if (typeName=="BallReplica") {BaseIrrlichtReplica *r = new BallReplica; r->demo=demo; return r;}
return 0;
}

Some files were not shown because too many files have changed in this diff Show More