Merge pull request #36 from Erihel/dev

Merge of new features: plugins and INI profile, changes from dev-graphics
dev-ui
Piotr Dziwiński 2012-08-12 10:15:19 -07:00
commit 50deedb6cb
115 changed files with 18216 additions and 2468 deletions

View File

@ -8,6 +8,7 @@ project(colobot C CXX)
find_package(OpenGL 1.4 REQUIRED)
find_package(SDL 1.2.10 REQUIRED)
find_package(SDL_image 1.2 REQUIRED)
find_package(SDL_ttf 2.0 REQUIRED)
find_package(PNG 1.2 REQUIRED)
# GLEW requirement depends on platform
@ -30,4 +31,4 @@ set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wold-style-cast -std=gnu++0x")
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${colobot_SOURCE_DIR}/cmake")
# Subdirectory with sources
add_subdirectory(src bin)
add_subdirectory(src bin lib)

1670
Doxyfile

File diff suppressed because it is too large Load Diff

539
lib/simpleini/ConvertUTF.c Normal file
View File

@ -0,0 +1,539 @@
/*
* Copyright 2001-2004 Unicode, Inc.
*
* Disclaimer
*
* This source code is provided as is by Unicode, Inc. No claims are
* made as to fitness for any particular purpose. No warranties of any
* kind are expressed or implied. The recipient agrees to determine
* applicability of information provided. If this file has been
* purchased on magnetic or optical media from Unicode, Inc., the
* sole remedy for any claim will be exchange of defective media
* within 90 days of receipt.
*
* Limitations on Rights to Redistribute This Code
*
* Unicode, Inc. hereby grants the right to freely use the information
* supplied in this file in the creation of products supporting the
* Unicode Standard, and to make copies of this file in any form
* for internal or external distribution as long as this notice
* remains attached.
*/
/* ---------------------------------------------------------------------
Conversions between UTF32, UTF-16, and UTF-8. Source code file.
Author: Mark E. Davis, 1994.
Rev History: Rick McGowan, fixes & updates May 2001.
Sept 2001: fixed const & error conditions per
mods suggested by S. Parent & A. Lillich.
June 2002: Tim Dodd added detection and handling of incomplete
source sequences, enhanced error detection, added casts
to eliminate compiler warnings.
July 2003: slight mods to back out aggressive FFFE detection.
Jan 2004: updated switches in from-UTF8 conversions.
Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.
See the header file "ConvertUTF.h" for complete documentation.
------------------------------------------------------------------------ */
#include "ConvertUTF.h"
#ifdef CVTUTF_DEBUG
#include <stdio.h>
#endif
static const int halfShift = 10; /* used for shifting by 10 bits */
static const UTF32 halfBase = 0x0010000UL;
static const UTF32 halfMask = 0x3FFUL;
#define UNI_SUR_HIGH_START (UTF32)0xD800
#define UNI_SUR_HIGH_END (UTF32)0xDBFF
#define UNI_SUR_LOW_START (UTF32)0xDC00
#define UNI_SUR_LOW_END (UTF32)0xDFFF
#define false 0
#define true 1
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF32toUTF16 (
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF32* source = *sourceStart;
UTF16* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch;
if (target >= targetEnd) {
result = targetExhausted; break;
}
ch = *source++;
if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
/* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
if (flags == strictConversion) {
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
*target++ = (UTF16)ch; /* normal case */
}
} else if (ch > UNI_MAX_LEGAL_UTF32) {
if (flags == strictConversion) {
result = sourceIllegal;
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
/* target is a character in range 0xFFFF - 0x10FFFF. */
if (target + 1 >= targetEnd) {
--source; /* Back up source pointer! */
result = targetExhausted; break;
}
ch -= halfBase;
*target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
*target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
}
}
*sourceStart = source;
*targetStart = target;
return result;
}
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF16toUTF32 (
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF16* source = *sourceStart;
UTF32* target = *targetStart;
UTF32 ch, ch2;
while (source < sourceEnd) {
const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
ch = *source++;
/* If we have a surrogate pair, convert to UTF32 first. */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
/* If the 16 bits following the high surrogate are in the source buffer... */
if (source < sourceEnd) {
ch2 = *source;
/* If it's a low surrogate, convert to UTF32. */
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
++source;
} else if (flags == strictConversion) { /* it's an unpaired high surrogate */
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
} else { /* We don't have the 16 bits following the high surrogate. */
--source; /* return to the high surrogate */
result = sourceExhausted;
break;
}
} else if (flags == strictConversion) {
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
if (target >= targetEnd) {
source = oldSource; /* Back up source pointer! */
result = targetExhausted; break;
}
*target++ = ch;
}
*sourceStart = source;
*targetStart = target;
#ifdef CVTUTF_DEBUG
if (result == sourceIllegal) {
fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2);
fflush(stderr);
}
#endif
return result;
}
/* --------------------------------------------------------------------- */
/*
* Index into the table below with the first byte of a UTF-8 sequence to
* get the number of trailing bytes that are supposed to follow it.
* Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
* left as-is for anyone who may want to do such conversion, which was
* allowed in earlier algorithms.
*/
static const char trailingBytesForUTF8[256] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
};
/*
* Magic values subtracted from a buffer value during UTF8 conversion.
* This table contains as many values as there might be trailing bytes
* in a UTF-8 sequence.
*/
static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
0x03C82080UL, 0xFA082080UL, 0x82082080UL };
/*
* Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
* into the first byte, depending on how many bytes follow. There are
* as many entries in this table as there are UTF-8 sequence types.
* (I.e., one byte sequence, two byte... etc.). Remember that sequencs
* for *legal* UTF-8 will be 4 or fewer bytes total.
*/
static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
/* --------------------------------------------------------------------- */
/* The interface converts a whole buffer to avoid function-call overhead.
* Constants have been gathered. Loops & conditionals have been removed as
* much as possible for efficiency, in favor of drop-through switches.
* (See "Note A" at the bottom of the file for equivalent code.)
* If your compiler supports it, the "isLegalUTF8" call can be turned
* into an inline function.
*/
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF16toUTF8 (
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF16* source = *sourceStart;
UTF8* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch;
unsigned short bytesToWrite = 0;
const UTF32 byteMask = 0xBF;
const UTF32 byteMark = 0x80;
const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
ch = *source++;
/* If we have a surrogate pair, convert to UTF32 first. */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
/* If the 16 bits following the high surrogate are in the source buffer... */
if (source < sourceEnd) {
UTF32 ch2 = *source;
/* If it's a low surrogate, convert to UTF32. */
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
++source;
} else if (flags == strictConversion) { /* it's an unpaired high surrogate */
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
} else { /* We don't have the 16 bits following the high surrogate. */
--source; /* return to the high surrogate */
result = sourceExhausted;
break;
}
} else if (flags == strictConversion) {
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
/* Figure out how many bytes the result will require */
if (ch < (UTF32)0x80) { bytesToWrite = 1;
} else if (ch < (UTF32)0x800) { bytesToWrite = 2;
} else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
} else if (ch < (UTF32)0x110000) { bytesToWrite = 4;
} else { bytesToWrite = 3;
ch = UNI_REPLACEMENT_CHAR;
}
target += bytesToWrite;
if (target > targetEnd) {
source = oldSource; /* Back up source pointer! */
target -= bytesToWrite; result = targetExhausted; break;
}
switch (bytesToWrite) { /* note: everything falls through. */
case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]);
}
target += bytesToWrite;
}
*sourceStart = source;
*targetStart = target;
return result;
}
/* --------------------------------------------------------------------- */
/*
* Utility routine to tell whether a sequence of bytes is legal UTF-8.
* This must be called with the length pre-determined by the first byte.
* If not calling this from ConvertUTF8to*, then the length can be set by:
* length = trailingBytesForUTF8[*source]+1;
* and the sequence is illegal right away if there aren't that many bytes
* available.
* If presented with a length > 4, this returns false. The Unicode
* definition of UTF-8 goes up to 4-byte sequences.
*/
static Boolean isLegalUTF8(const UTF8 *source, int length) {
UTF8 a;
const UTF8 *srcptr = source+length;
switch (length) {
default: return false;
/* Everything else falls through when "true"... */
case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
case 2: if ((a = (*--srcptr)) > 0xBF) return false;
switch (*source) {
/* no fall-through in this inner switch */
case 0xE0: if (a < 0xA0) return false; break;
case 0xED: if (a > 0x9F) return false; break;
case 0xF0: if (a < 0x90) return false; break;
case 0xF4: if (a > 0x8F) return false; break;
default: if (a < 0x80) return false;
}
case 1: if (*source >= 0x80 && *source < 0xC2) return false;
}
if (*source > 0xF4) return false;
return true;
}
/* --------------------------------------------------------------------- */
/*
* Exported function to return whether a UTF-8 sequence is legal or not.
* This is not used here; it's just exported.
*/
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {
int length = trailingBytesForUTF8[*source]+1;
if (source+length > sourceEnd) {
return false;
}
return isLegalUTF8(source, length);
}
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF8toUTF16 (
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF8* source = *sourceStart;
UTF16* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch = 0;
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
if (source + extraBytesToRead >= sourceEnd) {
result = sourceExhausted; break;
}
/* Do this check whether lenient or strict */
if (! isLegalUTF8(source, extraBytesToRead+1)) {
result = sourceIllegal;
break;
}
/*
* The cases all fall through. See "Note A" below.
*/
switch (extraBytesToRead) {
case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
case 3: ch += *source++; ch <<= 6;
case 2: ch += *source++; ch <<= 6;
case 1: ch += *source++; ch <<= 6;
case 0: ch += *source++;
}
ch -= offsetsFromUTF8[extraBytesToRead];
if (target >= targetEnd) {
source -= (extraBytesToRead+1); /* Back up source pointer! */
result = targetExhausted; break;
}
if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
if (flags == strictConversion) {
source -= (extraBytesToRead+1); /* return to the illegal value itself */
result = sourceIllegal;
break;
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
*target++ = (UTF16)ch; /* normal case */
}
} else if (ch > UNI_MAX_UTF16) {
if (flags == strictConversion) {
result = sourceIllegal;
source -= (extraBytesToRead+1); /* return to the start */
break; /* Bail out; shouldn't continue */
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
/* target is a character in range 0xFFFF - 0x10FFFF. */
if (target + 1 >= targetEnd) {
source -= (extraBytesToRead+1); /* Back up source pointer! */
result = targetExhausted; break;
}
ch -= halfBase;
*target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
*target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
}
}
*sourceStart = source;
*targetStart = target;
return result;
}
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF32toUTF8 (
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF32* source = *sourceStart;
UTF8* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch;
unsigned short bytesToWrite = 0;
const UTF32 byteMask = 0xBF;
const UTF32 byteMark = 0x80;
ch = *source++;
if (flags == strictConversion ) {
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
--source; /* return to the illegal value itself */
result = sourceIllegal;
break;
}
}
/*
* Figure out how many bytes the result will require. Turn any
* illegally large UTF32 things (> Plane 17) into replacement chars.
*/
if (ch < (UTF32)0x80) { bytesToWrite = 1;
} else if (ch < (UTF32)0x800) { bytesToWrite = 2;
} else if (ch < (UTF32)0x10000) { bytesToWrite = 3;
} else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4;
} else { bytesToWrite = 3;
ch = UNI_REPLACEMENT_CHAR;
result = sourceIllegal;
}
target += bytesToWrite;
if (target > targetEnd) {
--source; /* Back up source pointer! */
target -= bytesToWrite; result = targetExhausted; break;
}
switch (bytesToWrite) { /* note: everything falls through. */
case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
}
target += bytesToWrite;
}
*sourceStart = source;
*targetStart = target;
return result;
}
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF8toUTF32 (
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF8* source = *sourceStart;
UTF32* target = *targetStart;
while (source < sourceEnd) {
UTF32 ch = 0;
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
if (source + extraBytesToRead >= sourceEnd) {
result = sourceExhausted; break;
}
/* Do this check whether lenient or strict */
if (! isLegalUTF8(source, extraBytesToRead+1)) {
result = sourceIllegal;
break;
}
/*
* The cases all fall through. See "Note A" below.
*/
switch (extraBytesToRead) {
case 5: ch += *source++; ch <<= 6;
case 4: ch += *source++; ch <<= 6;
case 3: ch += *source++; ch <<= 6;
case 2: ch += *source++; ch <<= 6;
case 1: ch += *source++; ch <<= 6;
case 0: ch += *source++;
}
ch -= offsetsFromUTF8[extraBytesToRead];
if (target >= targetEnd) {
source -= (extraBytesToRead+1); /* Back up the source pointer! */
result = targetExhausted; break;
}
if (ch <= UNI_MAX_LEGAL_UTF32) {
/*
* UTF-16 surrogate values are illegal in UTF-32, and anything
* over Plane 17 (> 0x10FFFF) is illegal.
*/
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
if (flags == strictConversion) {
source -= (extraBytesToRead+1); /* return to the illegal value itself */
result = sourceIllegal;
break;
} else {
*target++ = UNI_REPLACEMENT_CHAR;
}
} else {
*target++ = ch;
}
} else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
result = sourceIllegal;
*target++ = UNI_REPLACEMENT_CHAR;
}
}
*sourceStart = source;
*targetStart = target;
return result;
}
/* ---------------------------------------------------------------------
Note A.
The fall-through switches in UTF-8 reading code save a
temp variable, some decrements & conditionals. The switches
are equivalent to the following loop:
{
int tmpBytesToRead = extraBytesToRead+1;
do {
ch += *source++;
--tmpBytesToRead;
if (tmpBytesToRead) ch <<= 6;
} while (tmpBytesToRead > 0);
}
In UTF-8 writing code, the switches on "bytesToWrite" are
similarly unrolled loops.
--------------------------------------------------------------------- */

149
lib/simpleini/ConvertUTF.h Normal file
View File

@ -0,0 +1,149 @@
/*
* Copyright 2001-2004 Unicode, Inc.
*
* Disclaimer
*
* This source code is provided as is by Unicode, Inc. No claims are
* made as to fitness for any particular purpose. No warranties of any
* kind are expressed or implied. The recipient agrees to determine
* applicability of information provided. If this file has been
* purchased on magnetic or optical media from Unicode, Inc., the
* sole remedy for any claim will be exchange of defective media
* within 90 days of receipt.
*
* Limitations on Rights to Redistribute This Code
*
* Unicode, Inc. hereby grants the right to freely use the information
* supplied in this file in the creation of products supporting the
* Unicode Standard, and to make copies of this file in any form
* for internal or external distribution as long as this notice
* remains attached.
*/
/* ---------------------------------------------------------------------
Conversions between UTF32, UTF-16, and UTF-8. Header file.
Several funtions are included here, forming a complete set of
conversions between the three formats. UTF-7 is not included
here, but is handled in a separate source file.
Each of these routines takes pointers to input buffers and output
buffers. The input buffers are const.
Each routine converts the text between *sourceStart and sourceEnd,
putting the result into the buffer between *targetStart and
targetEnd. Note: the end pointers are *after* the last item: e.g.
*(sourceEnd - 1) is the last item.
The return result indicates whether the conversion was successful,
and if not, whether the problem was in the source or target buffers.
(Only the first encountered problem is indicated.)
After the conversion, *sourceStart and *targetStart are both
updated to point to the end of last text successfully converted in
the respective buffers.
Input parameters:
sourceStart - pointer to a pointer to the source buffer.
The contents of this are modified on return so that
it points at the next thing to be converted.
targetStart - similarly, pointer to pointer to the target buffer.
sourceEnd, targetEnd - respectively pointers to the ends of the
two buffers, for overflow checking only.
These conversion functions take a ConversionFlags argument. When this
flag is set to strict, both irregular sequences and isolated surrogates
will cause an error. When the flag is set to lenient, both irregular
sequences and isolated surrogates are converted.
Whether the flag is strict or lenient, all illegal sequences will cause
an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
must check for illegal sequences.
When the flag is set to lenient, characters over 0x10FFFF are converted
to the replacement character; otherwise (when the flag is set to strict)
they constitute an error.
Output parameters:
The value "sourceIllegal" is returned from some routines if the input
sequence is malformed. When "sourceIllegal" is returned, the source
value will point to the illegal value that caused the problem. E.g.,
in UTF-8 when a sequence is malformed, it points to the start of the
malformed sequence.
Author: Mark E. Davis, 1994.
Rev History: Rick McGowan, fixes & updates May 2001.
Fixes & updates, Sept 2001.
------------------------------------------------------------------------ */
/* ---------------------------------------------------------------------
The following 4 definitions are compiler-specific.
The C standard does not guarantee that wchar_t has at least
16 bits, so wchar_t is no less portable than unsigned short!
All should be unsigned values to avoid sign extension during
bit mask & shift operations.
------------------------------------------------------------------------ */
typedef unsigned int UTF32; /* at least 32 bits */
typedef unsigned short UTF16; /* at least 16 bits */
typedef unsigned char UTF8; /* typically 8 bits */
typedef unsigned char Boolean; /* 0 or 1 */
/* Some fundamental constants */
#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
#define UNI_MAX_BMP (UTF32)0x0000FFFF
#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
typedef enum {
conversionOK, /* conversion successful */
sourceExhausted, /* partial character in source, but hit end */
targetExhausted, /* insuff. room in target for conversion */
sourceIllegal /* source sequence is illegal/malformed */
} ConversionResult;
typedef enum {
strictConversion = 0,
lenientConversion
} ConversionFlags;
/* This is for C++ and does no harm in C */
#ifdef __cplusplus
extern "C" {
#endif
ConversionResult ConvertUTF8toUTF16 (
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF16toUTF8 (
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF8toUTF32 (
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF32toUTF8 (
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF16toUTF32 (
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF32toUTF16 (
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
#ifdef __cplusplus
}
#endif
/* --------------------------------------------------------------------- */

28
lib/simpleini/Makefile Normal file
View File

@ -0,0 +1,28 @@
CC=g++
CFLAGS=-Wall
CPPFLAGS=-Wall
OBJS=testsi.o test1.o snippets.o ConvertUTF.o
help:
@echo This makefile is just for the test program \(use \"make clean all test\"\)
@echo Just include the SimpleIni.h header file to use it.
all: $(OBJS)
$(CC) -o testsi $(OBJS)
clean:
rm -f core *.o testsi
data:
sed 's/\r\n$$/\n/g' < test1-expected.ini > unix.out
mv unix.out test1-expected.ini
test: testsi
./testsi -u -m -l test1-input.ini > test1-blah.ini
diff test1-output.ini test1-expected.ini
install:
@echo No install required. Just include the SimpleIni.h header file to use it.
testsi.o test1.o snippets.o : SimpleIni.h

3370
lib/simpleini/SimpleIni.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleIni", "SimpleIni.vcproj", "{C23240A6-AA9D-4827-AF06-C98E97CA6DFB}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Debug Unicode = Debug Unicode
Release = Release
Release Unicode = Release Unicode
EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{C23240A6-AA9D-4827-AF06-C98E97CA6DFB}.Debug.ActiveCfg = Debug|Win32
{C23240A6-AA9D-4827-AF06-C98E97CA6DFB}.Debug.Build.0 = Debug|Win32
{C23240A6-AA9D-4827-AF06-C98E97CA6DFB}.Debug Unicode.ActiveCfg = Debug Unicode|Win32
{C23240A6-AA9D-4827-AF06-C98E97CA6DFB}.Debug Unicode.Build.0 = Debug Unicode|Win32
{C23240A6-AA9D-4827-AF06-C98E97CA6DFB}.Release.ActiveCfg = Release|Win32
{C23240A6-AA9D-4827-AF06-C98E97CA6DFB}.Release.Build.0 = Release|Win32
{C23240A6-AA9D-4827-AF06-C98E97CA6DFB}.Release Unicode.ActiveCfg = Release Unicode|Win32
{C23240A6-AA9D-4827-AF06-C98E97CA6DFB}.Release Unicode.Build.0 = Release Unicode|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,291 @@
<?xml version="1.0" encoding="shift_jis"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="SimpleIni"
ProjectGUID="{C23240A6-AA9D-4827-AF06-C98E97CA6DFB}"
RootNamespace="SimpleIni"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/testsi.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/SimpleIni.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/testsi.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug Unicode|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/testsi.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/SimpleIni.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release Unicode|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/testsi.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\snippets.cpp">
</File>
<File
RelativePath=".\test1.cpp">
</File>
<File
RelativePath=".\testsi.cpp">
</File>
</Filter>
<Filter
Name="Library Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\SimpleIni.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
<File
RelativePath=".\Makefile">
</File>
<File
RelativePath=".\testsi-EUCJP.ini">
</File>
<File
RelativePath=".\testsi-SJIS.ini">
</File>
<File
RelativePath=".\testsi-UTF8.ini">
</File>
</Filter>
<Filter
Name="Conversion Files"
Filter="">
<File
RelativePath=".\ConvertUTF.c">
</File>
<File
RelativePath=".\ConvertUTF.h">
</File>
</Filter>
<Filter
Name="Documentation"
Filter="">
<File
RelativePath=".\simpleini.doxy">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCustomBuildTool"
CommandLine="if not exist &quot;C:\Program Files\doxygen\bin\doxygen.exe&quot; goto done
echo Generating documentation...
&quot;C:\Program Files\doxygen\bin\doxygen.exe&quot; $(InputDir)simpleini.doxy
:done
"
Outputs="d:\src\simpleini-doc\html\index.html"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Tests"
Filter="">
<File
RelativePath=".\test1-expected.ini">
</File>
<File
RelativePath=".\test1-input.ini">
</File>
<File
RelativePath=".\test1-output.ini">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

36
lib/simpleini/ini.syn Normal file
View File

@ -0,0 +1,36 @@
; Syntax file for ini files - contributed by Brodie Thiesfield
;
; Suggested Colors:
; Comments (;#) Comments, Comments 2 Green
; Sections Characters Red
; Values Strings Blue
C=1
[Syntax]
Namespace1 = 6
IgnoreCase = Yes
KeyWordLength = 1
BracketChars =
OperatorChars =
PreprocStart =
SyntaxStart =
SyntaxEnd =
HexPrefix =
CommentStart =
CommentEnd =
CommentStartAlt =
CommentEndAlt =
SingleComment = #
SingleCommentCol =
SingleCommentAlt = ;
SingleCommentColAlt =
SingleCommentEsc =
StringsSpanLines = No
StringStart =
StringEnd =
StringAlt = =
StringEsc =
CharStart = [
CharEnd = ]
CharEsc =

26
lib/simpleini/package.cmd Normal file
View File

@ -0,0 +1,26 @@
set VERSION=4.15
set SEVENZIP="C:\Program Files\7-Zip\7z.exe"
FOR /F "tokens=*" %%G IN ('DIR /AD /B /S Debug*') DO (
DEL /S /Q "%%G"
RD "%%G"
)
FOR /F "tokens=*" %%G IN ('DIR /AD /B /S Release*') DO (
DEL /S /Q "%%G"
RD "%%G"
)
DEL /Q "SimpleIni.ncb"
ATTRIB -H "SimpleIni.suo"
DEL /Q "SimpleIni.suo"
DEL /Q "SimpleIni.opt"
DEL /Q testsi-out*.ini
DEL /Q test1-blah.ini
DEL /Q test1-output.ini
START "Generate documentation" /WAIT "C:\Program Files (x86)\doxygen\bin\doxygen.exe" SimpleIni.doxy
cd ..
del simpleini-%VERSION%.zip
%SEVENZIP% a -tzip -r- -x!simpleini\.svn simpleini-%VERSION%.zip simpleini\*
del simpleini-doc.zip
%SEVENZIP% a -tzip -r simpleini-doc.zip simpleini-doc\*
cd simpleini

1321
lib/simpleini/simpleini.doxy Normal file

File diff suppressed because it is too large Load Diff

178
lib/simpleini/simpleini.dsp Normal file
View File

@ -0,0 +1,178 @@
# Microsoft Developer Studio Project File - Name="simpleini" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=simpleini - Win32 Debug Unicode
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "simpleini.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "simpleini.mak" CFG="simpleini - Win32 Debug Unicode"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "simpleini - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "simpleini - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE "simpleini - Win32 Debug Unicode" (based on "Win32 (x86) Console Application")
!MESSAGE "simpleini - Win32 Release Unicode" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "simpleini - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0xc09 /d "NDEBUG"
# ADD RSC /l 0xc09 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/testsi.exe"
!ELSEIF "$(CFG)" == "simpleini - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "simpleini___Win32_Debug"
# PROP BASE Intermediate_Dir "simpleini___Win32_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c
# SUBTRACT CPP /Fr /YX
# ADD BASE RSC /l 0xc09 /d "_DEBUG"
# ADD RSC /l 0xc09 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/testsi.exe" /pdbtype:sept
!ELSEIF "$(CFG)" == "simpleini - Win32 Debug Unicode"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug Unicode"
# PROP BASE Intermediate_Dir "Debug Unicode"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug Unicode"
# PROP Intermediate_Dir "Debug Unicode"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /D "SI_USE_GENERIC_CONVERSION" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0xc09 /d "_DEBUG"
# ADD RSC /l 0xc09 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug Unicode/testsi.exe" /pdbtype:sept
!ELSEIF "$(CFG)" == "simpleini - Win32 Release Unicode"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release Unicode"
# PROP BASE Intermediate_Dir "Release Unicode"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release Unicode"
# PROP Intermediate_Dir "Release Unicode"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /D "SI_USE_GENERIC_CONVERSION" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0xc09 /d "NDEBUG"
# ADD RSC /l 0xc09 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release Unicode/testsi.exe"
!ENDIF
# Begin Target
# Name "simpleini - Win32 Release"
# Name "simpleini - Win32 Debug"
# Name "simpleini - Win32 Debug Unicode"
# Name "simpleini - Win32 Release Unicode"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\snippets.cpp
# End Source File
# Begin Source File
SOURCE=.\test1.cpp
# End Source File
# Begin Source File
SOURCE=.\testsi.cpp
# End Source File
# End Group
# Begin Group "Library Files"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\SimpleIni.h
# End Source File
# End Group
# Begin Group "Generic Files"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\ConvertUTF.c
# End Source File
# Begin Source File
SOURCE=.\ConvertUTF.h
# End Source File
# End Group
# End Target
# End Project

View File

@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "simpleini"=.\simpleini.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

123
lib/simpleini/snippets.cpp Normal file
View File

@ -0,0 +1,123 @@
// File: snippets.cpp
// Library: SimpleIni
// Author: Brodie Thiesfield <code@jellycan.com>
// Source: http://code.jellycan.com/simpleini/
//
// Snippets that are used on the website
#ifdef _WIN32
# pragma warning(disable: 4786)
#endif
#ifndef _WIN32
# include <unistd.h>
#endif
#include <fstream>
#define SI_SUPPORT_IOSTREAMS
#include "SimpleIni.h"
bool
snippets(
const char * a_pszFile,
bool a_bIsUtf8,
bool a_bUseMultiKey,
bool a_bUseMultiLine
)
{
// LOADING DATA
// load from a data file
CSimpleIniA ini(a_bIsUtf8, a_bUseMultiKey, a_bUseMultiLine);
SI_Error rc = ini.LoadFile(a_pszFile);
if (rc < 0) return false;
// load from a string
std::string strData;
rc = ini.LoadData(strData.c_str(), strData.size());
if (rc < 0) return false;
// GETTING SECTIONS AND KEYS
// get all sections
CSimpleIniA::TNamesDepend sections;
ini.GetAllSections(sections);
// get all keys in a section
CSimpleIniA::TNamesDepend keys;
ini.GetAllKeys("section-name", keys);
// GETTING VALUES
// get the value of a key
const char * pszValue = ini.GetValue("section-name",
"key-name", NULL /*default*/);
// get the value of a key which may have multiple
// values. If bHasMultipleValues is true, then just
// one value has been returned
bool bHasMultipleValues;
pszValue = ini.GetValue("section-name", "key-name",
NULL /*default*/, &bHasMultipleValues);
// get all values of a key with multiple values
CSimpleIniA::TNamesDepend values;
ini.GetAllValues("section-name", "key-name", values);
// sort the values into the original load order
#if defined(_MSC_VER) && _MSC_VER <= 1200
/** STL of VC6 doesn't allow me to specify my own comparator for list::sort() */
values.sort();
#else
values.sort(CSimpleIniA::Entry::LoadOrder());
#endif
// output all of the items
CSimpleIniA::TNamesDepend::const_iterator i;
for (i = values.begin(); i != values.end(); ++i) {
printf("key-name = '%s'\n", i->pItem);
}
// MODIFYING DATA
// adding a new section
rc = ini.SetValue("new-section", NULL, NULL);
if (rc < 0) return false;
printf("section: %s\n", rc == SI_INSERTED ?
"inserted" : "updated");
// adding a new key ("new-section" will be added
// automatically if it doesn't already exist.
rc = ini.SetValue("new-section", "new-key", "value");
if (rc < 0) return false;
printf("key: %s\n", rc == SI_INSERTED ?
"inserted" : "updated");
// changing the value of a key
rc = ini.SetValue("section", "key", "updated-value");
if (rc < 0) return false;
printf("key: %s\n", rc == SI_INSERTED ?
"inserted" : "updated");
// DELETING DATA
// deleting a key from a section. Optionally the entire
// section may be deleted if it is now empty.
ini.Delete("section-name", "key-name",
true /*delete the section if empty*/);
// deleting an entire section and all keys in it
ini.Delete("section-name", NULL);
// SAVING DATA
// save the data to a string
rc = ini.Save(strData);
if (rc < 0) return false;
// save the data back to the file
rc = ini.SaveFile(a_pszFile);
if (rc < 0) return false;
return true;
}

24
lib/simpleini/test.cmd Normal file
View File

@ -0,0 +1,24 @@
@echo off
Debug\testsi.exe -u -m -l test1-input.ini > test1-blah.ini
fc test1-expected.ini test1-output.ini
if errorlevel 1 goto error
"Debug Unicode\testsi.exe" -u -m -l test1-input.ini > test1-blah.ini
fc test1-expected.ini test1-output.ini
if errorlevel 1 goto error
Release\testsi.exe -u -m -l test1-input.ini > test1-blah.ini
fc test1-expected.ini test1-output.ini
if errorlevel 1 goto error
"Release Unicode\testsi.exe" -u -m -l test1-input.ini > test1-blah.ini
fc test1-expected.ini test1-output.ini
if errorlevel 1 goto error
exit /b 0
:error
echo Failed during test run. Output file doesn't match expected file.
pause
exit /b 1

View File

@ -0,0 +1,85 @@
; testsi-UTF8-std.ini : standard UTF-8 test file for SimpleIni automated testing
;
; The number after a section or key is the order that it is defined in this file
; to make it easier to see if it has been written out correctly. This file should
; be loaded with Unicode / MultiKey / MultiLine turned on.
; This comment should be joined on to the one below it about the key
; with no section.
; Key with no section
lonely-key = nosection
another = nosection either
; This key has no value
empty =
; This should be joined with the comment below about japanese.
; Another line which will be un-indented.
; This is a section of keys showing the word Japanese in different syllabies.
[ordered-1]
a-1 = blah
; this is in kanji
japanese-2 = 日本語
; this is in hiragana
japanese-3 = にほんご
; this is in katakana
japanese-4 = ニホンゴ
; this is in romaji
japanese-5 = nihongo
; kanji as the key
日本語-6 = japanese
[multi-2]
; value a
test = a
; value b
test = b
; value c
test = c
; value d
test = d
[multiline-3]
; This is obviously a multi-line entry
multiline-1 = <<<END_OF_TEXT
This is a multi-line comment. It
will continue until we have the word MULTI
on a line by itself.
日本語も。
END_OF_TEXT
; This looks like multi-line, but because the newline following the last
; line is discarded, it will be converted into a single line entry.
another-2 = This is not a multiline entry.
; If you wanted a multiline entry with a single line, you need to add
; an extra line to it.
another-3 = <<<END_OF_TEXT
This is a multiline entry.
END_OF_TEXT
[integer]
dec = 42
hex = 0x2a

View File

@ -0,0 +1,76 @@
; testsi-UTF8-std.ini : standard UTF-8 test file for SimpleIni automated testing
;
; The number after a section or key is the order that it is defined in this file
; to make it easier to see if it has been written out correctly. This file should
; be loaded with Unicode / MultiKey / MultiLine turned on.
; This comment should be joined on to the one below it about the key
; with no section.
; Key with no section
lonely-key = nosection
another = nosection either
; This key has no value
empty =
; This should be joined with the comment below about japanese.
; Another line which will be un-indented.
; This is a section of keys showing the word Japanese in different syllabies.
[ordered-1]
a-1 = blah
; this is in kanji
japanese-2 = 日本語
; this is in hiragana
japanese-3 = にほんご
; this is in katakana
japanese-4 = ニホンゴ
; this is in romaji
japanese-5 = nihongo
; kanji as the key
日本語-6 = japanese
[multi-2]
; value a
test = a
; value b
test = b
; value c
test = c
; value d
test = d
[multiline-3]
; This is obviously a multi-line entry
multiline-1 = <<<MULTI
This is a multi-line comment. It
will continue until we have the word MULTI
on a line by itself.
日本語も。
MULTI
; This looks like multi-line, but because the newline following the last
; line is discarded, it will be converted into a single line entry.
another-2 = <<<MULTI
This is not a multiline entry.
MULTI
; If you wanted a multiline entry with a single line, you need to add
; an extra line to it.
another-3 = <<<MULTI
This is a multiline entry.
MULTI
[integer]
dec = 42
hex = 0x2a

166
lib/simpleini/test1.cpp Normal file
View File

@ -0,0 +1,166 @@
// File: test1.cpp
// Library: SimpleIni
// Author: Brodie Thiesfield <code@jellycan.com>
// Source: http://code.jellycan.com/simpleini/
//
// Automated testing for SimpleIni streams
#ifdef _WIN32
# pragma warning(disable: 4786)
#endif
#ifdef _WIN32
# include <windows.h>
# define DELETE_FILE DeleteFileA
#else
# include <unistd.h>
# define DELETE_FILE unlink
#endif
#include <fstream>
#define SI_SUPPORT_IOSTREAMS
#include "SimpleIni.h"
class Test
{
std::string m_strTest;
public:
Test(const char * a_pszName)
: m_strTest(a_pszName)
{
printf("%s: test starting\n", m_strTest.c_str());
}
bool Success()
{
printf("%s: test succeeded\n", m_strTest.c_str());
return false;
}
bool Failure(const char * pszReason)
{
printf("%s: test FAILED (%s)\n", m_strTest.c_str(), pszReason);
return false;
}
};
bool FileComparisonTest(const char * a_pszFile1, const char * a_pszFile2) {
// ensure that the two files are the same
try {
std::string strFile1, strFile2;
char szBuf[1024];
FILE * fp = NULL;
#if __STDC_WANT_SECURE_LIB__
fopen_s(&fp, a_pszFile1, "rb");
#else
fp = fopen(a_pszFile1, "rb");
#endif
if (!fp) throw false;
while (!feof(fp)) {
size_t n = fread(szBuf, 1, sizeof(szBuf), fp);
strFile1.append(szBuf, n);
}
fclose(fp);
fp = NULL;
#if __STDC_WANT_SECURE_LIB__
fopen_s(&fp, a_pszFile2, "rb");
#else
fp = fopen(a_pszFile2, "rb");
#endif
if (!fp) throw false;
while (!feof(fp)) {
size_t n = fread(szBuf, 1, sizeof(szBuf), fp);
strFile2.append(szBuf, n);
}
fclose(fp);
if (strFile1 != strFile2) throw false;
}
catch (...) {
return false;
}
return true;
}
bool FileLoadTest(const char * a_pszFile1, const char * a_pszFile2) {
// ensure that the two files load into simpleini the same
CSimpleIniA ini(true, true, true);
bool b;
try {
ini.Reset();
if (ini.LoadFile(a_pszFile1) < 0) throw "Load failed for file 1";
if (ini.SaveFile("test1.ini") < 0) throw "Save failed for file 1";
ini.Reset();
if (ini.LoadFile(a_pszFile2) < 0) throw "Load failed for file 2";
if (ini.SaveFile("test2.ini") < 0) throw "Save failed for file 2";
b = FileComparisonTest("test1.ini", "test2.ini");
DELETE_FILE("test1.ini");
DELETE_FILE("test2.ini");
if (!b) throw "File comparison failed in FileLoadTest";
}
catch (...) {
return false;
}
return true;
}
bool TestStreams()
{
const char * rgszTestFile[3] = {
"test1-input.ini",
"test1-output.ini",
"test1-expected.ini"
};
Test oTest("TestStreams");
CSimpleIniW ini;
ini.SetUnicode(true);
ini.SetMultiKey(true);
ini.SetMultiLine(true);
// load the file
try {
std::ifstream instream;
instream.open(rgszTestFile[0], std::ifstream::in | std::ifstream::binary);
if (ini.LoadData(instream) < 0) throw false;
instream.close();
}
catch (...) {
return oTest.Failure("Failed to load file");
}
// standard contents test
//if (!StandardContentsTest(ini, oTest)) {
// return false;
//}
// save the file
try {
std::ofstream outfile;
outfile.open(rgszTestFile[1], std::ofstream::out | std::ofstream::binary);
if (ini.Save(outfile, true) < 0) throw false;
outfile.close();
}
catch (...) {
return oTest.Failure("Failed to save file");
}
// file comparison test
if (!FileComparisonTest(rgszTestFile[1], rgszTestFile[2])) {
return oTest.Failure("Failed file comparison");
}
if (!FileLoadTest(rgszTestFile[1], rgszTestFile[2])) {
return oTest.Failure("Failed file load comparison");
}
return oTest.Success();
}

View File

@ -0,0 +1,52 @@
; test file for SimpleIni
nosection=ok
NOSECTION=still ok
whitespace = ok
[standard]
foo=foo1
standard-1=foo
日本語=ok1
[Standard]
Foo=foo2
standard-2=foo
日本語=ok2
[ Whitespace ]
a=
[ whitespace in section name ]
whitespace in key name = whitespace in value name
; comments
; more comments
invalid
=invalid
====invalid
[Japanese]
nihongo = 日本語
日本語 = 日本語
[日本語]
nihongo = 日本語
日本語 = 日本語
[]
more=no section name
[MultiLine]
single = This is a single line.
multi = <<<MULTI
This is a multi-line value. It continues until the MULTI tag is found
on a line by itself with no whitespace before or after it. This value
will be returned to the user with all newlines and whitespace.
MULTI

View File

@ -0,0 +1,51 @@
; test file for SimpleIni
nosection=ok
NOSECTION=still ok
whitespace = ok
[standard]
foo=foo1
standard-1=foo
日本語=ok1
[Standard]
Foo=foo2
standard-2=foo
日本語=ok2
[ Whitespace ]
a=
[ whitespace in section name ]
whitespace in key name = whitespace in value name
; comments
; more comments
invalid
=invalid
====invalid
[Japanese]
nihongo = 日本語
日本語 = 日本語
[日本語]
nihongo = 日本語
日本語 = 日本語
[]
more=no section name
[MultiLine]
single = This is a single line.
multi = <<<MULTI
This is a multi-line value. It continues until the MULTI tag is found
on a line by itself with no whitespace before or after it. This value
will be returned to the user with all newlines and whitespace.
MULTI

View File

@ -0,0 +1,50 @@
; test file for SimpleIni
whitespace = ok
nosection=ok
NOSECTION=still ok
[standard]
foo=foo1
standard-1=foo
日本語=ok1
[Standard]
Foo=foo2
standard-2=foo
日本語=ok2
[ Whitespace ]
a=
[ whitespace in section name ]
whitespace in key name = whitespace in value name
; comments
; more comments
invalid
=invalid
====invalid
[Japanese]
nihongo = 日本語
日本語 = 日本語
[日本語]
nihongo = 日本語
日本語 = 日本語
[]
more=no section name
[MultiLine]
single = This is a single line.
multi = <<<MULTI
This is a multi-line value. It continues until the MULTI tag is found
on a line by itself with no whitespace before or after it. This value
will be returned to the user with all newlines and whitespace.
MULTI

309
lib/simpleini/testsi.cpp Normal file
View File

@ -0,0 +1,309 @@
// File: testsi.cpp
// Library: SimpleIni
// Author: Brodie Thiesfield <code@jellycan.com>
// Source: http://code.jellycan.com/simpleini/
//
// Demo of usage
#ifdef _WIN32
# pragma warning(disable: 4786)
#endif
#include <locale.h>
#include <stdio.h>
#include <cassert>
#define SI_SUPPORT_IOSTREAMS
#if defined(SI_SUPPORT_IOSTREAMS) && !defined(_UNICODE)
# include <fstream>
#endif
//#define SI_CONVERT_GENERIC
//#define SI_CONVERT_ICU
//#define SI_CONVERT_WIN32
#include "SimpleIni.h"
#ifdef SI_CONVERT_ICU
// if converting using ICU then we need the ICU library
# pragma comment(lib, "icuuc.lib")
#endif
#ifdef _WIN32
# include <tchar.h>
#else // !_WIN32
# define TCHAR char
# define _T(x) x
# define _tprintf printf
# define _tmain main
#endif // _WIN32
static void
Test(
CSimpleIni & ini
)
{
const TCHAR *pszSection = 0;
const TCHAR *pItem = 0;
const TCHAR *pszVal = 0;
// get the value of the key "foo" in section "standard"
bool bHasMulti;
pszVal = ini.GetValue(_T("standard"), _T("foo"), 0, &bHasMulti);
_tprintf(_T("\n-- Value of standard::foo is '%s' (hasMulti = %d)\n"),
pszVal ? pszVal : _T("(null)"), bHasMulti);
// set the value of the key "foo" in section "standard"
ini.SetValue(_T("standard"), _T("foo"), _T("wibble"));
pszVal = ini.GetValue(_T("standard"), _T("foo"), 0, &bHasMulti);
_tprintf(_T("\n-- Value of standard::foo is '%s' (hasMulti = %d)\n"),
pszVal ? pszVal : _T("(null)"), bHasMulti);
// get all values of the key "foo" in section "standard"
CSimpleIni::TNamesDepend values;
if (ini.GetAllValues(_T("standard"), _T("foo"), values)) {
_tprintf(_T("\n-- Values of standard::foo are:\n"));
CSimpleIni::TNamesDepend::const_iterator i = values.begin();
for (; i != values.end(); ++i) {
pszVal = i->pItem;
_tprintf(_T(" -> '%s'\n"), pszVal);
}
}
// get the size of the section [standard]
_tprintf(_T("\n-- Number of keys in section [standard] = %d\n"),
ini.GetSectionSize(_T("standard")));
// delete the key "foo" in section "standard"
ini.Delete(_T("standard"), _T("foo"));
pszVal = ini.GetValue(_T("standard"), _T("foo"), 0);
_tprintf(_T("\n-- Value of standard::foo is now '%s'\n"),
pszVal ? pszVal : _T("(null)"));
// get the size of the section [standard]
_tprintf(_T("\n-- Number of keys in section [standard] = %d\n"),
ini.GetSectionSize(_T("standard")));
// get the list of all key names for the section "standard"
_tprintf(_T("\n-- Dumping keys of section: [standard]\n"));
CSimpleIni::TNamesDepend keys;
ini.GetAllKeys(_T("standard"), keys);
// dump all of the key names
CSimpleIni::TNamesDepend::const_iterator iKey = keys.begin();
for ( ; iKey != keys.end(); ++iKey ) {
pItem = iKey->pItem;
_tprintf(_T("Key: %s\n"), pItem);
}
// add a decimal value
ini.SetLongValue(_T("integer"), _T("dec"), 42, NULL, false);
ini.SetLongValue(_T("integer"), _T("hex"), 42, NULL, true);
// add some bool values
ini.SetBoolValue(_T("bool"), _T("t"), true);
ini.SetBoolValue(_T("bool"), _T("f"), false);
// get the values back
assert(42 == ini.GetLongValue(_T("integer"), _T("dec")));
assert(42 == ini.GetLongValue(_T("integer"), _T("hex")));
assert(true == ini.GetBoolValue(_T("bool"), _T("t")));
assert(false == ini.GetBoolValue(_T("bool"), _T("f")));
// delete the section "standard"
ini.Delete(_T("standard"), NULL);
_tprintf(_T("\n-- Number of keys in section [standard] = %d\n"),
ini.GetSectionSize(_T("standard")));
// iterate through every section in the file
_tprintf(_T("\n-- Dumping all sections\n"));
CSimpleIni::TNamesDepend sections;
ini.GetAllSections(sections);
CSimpleIni::TNamesDepend::const_iterator iSection = sections.begin();
for ( ; iSection != sections.end(); ++iSection ) {
pszSection = iSection->pItem;
// print the section name
printf("\n");
if (*pszSection) {
_tprintf(_T("[%s]\n"), pszSection);
}
// if there are keys and values...
const CSimpleIni::TKeyVal * pSectionData = ini.GetSection(pszSection);
if (pSectionData) {
// iterate over all keys and dump the key name and value
CSimpleIni::TKeyVal::const_iterator iKeyVal = pSectionData->begin();
for ( ;iKeyVal != pSectionData->end(); ++iKeyVal) {
pItem = iKeyVal->first.pItem;
pszVal = iKeyVal->second;
_tprintf(_T("%s=%s\n"), pItem, pszVal);
}
}
}
}
#if defined(SI_SUPPORT_IOSTREAMS) && !defined(_UNICODE)
static bool
TestStreams(
const TCHAR * a_pszFile,
bool a_bIsUtf8,
bool a_bUseMultiKey,
bool a_bUseMultiLine
)
{
// load the file
CSimpleIni ini(a_bIsUtf8, a_bUseMultiKey, a_bUseMultiLine);
_tprintf(_T("Loading file: %s\n"), a_pszFile);
std::ifstream instream;
instream.open(a_pszFile, std::ifstream::in | std::ifstream::binary);
SI_Error rc = ini.LoadData(instream);
instream.close();
if (rc < 0) {
printf("Failed to open file.\n");
return false;
}
Test(ini);
// save the file (simple)
_tprintf(_T("\n-- Saving file to: testsi-out-streams.ini\n"));
std::ofstream outstream;
outstream.open("testsi-out-streams.ini", std::ofstream::out | std::ofstream::binary);
ini.Save(outstream);
outstream.close();
return true;
}
#endif // SI_SUPPORT_IOSTREAMS
static bool
TestFile(
const TCHAR * a_pszFile,
bool a_bIsUtf8,
bool a_bUseMultiKey,
bool a_bUseMultiLine
)
{
// load the file
CSimpleIni ini(a_bIsUtf8, a_bUseMultiKey, a_bUseMultiLine);
_tprintf(_T("Loading file: %s\n"), a_pszFile);
SI_Error rc = ini.LoadFile(a_pszFile);
if (rc < 0) {
printf("Failed to open file.\n");
return false;
}
// run the tests
Test(ini);
// save the file (simple)
_tprintf(_T("\n-- Saving file to: testsi-out.ini\n"));
ini.SaveFile("testsi-out.ini");
// save the file (with comments)
// Note: to save the file and add a comment to the beginning, use
// code such as the following.
_tprintf(_T("\n-- Saving file to: testsi-out-comment.ini\n"));
FILE * fp = NULL;
#if __STDC_WANT_SECURE_LIB__
fopen_s(&fp, "testsi-out-comment.ini", "wb");
#else
fp = fopen("testsi-out-comment.ini", "wb");
#endif
if (fp) {
CSimpleIni::FileWriter writer(fp);
if (a_bIsUtf8) {
writer.Write(SI_UTF8_SIGNATURE);
}
// add a string to the file in the correct text format
CSimpleIni::Converter convert = ini.GetConverter();
convert.ConvertToStore(_T("; output from testsi.cpp test program")
SI_NEWLINE SI_NEWLINE);
writer.Write(convert.Data());
ini.Save(writer, false);
fclose(fp);
}
return true;
}
static bool
ParseCommandLine(
int argc,
TCHAR * argv[],
const TCHAR * & a_pszFile,
bool & a_bIsUtf8,
bool & a_bUseMultiKey,
bool & a_bUseMultiLine
)
{
a_pszFile = 0;
a_bIsUtf8 = false;
a_bUseMultiKey = false;
a_bUseMultiLine = false;
for (--argc; argc > 0; --argc) {
if (argv[argc][0] == '-') {
switch (argv[argc][1]) {
case TCHAR('u'):
a_bIsUtf8 = true;
break;
case TCHAR('m'):
a_bUseMultiKey = true;
break;
case TCHAR('l'):
a_bUseMultiLine = true;
break;
}
}
else {
a_pszFile = argv[argc];
}
}
if (!a_pszFile) {
_tprintf(
_T("Usage: testsi [-u] [-m] [-l] iniFile\n")
_T(" -u Load file as UTF-8 (Default is to use system locale)\n")
_T(" -m Enable multiple keys\n")
_T(" -l Enable multiple line values\n")
);
return false;
}
return true;
}
extern bool TestStreams();
int
_tmain(
int argc,
TCHAR * argv[]
)
{
setlocale(LC_ALL, "");
// start of automated testing...
TestStreams();
// parse the command line
const TCHAR * pszFile;
bool bIsUtf8, bUseMultiKey, bUseMultiLine;
if (!ParseCommandLine(argc, argv, pszFile, bIsUtf8, bUseMultiKey, bUseMultiLine)) {
return 1;
}
// run the test
if (!TestFile(pszFile, bIsUtf8, bUseMultiKey, bUseMultiLine)) {
return 1;
}
#if defined(SI_SUPPORT_IOSTREAMS) && !defined(_UNICODE)
if (!TestStreams(pszFile, bIsUtf8, bUseMultiKey, bUseMultiLine)) {
return 1;
}
#endif
return 0;
}

View File

@ -67,7 +67,7 @@ common/iman.cpp
# common/restext.cpp
common/stringutils.cpp
graphics/core/color.cpp
# graphics/engine/camera.cpp # new code but depends on other modules
graphics/engine/camera.cpp
graphics/engine/cloud.cpp
graphics/engine/engine.cpp
graphics/engine/lightman.cpp
@ -176,6 +176,7 @@ graphics/opengl/gldevice.cpp
set(LIBS
${SDL_LIBRARY}
${SDLIMAGE_LIBRARY}
${SDLTTF_LIBRARY}
${OPENGL_LIBRARY}
${PNG_LIBRARIES}
${OPTIONAL_LIBS}

View File

@ -1,3 +1,4 @@
src/app
Contains the main class of the application.
/**
* \dir app
* Main class of the application and system functions
*/

View File

@ -122,6 +122,7 @@ bool CApplication::ParseArguments(int argc, char *argv[])
{
waitDataDir = false;
m_dataPath = arg;
continue;
}
if (arg == "-debug")
@ -153,10 +154,6 @@ bool CApplication::Create()
// Temporarily -- only in windowed mode
m_deviceConfig.fullScreen = false;
// Create the 3D engine
m_engine = new Gfx::CEngine(m_iMan, this);
/* // Create the sound instance.
m_sound = new CSound(m_iMan);
@ -218,27 +215,20 @@ bool CApplication::Create()
if (! m_device->Create() )
{
SystemDialog( SDT_ERROR, "COLOBT - Fatal Error",
std::string("Error in CDevice::Create() :\n") +
std::string(m_device->GetError()) );
std::string("Error in CDevice::Create()") );
m_exitCode = 1;
return false;
}
// Create the 3D engine
m_engine = new Gfx::CEngine(m_iMan, this);
m_engine->SetDevice(m_device);
if (! m_engine->Create() )
{
SystemDialog( SDT_ERROR, "COLOBT - Fatal Error",
std::string("Error in CEngine::Create() :\n") +
std::string(m_engine->GetError()) );
m_exitCode = 1;
return false;
}
if (! m_engine->AfterDeviceSetInit() )
{
SystemDialog( SDT_ERROR, "COLOBT - Fatal Error",
std::string("Error in CEngine::AfterDeviceSetInit() :\n") +
std::string(m_engine->GetError()) );
std::string("Error in CEngine::Init()") );
m_exitCode = 1;
return false;
}
@ -293,7 +283,7 @@ bool CApplication::CreateVideoSurface()
if (m_deviceConfig.hardwareAccel)
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
m_private->surface = SDL_SetVideoMode(m_deviceConfig.size.w, m_deviceConfig.size.h,
m_private->surface = SDL_SetVideoMode(m_deviceConfig.size.x, m_deviceConfig.size.y,
m_deviceConfig.bpp, videoFlags);
return true;
@ -315,8 +305,7 @@ void CApplication::Destroy()
if (m_engine != NULL)
{
if (m_engine->GetWasInit())
m_engine->Destroy();
m_engine->Destroy();
delete m_engine;
m_engine = NULL;
@ -324,8 +313,7 @@ void CApplication::Destroy()
if (m_device != NULL)
{
if (m_device->GetWasInit())
m_device->Destroy();
m_device->Destroy();
delete m_device;
m_device = NULL;
@ -508,6 +496,14 @@ void CApplication::UpdateJoystick()
}
}
void CApplication::UpdateMouse()
{
Math::IntPoint pos;
SDL_GetMouseState(&pos.x, &pos.y);
m_systemMousePos = m_engine->WindowToInterfaceCoords(pos);
m_engine->SetMousePos(m_systemMousePos);
}
int CApplication::Run()
{
m_active = true;
@ -582,17 +578,12 @@ int CApplication::Run()
m_robotMain->ProcessEvent(event); */
}
// Update game and render a frame during idle time (no messages are waiting)
bool ok = Render();
/* Update mouse position explicitly right before rendering
* because mouse events are usually way behind */
UpdateMouse();
// If an error occurs, push quit event to the queue
if (! ok)
{
SDL_Event quitEvent;
memset(&quitEvent, 0, sizeof(SDL_Event));
quitEvent.type = SDL_QUIT;
SDL_PushEvent(&quitEvent);
}
// Update game and render a frame during idle time (no messages are waiting)
Render();
}
}
@ -616,21 +607,6 @@ PressState TranslatePressState(unsigned char state)
return STATE_RELEASED;
}
/** Conversion of the position of the mouse from window coords to interface coords:
- x: 0=left, 1=right
- y: 0=down, 1=up */
Math::Point CApplication::WindowToInterfaceCoords(Math::IntPoint pos)
{
return Math::Point( static_cast<float>(pos.x) / static_cast<float>(m_deviceConfig.size.w),
1.0f - static_cast<float>(pos.y) / static_cast<float>(m_deviceConfig.size.h) );
}
Math::IntPoint CApplication::InterfaceToWindowCoords(Math::Point pos)
{
return Math::IntPoint(static_cast<int>(pos.x * m_deviceConfig.size.w),
static_cast<int>((1.0f - pos.y) * m_deviceConfig.size.h));
}
/** The SDL event parsed is stored internally.
If event is not available or is not understood, returned event is of type EVENT_NULL. */
Event CApplication::ParseEvent()
@ -666,14 +642,16 @@ Event CApplication::ParseEvent()
event.mouseButton.button = m_private->currentEvent.button.button;
event.mouseButton.state = TranslatePressState(m_private->currentEvent.button.state);
event.mouseButton.pos = WindowToInterfaceCoords(Math::IntPoint(m_private->currentEvent.button.x, m_private->currentEvent.button.y));
event.mouseButton.pos = m_engine->WindowToInterfaceCoords(
Math::IntPoint(m_private->currentEvent.button.x, m_private->currentEvent.button.y));
}
else if (m_private->currentEvent.type == SDL_MOUSEMOTION)
{
event.type = EVENT_MOUSE_MOVE;
event.mouseMove.state = TranslatePressState(m_private->currentEvent.button.state);
event.mouseMove.pos = WindowToInterfaceCoords(Math::IntPoint(m_private->currentEvent.button.x, m_private->currentEvent.button.y));
event.mouseMove.pos = m_engine->WindowToInterfaceCoords(
Math::IntPoint(m_private->currentEvent.button.x, m_private->currentEvent.button.y));
}
else if (m_private->currentEvent.type == SDL_JOYAXISMOTION)
{
@ -774,17 +752,13 @@ bool CApplication::ProcessEvent(const Event &event)
return true;
}
/** Renders the frame and swaps buffers as necessary. Returns \c false on error. */
bool CApplication::Render()
/** Renders the frame and swaps buffers as necessary */
void CApplication::Render()
{
bool result = m_engine->Render();
if (! result)
return false;
m_engine->Render();
if (m_deviceConfig.doubleBuf)
SDL_GL_SwapBuffers();
return true;
}
void CApplication::StepSimulation(float rTime)
@ -792,7 +766,12 @@ void CApplication::StepSimulation(float rTime)
// TODO
}
VideoQueryResult CApplication::GetVideoResolutionList(std::vector<Math::IntSize> &resolutions,
Gfx::GLDeviceConfig CApplication::GetVideoConfig()
{
return m_deviceConfig;
}
VideoQueryResult CApplication::GetVideoResolutionList(std::vector<Math::IntPoint> &resolutions,
bool fullScreen, bool resizeable)
{
resolutions.clear();
@ -830,7 +809,7 @@ VideoQueryResult CApplication::GetVideoResolutionList(std::vector<Math::IntSize>
for (int i = 0; modes[i] != NULL; ++i)
resolutions.push_back(Math::IntSize(modes[i]->w, modes[i]->h));
resolutions.push_back(Math::IntPoint(modes[i]->w, modes[i]->h));
return VIDEO_QUERY_OK;
}
@ -888,10 +867,9 @@ bool CApplication::GetSystemMouseVisibile()
return result == SDL_ENABLE;
}
void CApplication::SetSystemMousePos(Math::Point pos)
{
Math::IntPoint windowPos = InterfaceToWindowCoords(pos);
Math::IntPoint windowPos = m_engine->InterfaceToWindowCoords(pos);
SDL_WarpMouse(windowPos.x, windowPos.y);
m_systemMousePos = pos;
}

View File

@ -15,7 +15,10 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// app.h
/**
* \file app/app.h
* \brief CApplication class
*/
#pragma once
@ -25,7 +28,6 @@
#include "graphics/core/device.h"
#include "graphics/engine/engine.h"
#include "graphics/opengl/gldevice.h"
#include "math/intsize.h"
#include <string>
#include <vector>
@ -133,7 +135,7 @@ public:
void Destroy();
//! Returns a list of possible video modes
VideoQueryResult GetVideoResolutionList(std::vector<Math::IntSize> &resolutions,
VideoQueryResult GetVideoResolutionList(std::vector<Math::IntPoint> &resolutions,
bool fullScreen, bool resizeable);
//! Returns the current video mode
@ -162,6 +164,9 @@ public:
//! Polls the state of joystick axes and buttons
void UpdateJoystick();
//! Updates the mouse position explicitly
void UpdateMouse();
void FlushPressKey();
void ResetKey();
void SetKey(int keyRank, int option, int key);
@ -199,18 +204,13 @@ protected:
//! Handles some incoming events
bool ProcessEvent(const Event &event);
//! Renders the image in window
bool Render();
void Render();
//! Opens the joystick device
bool OpenJoystick();
//! Closes the joystick device
void CloseJoystick();
//! Converts window coords to interface coords
Math::Point WindowToInterfaceCoords(Math::IntPoint pos);
//! Converts the interface coords to window coords
Math::IntPoint InterfaceToWindowCoords(Math::Point pos);
protected:
//! Instance manager
CInstanceManager* m_iMan;

View File

@ -15,7 +15,10 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// main.cpp
/**
* \file app/main.cpp
* \brief Entry point of application - main() function
*/
#include "app/app.h"
#include "app/system.h"

View File

@ -15,7 +15,10 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// system.h
/**
* \file app/system.h
* \brief System functions: time stamps, info dialogs, etc.
*/
#pragma once
@ -26,7 +29,7 @@
/* Dialog utils */
/**
* \enum SysDialogType
* \enum SystemDialogType
* \brief Type of system dialog
*/
enum SystemDialogType
@ -44,7 +47,7 @@ enum SystemDialogType
};
/**
* \enum SysDialogResult
* \enum SystemDialogResult
* \brief Result of system dialog
*
* Means which button was pressed.

View File

@ -15,10 +15,13 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// system_linux.h
/**
* \file app/system_linux.h
* \brief Linux-specific implementation of system functions
*/
/* This header contains Linux-specific code for system utils
from system.h. There is no separate .cpp module for simplicity.*/
/* NOTE: code is contained in this header;
* there is no separate .cpp module for simplicity */
#include <sys/time.h>
#include <time.h>

View File

@ -15,10 +15,13 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// system_other.h
/**
* \file app/system_other.h
* \brief Fallback code for other systems
*/
/* This header contains fallback code for other platforms for system utils
from system.h. There is no separate .cpp module for simplicity.*/
/* NOTE: code is contained in this header;
* there is no separate .cpp module for simplicity */
#include <SDL/SDL.h>

View File

@ -15,10 +15,13 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// system_windows.h
/**
* \file app/system_windows.h
* \brief Windows-specific implementation of system functions
*/
/* This header contains Windows-specific code for system utils
from system.h. There is no separate .cpp module for simplicity.*/
/* NOTE: code is contained in this header;
* there is no separate .cpp module for simplicity */
#include <windows.h>

View File

@ -1,3 +1,4 @@
src/common
Contains headers and modules with common structs and enums.
/**
* \dir common
* \brief Structs and utils shared throughout the application
*/

View File

@ -19,8 +19,8 @@
#pragma once
#include "common/key.h"
#include "math/point.h"
#include <common/key.h>
#include <math/point.h>
#include <string.h>
@ -40,9 +40,10 @@ enum EventType
EVENT_NULL = 0,
//! Event sent on user or system quit request
EVENT_QUIT = 1,
EVENT_QUIT = 1,
//? EVENT_FRAME = 2,
//! Frame update event
EVENT_FRAME = 2,
//! Event sent after pressing a mouse button
EVENT_MOUSE_BUTTON_DOWN = 3,
@ -669,29 +670,41 @@ struct Event
//! If true, the event was produced by system (SDL); else, it has come from user interface
bool systemEvent;
//! Additional data for EVENT_KEY_DOWN and EVENT_KEY_UP
KeyEventData key;
//! Additional data for EVENT_MOUSE_BUTTON_DOWN and EVENT_MOUSE_BUTTON_UP
MouseButtonEventData mouseButton;
//! Additional data for EVENT_MOUSE_MOVE
MouseMoveEventData mouseMove;
//! Additional data for EVENT_JOY
JoyAxisEventData joyAxis;
//! Additional data for EVENT_JOY_AXIS
JoyButtonEventData joyButton;
//! Additional data for EVENT_ACTIVE
ActiveEventData active;
union
{
//! Additional data for EVENT_KEY_DOWN and EVENT_KEY_UP
KeyEventData key;
//! Additional data for EVENT_MOUSE_BUTTON_DOWN and EVENT_MOUSE_BUTTON_UP
MouseButtonEventData mouseButton;
//! Additional data for EVENT_MOUSE_MOVE
MouseMoveEventData mouseMove;
//! Additional data for EVENT_JOY
JoyAxisEventData joyAxis;
//! Additional data for EVENT_JOY_AXIS
JoyButtonEventData joyButton;
//! Additional data for EVENT_ACTIVE
ActiveEventData active;
};
//? long param; // parameter
//? Math::Point pos; // mouse position (0 .. 1)
//? float axeX; // control the X axis (-1 .. 1)
//? float axeY; // control of the Y axis (-1 .. 1)
//? float axeZ; // control the Z axis (-1 .. 1)
//? short keyState; // state of the keyboard (KS_ *)
//? float rTime; // relative time
// TODO: refactor/rewrite
long param; // parameter
Math::Point pos; // mouse position (0 .. 1)
float axeX; // control the X axis (-1 .. 1)
float axeY; // control of the Y axis (-1 .. 1)
float axeZ; // control the Z axis (-1 .. 1)
short keyState; // state of the keyboard (KS_ *)
float rTime; // relative time
Event(EventType aType = EVENT_NULL)
: type(aType), systemEvent(false) {}
{
type = aType;
systemEvent = false;
param = 0;
axeX = axeY = axeZ = 0.0f;
keyState = 0;
rTime = 0.0f;
}
};

View File

@ -23,6 +23,21 @@
#include "common/iman.h"
template<> CInstanceManager* CSingleton<CInstanceManager>::mInstance = nullptr;
CInstanceManager& CInstanceManager::GetInstance()
{
assert(mInstance);
return *mInstance;
}
CInstanceManager* CInstanceManager::GetInstancePointer()
{
assert(mInstance);
return mInstance;
}
// Object's constructor.

View File

@ -18,8 +18,8 @@
#pragma once
#include "common/misc.h"
#include <common/singleton.h>
#include <common/misc.h>
@ -32,7 +32,7 @@ struct BaseClass
class CInstanceManager
class CInstanceManager : public CSingleton<CInstanceManager>
{
public:
CInstanceManager();
@ -44,6 +44,8 @@ public:
bool DeleteInstance(ClassType classType, void* pointer);
void* SearchInstance(ClassType classType, int rank=0);
static CInstanceManager& GetInstance();
static CInstanceManager* GetInstancePointer();
protected:
void Compress(ClassType classType);

View File

@ -21,21 +21,7 @@
#include <stdio.h>
template<> CLogger* CSingleton<CLogger>::mInstance = 0;
CLogger& CLogger::GetInstance()
{
assert(mInstance);
return *mInstance;
}
CLogger* CLogger::GetInstancePointer()
{
assert(mInstance);
return mInstance;
}
template<> CLogger* CSingleton<CLogger>::mInstance = nullptr;
CLogger::CLogger()

View File

@ -21,6 +21,7 @@
#include <string>
#include <cstdarg>
#include <cstdio>
#include <common/singleton.h>
@ -57,42 +58,39 @@ class CLogger : public CSingleton<CLogger>
~CLogger();
/** Write message to console or file
* @param const char str - message to write
* @param str - message to write
* @param ... - additional arguments
*/
void Message(const char *str, ...);
/** Write message to console or file with LOG_INFO level
* @param const char str - message to write
* @param str - message to write
* @param ... - additional arguments
*/
void Info(const char *str, ...);
/** Write message to console or file with LOG_WARN level
* @param const char str - message to write
* @param str - message to write
* @param ... - additional arguments
*/
void Warn(const char *str, ...);
/** Write message to console or file with LOG_ERROR level
* @param const char str - message to write
* @param str - message to write
* @param ... - additional arguments
*/
void Error(const char *str, ...);
/** Set output file to write logs to
* @param std::string filename - output file to write to
* @param filename - output file to write to
*/
void SetOutputFile(std::string filename);
/** Set log level. Logs with level below will not be shown
* @param LogType level - minimum log level to write
* @param level - minimum log level to write
*/
void SetLogLevel(LogType level);
static CLogger& GetInstance();
static CLogger* GetInstancePointer();
private:
std::string mFilename;
FILE *mFile;

View File

@ -17,98 +17,89 @@
// profile.cpp
#include <stdio.h>
#include <d3d.h>
#include <stdlib.h>
#include "common/language.h"
#include "common/struct.h"
#include "common/profile.h"
#include <common/profile.h>
static char g_filename[100];
template<> CProfile* CSingleton<CProfile>::mInstance = nullptr;
bool InitCurrentDirectory()
CProfile::CProfile()
{
#if _SCHOOL
_fullpath(g_filename, "ceebot.ini", 100);
#else
_fullpath(g_filename, "colobot.ini", 100);
#endif
return true;
m_ini = new CSimpleIniA();
m_ini->SetUnicode();
m_ini->SetMultiKey();
}
bool SetLocalProfileString(char* section, char* key, char* string)
CProfile::~CProfile()
{
WritePrivateProfileString(section, key, string, g_filename);
return true;
m_ini->Reset();
delete m_ini;
}
bool GetLocalProfileString(char* section, char* key, char* buffer, int max)
{
int nb;
nb = GetPrivateProfileString(section, key, "", buffer, max, g_filename);
if ( nb == 0 )
{
buffer[0] = 0;
return false;
bool CProfile::InitCurrentDirectory()
{
bool result = m_ini->LoadFile("colobot.ini") == SI_OK;
return result;
}
bool CProfile::SetLocalProfileString(std::string section, std::string key, std::string value)
{
return (m_ini->SetValue(section.c_str(), key.c_str(), value.c_str()) == SI_OK);
}
bool CProfile::GetLocalProfileString(std::string section, std::string key, std::string &buffer)
{
const char* value = m_ini->GetValue(section.c_str(), key.c_str(), nullptr);
if (strlen(value) > 0) {
buffer = std::string(value);
return true;
}
return false;
}
bool CProfile::SetLocalProfileInt(std::string section, std::string key, int value)
{
return (m_ini->SetLongValue(section.c_str(), key.c_str(), value) == SI_OK);
}
bool CProfile::GetLocalProfileInt(std::string section, std::string key, int &value)
{
value = m_ini->GetLongValue(section.c_str(), key.c_str(), 0L);
return true;
}
bool SetLocalProfileInt(char* section, char* key, int value)
bool CProfile::SetLocalProfileFloat(std::string section, std::string key, float value)
{
char s[20];
return (m_ini->SetDoubleValue(section.c_str(), key.c_str(), value) == SI_OK);
}
sprintf(s, "%d", value);
WritePrivateProfileString(section, key, s, g_filename);
bool CProfile::GetLocalProfileFloat(std::string section, std::string key, float &value)
{
value = m_ini->GetDoubleValue(section.c_str(), key.c_str(), 0.0d);
return true;
}
bool GetLocalProfileInt(char* section, char* key, int &value)
{
char s[20];
int nb;
nb = GetPrivateProfileString(section, key, "", s, 20, g_filename);
if ( nb == 0 )
{
value = 0;
return false;
std::vector< std::string > CProfile::GetLocalProfileSection(std::string section, std::string key)
{
std::vector< std::string > ret_list;
CSimpleIniA::TNamesDepend values;
m_ini->GetAllValues(section.c_str(), key.c_str(), values);
values.sort(CSimpleIniA::Entry::LoadOrder());
for (auto item : values) {
ret_list.push_back(item.pItem);
}
sscanf(s, "%d", &value);
return true;
return ret_list;
}
bool SetLocalProfileFloat(char* section, char* key, float value)
{
char s[20];
sprintf(s, "%.2f", value);
WritePrivateProfileString(section, key, s, g_filename);
return true;
}
bool GetLocalProfileFloat(char* section, char* key, float &value)
{
char s[20];
int nb;
nb = GetPrivateProfileString(section, key, "", s, 20, g_filename);
if ( nb == 0 )
{
value = 0.0f;
return false;
}
sscanf(s, "%f", &value);
return true;
}

View File

@ -18,13 +18,97 @@
#pragma once
#include <cstdlib>
#include <vector>
#include <utility>
extern bool InitCurrentDirectory();
extern bool SetLocalProfileString(char* section, char* key, char* string);
extern bool GetLocalProfileString(char* section, char* key, char* buffer, int max);
extern bool SetLocalProfileInt(char* section, char* key, int value);
extern bool GetLocalProfileInt(char* section, char* key, int &value);
extern bool SetLocalProfileFloat(char* section, char* key, float value);
extern bool GetLocalProfileFloat(char* section, char* key, float &value);
#include <lib/simpleini/SimpleIni.h>
#include <common/singleton.h>
/**
* @file common/profile.h
* @brief Class for loading profile (currently for loading ini config file)
*/
/**
* @class CProfile
*
* @brief Class for loading profile (currently for loading ini config file)
*
*/
class CProfile : public CSingleton<CProfile>
{
public:
CProfile();
~CProfile();
/** Loads colobot.ini from current directory
* @return return true on success
*/
bool InitCurrentDirectory();
/** Sets string value in section under specified key
* @param std::string section
* @param std::string key
* @param std::string value
* @return return true on success
*/
bool SetLocalProfileString(std::string section, std::string key, std::string value);
/** Gets string value in section under specified key
* @param std::string section
* @param std::string key
* @param std::string& buffer
* @return return true on success
*/
bool GetLocalProfileString(std::string section, std::string key, std::string& buffer);
/** Sets int value in section under specified key
* @param std::string section
* @param std::string key
* @param int value
* @return return true on success
*/
bool SetLocalProfileInt(std::string section, std::string key, int value);
/** Gets int value in section under specified key
* @param std::string section
* @param std::string key
* @param int& value
* @return return true on success
*/
bool GetLocalProfileInt(std::string section, std::string key, int &value);
/** Sets float value in section under specified key
* @param std::string section
* @param std::string key
* @param float value
* @return return true on success
*/
bool SetLocalProfileFloat(std::string section, std::string key, float value);
/** Gets float value in section under specified key
* @param std::string section
* @param std::string key
* @param float& value
* @return return true on success
*/
bool GetLocalProfileFloat(std::string section, std::string key, float &value);
/** Gets all values in section under specified key
* @param std::string section
* @param std::string key
* @return vector of values
*/
std::vector< std::string > GetLocalProfileSection(std::string section, std::string key);
private:
CSimpleIniA *m_ini;
};
//! Global function to get profile instance
inline CProfile* GetProfile() {
return CProfile::GetInstancePointer();
}

View File

@ -135,15 +135,11 @@ int StrUtils::Utf8CharSizeAt(const std::string &str, unsigned int pos)
size_t StrUtils::Utf8StringLength(const std::string &str)
{
size_t result = 0;
for (unsigned int i = 0; i < str.size(); ++i)
unsigned int i = 0;
while (i < str.size())
{
char ch = str[i];
if ((ch & 0x80) == 0)
i += Utf8CharSizeAt(str, i);
++result;
else if ((ch & 0xC0) == 0xC0)
result += 2;
else
result += 3;
}
return result;
}

View File

@ -1,6 +1,12 @@
cmake_minimum_required(VERSION 2.8)
set(CMAKE_BUILD_TYPE debug)
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g -O0")
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g -O0 -std=c++11")
include_directories("../../")
include_directories("../../../")
add_executable(image_test ../image.cpp image_test.cpp)
add_executable(profile_test ../profile.cpp profile_test.cpp)
add_test(profile_test ./profile_test)

View File

@ -0,0 +1,15 @@
[test_float]
float_value=1.5
[test_string]
string_value=Hello world
[test_int]
int_value=42
[test_multi]
entry=1
entry=2
entry=3
entry=4
entry=5

View File

@ -0,0 +1,43 @@
#include "../profile.h"
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
CProfile profile;
profile.InitCurrentDirectory(); // load colobot.ini file
string result;
profile.GetLocalProfileString("test_string", "string_value", result);
if (result != "Hello world") {
cout << "GetLocalProfileString failed!" << endl;
return 1;
}
int int_value;
profile.GetLocalProfileInt("test_int", "int_value", int_value);
if (int_value != 42) {
cout << "GetLocalProfileInt failed!" << endl;
return 1;
}
float float_value;
profile.GetLocalProfileFloat("test_float", "float_value", float_value);
if (float_value != 1.5) {
cout << "GetLocalProfileFloat failed!" << endl;
return 1;
}
vector<string> list;
list = profile.GetLocalProfileSection("test_multi", "entry");
if (list.size() != 5) {
cout << "GetLocalProfileSection failed!" << endl;
return 1;
}
return 0;
}

View File

@ -1,3 +1,12 @@
src/graphics
/**
* \dir graphics
* \brief Graphics engine
*/
Graphics engine
/**
* \namespace Gfx
* \brief Namespace for (new) graphics code
*
* This namespace was created to avoid clashing with old code, but now it still serves,
* defining a border between pure graphics engine and other parts of application.
*/

View File

@ -1,6 +1,7 @@
src/graphics/core
Abstract core of graphics engine
Core types, enums, structs and CDevice abstract class that define
the abstract graphics device used in graphics engine
/**
* \dir graphics/core
* \brief Abstract core of graphics engine
*
* Core types, enums, structs and CDevice abstract class that define
* the abstract graphics device used in graphics engine
*/

View File

@ -14,11 +14,13 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// color.h
/**
* \file graphics/core/color.h
* \brief Color structs and related functions
*/
#pragma once
#include <sstream>
@ -66,6 +68,11 @@ struct Color
{
return r == other.r && g == other.g && b == other.b && a == other.a;
}
inline bool operator!=(const Gfx::Color &other) const
{
return ! this->operator==(other);
}
};
/**

View File

@ -15,7 +15,10 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// device.h
/**
* \file graphics/core/device.h
* \brief Abstract graphics device - Gfx::CDevice class and related structs/enums
*/
#pragma once
@ -25,13 +28,14 @@
#include "graphics/core/material.h"
#include "graphics/core/texture.h"
#include "graphics/core/vertex.h"
#include "math/intsize.h"
#include "math/intpoint.h"
#include "math/matrix.h"
#include <string>
class CImage;
struct ImageData;
namespace Gfx {
@ -45,7 +49,7 @@ namespace Gfx {
struct DeviceConfig
{
//! Screen size
Math::IntSize size;
Math::IntPoint size;
//! Bits per pixel
int bpp;
//! Full screen
@ -63,7 +67,7 @@ struct DeviceConfig
//! Loads the default values
inline void LoadDefault()
{
size = Math::IntSize(800, 600);
size = Math::IntPoint(800, 600);
bpp = 32;
fullScreen = false;
resizeable = false;
@ -149,9 +153,9 @@ enum FogMode
\brief Culling mode for polygons */
enum CullMode
{
//! Cull clockwise side
//! Cull clockwise faces
CULL_CW,
//! Cull counter-clockwise side
//! Cull counter-clockwise faces
CULL_CCW
};
@ -274,13 +278,14 @@ class CDevice
public:
virtual ~CDevice() {}
//! Provides a hook to debug graphics code (implementation-specific)
virtual void DebugHook() = 0;
//! Initializes the device, setting the initial state
virtual bool Create() = 0;
//! Destroys the device, releasing every acquired resource
virtual void Destroy() = 0;
//! Returns whether the device has been initialized
virtual bool GetWasInit() = 0;
//! Returns the last encountered error
virtual std::string GetError() = 0;
@ -317,6 +322,8 @@ public:
//! Creates a texture from image; the image can be safely removed after that
virtual Gfx::Texture CreateTexture(CImage *image, const Gfx::TextureCreateParams &params) = 0;
//! Creates a texture from raw image data; image data can be freed after that
virtual Gfx::Texture CreateTexture(ImageData *data, const Gfx::TextureCreateParams &params) = 0;
//! Deletes a given texture, freeing it from video memory
virtual void DestroyTexture(const Gfx::Texture &texture) = 0;
//! Deletes all textures created so far
@ -324,8 +331,10 @@ public:
//! Returns the maximum number of multitexture stages
virtual int GetMaxTextureCount() = 0;
//! Sets the (multi)texture at given index
//! Sets the texture at given texture stage
virtual void SetTexture(int index, const Gfx::Texture &texture) = 0;
//! Sets the texture image by ID at given texture stage
virtual void SetTexture(int index, unsigned int textureId) = 0;
//! Returns the (multi)texture at given index
virtual Gfx::Texture GetTexture(int index) = 0;
//! Enables/disables the given texture stage

View File

@ -15,7 +15,10 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// light.h
/**
* \file graphics/core/light.h
* \brief Light struct and related enums
*/
#pragma once

View File

@ -14,7 +14,10 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// material.h
/**
* \file graphics/core/material.h
* \brief Material struct
*/
#pragma once

View File

@ -14,11 +14,14 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// texture.h
/**
* \file graphics/core/texture.h
* \brief Texture struct and related enums
*/
#pragma once
#include "math/intsize.h"
#include "math/intpoint.h"
namespace Gfx {
@ -194,7 +197,7 @@ struct Texture
//! ID of the texture in graphics engine
unsigned int id;
//! Size of texture
Math::IntSize size;
Math::IntPoint size;
//! Whether the texture has alpha channel
bool alpha;

View File

@ -14,7 +14,10 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// vertex.h
/**
* \file graphics/core/vertex.h
* \brief Vertex structs
*/
#pragma once

View File

@ -1,3 +1,4 @@
src/graphics/d3d
Possible future DirectX implementation of graphics engine
/**
* \dir graphics/d3d
* \brief Possible future DirectX implementation of graphics engine
*/

View File

@ -1,8 +1,9 @@
src/graphics/engine
Graphics engine
CEngine class and various other classes implementing the main features
of graphics engine from model loading to decorative particles
Graphics operations are done on abstract interface from src/graphics/core
/**
* \dir graphics/engine
* \brief Graphics engine
*
* CEngine class and various other classes implementing the main features
* of graphics engine from model loading to decorative particles
*
* Graphics operations are done on abstract interface from src/graphics/core
*/

View File

@ -29,6 +29,66 @@
#include "physics/physics.h"
// TODO temporary stubs for CObject and CPhysics
void CObject::SetTransparency(float)
{
}
CObject* CObject::GetFret()
{
return nullptr;
}
CObject* CObject::GetPower()
{
return nullptr;
}
CObject* CObject::GetTruck()
{
return nullptr;
}
ObjectType CObject::GetType()
{
return OBJECT_NULL;
}
void CObject::SetGunGoalH(float)
{
}
void CObject::GetGlobalSphere(Math::Vector &pos, float &radius)
{
}
float CObject::GetAngleY(int)
{
return 0.0f;
}
Math::Vector CObject::GetPosition(int)
{
return Math::Vector();
}
void CObject::SetViewFromHere(Math::Vector &eye, float &dirH, float &dirV,
Math::Vector &lookat, Math::Vector &upVec,
Gfx::CameraType type)
{
}
CPhysics* CObject::GetPhysics()
{
return nullptr;
}
bool CPhysics::GetLand()
{
return false;
}
//! Changes the level of transparency of an object and objects transported (battery & cargo)
void SetTransparency(CObject* obj, float value)
{
@ -332,7 +392,7 @@ void Gfx::CCamera::SetType(CameraType type)
SetSmooth(Gfx::CAM_SMOOTH_NORM);
}
CameraType Gfx::CCamera::GetType()
Gfx::CameraType Gfx::CCamera::GetType()
{
return m_type;
}
@ -342,7 +402,7 @@ void Gfx::CCamera::SetSmooth(CameraSmooth type)
m_smooth = type;
}
CameraSmooth Gfx::CCamera::GetSmoth()
Gfx::CameraSmooth Gfx::CCamera::GetSmoth()
{
return m_smooth;
}
@ -692,7 +752,7 @@ void Gfx::CCamera::OverFrame(const Event &event)
}
else
{
color = Gfx::Color(0.0f. 0.0f, 0.0f);
color = Gfx::Color(0.0f, 0.0f, 0.0f);
}
color.a = 0.0f;
m_engine->SetOverColor(color, m_overMode);
@ -873,7 +933,7 @@ bool Gfx::CCamera::IsCollisionBack(Math::Vector &eye, Math::Vector lookat)
for (int i = 0 ;i < 1000000; i++)
{
CObject *obj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
CObject *obj = static_cast<CObject*>( m_iMan->SearchInstance(CLASS_OBJECT, i) );
if (obj == NULL) break;
if (obj->GetTruck()) continue; // battery or cargo?
@ -899,7 +959,7 @@ bool Gfx::CCamera::IsCollisionBack(Math::Vector &eye, Math::Vector lookat)
iType == OBJECT_SAFE ||
iType == OBJECT_HUSTON ) continue;
ObjType oType = obj->GetType();
ObjectType oType = obj->GetType();
if ( oType == OBJECT_HUMAN ||
oType == OBJECT_TECH ||
oType == OBJECT_TOTO ||
@ -995,7 +1055,6 @@ bool Gfx::CCamera::EventProcess(const Event &event)
{
switch (event.type)
{
// TODO: frame update event
case EVENT_FRAME:
EventFrame(event);
break;
@ -1004,11 +1063,11 @@ bool Gfx::CCamera::EventProcess(const Event &event)
EventMouseMove(event);
break;
case EVENT_KEY_DOWN:
// TODO: mouse wheel event
// TODO: mouse wheel event
/*case EVENT_KEY_DOWN:
if ( event.param == VK_WHEELUP ) EventMouseWheel(+1);
if ( event.param == VK_WHEELDOWN ) EventMouseWheel(-1);
break;
break;*/
default:
break;
@ -1489,8 +1548,6 @@ bool Gfx::CCamera::EventFrameFix(const Event &event)
bool Gfx::CCamera::EventFrameExplo(const Event &event)
{
float factor = m_heightEye * 0.5f + 30.0f;
if (m_mouseDirH != 0.0f)
m_directionH -= m_mouseDirH * event.rTime * 0.7f * m_speed;
@ -1526,7 +1583,7 @@ bool Gfx::CCamera::EventFrameOnBoard(const Event &event)
{
Math::Vector lookatPt, upVec;
m_cameraObj->SetViewFromHere(m_eyePt, m_directionH, m_directionV,
lookatPt, vUpVec, m_type);
lookatPt, upVec, m_type);
Math::Vector eye = m_effectOffset * 0.3f + m_eyePt;
Math::Vector lookat = m_effectOffset * 0.3f + lookatPt;

View File

@ -15,7 +15,10 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// camera.h
/**
* \file graphics/engine/camera.h
* \brief Camera handling - Gfx::CCamera class
*/
#pragma once
@ -353,13 +356,13 @@ protected:
float m_centeringTime;
float m_centeringProgress;
CameraEffect m_effectType;
Gfx::CameraEffect m_effectType;
Math::Vector m_effectPos;
float m_effectForce;
float m_effectProgress;
Math::Vector m_effectOffset;
OverEffect m_overType;
Gfx::CameraOverEffect m_overType;
float m_overForce;
float m_overTime;
Gfx::Color m_overColorBase;

View File

@ -19,5 +19,265 @@
#include "graphics/engine/cloud.h"
#include "common/iman.h"
#include "graphics/engine/engine.h"
#include "graphics/engine/terrain.h"
#include "math/geometry.h"
// TODO implementation
const int CLOUD_LINE_PREALLOCATE_COUNT = 100;
const int DIMEXPAND = 4; // extension of the dimensions
Gfx::CCloud::CCloud(CInstanceManager* iMan, Gfx::CEngine* engine)
{
m_iMan = iMan;
m_iMan->AddInstance(CLASS_CLOUD, this);
m_engine = engine;
m_terrain = nullptr;
m_level = 0.0f;
m_wind = Math::Vector(0.0f, 0.0f, 0.0f);
m_subdiv = 8;
m_enable = true;
m_line.reserve(CLOUD_LINE_PREALLOCATE_COUNT);
}
Gfx::CCloud::~CCloud()
{
m_iMan = nullptr;
m_engine = nullptr;
m_terrain = nullptr;
}
bool Gfx::CCloud::EventProcess(const Event &event)
{
if ( event.type == EVENT_FRAME )
return EventFrame(event);
return true;
}
bool Gfx::CCloud::EventFrame(const Event &event)
{
if (m_engine->GetPause()) return true;
m_time += event.rTime;
if (m_level == 0.0f) return true;
if (m_time - m_lastTest < 0.2f) return true;
m_lastTest = m_time;
return true;
}
void Gfx::CCloud::AdjustLevel(Math::Vector &pos, Math::Vector &eye, float deep,
Math::Point &uv1, Math::Point &uv2)
{
uv1.x = (pos.x+20000.0f)/1280.0f;
uv1.y = (pos.z+20000.0f)/1280.0f;
uv1.x -= m_time*(m_wind.x/100.0f);
uv1.y -= m_time*(m_wind.z/100.0f);
uv2.x = 0.0f;
uv2.y = 0.0f;
float dist = Math::DistanceProjected(pos, eye);
float factor = powf(dist/deep, 2.0f);
pos.y -= m_level*factor*10.0f;
}
void Gfx::CCloud::Draw()
{
/* TODO!
LPDIRECT3DDEVICE7 device;
D3DVERTEX2* vertex;
Math::Matrix* matView;
D3DMATERIAL7 material;
Math::Matrix matrix;
Math::Vector n, pos, p, eye;
Math::Point uv1, uv2;
float iDeep, deep, size, fogStart, fogEnd;
int i, j, u;
if ( !m_enable ) return;
if ( m_level == 0.0f ) return;
if ( m_lineUsed == 0 ) return;
vertex = (D3DVERTEX2*)malloc(sizeof(D3DVERTEX2)*(m_brick+2)*2);
iDeep = m_engine->GetDeepView();
deep = (m_brick*m_size)/2.0f;
m_engine->SetDeepView(deep);
m_engine->SetFocus(m_engine->GetFocus());
m_engine->UpdateMatProj(); // increases the depth of view
fogStart = deep*0.15f;
fogEnd = deep*0.24f;
device = m_engine->GetD3DDevice();
device->SetRenderState(D3DRENDERSTATE_AMBIENT, 0x00000000);
device->SetRenderState(D3DRENDERSTATE_LIGHTING, false);
device->SetRenderState(D3DRENDERSTATE_ZENABLE, false);
device->SetRenderState(D3DRENDERSTATE_FOGENABLE, true);
device->SetRenderState(D3DRENDERSTATE_FOGSTART, F2DW(fogStart));
device->SetRenderState(D3DRENDERSTATE_FOGEND, F2DW(fogEnd));
matView = m_engine->GetMatView();
{
D3DMATRIX mat = MAT_TO_D3DMAT(*matView);
device->SetTransform(D3DTRANSFORMSTATE_VIEW, &mat);
}
ZeroMemory( &material, sizeof(D3DMATERIAL7) );
material.diffuse = m_diffuse;
material.ambient = m_ambient;
m_engine->SetMaterial(material);
m_engine->SetTexture(m_filename, 0);
m_engine->SetTexture(m_filename, 1);
m_engine->SetState(D3DSTATETTb|D3DSTATEFOG|D3DSTATEWRAP);
matrix.LoadIdentity();
{
D3DMATRIX mat = MAT_TO_D3DMAT(matrix);
device->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat);
}
size = m_size/2.0f;
eye = m_engine->GetEyePt();
n = Math::Vector(0.0f, -1.0f, 0.0f);
// Draws all the lines.
for ( i=0 ; i<m_lineUsed ; i++ )
{
pos.y = m_level;
pos.z = m_line[i].pz;
pos.x = m_line[i].px1;
u = 0;
p.x = pos.x-size;
p.z = pos.z+size;
p.y = pos.y;
AdjustLevel(p, eye, deep, uv1, uv2);
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y);
p.x = pos.x-size;
p.z = pos.z-size;
p.y = pos.y;
AdjustLevel(p, eye, deep, uv1, uv2);
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y);
for ( j=0 ; j<m_line[i].len ; j++ )
{
p.x = pos.x+size;
p.z = pos.z+size;
p.y = pos.y;
AdjustLevel(p, eye, deep, uv1, uv2);
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y);
p.x = pos.x+size;
p.z = pos.z-size;
p.y = pos.y;
AdjustLevel(p, eye, deep, uv1, uv2);
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y);
pos.x += size*2.0f;
}
device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, u, NULL);
m_engine->AddStatisticTriangle(u-2);
}
m_engine->SetDeepView(iDeep);
m_engine->SetFocus(m_engine->GetFocus());
m_engine->UpdateMatProj(); // gives depth to initial
free(vertex); */
}
void Gfx::CCloud::CreateLine(int x, int y, int len)
{
Gfx::CloudLine line;
line.x = x;
line.y = y;
line.len = len;
float offset = m_brick*m_size/2.0f - m_size/2.0f;
line.px1 = m_size* line.x - offset;
line.px2 = m_size*(line.x+line.len) - offset;
line.pz = m_size* line.y - offset;
m_line.push_back(line);
}
void Gfx::CCloud::Create(const std::string& fileName,
Gfx::Color diffuse, Gfx::Color ambient,
float level)
{
m_diffuse = diffuse;
m_ambient = ambient;
m_level = level;
m_time = 0.0f;
m_lastTest = 0.0f;
m_fileName = fileName;
if (! m_fileName.empty())
m_engine->LoadTexture(m_fileName);
if (m_terrain == nullptr)
m_terrain = static_cast<CTerrain*>(m_iMan->SearchInstance(CLASS_TERRAIN));
m_wind = m_terrain->GetWind();
m_brick = m_terrain->GetBrick()*m_terrain->GetMosaic()*DIMEXPAND;
m_size = m_terrain->GetSize();
m_brick /= m_subdiv*DIMEXPAND;
m_size *= m_subdiv*DIMEXPAND;
if (m_level == 0.0f)
return;
m_line.clear();
for (int y = 0; y < m_brick; y++)
CreateLine(0, y, m_brick);
return;
}
void Gfx::CCloud::Flush()
{
m_level = 0.0f;
}
void Gfx::CCloud::SetLevel(float level)
{
m_level = level;
Create(m_fileName, m_diffuse, m_ambient, m_level);
}
float Gfx::CCloud::GetLevel()
{
return m_level;
}
void Gfx::CCloud::SetEnable(bool enable)
{
m_enable = enable;
}
bool Gfx::CCloud::GetEnable()
{
return m_enable;
}

View File

@ -15,7 +15,10 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// cloud.h
/**
* \file graphics/engine/cloud.h
* \brief Cloud rendering - Gfx::CCloud class
*/
#pragma once
@ -24,6 +27,9 @@
#include "math/point.h"
#include "math/vector.h"
#include <vector>
#include <string>
class CInstanceManager;
@ -34,13 +40,20 @@ namespace Gfx {
class CEngine;
class CTerrain;
const short MAXCLOUDLINE = 100;
struct CloudLine
{
short x, y; // beginning
short len; // in length x
//! Beginning
short x, y;
//! In length x
short len;
float px1, px2, pz;
CloudLine()
{
x = y = 0;
len = 0;
px1 = px2 = pz = 0;
}
};
@ -51,43 +64,59 @@ public:
~CCloud();
bool EventProcess(const Event &event);
//! Removes all the clouds
void Flush();
bool Create(const char *filename, Gfx::Color diffuse, Gfx::Color ambient, float level);
//! Creates all areas of cloud
void Create(const std::string& fileName, Gfx::Color diffuse, Gfx::Color ambient, float level);
//! Draw the clouds
void Draw();
bool SetLevel(float level);
float RetLevel();
//! Modifies the cloud level
void SetLevel(float level);
//! Returns the current level of clouds
float GetLevel();
void SetEnable(bool bEnable);
bool RetEnable();
//! Activate management of clouds
void SetEnable(bool enable);
bool GetEnable();
protected:
//! Makes the clouds evolve
bool EventFrame(const Event &event);
void AdjustLevel(Math::Vector &pos, Math::Vector &eye, float deep, Math::Point &uv1, Math::Point &uv2);
bool CreateLine(int x, int y, int len);
//! Adjusts the position to normal, to imitate the clouds at movement
void AdjustLevel(Math::Vector &pos, Math::Vector &eye, float deep,
Math::Point &uv1, Math::Point &uv2);
//! Updates the positions, relative to the ground
void CreateLine(int x, int y, int len);
protected:
CInstanceManager* m_iMan;
CEngine* m_engine;
CTerrain* m_terrain;
CInstanceManager* m_iMan;
Gfx::CEngine* m_engine;
Gfx::CTerrain* m_terrain;
char m_filename[100];
float m_level; // overall level
Math::Point m_speed; // feedrate (wind)
Gfx::Color m_diffuse; // diffuse color
Gfx::Color m_ambient; // ambient color
std::string m_fileName;
//! Overall level
float m_level;
//! Feedrate (wind)
Math::Point m_speed;
//! Diffuse color
Gfx::Color m_diffuse;
//! Ambient color
Gfx::Color m_ambient;
float m_time;
float m_lastTest;
int m_subdiv;
Math::Vector m_wind; // wind speed
int m_brick; // brick mosaic
float m_size; // size of a brick element
//! Wind speed
Math::Vector m_wind;
//! Brick mosaic
int m_brick;
//! Size of a brick element
float m_size;
int m_lineUsed;
CloudLine m_line[MAXCLOUDLINE];
std::vector<Gfx::CloudLine> m_line;
bool m_bEnable;
bool m_enable;
};

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
// * This file is part of the COLOBOT source code
// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
// * Copyright (C) 2001-2008, Daniel ROUX& EPSITEC SA, www.epsitec.ch
// * Copyright (C) 2012, Polish Portal of Colobot (PPC)
// *
// * This program is free software: you can redistribute it and/or modify
@ -15,18 +15,20 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// engine.h
/**
* \file graphics/engine/engine.h
* \brief Main graphics engine - Gfx::CEngine class
*/
#pragma once
#include "app/system.h"
#include "common/event.h"
#include "graphics/core/color.h"
#include "graphics/core/material.h"
#include "graphics/core/texture.h"
#include "graphics/core/vertex.h"
#include "math/intpoint.h"
#include "math/intsize.h"
#include "math/matrix.h"
#include "math/point.h"
#include "math/vector.h"
@ -35,12 +37,13 @@
#include <string>
#include <vector>
#include <map>
#include <set>
class CApplication;
class CInstanceManager;
class CObject;
class CSound;
class CSoundInterface;
namespace Gfx {
@ -76,7 +79,7 @@ struct EngineTriangle
Gfx::VertexTex2 triangle[3];
//! Material
Gfx::Material material;
//! Render state (TODO: ?)
//! Render state
int state;
//! 1st texture
Gfx::Texture tex1;
@ -169,7 +172,10 @@ struct EngineObjLevel5
Gfx::EngineTriangleType type;
std::vector<Gfx::VertexTex2> vertices;
EngineObjLevel5();
EngineObjLevel5()
{
state = 0;
}
};
/**
@ -181,7 +187,10 @@ struct EngineObjLevel4
std::vector<Gfx::EngineObjLevel5> up;
Gfx::EngineObjLevel3* down;
EngineObjLevel4();
EngineObjLevel4()
{
reserved = 0;
}
};
/**
@ -194,7 +203,10 @@ struct EngineObjLevel3
std::vector<Gfx::EngineObjLevel4> up;
Gfx::EngineObjLevel2* down;
EngineObjLevel3();
EngineObjLevel3()
{
min = max = 0.0f;
}
};
/**
@ -206,7 +218,10 @@ struct EngineObjLevel2
std::vector<Gfx::EngineObjLevel3> up;
Gfx::EngineObjLevel1* down;
EngineObjLevel2();
EngineObjLevel2()
{
objRank = 0;
}
};
/**
@ -218,7 +233,7 @@ struct EngineObjLevel1
Gfx::Texture tex2;
std::vector<Gfx::EngineObjLevel2> up;
EngineObjLevel1();
EngineObjLevel1() {}
};
/**
@ -297,12 +312,14 @@ struct EngineGroundSpot
\brief Phase of life of an EngineGroundMark */
enum EngineGroundMarkPhase
{
//! Null phase
ENG_GR_MARK_PHASE_NULL = 0,
//! Increase
ENG_GR_MARK_PHASE_INC = 1,
//! Fixed
ENG_GR_MARK_PHASE_FIX = 2,
//! Decrease
ENG_GR_MARK_PHASE_DEC = 2
ENG_GR_MARK_PHASE_DEC = 3
};
/**
@ -407,7 +424,13 @@ enum EngineRenderState
//! The transparent color (black = no)
ENG_RSTATE_TCOLOR_BLACK = (1<<16),
//! The transparent color (white = no)
ENG_RSTATE_TCOLOR_WHITE = (1<<17)
ENG_RSTATE_TCOLOR_WHITE = (1<<17),
//! Mode for rendering text
ENG_RSTATE_TEXT = (1<<18),
//! Only opaque texture, no blending, etc.
ENG_RSTATE_OPAQUE_TEXTURE = (1<<19),
//! Only opaque color, no texture, blending, etc.
ENG_RSTATE_OPAQUE_COLOR = (1<<20)
};
@ -511,114 +534,138 @@ struct EngineMouse
class CEngine
{
public:
CEngine(CInstanceManager *iMan, CApplication *app);
CEngine(CInstanceManager* iMan, CApplication* app);
~CEngine();
//! Returns whether the device was initialized
bool GetWasInit();
//! Returns the last error encountered
std::string GetError();
//! Sets the device to be used
void SetDevice(Gfx::CDevice* device);
//! Returns the current device
Gfx::CDevice* GetDevice();
//! Performs the first initialization, before a device was set
//! Sets the terrain object
void SetTerrain(Gfx::CTerrain* terrain);
//! Returns the text rendering engine
CText* GetText();
//! Performs the initialization; must be called after device was set
bool Create();
//! Frees all resources before exit
void Destroy();
//! Sets the device to be used
void SetDevice(Gfx::CDevice *device);
//! Returns the current device
Gfx::CDevice* GetDevice();
//! Performs initialization after a device was created and set
bool AfterDeviceSetInit();
//! Resets some states and flushes textures after device was changed (e.g. resoulution changed)
void ResetAfterDeviceChanged();
void SetTerrain(Gfx::CTerrain* terrain);
//! Called once per frame, the call is the entry point for rendering
void Render();
//! Processes incoming event
bool ProcessEvent(const Event &event);
bool ProcessEvent(const Event& event);
//! Renders a single frame
bool Render();
//! Called once per frame, the call is the entry point for animating the scene
void FrameMove(float rTime);
//! Evolved throughout the game
void StepSimulation(float rTime);
bool WriteProfile();
//! Writes a screenshot containing the current frame
bool WriteScreenShot(const std::string& fileName, int width, int height);
//! Reads settings from INI
bool ReadSettings();
//! Writes settings to INI
bool WriteSettings();
//@{
//! Management of game pause mode
void SetPause(bool pause);
bool GetPause();
//@}
//@{
//! Management of lock for the duration of movie sequence
void SetMovieLock(bool lock);
bool GetMovieLock();
//@}
void SetShowStat(bool show);
bool GetShowStat();
//@{
//! Management of displaying statistic information
void SetShowStats(bool show);
bool GetShowStats();
//@}
//! Enables/disables rendering
void SetRenderEnable(bool enable);
int OneTimeSceneInit();
int InitDeviceObjects();
int DeleteDeviceObjects();
int RestoreSurfaces();
int FrameMove(float rTime);
void StepSimulation(float rTime);
int FinalCleanup();
//! Returns current size of viewport window
Math::IntPoint GetWindowSize();
//! Returns the last size of viewport window
Math::IntPoint GetLastWindowSize();
//@{
//! Conversion functions between window and interface coordinates
/** Window coordinates are from top-left (0,0) to bottom-right (w,h) - size of window
Interface cords are from bottom-left (0,0) to top-right (1,1) - and do not depend on window size */
Math::Point WindowToInterfaceCoords(Math::IntPoint pos);
Math::IntPoint InterfaceToWindowCoords(Math::Point pos);
//@}
//@{
//! Conversion functions between window and interface sizes
/** Unlike coordinate conversions, this is only scale conversion, not translation and scale. */
Math::Point WindowToInterfaceSize(Math::IntPoint size);
Math::IntPoint InterfaceToWindowSize(Math::Point size);
//@}
//! Returns the name of directory with textures
std::string GetTextureDir();
//! Increments the triangle counter for the current frame
void AddStatisticTriangle(int nb);
//! Returns the number of triangles in current frame
int GetStatisticTriangle();
void SetHiliteRank(int *rankList);
bool GetHilite(Math::Point &p1, Math::Point &p2);
bool GetSpriteCoord(int &x, int &y);
void SetInfoText(int line, char* text);
char* GetInfoText(int line);
void FirstExecuteAdapt(bool first);
bool GetFullScreen();
Math::Matrix* GetMatView();
Math::Matrix* GetMatLeftView();
Math::Matrix* GetMatRightView();
/* *************** Object management *************** */
void TimeInit();
void TimeEnterGel();
void TimeExitGel();
float TimeGet();
int GetRestCreate();
int CreateObject();
void FlushObject();
bool DeleteObject(int objRank);
bool SetDrawWorld(int objRank, bool draw);
bool SetDrawFront(int objRank, bool draw);
bool AddTriangle(int objRank, Gfx::VertexTex2* vertex, int nb, const Gfx::Material &mat,
bool AddTriangle(int objRank, Gfx::VertexTex2* vertex, int nb, const Gfx::Material& mat,
int state, std::string texName1, std::string texName2,
float min, float max, bool globalUpdate);
bool AddSurface(int objRank, Gfx::VertexTex2* vertex, int nb, const Gfx::Material &mat,
bool AddSurface(int objRank, Gfx::VertexTex2* vertex, int nb, const Gfx::Material& mat,
int state, std::string texName1, std::string texName2,
float min, float max, bool globalUpdate);
bool AddQuick(int objRank, Gfx::EngineObjLevel5* buffer,
bool AddQuick(int objRank, const Gfx::EngineObjLevel5& buffer,
std::string texName1, std::string texName2,
float min, float max, bool globalUpdate);
Gfx::EngineObjLevel5* SearchTriangle(int objRank, const Gfx::Material &mat,
Gfx::EngineObjLevel5* SearchTriangle(int objRank, const Gfx::Material& mat,
int state, std::string texName1, std::string texName2,
float min, float max);
void ChangeLOD();
bool ChangeSecondTexture(int objRank, char* texName2);
bool ChangeSecondTexture(int objRank, const std::string& texName2);
int GetTotalTriangles(int objRank);
int GetTriangles(int objRank, float min, float max, Gfx::EngineTriangle* buffer, int size, float percent);
bool GetBBox(int objRank, Math::Vector &min, Math::Vector &max);
bool ChangeTextureMapping(int objRank, const Gfx::Material &mat, int state,
const std::string &texName1, const std::string &texName2,
bool GetBBox(int objRank, Math::Vector& min, Math::Vector& max);
bool ChangeTextureMapping(int objRank, const Gfx::Material& mat, int state,
const std::string& texName1, const std::string& texName2,
float min, float max, Gfx::EngineTextureMapping mode,
float au, float bu, float av, float bv);
bool TrackTextureMapping(int objRank, const Gfx::Material &mat, int state,
const std::string &texName1, const std::string &texName2,
bool TrackTextureMapping(int objRank, const Gfx::Material& mat, int state,
const std::string& texName1, const std::string& texName2,
float min, float max, Gfx::EngineTextureMapping mode,
float pos, float factor, float tl, float ts, float tt);
bool SetObjectTransform(int objRank, const Math::Matrix &transform);
bool GetObjectTransform(int objRank, Math::Matrix &transform);
bool SetObjectTransform(int objRank, const Math::Matrix& transform);
bool GetObjectTransform(int objRank, Math::Matrix& transform);
bool SetObjectType(int objRank, Gfx::EngineObjectType type);
Gfx::EngineObjectType GetObjectType(int objRank);
bool SetObjectTransparency(int objRank, float value);
@ -627,20 +674,25 @@ public:
void ShadowDelete(int objRank);
bool SetObjectShadowHide(int objRank, bool hide);
bool SetObjectShadowType(int objRank, Gfx::EngineShadowType type);
bool SetObjectShadowPos(int objRank, const Math::Vector &pos);
bool SetObjectShadowNormal(int objRank, const Math::Vector &n);
bool SetObjectShadowPos(int objRank, const Math::Vector& pos);
bool SetObjectShadowNormal(int objRank, const Math::Vector& n);
bool SetObjectShadowAngle(int objRank, float angle);
bool SetObjectShadowRadius(int objRank, float radius);
bool SetObjectShadowIntensity(int objRank, float intensity);
bool SetObjectShadowHeight(int objRank, float h);
float GetObjectShadowRadius(int objRank);
//! Lists the ranks of objects and subobjects selected
void SetHighlightRank(int* rankList);
//! Returns the highlighted rectangle
bool GetHighlight(Math::Point& p1, Math::Point& p2);
void GroundSpotFlush();
int GroundSpotCreate();
void GroundSpotDelete(int rank);
bool SetObjectGroundSpotPos(int rank, const Math::Vector &pos);
bool SetObjectGroundSpotPos(int rank, const Math::Vector& pos);
bool SetObjectGroundSpotRadius(int rank, float radius);
bool SetObjectGroundSpotColor(int rank, const Gfx::Color &color);
bool SetObjectGroundSpotColor(int rank, const Gfx::Color& color);
bool SetObjectGroundSpotMinMax(int rank, float min, float max);
bool SetObjectGroundSpotSmooth(int rank, float smooth);
@ -649,216 +701,356 @@ public:
int dx, int dy, char* table);
bool GroundMarkDelete(int rank);
//! Updates the state after creating objects
void Update();
void SetViewParams(const Math::Vector &eyePt, const Math::Vector &lookatPt,
const Math::Vector &upVec, float eyeDistance);
Gfx::Texture CreateTexture(const std::string &texName,
const Gfx::TextureCreateParams &params);
Gfx::Texture CreateTexture(const std::string &texName);
void DestroyTexture(const std::string &texName);
/* *************** Mode setting *************** */
bool LoadTexture(const std::string &name, int stage = 0);
//! Sets the current rendering state
void SetState(int state, const Gfx::Color& color = Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f));
//! Sets the current material
void SetMaterial(const Gfx::Material& mat);
//! Specifies the location and direction of view
void SetViewParams(const Math::Vector& eyePt, const Math::Vector& lookatPt,
const Math::Vector& upVec, float eyeDistance);
//! Creates texture with the specified params
Gfx::Texture CreateTexture(const std::string& texName,
const Gfx::TextureCreateParams& params);
//! Creates texture
Gfx::Texture CreateTexture(const std::string& texName);
//! Destroys texture, unloading it and removing from cache
void DestroyTexture(const std::string& texName);
//! Loads texture, creating it if not already present
bool LoadTexture(const std::string& name);
//! Loads all necessary textures
bool LoadAllTextures();
//! Sets texture for given stage; if not present in cache, the texture is loaded
bool SetTexture(const std::string& name, int stage = 0);
//@{
//! Border management (distance limits) depends of the resolution (LOD = level-of-detail)
void SetLimitLOD(int rank, float limit);
float GetLimitLOD(int rank, bool last=false);
//@}
//! Defines of the distance field of vision
void SetTerrainVision(float vision);
//@{
//! Management of camera angle
/**
0.75 = normal
1.50 = wide-angle */
void SetFocus(float focus);
float GetFocus();
//@}
//@{
//! Management of the global mode of marking
void SetGroundSpot(bool mode);
bool GetGroundSpot();
//@}
//@{
//! Management of the global mode of shading
void SetShadow(bool mode);
bool GetShadow();
//@}
//@{
//! Management of the global mode of contamination
void SetDirty(bool mode);
bool GetDirty();
//@}
//@{
//! Management of the global mode of horizontal fog patches
void SetFog(bool mode);
bool GetFog();
//@}
//! Indicates whether it is possible to give a color SetState
bool GetStateColor();
//@{
//! Management of the global mode of secondary texturing
void SetSecondTexture(int texNum);
int GetSecondTexture();
//@}
//@{
//! Management of view mode
void SetRankView(int rank);
int GetRankView();
//@}
//! Whether to draw the world
void SetDrawWorld(bool draw);
//! Whether to draw the world on the interface
void SetDrawFront(bool draw);
void SetAmbientColor(const Gfx::Color &color, int rank = 0);
//@{
//! Ambient color management
void SetAmbientColor(const Gfx::Color& color, int rank = 0);
Gfx::Color GetAmbientColor(int rank = 0);
//@}
void SetWaterAddColor(const Gfx::Color &color);
//@{
//! Color management under water
void SetWaterAddColor(const Gfx::Color& color);
Gfx::Color GetWaterAddColor();
//@}
void SetFogColor(const Gfx::Color &color, int rank = 0);
//@{
//! Management of the fog color
void SetFogColor(const Gfx::Color& color, int rank = 0);
Gfx::Color GetFogColor(int rank = 0);
//@}
//@{
//! Management of the depth of field.
/** Beyond this distance, nothing is visible.
Shortly (according SetFogStart), one enters the fog. */
void SetDeepView(float length, int rank = 0, bool ref=false);
float GetDeepView(int rank = 0);
//@}
//@{
//! Management the start of fog.
/** With 0.0, the fog from the point of view (fog max).
With 1.0, the fog from the depth of field (no fog). */
void SetFogStart(float start, int rank = 0);
float GetFogStart(int rank = 0);
//@}
void SetBackground(const std::string &name, Gfx::Color up = Gfx::Color(), Gfx::Color down = Gfx::Color(),
//@{
//! Management of the background image to use
void SetBackground(const std::string& name, Gfx::Color up = Gfx::Color(), Gfx::Color down = Gfx::Color(),
Gfx::Color cloudUp = Gfx::Color(), Gfx::Color cloudDown = Gfx::Color(),
bool full = false, bool quarter = false);
void GetBackground(const std::string &name, Gfx::Color &up, Gfx::Color &down,
Gfx::Color &cloudUp, Gfx::Color &cloudDown,
bool &full, bool &quarter);
void SetFrontsizeName(char *name);
void SetOverFront(bool front);
void SetOverColor(const Gfx::Color &color = Gfx::Color(), int mode = ENG_RSTATE_TCOLOR_BLACK);
void GetBackground(std::string& name, Gfx::Color& up, Gfx::Color& down,
Gfx::Color& cloudUp, Gfx::Color& cloudDown,
bool& full, bool& quarter);
//@}
//! Specifies the name of foreground texture
void SetForegroundName(const std::string& name);
//! Specifies whether to draw the foreground
void SetOverFront(bool front);
//! Sets the foreground overlay color
void SetOverColor(const Gfx::Color& color = Gfx::Color(), int mode = ENG_RSTATE_TCOLOR_BLACK);
//@{
//! Management of the particle density
void SetParticleDensity(float value);
float GetParticleDensity();
//@}
//! Adapts particle factor according to particle density
float ParticleAdapt(float factor);
//@{
//! Management of the distance of clipping.
void SetClippingDistance(float value);
float GetClippingDistance();
//@}
//@{
//! Management of objects detals.
void SetObjectDetail(float value);
float GetObjectDetail();
//@}
//@{
//! The amount of management objects gadgets
void SetGadgetQuantity(float value);
float GetGadgetQuantity();
//@}
//@{
//! Management the quality of textures
void SetTextureQuality(int value);
int GetTextureQuality();
//@}
//@{
//! Management mode of toto
void SetTotoMode(bool present);
bool GetTotoMode();
//@}
//@{
//! Management the mode of foreground
void SetLensMode(bool present);
bool GetLensMode();
//@}
//@{
//! Management the mode of water
void SetWaterMode(bool present);
bool GetWaterMode();
//@}
void SetLightingMode(bool present);
bool GetLightingMode();
//@{
//! Management the mode of sky
void SetSkyMode(bool present);
bool GetSkyMode();
//@}
//@{
//! Management the mode of background
void SetBackForce(bool present);
bool GetBackForce();
//@}
//@{
//! Management the mode of planets
void SetPlanetMode(bool present);
bool GetPlanetMode();
//@}
//@{
//! Managing the mode of dynamic lights.
void SetLightMode(bool present);
bool GetLightMode();
//@}
//@{
// TODO: move to more appropriate class ?
//! Management of the indentation mode while editing (CEdit)
void SetEditIndentMode(bool autoIndent);
bool GetEditIndentMode();
//@}
//@{
// TODO: move to more appropriate class ?
//! Management of tab indent when editing (CEdit)
void SetEditIndentValue(int value);
int GetEditIndentValue();
//@}
//@{
//! Management of game speed
void SetSpeed(float speed);
float GetSpeed();
//@{
//! Management of precision of robot tracks
void SetTracePrecision(float factor);
float GetTracePrecision();
//@}
void SetFocus(float focus);
float GetFocus();
Math::Vector GetEyePt();
Math::Vector GetLookatPt();
float GetEyeDirH();
float GetEyeDirV();
Math::Point GetDim();
void UpdateMatProj();
void ApplyChange();
void FlushPressKey();
void ResetKey();
void SetKey(int keyRank, int option, int key);
int GetKey(int keyRank, int option);
void SetJoystick(bool enable);
bool GetJoystick();
void SetDebugMode(bool mode);
bool GetDebugMode();
bool GetSetupMode();
bool IsVisiblePoint(const Math::Vector &pos);
int DetectObject(Math::Point mouse);
void SetState(int state, Gfx::Color color = Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f));
void SetTexture(const std::string &name, int stage = 0);
void SetMaterial(const Gfx::Material &mat);
//@{
//! Management of mouse cursor visibility
void SetMouseVisible(bool show);
bool GetMouseVisible();
//@}
//@{
//! Management of mouse cursor position
void SetMousePos(Math::Point pos);
Math::Point GetMousePos();
//@}
//@{
//! Management of mouse cursor type
void SetMouseType(Gfx::EngineMouseType type);
Gfx::EngineMouseType GetMouseType();
//@}
CText* GetText();
//! Returns the view matrix
const Math::Matrix& GetMatView();
//! Returns the camera center point
Math::Vector GetEyePt();
//! Returns the camera target point
Math::Vector GetLookatPt();
//! Returns the horizontal direction angle of view
float GetEyeDirH();
//! Returns the vertical direction angle of view
float GetEyeDirV();
//! Indicates whether a point is visible
bool IsVisiblePoint(const Math::Vector& pos);
bool ChangeColor(char *name, Gfx::Color colorRef1, Gfx::Color colorNew1,
Gfx::Color colorRef2, Gfx::Color colorNew2,
float tolerance1, float tolerance2,
Math::Point ts, Math::Point ti,
Math::Point *pExclu=0, float shift=0.0f, bool hSV=false);
bool OpenImage(char *name);
bool CopyImage();
bool LoadImage();
bool ScrollImage(int dx, int dy);
bool SetDot(int x, int y, Gfx::Color color);
bool CloseImage();
bool WriteScreenShot(char *filename, int width, int height);
//bool GetRenderDC(HDC &hDC);
//bool ReleaseRenderDC(HDC &hDC);
//PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp);
//bool CreateBMPFile(LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC);
//! Resets the projection matrix after changes
void UpdateMatProj();
//! Updates the scene after a change of parameters
void ApplyChange();
protected:
//! Prepares the interface for 3D scene
void Draw3DScene();
//! Draws the user interface over the scene
void DrawInterface();
void SetUp3DView();
bool Draw3DScene();
//! Updates the textures used for drawing ground spot
void UpdateGroundSpotTextures();
void SetUpInterfaceView();
bool DrawInterface();
void DrawGroundSpot();
//! Draws shadows
void DrawShadow();
//! Draws the gradient background
void DrawBackground();
void DrawBackgroundGradient(Gfx::Color up, Gfx::Color down);
void DrawBackgroundImageQuarter(Math::Point p1, Math::Point p2, char *name);
//! Draws the gradient background
void DrawBackgroundGradient(const Gfx::Color& up, const Gfx::Color& down);
//! Draws a portion of the image background
void DrawBackgroundImageQuarter(Math::Point p1, Math::Point p2, const std::string& name);
//! Draws the image background
void DrawBackgroundImage();
//! Draws all the planets
void DrawPlanet();
void DrawFrontsize();
//! Draws the image foreground
void DrawForegroundImage();
//! Draws the foreground color
void DrawOverColor();
void DrawHilite();
//! Draws the rectangle of the object highlighted
void DrawHighlight();
//! Draws the mouse cursor
void DrawMouse();
//! Draw part of mouse cursor sprite
void DrawMouseSprite(Math::Point pos, Math::Point dim, int icon);
/*
Gfx::ObjLevel2* AddLevel1(Gfx::ObjLevel1 *&p1, char* texName1, char* texName2);
Gfx::ObjLevel3* AddLevel2(Gfx::ObjLevel2 *&p2, int objRank);
Gfx::ObjLevel4* AddLevel3(Gfx::ObjLevel3 *&p3, float min, float max);
Gfx::ObjLevel5* AddLevel4(Gfx::ObjLevel4 *&p4, int reserve);
Gfx::ObjLevel6* AddLevel5(Gfx::ObjLevel5 *&p5, Gfx::TriangleType type, const Gfx::Material &mat, int state, int nb);*/
//! Tests whether the given object is visible
bool IsVisible(int objRank);
//! Detects whether an object is affected by the mouse
bool DetectBBox(int objRank, Math::Point mouse);
bool GetBBox2D(int objRank, Math::Point &min, Math::Point &max);
bool DetectTriangle(Math::Point mouse, Gfx::VertexTex2 *triangle, int objRank, float &dist);
bool TransformPoint(Math::Vector &p2D, int objRank, Math::Vector p3D);
//! Compute and return the 2D box on screen of any object
bool GetBBox2D(int objRank, Math::Point& min, Math::Point& max);
//! Detects the target object that is selected with the mouse
/** Returns the rank of the object or -1. */
int DetectObject(Math::Point mouse);
//! Detects whether the mouse is in a triangle.
bool DetectTriangle(Math::Point mouse, Gfx::VertexTex2* triangle, int objRank, float& dist);
//! Transforms a 3D point (x, y, z) in 2D space (x, y, -) of the window
/** The coordinated p2D.z gives the distance. */
bool TransformPoint(Math::Vector& p2D, int objRank, Math::Vector p3D);
//! Calculates the distances between the viewpoint and the origin of different objects
void ComputeDistance();
//! Updates all the geometric parameters of objects
void UpdateGeometry();
protected:
CInstanceManager* m_iMan;
CApplication* m_app;
CSound* m_sound;
CSoundInterface* m_sound;
Gfx::CDevice* m_device;
Gfx::CText* m_text;
Gfx::CLightManager* m_lightMan;
@ -869,51 +1061,54 @@ protected:
Gfx::CPlanet* m_planet;
Gfx::CTerrain* m_terrain;
bool m_wasInit;
//! Last encountered error
std::string m_error;
//! Whether to show stats (FPS, etc)
bool m_showStats;
int m_blackSrcBlend[2];
int m_blackDestBlend[2];
int m_whiteSrcBlend[2];
int m_whiteDestBlend[2];
int m_diffuseSrcBlend[2];
int m_diffuseDestBlend[2];
int m_alphaSrcBlend[2];
int m_alphaDestBlend[2];
Math::Matrix m_matProj;
Math::Matrix m_matLeftView;
Math::Matrix m_matRightView;
Math::Matrix m_matView;
float m_focus;
Math::Matrix m_matWorldInterface;
Math::Matrix m_matProjInterface;
Math::Matrix m_matViewInterface;
long m_baseTime;
long m_stopTime;
float m_absTime;
float m_lastTime;
//! Speed of animation
float m_speed;
//! Pause mode
bool m_pause;
//! Rendering enabled?
bool m_render;
//! Lock for duration of movie?
bool m_movieLock;
//! Current size of window
Math::IntSize m_size;
Math::IntSize m_lastSize;
//! Projection matrix for 3D scene
Math::Matrix m_matProj;
//! View matrix for 3D scene
Math::Matrix m_matView;
//! Camera angle for 3D scene
float m_focus;
//! World matrix for 2D interface
Math::Matrix m_matWorldInterface;
//! Projection matrix for 2D interface
Math::Matrix m_matProjInterface;
//! View matrix for 2D interface
Math::Matrix m_matViewInterface;
//! Current size of viewport window
Math::IntPoint m_size;
//! Previous size of viewport window
Math::IntPoint m_lastSize;
//! Root of tree object structure (level 1 list)
std::vector<Gfx::EngineObjLevel1> m_objectTree;
//! Object parameters
std::vector<Gfx::EngineObject> m_objects;
std::vector<Gfx::EngineShadow> m_shadow;
std::vector<Gfx::EngineGroundSpot> m_groundSpot;
//! Shadow list
std::vector<Gfx::EngineShadow> m_shadows;
//! Ground spot list
std::vector<Gfx::EngineGroundSpot> m_groundSpots;
//! Ground mark
Gfx::EngineGroundMark m_groundMark;
//! Location of camera
Math::Vector m_eyePt;
//! Camera target
Math::Vector m_lookatPt;
float m_eyeDirH;
float m_eyeDirV;
@ -926,7 +1121,6 @@ protected:
Gfx::Color m_waterAddColor;
int m_statisticTriangle;
bool m_updateGeometry;
//char m_infoText[10][200];
int m_alphaMode;
bool m_stateColor;
bool m_forceStateColor;
@ -946,11 +1140,11 @@ protected:
bool m_overFront;
Gfx::Color m_overColor;
int m_overMode;
std::string m_frontsizeName;
std::string m_foregroundName;
bool m_drawWorld;
bool m_drawFront;
float m_limitLOD[2];
float m_particuleDensity;
float m_particleDensity;
float m_clippingDistance;
float m_lastClippingDistance;
float m_objectDetail;
@ -969,34 +1163,53 @@ protected:
int m_editIndentValue;
float m_tracePrecision;
int m_hiliteRank[100];
bool m_hilite;
Math::Point m_hiliteP1;
Math::Point m_hiliteP2;
int m_lastState;
Gfx::Color m_lastColor;
char m_lastTexture[2][50];
Gfx::Material m_lastMaterial;
//! Ranks of highlighted objects
int m_highlightRank[100];
//! Highlight visible?
bool m_highlight;
//! Time counter for highlight animation
float m_highlightTime;
//@{
//! Highlight rectangle points
Math::Point m_highlightP1;
Math::Point m_highlightP2;
//@}
//! Texture directory name
std::string m_texPath;
//! Default texture create params
Gfx::TextureCreateParams m_defaultTexParams;
//! Map of loaded textures (by name)
std::map<std::string, Gfx::Texture> m_texNameMap;
//! Reverse map of loaded textures (by texture)
std::map<Gfx::Texture, std::string> m_revTexNameMap;
//! Blacklist map of textures
/** Textures on this list were not successful in first loading,
* so are disabled for subsequent load calls. */
std::set<std::string> m_texBlacklist;
//! Mouse cursor definitions
Gfx::EngineMouse m_mice[Gfx::ENG_MOUSE_COUNT];
//! Texture with mouse cursors
Gfx::Texture m_miceTexture;
//! Size of mouse cursor
Math::Point m_mouseSize;
//! Type of mouse cursor
Gfx::EngineMouseType m_mouseType;
//! Position of mouse in interface coords
Math::Point m_mousePos;
//! Is mouse visible?
bool m_mouseVisible;
//LPDIRECTDRAWSURFACE7 m_imageSurface;
//DDSURFACEDESC2 m_imageDDSD;
//WORD* m_imageCopy;
//int m_imageDX;
//int m_imageDY;
//! Last engine render state (-1 at the beginning of frame)
int m_lastState;
//! Last color set with render state
Gfx::Color m_lastColor;
//! Last texture names for 2 used texture stages
std::string m_lastTexture[2];
//! Last material
Gfx::Material m_lastMaterial;
};
}; // namespace Gfx

View File

@ -15,7 +15,10 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// lightman.h
/**
* \file graphics/engine/lightman.h
* \brief Dynamic light manager - Gfx::CLightManager class
*/
#pragma once

View File

@ -19,5 +19,71 @@
#include "graphics/engine/lightning.h"
#include "common/logger.h"
// TODO implementation
Gfx::CLightning::CLightning(CInstanceManager* iMan, Gfx::CEngine* engine)
{
GetLogger()->Info("CLightning::CLightning() stub!\n");
// TODO!
}
Gfx::CLightning::~CLightning()
{
GetLogger()->Info("CLightning::~CLightning() stub!\n");
// TODO!
}
void Gfx::CLightning::Flush()
{
GetLogger()->Info("CLightning::Flush() stub!\n");
// TODO!
}
bool Gfx::CLightning::EventProcess(const Event &event)
{
GetLogger()->Info("CLightning::EventProcess() stub!\n");
// TODO!
return true;
}
bool Gfx::CLightning::Create(float sleep, float delay, float magnetic)
{
GetLogger()->Info("CLightning::Create() stub!\n");
// TODO!
return true;
}
bool Gfx::CLightning::GetStatus(float &sleep, float &delay, float &magnetic, float &progress)
{
GetLogger()->Info("CLightning::GetStatus() stub!\n");
// TODO!
return true;
}
bool Gfx::CLightning::SetStatus(float sleep, float delay, float magnetic, float progress)
{
GetLogger()->Info("CLightning::SetStatus() stub!\n");
// TODO!
return true;
}
void Gfx::CLightning::Draw()
{
GetLogger()->Info("CLightning::Draw() stub!\n");
// TODO!
}
bool Gfx::CLightning::EventFrame(const Event &event)
{
GetLogger()->Info("CLightning::EventFrame() stub!\n");
// TODO!
return true;
}
CObject* Gfx::CLightning::SearchObject(Math::Vector pos)
{
GetLogger()->Info("CLightning::SearchObject() stub!\n");
// TODO!
return nullptr;
}

View File

@ -15,7 +15,10 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// lightning.h (aka blitz.h)
/**
* \file graphics/engine/lightning.h
* \brief Lightning rendering - Gfx::CLightning class (aka blitz)
*/
#pragma once
@ -73,7 +76,7 @@ protected:
float m_sleep;
float m_delay;
float m_magnetic;
BlitzPhase m_phase;
Gfx::BlitzPhase m_phase;
float m_time;
float m_speed;
float m_progress;

View File

@ -15,7 +15,10 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// modelfile.h (aka modfile.h)
/**
* \file graphics/engine/modelfile.h
* \brief Model loading - Gfx::CModelFile class (aka modfile)
*/
#include "graphics/engine/engine.h"
#include "graphics/core/vertex.h"

View File

@ -19,5 +19,284 @@
#include "graphics/engine/particle.h"
#include "common/logger.h"
// TODO implementation
Gfx::CParticle::CParticle(CInstanceManager* iMan, Gfx::CEngine* engine)
{
GetLogger()->Info("CParticle::CParticle() stub!\n");
// TODO!
}
Gfx::CParticle::~CParticle()
{
GetLogger()->Info("CParticle::~CParticle() stub!\n");
// TODO!
}
void Gfx::CParticle::SetDevice(Gfx::CDevice* device)
{
GetLogger()->Info("CParticle::SetDevice() stub!\n");
// TODO!
}
void Gfx::CParticle::FlushParticle()
{
GetLogger()->Info("CParticle::FlushParticle() stub!\n");
// TODO!
}
void Gfx::CParticle::FlushParticle(int sheet)
{
GetLogger()->Info("CParticle::FlushParticle() stub!\n");
// TODO!
}
int Gfx::CParticle::CreateParticle(Math::Vector pos, Math::Vector speed, Math::Point dim,
Gfx::ParticleType type, float duration, float mass,
float windSensitivity, int sheet)
{
GetLogger()->Info("CParticle::CreateParticle() stub!\n");
// TODO!
return 0;
}
int Gfx::CParticle::CreateFrag(Math::Vector pos, Math::Vector speed, Gfx::EngineTriangle *triangle,
Gfx::ParticleType type, float duration, float mass,
float windSensitivity, int sheet)
{
GetLogger()->Info("CParticle::CreateFrag() stub!\n");
// TODO!
return 0;
}
int Gfx::CParticle::CreatePart(Math::Vector pos, Math::Vector speed, Gfx::ParticleType type,
float duration, float mass, float weight,
float windSensitivity, int sheet)
{
GetLogger()->Info("CParticle::CreatePart() stub!\n");
// TODO!
return 0;
}
int Gfx::CParticle::CreateRay(Math::Vector pos, Math::Vector goal, Gfx::ParticleType type, Math::Point dim,
float duration, int sheet)
{
GetLogger()->Info("CParticle::CreateRay() stub!\n");
// TODO!
return 0;
}
int Gfx::CParticle::CreateTrack(Math::Vector pos, Math::Vector speed, Math::Point dim, Gfx::ParticleType type,
float duration, float mass, float length, float width)
{
GetLogger()->Info("CParticle::CreateTrack() stub!\n");
// TODO!
return 0;
}
void Gfx::CParticle::CreateWheelTrace(const Math::Vector &p1, const Math::Vector &p2, const Math::Vector &p3,
const Math::Vector &p4, Gfx::ParticleType type)
{
GetLogger()->Info("CParticle::CreateWheelTrace() stub!\n");
// TODO!
}
void Gfx::CParticle::DeleteParticle(Gfx::ParticleType type)
{
GetLogger()->Info("CParticle::DeleteParticle() stub!\n");
// TODO!
}
void Gfx::CParticle::DeleteParticle(int channel)
{
GetLogger()->Info("CParticle::DeleteParticle() stub!\n");
// TODO!
}
void Gfx::CParticle::SetObjectLink(int channel, CObject *object)
{
GetLogger()->Info("CParticle::SetObjectLink() stub!\n");
// TODO!
}
void Gfx::CParticle::SetObjectFather(int channel, CObject *object)
{
GetLogger()->Info("CParticle::SetObjectFather() stub!\n");
// TODO!
}
void Gfx::CParticle::SetPosition(int channel, Math::Vector pos)
{
GetLogger()->Info("CParticle::SetPosition() stub!\n");
// TODO!
}
void Gfx::CParticle::SetDimension(int channel, Math::Point dim)
{
GetLogger()->Info("CParticle::SetDimension() stub!\n");
// TODO!
}
void Gfx::CParticle::SetZoom(int channel, float zoom)
{
GetLogger()->Info("CParticle::SetZoom() stub!\n");
// TODO!
}
void Gfx::CParticle::SetAngle(int channel, float angle)
{
GetLogger()->Info("CParticle::SetAngle() stub!\n");
// TODO!
}
void Gfx::CParticle::SetIntensity(int channel, float intensity)
{
GetLogger()->Info("CParticle::SetIntensity() stub!\n");
// TODO!
}
void Gfx::CParticle::SetParam(int channel, Math::Vector pos, Math::Point dim, float zoom, float angle, float intensity)
{
GetLogger()->Info("CParticle::SetParam() stub!\n");
// TODO!
}
void Gfx::CParticle::SetPhase(int channel, Gfx::ParticlePhase phase, float duration)
{
GetLogger()->Info("CParticle::SetPhase() stub!\n");
// TODO!
}
bool Gfx::CParticle::GetPosition(int channel, Math::Vector &pos)
{
GetLogger()->Info("CParticle::GetPosition() stub!\n");
// TODO!
return true;
}
Gfx::Color Gfx::CParticle::GetFogColor(Math::Vector pos)
{
GetLogger()->Info("CParticle::GetFogColor() stub!\n");
// TODO!
return Gfx::Color();
}
void Gfx::CParticle::SetFrameUpdate(int sheet, bool update)
{
GetLogger()->Info("CParticle::SetFrameUpdate() stub!\n");
// TODO!
}
void Gfx::CParticle::FrameParticle(float rTime)
{
GetLogger()->Info("CParticle::FrameParticle() stub!\n");
// TODO!
}
void Gfx::CParticle::DrawParticle(int sheet)
{
GetLogger()->Info("CParticle::DrawParticle() stub!\n");
// TODO!
}
bool Gfx::CParticle::WriteWheelTrace(char *filename, int width, int height, Math::Vector dl, Math::Vector ur)
{
GetLogger()->Info("CParticle::WriteWheelTrace() stub!\n");
// TODO!
return true;
}
void Gfx::CParticle::DeleteRank(int rank)
{
GetLogger()->Info("CParticle::DeleteRank() stub!\n");
// TODO!
}
bool Gfx::CParticle::CheckChannel(int &channel)
{
GetLogger()->Info("CParticle::CheckChannel() stub!\n");
// TODO!
return true;
}
void Gfx::CParticle::DrawParticleTriangle(int i)
{
GetLogger()->Info("CParticle::DrawParticleTriangle() stub!\n");
// TODO!
}
void Gfx::CParticle::DrawParticleNorm(int i)
{
GetLogger()->Info("CParticle::DrawParticleNorm() stub!\n");
// TODO!
}
void Gfx::CParticle::DrawParticleFlat(int i)
{
GetLogger()->Info("CParticle::DrawParticleFlat() stub!\n");
// TODO!
}
void Gfx::CParticle::DrawParticleFog(int i)
{
GetLogger()->Info("CParticle::DrawParticleFog() stub!\n");
// TODO!
}
void Gfx::CParticle::DrawParticleRay(int i)
{
GetLogger()->Info("CParticle::DrawParticleRay() stub!\n");
// TODO!
}
void Gfx::CParticle::DrawParticleSphere(int i)
{
GetLogger()->Info("CParticle::DrawParticleSphere() stub!\n");
// TODO!
}
void Gfx::CParticle::DrawParticleCylinder(int i)
{
GetLogger()->Info("CParticle::DrawParticleCylinder() stub!\n");
// TODO!
}
void Gfx::CParticle::DrawParticleWheel(int i)
{
GetLogger()->Info("CParticle::DrawParticleWheel() stub!\n");
// TODO!
}
CObject* Gfx::CParticle::SearchObjectGun(Math::Vector old, Math::Vector pos, Gfx::ParticleType type, CObject *father)
{
GetLogger()->Info("CParticle::SearchObjectGun() stub!\n");
// TODO!
return nullptr;
}
CObject* Gfx::CParticle::SearchObjectRay(Math::Vector pos, Math::Vector goal, Gfx::ParticleType type, CObject *father)
{
GetLogger()->Info("CParticle::SearchObjectRay() stub!\n");
// TODO!
return nullptr;
}
void Gfx::CParticle::Play(Sound sound, Math::Vector pos, float amplitude)
{
GetLogger()->Info("CParticle::Play() stub!\n");
// TODO!
}
bool Gfx::CParticle::TrackMove(int i, Math::Vector pos, float progress)
{
GetLogger()->Info("CParticle::TrackMove() stub!\n");
// TODO!
return true;
}
void Gfx::CParticle::TrackDraw(int i, Gfx::ParticleType type)
{
GetLogger()->Info("CParticle::TrackDraw() stub!\n");
// TODO!
}

View File

@ -15,7 +15,10 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// particle.h (aka particule.h)
/**
* \file graphics/engine/particle.h
* \brief Particle rendering - Gfx::CParticle class (aka particule)
*/
#pragma once
@ -202,26 +205,26 @@ enum ParticlePhase
struct Particle
{
char bUsed; // TRUE -> particle used
char bRay; // TRUE -> ray with goal
unsigned short uniqueStamp; // unique mark
char used; // TRUE -> particle used
char ray; // TRUE -> ray with goal
unsigned short uniqueStamp; // unique mark
short sheet; // sheet (0..n)
ParticleType type; // type PARTI*
ParticlePhase phase; // phase PARPH*
ParticleType type; // type PARTI*
ParticlePhase phase; // phase PARPH*
float mass; // mass of the particle (in rebounding)
float weight; // weight of the particle (for noise)
float duration; // length of life
Math::Vector pos; // absolute position (relative if object links)
Math::Vector goal; // goal position (if bRay)
Math::Vector speed; // speed of displacement
Math::Vector pos; // absolute position (relative if object links)
Math::Vector goal; // goal position (if ray)
Math::Vector speed; // speed of displacement
float windSensitivity;
short bounce; // number of rebounds
Math::Point dim; // dimensions of the rectangle
Math::Point dim; // dimensions of the rectangle
float zoom; // zoom (0..1)
float angle; // angle of rotation
float intensity; // intensity
Math::Point texSup; // coordinated upper texture
Math::Point texInf; // coordinated lower texture
Math::Point texSup; // coordinated upper texture
Math::Point texInf; // coordinated lower texture
float time; // age of the particle (0..n)
float phaseTime; // age at the beginning of phase
float testTime; // time since last test
@ -233,22 +236,22 @@ struct Particle
struct Track
{
char bUsed; // TRUE -> drag used
char bDrawParticle;
char used; // TRUE -> drag used
char drawParticle;
float step; // duration of not
float last; // increase last not memorized
float intensity; // intensity at starting (0..1)
float width; // tail width
int used; // number of positions in "pos"
int head; // head to write index
Math::Vector pos[MAXTRACKLEN];
int posUsed; // number of positions in "pos"
int head; // head to write index
Math::Vector pos[MAXTRACKLEN];
float len[MAXTRACKLEN];
};
struct WheelTrace
{
ParticleType type; // type PARTI*
Math::Vector pos[4]; // rectangle positions
ParticleType type; // type PARTI*
Math::Vector pos[4]; // rectangle positions
float startTime; // beginning of life
};
@ -257,20 +260,29 @@ struct WheelTrace
class CParticle
{
public:
CParticle(CInstanceManager* iMan, CEngine* engine);
CParticle(CInstanceManager* iMan, Gfx::CEngine* engine);
~CParticle();
void SetGLDevice(CDevice device);
void SetDevice(Gfx::CDevice* device);
void FlushParticle();
void FlushParticle(int sheet);
int CreateParticle(Math::Vector pos, Math::Vector speed, Math::Point dim, ParticleType type, float duration=1.0f, float mass=0.0f, float windSensitivity=1.0f, int sheet=0);
int CreateFrag(Math::Vector pos, Math::Vector speed, Gfx::EngineTriangle *triangle, ParticleType type, float duration=1.0f, float mass=0.0f, float windSensitivity=1.0f, int sheet=0);
int CreatePart(Math::Vector pos, Math::Vector speed, ParticleType type, float duration=1.0f, float mass=0.0f, float weight=0.0f, float windSensitivity=1.0f, int sheet=0);
int CreateRay(Math::Vector pos, Math::Vector goal, ParticleType type, Math::Point dim, float duration=1.0f, int sheet=0);
int CreateTrack(Math::Vector pos, Math::Vector speed, Math::Point dim, ParticleType type, float duration=1.0f, float mass=0.0f, float length=10.0f, float width=1.0f);
void CreateWheelTrace(const Math::Vector &p1, const Math::Vector &p2, const Math::Vector &p3, const Math::Vector &p4, ParticleType type);
void DeleteParticle(ParticleType type);
int CreateParticle(Math::Vector pos, Math::Vector speed, Math::Point dim,
Gfx::ParticleType type, float duration=1.0f, float mass=0.0f,
float windSensitivity=1.0f, int sheet=0);
int CreateFrag(Math::Vector pos, Math::Vector speed, Gfx::EngineTriangle *triangle,
Gfx::ParticleType type, float duration=1.0f, float mass=0.0f,
float windSensitivity=1.0f, int sheet=0);
int CreatePart(Math::Vector pos, Math::Vector speed, Gfx::ParticleType type,
float duration=1.0f, float mass=0.0f, float weight=0.0f,
float windSensitivity=1.0f, int sheet=0);
int CreateRay(Math::Vector pos, Math::Vector goal, Gfx::ParticleType type, Math::Point dim,
float duration=1.0f, int sheet=0);
int CreateTrack(Math::Vector pos, Math::Vector speed, Math::Point dim, Gfx::ParticleType type,
float duration=1.0f, float mass=0.0f, float length=10.0f, float width=1.0f);
void CreateWheelTrace(const Math::Vector &p1, const Math::Vector &p2, const Math::Vector &p3,
const Math::Vector &p4, Gfx::ParticleType type);
void DeleteParticle(Gfx::ParticleType type);
void DeleteParticle(int channel);
void SetObjectLink(int channel, CObject *object);
void SetObjectFather(int channel, CObject *object);
@ -280,12 +292,12 @@ public:
void SetAngle(int channel, float angle);
void SetIntensity(int channel, float intensity);
void SetParam(int channel, Math::Vector pos, Math::Point dim, float zoom, float angle, float intensity);
void SetPhase(int channel, ParticlePhase phase, float duration);
void SetPhase(int channel, Gfx::ParticlePhase phase, float duration);
bool GetPosition(int channel, Math::Vector &pos);
Gfx::Color RetFogColor(Math::Vector pos);
Gfx::Color GetFogColor(Math::Vector pos);
void SetFrameUpdate(int sheet, bool bUpdate);
void SetFrameUpdate(int sheet, bool update);
void FrameParticle(float rTime);
void DrawParticle(int sheet);
@ -302,29 +314,29 @@ protected:
void DrawParticleSphere(int i);
void DrawParticleCylinder(int i);
void DrawParticleWheel(int i);
CObject* SearchObjectGun(Math::Vector old, Math::Vector pos, ParticleType type, CObject *father);
CObject* SearchObjectRay(Math::Vector pos, Math::Vector goal, ParticleType type, CObject *father);
CObject* SearchObjectGun(Math::Vector old, Math::Vector pos, Gfx::ParticleType type, CObject *father);
CObject* SearchObjectRay(Math::Vector pos, Math::Vector goal, Gfx::ParticleType type, CObject *father);
void Play(Sound sound, Math::Vector pos, float amplitude);
bool TrackMove(int i, Math::Vector pos, float progress);
void TrackDraw(int i, ParticleType type);
void TrackDraw(int i, Gfx::ParticleType type);
protected:
CInstanceManager* m_iMan;
CEngine* m_engine;
CDevice* m_pDevice;
CRobotMain* m_main;
CTerrain* m_terrain;
CWater* m_water;
CSound* m_sound;
Gfx::CEngine* m_engine;
Gfx::CDevice* m_device;
Gfx::CTerrain* m_terrain;
Gfx::CWater* m_water;
CRobotMain* m_main;
CSound* m_sound;
Gfx::Particle m_particule[MAXPARTICULE*MAXPARTITYPE];
Gfx::EngineTriangle m_triangle[MAXPARTICULE]; // triangle if PartiType == 0
Track m_track[MAXTRACK];
Gfx::Track m_track[MAXTRACK];
int m_wheelTraceTotal;
int m_wheelTraceIndex;
WheelTrace m_wheelTrace[MAXWHEELTRACE];
Gfx::WheelTrace m_wheelTrace[MAXWHEELTRACE];
int m_totalInterface[MAXPARTITYPE][SH_MAX];
bool m_bFrameUpdate[SH_MAX];
bool m_frameUpdate[SH_MAX];
int m_fogTotal;
int m_fog[MAXPARTIFOG];
int m_uniqueStamp;

View File

@ -19,5 +19,167 @@
#include "graphics/engine/planet.h"
#include "common/iman.h"
#include "graphics/core/device.h"
#include "graphics/engine/engine.h"
// TODO implementation
const int PLANET_PREALLOCATE_COUNT = 10;
Gfx::CPlanet::CPlanet(CInstanceManager* iMan, Gfx::CEngine* engine)
{
m_iMan = iMan;
m_iMan->AddInstance(CLASS_PLANET, this);
m_planet[0].reserve(PLANET_PREALLOCATE_COUNT);
m_planet[1].reserve(PLANET_PREALLOCATE_COUNT);
m_engine = engine;
Flush();
}
Gfx::CPlanet::~CPlanet()
{
m_iMan = nullptr;
}
void Gfx::CPlanet::Flush()
{
for (int j = 0; j < 2; j++)
m_planet[j].clear();
m_planetExist = false;
m_mode = 0;
m_time = 0.0f;
}
bool Gfx::CPlanet::EventProcess(const Event &event)
{
if (event.type == EVENT_FRAME)
return EventFrame(event);
return true;
}
bool Gfx::CPlanet::EventFrame(const Event &event)
{
if (m_engine->GetPause()) return true;
m_time += event.rTime;
for (int i = 0; i < static_cast<int>( m_planet[m_mode].size() ); i++)
{
float a = m_time*m_planet[m_mode][i].speed;
if (a < 0.0f)
a += Math::PI*1000.0f;
m_planet[m_mode][i].angle.x = a+m_planet[m_mode][i].start.x;
m_planet[m_mode][i].angle.y = sinf(a)*sinf(m_planet[m_mode][i].dir)+m_planet[m_mode][i].start.y;
}
return true;
}
void Gfx::CPlanet::LoadTexture()
{
for (int j = 0; j < 2; j++)
{
for (int i = 0; i < static_cast<int>( m_planet[j].size() ); i++)
{
m_engine->LoadTexture(m_planet[j][i].name);
}
}
}
void Gfx::CPlanet::Draw()
{
Gfx::CDevice* device = m_engine->GetDevice();
float eyeDirH = m_engine->GetEyeDirH();
float eyeDirV = m_engine->GetEyeDirV();
Math::Vector n = Math::Vector(0.0f, 0.0f, -1.0f); // normal
float dp = 0.5f/256.0f;
for (int i = 0; i < static_cast<int>( m_planet[m_mode].size() ); i++)
{
m_engine->SetTexture(m_planet[m_mode][i].name);
if (m_planet[m_mode][i].transparent)
m_engine->SetState(Gfx::ENG_RSTATE_WRAP | Gfx::ENG_RSTATE_ALPHA);
else
m_engine->SetState(Gfx::ENG_RSTATE_WRAP | Gfx::ENG_RSTATE_TTEXTURE_BLACK);
Math::Point p1, p2;
float a = eyeDirH + m_planet[m_mode][i].angle.x;
p1.x = Math::Mod(a, Math::PI*2.0f)-0.5f;
a = eyeDirV + m_planet[m_mode][i].angle.y;
p1.y = 0.4f+(Math::Mod(a+Math::PI, Math::PI*2.0f)-Math::PI)*(2.0f/Math::PI);
p1.x -= m_planet[m_mode][i].dim/2.0f*0.75f;
p1.y -= m_planet[m_mode][i].dim/2.0f;
p2.x = p1.x+m_planet[m_mode][i].dim*0.75f;
p2.y = p1.y+m_planet[m_mode][i].dim;
float u1 = m_planet[m_mode][i].uv1.x + dp;
float v1 = m_planet[m_mode][i].uv1.y + dp;
float u2 = m_planet[m_mode][i].uv2.x - dp;
float v2 = m_planet[m_mode][i].uv2.y - dp;
Gfx::Vertex quad[4] =
{
Gfx::Vertex(Math::Vector(p1.x, p1.y, 0.0f), n, Math::Point(u1, v2)),
Gfx::Vertex(Math::Vector(p1.x, p2.y, 0.0f), n, Math::Point(u1, v1)),
Gfx::Vertex(Math::Vector(p2.x, p1.y, 0.0f), n, Math::Point(u2, v2)),
Gfx::Vertex(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(u2, v1))
};
device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4);
m_engine->AddStatisticTriangle(2);
}
}
void Gfx::CPlanet::Create(int mode, Math::Point start, float dim, float speed,
float dir, const std::string& name, Math::Point uv1, Math::Point uv2)
{
if (mode < 0) mode = 0;
if (mode > 1) mode = 1;
Gfx::Planet planet;
planet.start = start;
planet.angle = start;
planet.dim = dim;
planet.speed = speed;
planet.dir = dir;
planet.name = name;
planet.uv1 = uv1;
planet.uv2 = uv2;
planet.transparent = planet.name.find("planet") != std::string::npos;
m_planet[mode].push_back(planet);
m_planetExist = true;
}
bool Gfx::CPlanet::PlanetExist()
{
return m_planetExist;
}
void Gfx::CPlanet::SetMode(int mode)
{
if (mode < 0) mode = 0;
if (mode > 1) mode = 1;
m_mode = mode;
}
int Gfx::CPlanet::GetMode()
{
return m_mode;
}

View File

@ -15,13 +15,18 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// planet.h
/**
* \file graphics/engine/planet.h
* \brief Planet rendering - Gfx::CPlanet class
*/
#pragma once
#include "common/event.h"
#include "math/point.h"
#include <vector>
class CInstanceManager;
@ -30,51 +35,69 @@ namespace Gfx {
class CEngine;
const short MAXPLANET = 10;
struct Planet
{
char bUsed; // TRUE -> planet exists
Math::Point start; // initial position in degrees
Math::Point angle; // current position in degrees
float dim; // dimensions (0..1)
float speed; // speed
float dir; // direction in the sky
char name[20]; // name of the texture
Math::Point uv1, uv2; // texture mapping
char bTGA; // texture .TGA
//! Initial position in degrees
Math::Point start;
//! Current position in degrees
Math::Point angle;
//! Dimensions (0..1)
float dim;
//! Speed
float speed;
//! Direction in the sky
float dir;
//! Name of the texture
std::string name;
//! Texture mapping
Math::Point uv1, uv2;
//! Transparent texture
bool transparent;
Planet()
{
dim = speed = dir = 0.0f;
transparent = false;
}
};
class CPlanet {
class CPlanet
{
public:
CPlanet(CInstanceManager* iMan, CEngine* engine);
CPlanet(CInstanceManager* iMan, Gfx::CEngine* engine);
~CPlanet();
//! Removes all the planets
void Flush();
//! Management of an event
bool EventProcess(const Event &event);
bool Create(int mode, Math::Point start, float dim, float speed, float dir, char *name, Math::Point uv1, Math::Point uv2);
//! Creates a new planet
void Create(int mode, Math::Point start, float dim, float speed, float dir,
const std::string& name, Math::Point uv1, Math::Point uv2);
//! Indicates if there is at least one planet
bool PlanetExist();
//! Load all the textures for the planets
void LoadTexture();
//! Draws all the planets
void Draw();
//@{
//! Choice of mode
void SetMode(int mode);
int RetMode();
int GetMode();
//@}
protected:
//! Makes the planets evolve
bool EventFrame(const Event &event);
protected:
CInstanceManager* m_iMan;
CEngine* m_engine;
CInstanceManager* m_iMan;
Gfx::CEngine* m_engine;
float m_time;
int m_mode;
Planet m_planet[2][MAXPLANET];
bool m_bPlanetExist;
float m_time;
int m_mode;
std::vector<Gfx::Planet> m_planet[2];
bool m_planetExist;
};
}; // namespace Gfx

View File

@ -19,5 +19,161 @@
#include "graphics/engine/pyro.h"
#include "common/logger.h"
// TODO implementation
Gfx::CPyro::CPyro(CInstanceManager* iMan)
{
GetLogger()->Info("CParticle::CPyro() stub!\n");
// TODO!
}
Gfx::CPyro::~CPyro()
{
GetLogger()->Info("CPyro::~CPyro() stub!");
// TODO!
}
void Gfx::CPyro::DeleteObject(bool all)
{
GetLogger()->Info("CPyro::DeleteObject() stub!");
// TODO!
}
bool Gfx::CPyro::Create(Gfx::PyroType type, CObject* pObj, float force)
{
GetLogger()->Info("CPyro::Create() stub!");
// TODO!
return true;
}
bool Gfx::CPyro::EventProcess(const Event &event)
{
GetLogger()->Info("CPyro::EventProcess() stub!\n");
// TODO!
return true;
}
Error Gfx::CPyro::IsEnded()
{
GetLogger()->Info("CPyro::IsEnded() stub!\n");
// TODO!
return ERR_OK;
}
void Gfx::CPyro::CutObjectLink(CObject* pObj)
{
GetLogger()->Info("CPyro::CutObjectLink() stub!\n");
// TODO!
}
void Gfx::CPyro::DisplayError(PyroType type, CObject* pObj)
{
GetLogger()->Info("CPyro::DisplayError() stub!\n");
// TODO!
}
bool Gfx::CPyro::CreateLight(Math::Vector pos, float height)
{
GetLogger()->Info("CPyro::CreateLight() stub!\n");
// TODO!
return true;
}
void Gfx::CPyro::DeleteObject(bool primary, bool secondary)
{
GetLogger()->Info("CPyro::DeleteObject() stub!\n");
// TODO!
}
void Gfx::CPyro::CreateTriangle(CObject* pObj, ObjectType oType, int part)
{
GetLogger()->Info("CPyro::CreateTriangle() stub!\n");
// TODO!
}
void Gfx::CPyro::ExploStart()
{
GetLogger()->Info("CPyro::ExploStart() stub!\n");
// TODO!
}
void Gfx::CPyro::ExploTerminate()
{
GetLogger()->Info("CPyro::ExploTerminate() stub!\n");
// TODO!
}
void Gfx::CPyro::BurnStart()
{
GetLogger()->Info("CPyro::BurnStart() stub!\n");
// TODO!
}
void Gfx::CPyro::BurnAddPart(int part, Math::Vector pos, Math::Vector angle)
{
GetLogger()->Info("CPyro::BurnAddPart() stub!\n");
// TODO!
}
void Gfx::CPyro::BurnProgress()
{
GetLogger()->Info("CPyro::BurnProgress() stub!\n");
// TODO!
}
bool Gfx::CPyro::BurnIsKeepPart(int part)
{
GetLogger()->Info("CPyro::BurnIsKeepPart() stub!\n");
// TODO!
return true;
}
void Gfx::CPyro::BurnTerminate()
{
GetLogger()->Info("CPyro::BurnTerminate() stub!\n");
// TODO!
}
void Gfx::CPyro::FallStart()
{
GetLogger()->Info("CPyro::FallStart() stub!\n");
// TODO!
}
CObject* Gfx::CPyro::FallSearchBeeExplo()
{
GetLogger()->Info("CPyro::FallSearchBeeExplo() stub!\n");
// TODO!
return nullptr;
}
void Gfx::CPyro::FallProgress(float rTime)
{
GetLogger()->Info("CPyro::FallProgress() stub!\n");
// TODO!
}
Error Gfx::CPyro::FallIsEnded()
{
GetLogger()->Info("CPyro::FallIsEnded() stub!\n");
// TODO!
return ERR_OK;
}
void Gfx::CPyro::LightOperFlush()
{
GetLogger()->Info("CPyro::LightOperFlush() stub!\n");
// TODO!
}
void Gfx::CPyro::LightOperAdd(float progress, float intensity, float r, float g, float b)
{
GetLogger()->Info("CPyro::LightOperAdd() stub!\n");
// TODO!
}
void Gfx::CPyro::LightOperFrame(float rTime)
{
GetLogger()->Info("CPyro::LightOperFrame() stub!\n");
// TODO!
}

View File

@ -15,15 +15,16 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// pyro.h
/**
* \file graphics/engine/pyro.h
* \brief Fire effect rendering - Gfx::CPyro class
*/
#pragma once
#include "common/misc.h"
#include "graphics/engine/engine.h"
//#include "object/object.h"
// TEMPORARILY!
enum ObjectType {};
#include "object/object.h"
class CInstanceManager;
@ -90,13 +91,14 @@ struct PyroLightOper
class CPyro {
class CPyro
{
public:
CPyro(CInstanceManager* iMan);
~CPyro();
void DeleteObject(bool bAll=false);
bool Create(PyroType type, CObject* pObj, float force=1.0f);
void DeleteObject(bool all=false);
bool Create(Gfx::PyroType type, CObject* pObj, float force=1.0f);
bool EventProcess(const Event &event);
Error IsEnded();
void CutObjectLink(CObject* pObj);
@ -104,7 +106,7 @@ public:
protected:
void DisplayError(PyroType type, CObject* pObj);
bool CreateLight(Math::Vector pos, float height);
void DeleteObject(bool bPrimary, bool bSecondary);
void DeleteObject(bool primary, bool secondary);
void CreateTriangle(CObject* pObj, ObjectType oType, int part);
@ -127,21 +129,21 @@ protected:
void LightOperFrame(float rTime);
protected:
CInstanceManager* m_iMan;
CEngine* m_engine;
CTerrain* m_terrain;
CCamera* m_camera;
CParticle* m_particule;
CLight* m_light;
CObject* m_object;
CDisplayText* m_displayText;
CRobotMain* m_main;
CSound* m_sound;
CInstanceManager* m_iMan;
Gfx::CEngine* m_engine;
Gfx::CTerrain* m_terrain;
Gfx::CCamera* m_camera;
Gfx::CParticle* m_particule;
Gfx::CLightManager* m_lightMan;
CObject* m_object;
CDisplayText* m_displayText;
CRobotMain* m_main;
CSound* m_sound;
Math::Vector m_pos; // center of the effect
Math::Vector m_posPower; // center of the battery
bool m_bPower; // battery exists?
PyroType m_type;
Math::Vector m_pos; // center of the effect
Math::Vector m_posPower; // center of the battery
bool m_power; // battery exists?
Gfx::PyroType m_type;
float m_force;
float m_size;
float m_progress;
@ -153,22 +155,22 @@ protected:
int m_lightRank;
int m_lightOperTotal;
PyroLightOper m_lightOper[10];
Gfx::PyroLightOper m_lightOper[10];
float m_lightHeight;
ObjectType m_burnType;
int m_burnPartTotal;
PyroBurnPart m_burnPart[10];
Gfx::PyroBurnPart m_burnPart[10];
int m_burnKeepPart[10];
float m_burnFall;
float m_fallFloor;
float m_fallSpeed;
float m_fallBulletTime;
bool m_bFallEnding;
bool m_fallEnding;
int m_crashSphereUsed; // number of spheres used
Math::Vector m_crashSpherePos[50];
Math::Vector m_crashSpherePos[50];
float m_crashSphereRadius[50];
};

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,10 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// terrain.h
/**
* \file graphics/engine/terrain.h
* \brief Terrain rendering - Gfx::CTerrain class
*/
#pragma once
@ -40,56 +43,72 @@ enum TerrainRes
TR_STONE = 1,
TR_URANIUM = 2,
TR_POWER = 3,
TR_KEYa = 4,
TR_KEYb = 5,
TR_KEYc = 6,
TR_KEYd = 7,
TR_KEY_A = 4,
TR_KEY_B = 5,
TR_KEY_C = 6,
TR_KEY_D = 7,
};
const short MAXBUILDINGLEVEL = 100;
struct BuildingLevel
{
Math::Vector center;
float factor;
float min;
float max;
float level;
float height;
float bboxMinX;
float bboxMaxX;
float bboxMinZ;
float bboxMaxZ;
Math::Vector center;
float factor;
float min;
float max;
float level;
float height;
float bboxMinX;
float bboxMaxX;
float bboxMinZ;
float bboxMaxZ;
BuildingLevel()
{
factor = min = max = level = height = 0.0f;
bboxMinX = bboxMaxX = bboxMinZ = bboxMaxZ = 0.0f;
}
};
const short MAXMATTERRAIN = 100;
struct TerrainMaterial
{
short id;
char texName[20];
std::string texName;
float u,v;
float hardness;
char mat[4]; // up, right, down, left
TerrainMaterial()
{
id = 0;
u = v = 0.0f;
hardness = 0.0f;
mat[0] = mat[1] = mat[2] = mat[3] = 0;
}
};
struct DotLevel
{
short id;
char mat[4]; // up, right, down, left
DotLevel()
{
id = 0;
mat[0] = mat[1] = mat[2] = mat[3] = 0;
}
};
const short MAXFLYINGLIMIT = 10;
struct FlyingLimit
{
Math::Vector center;
float extRadius;
float intRadius;
float maxHeight;
Math::Vector center;
float extRadius;
float intRadius;
float maxHeight;
FlyingLimit()
{
extRadius = intRadius = maxHeight = 0.0f;
}
};
@ -100,72 +119,124 @@ public:
CTerrain(CInstanceManager* iMan);
~CTerrain();
bool Generate(int mosaic, int brickP2, float size, float vision, int depth, float hardness);
bool InitTextures(char* baseName, int* table, int dx, int dy);
//! Generates a new flat terrain
bool Generate(int mosaic, int brickPow2, float size, float vision, int depth, float hardness);
//! Initializes the names of textures to use for the land
bool InitTextures(const std::string& baseName, int* table, int dx, int dy);
//! Empties level
void LevelFlush();
bool LevelMaterial(int id, char* baseName, float u, float v, int up, int right, int down, int left, float hardness);
//! Initializes the names of textures to use for the land
void LevelMaterial(int id, std::string& baseName, float u, float v, int up, int right, int down, int left, float hardness);
//! Initializes all the ground with a material
bool LevelInit(int id);
//! Generates a level in the terrain
bool LevelGenerate(int *id, float min, float max, float slope, float freq, Math::Vector center, float radius);
//! Initializes a completely flat terrain
void FlushRelief();
bool ReliefFromBMP(const char* filename, float scaleRelief, bool adjustBorder);
bool ReliefFromDXF(const char* filename, float scaleRelief);
bool ResFromBMP(const char* filename);
bool CreateObjects(bool bMultiRes);
bool Terraform(const Math::Vector &p1, const Math::Vector &p2, float height);
//! Load relief from a PNG file
bool ReliefFromPNG(const std::string& filename, float scaleRelief, bool adjustBorder);
//! Load resources from a PNG file
bool ResFromPNG(const std::string& filename);
//! Creates all objects of the terrain within the 3D engine
bool CreateObjects(bool multiRes);
//! Modifies the terrain's relief
bool Terraform(const Math::Vector& p1, const Math::Vector& p2, float height);
void SetWind(Math::Vector speed);
Math::Vector RetWind();
//@{
//! Management of the wind
void SetWind(Math::Vector speed);
Math::Vector GetWind();
//@}
float RetFineSlope(const Math::Vector &pos);
float RetCoarseSlope(const Math::Vector &pos);
bool GetNormal(Math::Vector &n, const Math::Vector &p);
float RetFloorLevel(const Math::Vector &p, bool bBrut=false, bool bWater=false);
float RetFloorHeight(const Math::Vector &p, bool bBrut=false, bool bWater=false);
bool MoveOnFloor(Math::Vector &p, bool bBrut=false, bool bWater=false);
bool ValidPosition(Math::Vector &p, float marging);
TerrainRes RetResource(const Math::Vector &p);
//! Gives the exact slope of the terrain of a place given
float GetFineSlope(const Math::Vector& pos);
//! Gives the approximate slope of the terrain of a specific location
float GetCoarseSlope(const Math::Vector& pos);
//! Gives the normal vector at the position p (x,-,z) of the ground
bool GetNormal(Math::Vector& n, const Math::Vector &p);
//! returns the height of the ground
float GetFloorLevel(const Math::Vector& p, bool brut=false, bool water=false);
//! Returns the height to the ground
float GetFloorHeight(const Math::Vector& p, bool brut=false, bool water=false);
//! Modifies the coordinate "y" of point "p" to rest on the ground floor
bool MoveOnFloor(Math::Vector& p, bool brut=false, bool water=false);
//! Modifies a coordinate so that it is on the ground
bool ValidPosition(Math::Vector& p, float marging);
//! Returns the resource type available underground
Gfx::TerrainRes GetResource(const Math::Vector& p);
//! Adjusts a position so that it does not exceed the boundaries
void LimitPos(Math::Vector &pos);
//! Empty the table of elevations
void FlushBuildingLevel();
//! Adds a new elevation for a building
bool AddBuildingLevel(Math::Vector center, float min, float max, float height, float factor);
//! Updates the elevation for a building when it was moved up (after a terraforming)
bool UpdateBuildingLevel(Math::Vector center);
//! Removes the elevation for a building when it was destroyed
bool DeleteBuildingLevel(Math::Vector center);
float RetBuildingFactor(const Math::Vector &p);
float RetHardness(const Math::Vector &p);
//! Returns the influence factor whether a position is on a possible rise
float GetBuildingFactor(const Math::Vector& p);
float GetHardness(const Math::Vector& p);
int RetMosaic();
int RetBrick();
float RetSize();
float RetScaleRelief();
int GetMosaic();
int GetBrick();
float GetSize();
float GetScaleRelief();
//! Shows the flat areas on the ground
void GroundFlat(Math::Vector pos);
float RetFlatZoneRadius(Math::Vector center, float max);
//! Calculates the radius of the largest flat area available
float GetFlatZoneRadius(Math::Vector center, float max);
//@{
//! Management of the global max flying height
void SetFlyingMaxHeight(float height);
float RetFlyingMaxHeight();
float GetFlyingMaxHeight();
//@}
//! Empty the table of flying limits
void FlushFlyingLimit();
bool AddFlyingLimit(Math::Vector center, float extRadius, float intRadius, float maxHeight);
float RetFlyingLimit(Math::Vector pos, bool bNoLimit);
//! Adds a new flying limit
void AddFlyingLimit(Math::Vector center, float extRadius, float intRadius, float maxHeight);
//! Returns the maximum height of flight
float GetFlyingLimit(Math::Vector pos, bool noLimit);
protected:
//! Adds a point of elevation in the buffer of relief
bool ReliefAddDot(Math::Vector pos, float scaleRelief);
//! Adjust the edges of each mosaic to be compatible with all lower resolutions
void AdjustRelief();
Math::Vector RetVector(int x, int y);
Gfx::VertexTex2 RetVertex(int x, int y, int step);
bool CreateMosaic(int ox, int oy, int step, int objRank, const Gfx::Material &mat, float min, float max);
bool CreateSquare(bool bMultiRes, int x, int y);
//! Calculates a vector of the terrain
Math::Vector GetVector(int x, int y);
//! Calculates a vertex of the terrain
Gfx::VertexTex2 GetVertex(int x, int y, int step);
//! Creates all objects of a mosaic
bool CreateMosaic(int ox, int oy, int step, int objRank, const Gfx::Material& mat, float min, float max);
//! Creates all objects in a mesh square ground
bool CreateSquare(bool multiRes, int x, int y);
TerrainMaterial* LevelSearchMat(int id);
void LevelTextureName(int x, int y, char *name, Math::Point &uv);
float LevelRetHeight(int x, int y);
//! Seeks a materials based on theirs identifier
Gfx::TerrainMaterial* LevelSearchMat(int id);
//! Chooses texture to use for a given square
void LevelTextureName(int x, int y, std::string& name, Math::Point &uv);
//! Returns the height of the terrain
float LevelGetHeight(int x, int y);
//! Decide whether a point is using the materials
bool LevelGetDot(int x, int y, float min, float max, float slope);
//! Seeks if material exists
int LevelTestMat(char *mat);
//! Modifies the state of a point and its four neighbors, without testing if possible
void LevelSetDot(int x, int y, int id, char *mat);
//! Tests if a material can give a place, according to its four neighbors. If yes, puts the point.
bool LevelIfDot(int x, int y, int id, char *mat);
//! Modifies the state of a point
bool LevelPutDot(int x, int y, int id);
//! Initializes a table with empty levels
void LevelOpenTable();
//! Closes the level table
void LevelCloseTable();
//! Adjusts a position according to a possible rise
void AdjustBuildingLevel(Math::Vector &p);
protected:
@ -173,39 +244,49 @@ protected:
CEngine* m_engine;
CWater* m_water;
int m_mosaic; // number of mosaics
int m_brick; // number of bricks per mosaics
float m_size; // size of an item in an brick
float m_vision; // vision before a change of resolution
float* m_relief; // table of the relief
int* m_texture; // table of textures
int* m_objRank; // table of rows of objects
bool m_bMultiText;
bool m_bLevelText;
float m_scaleMapping; // scale of the mapping
//! Number of mosaics
int m_mosaic;
//! Number of bricks per mosaics
int m_brick;
int m_levelDotSize;
//! Size of an item in a brick
float m_size;
//! Vision before a change of resolution
float m_vision;
//! Table of the relief
std::vector<float> m_relief;
//! Table of textures
std::vector<int> m_texture;
//! Table of rows of objects
std::vector<int> m_objRank;
//! Table of resources
std::vector<unsigned char> m_resources;
bool m_multiText;
bool m_levelText;
//! Scale of the mapping
float m_scaleMapping;
float m_scaleRelief;
int m_subdivMapping;
int m_depth; // number of different resolutions (1,2,3,4)
char m_texBaseName[20];
char m_texBaseExt[10];
int m_subdivMapping;
//! Number of different resolutions (1,2,3,4)
int m_depth;
std::string m_texBaseName;
std::string m_texBaseExt;
float m_defHardness;
TerrainMaterial m_levelMat[MAXMATTERRAIN+1];
int m_levelMatTotal;
std::vector<TerrainMaterial> m_levelMat;
std::vector<Gfx::DotLevel> m_levelDot;
int m_levelMatMax;
int m_levelDotSize;
DotLevel* m_levelDot;
int m_levelID;
int m_buildingUsed;
BuildingLevel m_buildingTable[MAXBUILDINGLEVEL];
std::vector<Gfx::BuildingLevel> m_buildingLevels;
unsigned char* m_resources;
Math::Vector m_wind; // wind speed
//! Wind speed
Math::Vector m_wind;
//! Global flying height limit
float m_flyingMaxHeight;
int m_flyingLimitTotal;
FlyingLimit m_flyingLimit[MAXFLYINGLIMIT];
//! List of local flight limits
std::vector<Gfx::FlyingLimit> m_flyingLimits;
};
}; // namespace Gfx

View File

@ -19,5 +19,784 @@
#include "graphics/engine/text.h"
#include "app/app.h"
#include "common/image.h"
#include "common/iman.h"
#include "common/logger.h"
#include "common/stringutils.h"
#include "math/func.h"
// TODO implementation
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
namespace Gfx
{
/**
\struct CachedFont
\brief Base TTF font with UTF-8 char cache */
struct CachedFont
{
TTF_Font* font;
std::map<Gfx::UTF8Char, Gfx::CharTexture> cache;
CachedFont() : font(nullptr) {}
};
};
Gfx::CText::CText(CInstanceManager *iMan, Gfx::CEngine* engine)
{
m_iMan = iMan;
m_iMan->AddInstance(CLASS_TEXT, this);
m_device = nullptr;
m_engine = engine;
m_defaultSize = 12.0f;
m_fontPath = "fonts";
m_lastFontType = Gfx::FONT_COLOBOT;
m_lastFontSize = 0;
m_lastCachedFont = nullptr;
}
Gfx::CText::~CText()
{
m_iMan->DeleteInstance(CLASS_TEXT, this);
m_iMan = nullptr;
m_device = nullptr;
m_engine = nullptr;
}
bool Gfx::CText::Create()
{
if (TTF_Init() != 0)
{
m_error = std::string("TTF_Init error: ") + std::string(TTF_GetError());
return false;
}
m_fonts[Gfx::FONT_COLOBOT] = new MultisizeFont("dvu_sans.ttf");
m_fonts[Gfx::FONT_COLOBOT_BOLD] = new MultisizeFont("dvu_sans_bold.ttf");
m_fonts[Gfx::FONT_COLOBOT_ITALIC] = new MultisizeFont("dvu_sans_italic.ttf");
m_fonts[Gfx::FONT_COURIER] = new MultisizeFont("dvu_sans_mono.ttf");
m_fonts[Gfx::FONT_COURIER_BOLD] = new MultisizeFont("dvu_sans_mono_bold.ttf");
for (auto it = m_fonts.begin(); it != m_fonts.end(); ++it)
{
Gfx::FontType type = (*it).first;
CachedFont* cf = GetOrOpenFont(type, m_defaultSize);
if (cf == nullptr || cf->font == nullptr)
return false;
}
return true;
}
void Gfx::CText::Destroy()
{
for (auto it = m_fonts.begin(); it != m_fonts.end(); ++it)
{
MultisizeFont* mf = (*it).second;
for (auto jt = mf->fonts.begin(); jt != mf->fonts.end(); ++jt)
{
CachedFont* cf = (*jt).second;
TTF_CloseFont(cf->font);
cf->font = nullptr;
delete cf;
}
mf->fonts.clear();
delete mf;
}
m_fonts.clear();
m_lastCachedFont = nullptr;
TTF_Quit();
}
void Gfx::CText::SetDevice(Gfx::CDevice* device)
{
m_device = device;
}
std::string Gfx::CText::GetError()
{
return m_error;
}
void Gfx::CText::FlushCache()
{
for (auto it = m_fonts.begin(); it != m_fonts.end(); ++it)
{
MultisizeFont *mf = (*it).second;
for (auto jt = mf->fonts.begin(); jt != mf->fonts.end(); ++jt)
{
CachedFont *f = (*jt).second;
f->cache.clear();
}
}
}
void Gfx::CText::DrawText(const std::string &text, const std::vector<FontMetaChar> &format,
float size, Math::Point pos, float width, Gfx::TextAlign align,
int eol)
{
float sw = 0.0f;
if (align == Gfx::TEXT_ALIGN_CENTER)
{
sw = GetStringWidth(text, format, size);
if (sw > width) sw = width;
pos.x -= sw / 2.0f;
}
else if (align == Gfx::TEXT_ALIGN_RIGHT)
{
sw = GetStringWidth(text, format, size);
if (sw > width) sw = width;
pos.x -= sw;
}
DrawString(text, format, size, pos, width, eol);
}
void Gfx::CText::DrawText(const std::string &text, Gfx::FontType font,
float size, Math::Point pos, float width, Gfx::TextAlign align,
int eol)
{
float sw = 0.0f;
if (align == Gfx::TEXT_ALIGN_CENTER)
{
sw = GetStringWidth(text, font, size);
if (sw > width) sw = width;
pos.x -= sw / 2.0f;
}
else if (align == Gfx::TEXT_ALIGN_RIGHT)
{
sw = GetStringWidth(text, font, size);
if (sw > width) sw = width;
pos.x -= sw;
}
DrawString(text, font, size, pos, width, eol);
}
void Gfx::CText::SizeText(const std::string &text, const std::vector<FontMetaChar> &format,
float size, Math::Point pos, Gfx::TextAlign align,
Math::Point &start, Math::Point &end)
{
start = end = pos;
float sw = GetStringWidth(text, format, size);
end.x += sw;
if (align == Gfx::TEXT_ALIGN_CENTER)
{
start.x -= sw/2.0f;
end.x -= sw/2.0f;
}
else if (align == Gfx::TEXT_ALIGN_RIGHT)
{
start.x -= sw;
end.x -= sw;
}
start.y -= GetDescent(Gfx::FONT_COLOBOT, size);
end.y += GetAscent(Gfx::FONT_COLOBOT, size);
}
void Gfx::CText::SizeText(const std::string &text, Gfx::FontType font,
float size, Math::Point pos, Gfx::TextAlign align,
Math::Point &start, Math::Point &end)
{
start = end = pos;
float sw = GetStringWidth(text, font, size);
end.x += sw;
if (align == Gfx::TEXT_ALIGN_CENTER)
{
start.x -= sw/2.0f;
end.x -= sw/2.0f;
}
else if (align == Gfx::TEXT_ALIGN_RIGHT)
{
start.x -= sw;
end.x -= sw;
}
start.y -= GetDescent(font, size);
end.y += GetAscent(font, size);
}
float Gfx::CText::GetAscent(Gfx::FontType font, float size)
{
assert(font != Gfx::FONT_BUTTON);
Gfx::CachedFont* cf = GetOrOpenFont(font, size);
assert(cf != nullptr);
Math::IntPoint wndSize;
wndSize.y = TTF_FontAscent(cf->font);
Math::Point ifSize = m_engine->WindowToInterfaceSize(wndSize);
return ifSize.y;
}
float Gfx::CText::GetDescent(Gfx::FontType font, float size)
{
assert(font != Gfx::FONT_BUTTON);
Gfx::CachedFont* cf = GetOrOpenFont(font, size);
assert(cf != nullptr);
Math::IntPoint wndSize;
wndSize.y = TTF_FontDescent(cf->font);
Math::Point ifSize = m_engine->WindowToInterfaceSize(wndSize);
return ifSize.y;
}
float Gfx::CText::GetHeight(Gfx::FontType font, float size)
{
assert(font != Gfx::FONT_BUTTON);
Gfx::CachedFont* cf = GetOrOpenFont(font, size);
assert(cf != nullptr);
Math::IntPoint wndSize;
wndSize.y = TTF_FontHeight(cf->font);
Math::Point ifSize = m_engine->WindowToInterfaceSize(wndSize);
return ifSize.y;
}
float Gfx::CText::GetStringWidth(const std::string &text,
const std::vector<FontMetaChar> &format, float size)
{
assert(StrUtils::Utf8StringLength(text) == format.size());
float width = 0.0f;
unsigned int index = 0;
unsigned int fmtIndex = 0;
while (index < text.length())
{
Gfx::FontType font = static_cast<Gfx::FontType>(format[fmtIndex] & Gfx::FONT_MASK_FONT);
Gfx::UTF8Char ch;
int len = StrUtils::Utf8CharSizeAt(text, index);
if (len >= 1)
ch.c1 = text[index];
if (len >= 2)
ch.c2 = text[index+1];
if (len >= 3)
ch.c3 = text[index+2];
width += GetCharWidth(ch, font, size, width);
index += len;
fmtIndex++;
}
return width;
}
float Gfx::CText::GetStringWidth(const std::string &text, Gfx::FontType font, float size)
{
assert(font != Gfx::FONT_BUTTON);
// TODO: special chars?
Gfx::CachedFont* cf = GetOrOpenFont(font, size);
assert(cf != nullptr);
Math::IntPoint wndSize;
TTF_SizeUTF8(cf->font, text.c_str(), &wndSize.x, &wndSize.y);
Math::Point ifSize = m_engine->WindowToInterfaceSize(wndSize);
return ifSize.x;
}
float Gfx::CText::GetCharWidth(Gfx::UTF8Char ch, Gfx::FontType font, float size, float offset)
{
// TODO: if (font == Gfx::FONT_BUTTON)
if (font == Gfx::FONT_BUTTON) return 0.0f;
// TODO: special chars?
// TODO: tab sizing
Gfx::CachedFont* cf = GetOrOpenFont(font, size);
assert(cf != nullptr);
Gfx::CharTexture tex;
auto it = cf->cache.find(ch);
if (it != cf->cache.end())
tex = (*it).second;
else
tex = CreateCharTexture(ch, cf);
return tex.charSize.x;
}
int Gfx::CText::Justify(const std::string &text, const std::vector<FontMetaChar> &format,
float size, float width)
{
assert(StrUtils::Utf8StringLength(text) == format.size());
float pos = 0.0f;
int cut = 0;
unsigned int index = 0;
unsigned int fmtIndex = 0;
while (index < text.length())
{
Gfx::FontType font = static_cast<Gfx::FontType>(format[fmtIndex] & Gfx::FONT_MASK_FONT);
Gfx::UTF8Char ch;
int len = StrUtils::Utf8CharSizeAt(text, index);
if (len >= 1)
ch.c1 = text[index];
if (len >= 2)
ch.c2 = text[index+1];
if (len >= 3)
ch.c3 = text[index+2];
if (font != Gfx::FONT_BUTTON)
{
if (ch.c1 == '\n')
return index+1;
if (ch.c1 == ' ')
cut = index+1;
}
pos += GetCharWidth(ch, font, size, pos);
if (pos > width)
{
if (cut == 0) return index;
else return cut;
}
index += len;
fmtIndex++;
}
return index;
}
int Gfx::CText::Justify(const std::string &text, Gfx::FontType font, float size, float width)
{
assert(font != Gfx::FONT_BUTTON);
float pos = 0.0f;
int cut = 0;
unsigned int index = 0;
while (index < text.length())
{
Gfx::UTF8Char ch;
int len = StrUtils::Utf8CharSizeAt(text, index);
if (len >= 1)
ch.c1 = text[index];
if (len >= 2)
ch.c2 = text[index+1];
if (len >= 3)
ch.c3 = text[index+2];
index += len;
if (ch.c1 == '\n')
return index+1;
if (ch.c1 == ' ' )
cut = index+1;
pos += GetCharWidth(ch, font, size, pos);
if (pos > width)
{
if (cut == 0) return index;
else return cut;
}
}
return index;
}
int Gfx::CText::Detect(const std::string &text, const std::vector<FontMetaChar> &format,
float size, float offset)
{
assert(StrUtils::Utf8StringLength(text) == format.size());
float pos = 0.0f;
unsigned int index = 0;
unsigned int fmtIndex = 0;
while (index < text.length())
{
Gfx::FontType font = static_cast<Gfx::FontType>(format[fmtIndex] & Gfx::FONT_MASK_FONT);
// TODO: if (font == Gfx::FONT_BUTTON)
if (font == Gfx::FONT_BUTTON) continue;
Gfx::UTF8Char ch;
int len = StrUtils::Utf8CharSizeAt(text, index);
if (len >= 1)
ch.c1 = text[index];
if (len >= 2)
ch.c2 = text[index+1];
if (len >= 3)
ch.c3 = text[index+2];
if (ch.c1 == '\n')
return index;
float width = GetCharWidth(ch, font, size, pos);
if (offset <= pos + width/2.0f)
return index;
pos += width;
index += len;
fmtIndex++;
}
return index;
}
int Gfx::CText::Detect(const std::string &text, Gfx::FontType font, float size, float offset)
{
assert(font != Gfx::FONT_BUTTON);
float pos = 0.0f;
unsigned int index = 0;
while (index < text.length())
{
Gfx::UTF8Char ch;
int len = StrUtils::Utf8CharSizeAt(text, index);
if (len >= 1)
ch.c1 = text[index];
if (len >= 2)
ch.c2 = text[index+1];
if (len >= 3)
ch.c3 = text[index+2];
index += len;
if (ch.c1 == '\n')
return index;
float width = GetCharWidth(ch, font, size, pos);
if (offset <= pos + width/2.0f)
return index;
pos += width;
}
return index;
}
void Gfx::CText::DrawString(const std::string &text, const std::vector<FontMetaChar> &format,
float size, Math::Point pos, float width, int eol)
{
assert(StrUtils::Utf8StringLength(text) == format.size());
m_engine->SetState(Gfx::ENG_RSTATE_TEXT);
Gfx::FontType font = Gfx::FONT_COLOBOT;
float start = pos.x;
unsigned int index = 0;
unsigned int fmtIndex = 0;
while (index < text.length())
{
font = static_cast<Gfx::FontType>(format[fmtIndex] & Gfx::FONT_MASK_FONT);
// TODO: if (font == Gfx::FONT_BUTTON)
if (font == Gfx::FONT_BUTTON) continue;
Gfx::UTF8Char ch;
int len = StrUtils::Utf8CharSizeAt(text, index);
if (len >= 1)
ch.c1 = text[index];
if (len >= 2)
ch.c2 = text[index+1];
if (len >= 3)
ch.c3 = text[index+2];
float offset = pos.x - start;
float cw = GetCharWidth(ch, font, size, offset);
if (offset + cw > width) // exceeds the maximum width?
{
// TODO: special end-of-line char
break;
}
Gfx::FontHighlight hl = static_cast<Gfx::FontHighlight>(format[fmtIndex] & Gfx::FONT_MASK_HIGHLIGHT);
if (hl != Gfx::FONT_HIGHLIGHT_NONE)
{
Math::Point charSize;
charSize.x = GetCharWidth(ch, font, size, offset);
charSize.y = GetHeight(font, size);
DrawHighlight(hl, pos, charSize);
}
DrawChar(ch, font, size, pos);
index += len;
fmtIndex++;
}
// TODO: eol
}
void Gfx::CText::DrawString(const std::string &text, Gfx::FontType font,
float size, Math::Point pos, float width, int eol)
{
assert(font != Gfx::FONT_BUTTON);
m_engine->SetState(Gfx::ENG_RSTATE_TEXT);
unsigned int index = 0;
while (index < text.length())
{
Gfx::UTF8Char ch;
int len = StrUtils::Utf8CharSizeAt(text, index);
if (len >= 1)
ch.c1 = text[index];
if (len >= 2)
ch.c2 = text[index+1];
if (len >= 3)
ch.c3 = text[index+2];
index += len;
DrawChar(ch, font, size, pos);
}
}
void Gfx::CText::DrawHighlight(Gfx::FontHighlight hl, Math::Point pos, Math::Point size)
{
// Gradient colors
Gfx::Color grad[4];
// TODO: switch to alpha factors
switch (hl)
{
case Gfx::FONT_HIGHLIGHT_LINK:
grad[0] = grad[1] = grad[2] = grad[3] = Gfx::Color(0.0f, 0.0f, 1.0f, 0.5f);
break;
case Gfx::FONT_HIGHLIGHT_TOKEN:
grad[0] = grad[1] = Gfx::Color(248.0f / 256.0f, 248.0f / 256.0f, 248.0f / 256.0f, 0.5f);
grad[2] = grad[3] = Gfx::Color(248.0f / 256.0f, 220.0f / 256.0f, 188.0f / 256.0f, 0.5f);
break;
case Gfx::FONT_HIGHLIGHT_TYPE:
grad[0] = grad[1] = Gfx::Color(248.0f / 256.0f, 248.0f / 256.0f, 248.0f / 256.0f, 0.5f);
grad[2] = grad[3] = Gfx::Color(169.0f / 256.0f, 234.0f / 256.0f, 169.0f / 256.0f, 0.5f);
break;
case Gfx::FONT_HIGHLIGHT_CONST:
grad[0] = grad[1] = Gfx::Color(248.0f / 256.0f, 248.0f / 256.0f, 248.0f / 256.0f, 0.5f);
grad[2] = grad[3] = Gfx::Color(248.0f / 256.0f, 176.0f / 256.0f, 169.0f / 256.0f, 0.5f);
break;
case Gfx::FONT_HIGHLIGHT_REM:
grad[0] = grad[1] = Gfx::Color(248.0f / 256.0f, 248.0f / 256.0f, 248.0f / 256.0f, 0.5f);
grad[2] = grad[3] = Gfx::Color(248.0f / 256.0f, 169.0f / 256.0f, 248.0f / 256.0f, 0.5f);
break;
case Gfx::FONT_HIGHLIGHT_KEY:
grad[0] = grad[1] = grad[2] = grad[3] =
Gfx::Color(192.0f / 256.0f, 192.0f / 256.0f, 192.0f / 256.0f, 0.5f);
break;
default:
return;
}
Math::IntPoint vsize = m_engine->GetWindowSize();
float h = 0.0f;
if (vsize.y <= 768.0f) // 1024x768 or less?
h = 1.01f / vsize.y; // 1 pixel
else // more than 1024x768?
h = 2.0f / vsize.y; // 2 pixels
Math::Point p1, p2;
p1.x = pos.x;
p2.x = pos.x + size.x;
if (hl == Gfx::FONT_HIGHLIGHT_LINK)
{
p1.y = pos.y;
p2.y = pos.y + h; // just emphasized
}
else
{
p1.y = pos.y;
p2.y = pos.y + size.y;
}
m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, false);
Gfx::VertexCol quad[] =
{
Gfx::VertexCol(Math::Vector(p1.x, p1.y, 0.0f), grad[3]),
Gfx::VertexCol(Math::Vector(p1.x, p2.y, 0.0f), grad[0]),
Gfx::VertexCol(Math::Vector(p2.x, p1.y, 0.0f), grad[2]),
Gfx::VertexCol(Math::Vector(p2.x, p2.y, 0.0f), grad[1])
};
m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4);
m_engine->AddStatisticTriangle(2);
m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true);
}
void Gfx::CText::DrawChar(Gfx::UTF8Char ch, Gfx::FontType font, float size, Math::Point &pos)
{
// TODO: if (font == Gfx::FONT_BUTTON)
if (font == Gfx::FONT_BUTTON) return;
// TODO: special chars?
CachedFont* cf = GetOrOpenFont(font, size);
if (cf == nullptr)
return;
auto it = cf->cache.find(ch);
CharTexture tex;
if (it != cf->cache.end())
{
tex = (*it).second;
}
else
{
tex = CreateCharTexture(ch, cf);
if (tex.id == 0) // invalid
return;
cf->cache[ch] = tex;
}
Math::Point p1(pos.x, pos.y + tex.charSize.y - tex.texSize.y);
Math::Point p2(pos.x + tex.texSize.x, pos.y + tex.charSize.y);
Math::Vector n(0.0f, 0.0f, -1.0f); // normal
Gfx::Vertex quad[4] =
{
Gfx::Vertex(Math::Vector(p1.x, p1.y, 0.0f), n, Math::Point(0.0f, 1.0f)),
Gfx::Vertex(Math::Vector(p1.x, p2.y, 0.0f), n, Math::Point(0.0f, 0.0f)),
Gfx::Vertex(Math::Vector(p2.x, p1.y, 0.0f), n, Math::Point(1.0f, 1.0f)),
Gfx::Vertex(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(1.0f, 0.0f))
};
m_device->SetTexture(0, tex.id);
m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4);
m_engine->AddStatisticTriangle(2);
pos.x += tex.charSize.x;
}
Gfx::CachedFont* Gfx::CText::GetOrOpenFont(Gfx::FontType font, float size)
{
// TODO: sizing
int pointSize = static_cast<int>(size);
if (m_lastCachedFont != nullptr)
{
if (m_lastFontType == font && m_lastFontSize == pointSize)
return m_lastCachedFont;
}
auto it = m_fonts.find(font);
if (it == m_fonts.end())
{
m_error = std::string("Invalid font type ") + StrUtils::ToString<int>(static_cast<int>(font));
return nullptr;
}
MultisizeFont* mf = (*it).second;
auto jt = mf->fonts.find(pointSize);
if (jt != mf->fonts.end())
{
m_lastCachedFont = (*jt).second;
m_lastFontType = font;
m_lastFontSize = pointSize;
return m_lastCachedFont;
}
std::string path = CApplication::GetInstance().GetDataFilePath(m_fontPath, mf->fileName);
m_lastCachedFont = new CachedFont();
m_lastCachedFont->font = TTF_OpenFont(path.c_str(), pointSize);
if (m_lastCachedFont->font == nullptr)
m_error = std::string("TTF_OpenFont error ") + std::string(TTF_GetError());
mf->fonts[pointSize] = m_lastCachedFont;
return m_lastCachedFont;
}
Gfx::CharTexture Gfx::CText::CreateCharTexture(Gfx::UTF8Char ch, Gfx::CachedFont* font)
{
CharTexture texture;
SDL_Surface* textSurface = nullptr;
SDL_Color white = {255, 255, 255, 0};
char str[] = { ch.c1, ch.c2, ch.c3, '\0' };
textSurface = TTF_RenderUTF8_Blended(font->font, str, white);
if (textSurface == nullptr)
{
m_error = "TTF_Render error";
return texture;
}
int w = Math::NextPowerOfTwo(textSurface->w);
int h = Math::NextPowerOfTwo(textSurface->h);
textSurface->flags = textSurface->flags & (~SDL_SRCALPHA);
SDL_Surface* textureSurface = SDL_CreateRGBSurface(0, w, h, 32, 0x00ff0000, 0x0000ff00,
0x000000ff, 0xff000000);
SDL_BlitSurface(textSurface, NULL, textureSurface, NULL);
ImageData data;
data.surface = textureSurface;
Gfx::TextureCreateParams createParams;
createParams.format = Gfx::TEX_IMG_RGBA;
createParams.minFilter = Gfx::TEX_MIN_FILTER_NEAREST;
createParams.magFilter = Gfx::TEX_MAG_FILTER_NEAREST;
createParams.mipmap = false;
Gfx::Texture tex = m_device->CreateTexture(&data, createParams);
data.surface = nullptr;
SDL_FreeSurface(textSurface);
SDL_FreeSurface(textureSurface);
if (! tex.valid)
{
m_error = "Texture create error";
return texture;
}
texture.id = tex.id;
texture.texSize = m_engine->WindowToInterfaceSize(Math::IntPoint(textureSurface->w, textureSurface->h));
texture.charSize = m_engine->WindowToInterfaceSize(Math::IntPoint(textSurface->w, textSurface->h));
return texture;
}

View File

@ -15,99 +15,287 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// text.h
/**
* \file graphics/engine/text.h
* \brief Text rendering - Gfx::CText class
*/
#pragma once
#include "graphics/engine/engine.h"
#include "graphics/core/device.h"
#include "math/point.h"
#include <vector>
#include <map>
class CInstanceManager;
namespace Gfx {
const float SMALLFONT = 10.0f;
const float BIGFONT = 15.0f;
class CEngine;
class CDevice;
const float NORMSTRETCH = 0.8f;
//! Standard small font size
const float FONT_SIZE_SMALL = 10.0f;
//! Standard big font size
const float FONT_SIZE_BIG = 15.0f;
/**
\enum TextAlign
\brief Type of text alignment */
enum TextAlign
{
TEXT_ALIGN_RIGHT,
TEXT_ALIGN_LEFT,
TEXT_ALIGN_CENTER
};
/* Font meta char constants */
//! Type used for font character metainfo
typedef short FontMetaChar;
/**
\enum FontType
\brief Type of font
Bitmask in lower 4 bits (mask 0x00f) */
enum FontType
{
FONT_COLOBOT = 0,
FONT_COURIER = 1,
FONT_BUTTON = 2,
//! Flag for bold font subtype
FONT_BOLD = 0x04,
//! Flag for italic font subtype
FONT_ITALIC = 0x08,
//! Default colobot font used for interface
FONT_COLOBOT = 0x00,
//! Alias for bold colobot font
FONT_COLOBOT_BOLD = FONT_COLOBOT | FONT_BOLD,
//! Alias for italic colobot font
FONT_COLOBOT_ITALIC = FONT_COLOBOT | FONT_ITALIC,
//! Courier (monospace) font used mainly in code editor (only regular & bold)
FONT_COURIER = 0x01,
//! Alias for bold courier font
FONT_COURIER_BOLD = FONT_COURIER | FONT_BOLD,
// 0x02 left for possible another font
//! Pseudo-font loaded from textures for buttons, icons, etc.
FONT_BUTTON = 0x03,
};
/**
\enum FontTitle
\brief Size of font title
Used internally by CEdit
Bitmask in 2 bits left shifted 4 (mask 0x030) */
enum FontTitle
{
TITLE_BIG = 0x04,
TITLE_NORM = 0x08,
TITLE_LITTLE = 0x0c,
FONT_TITLE_BIG = 0x01 << 4,
FONT_TITLE_NORM = 0x02 << 4,
FONT_TITLE_LITTLE = 0x03 << 4,
};
enum FontColor
/**
\enum FontHighlight
\brief Type of color highlight for text
Bitmask in 3 bits left shifted 6 (mask 0x1c0) */
enum FontHighlight
{
COLOR_LINK = 0x10,
COLOR_TOKEN = 0x20,
COLOR_TYPE = 0x30,
COLOR_CONST = 0x40,
COLOR_REM = 0x50,
COLOR_KEY = 0x60,
COLOR_TABLE = 0x70,
FONT_HIGHLIGHT_NONE = 0x00 << 6,
FONT_HIGHLIGHT_LINK = 0x01 << 6,
FONT_HIGHLIGHT_TOKEN = 0x02 << 6,
FONT_HIGHLIGHT_TYPE = 0x03 << 6,
FONT_HIGHLIGHT_CONST = 0x04 << 6,
FONT_HIGHLIGHT_REM = 0x05 << 6,
FONT_HIGHLIGHT_KEY = 0x06 << 6,
FONT_HIGHLIGHT_TABLE = 0x07 << 6,
};
const short FONT_MASK = 0x03;
const short TITLE_MASK = 0x0c;
const short COLOR_MASK = 0x70;
const short IMAGE_MASK = 0x80;
/**
\enum FontMask
\brief Masks in FontMetaChar for different attributes */
enum FontMask
{
//! Mask for FontType
FONT_MASK_FONT = 0x00f,
//! Mask for FontTitle
FONT_MASK_TITLE = 0x030,
//! Mask for FontHighlight
FONT_MASK_HIGHLIGHT = 0x1c0,
//! Mask for image bit (TODO: not used?)
FONT_MASK_IMAGE = 0x200
};
/**
\struct UTF8Char
\brief UTF-8 character in font cache
class CText {
Only 3-byte chars are supported */
struct UTF8Char
{
char c1, c2, c3;
explicit UTF8Char(char ch1 = '\0', char ch2 = '\0', char ch3 = '\0')
: c1(ch1), c2(ch2), c3(ch3) {}
inline bool operator<(const UTF8Char &other) const
{
if (c1 < other.c1)
return true;
else if (c1 > other.c1)
return false;
if (c2 < other.c2)
return true;
else if (c2 > other.c2)
return false;
return c3 < other.c3;
}
inline bool operator==(const UTF8Char &other) const
{
return c1 == other.c1 && c2 == other.c2 && c3 == other.c3;
}
};
/**
\struct CharTexture
\brief Texture of font character */
struct CharTexture
{
unsigned int id;
Math::Point texSize;
Math::Point charSize;
CharTexture() : id(0) {}
};
// Definition is private - in text.cpp
struct CachedFont;
/**
\struct MultisizeFont
\brief Font with multiple possible sizes */
struct MultisizeFont
{
std::string fileName;
std::map<int, CachedFont*> fonts;
MultisizeFont(const std::string &fn)
: fileName(fn) {}
};
/**
\class CText
\brief Text rendering engine
CText is responsible for drawing text in 2D interface. Font rendering is done using
textures generated by SDL_ttf from TTF font files.
All functions rendering text are divided into two types:
- single font - function takes a single Gfx::FontType argument that (along with size)
determines the font to be used for all characters,
- multi-font - function takes the text as one argument and a std::vector of FontMetaChar
with per-character formatting information (font, highlights and some other info used by CEdit)
All font rendering is done in UTF-8.
*/
class CText
{
public:
CText(CInstanceManager *iMan, Gfx::CEngine* engine);
~CText();
//! Sets the device to be used
void SetDevice(Gfx::CDevice *device);
void DrawText(char *string, char *format, int len, Math::Point pos, float width, int justif, float size, float stretch, int eol);
void DrawText(char *string, char *format, Math::Point pos, float width, int justif, float size, float stretch, int eol);
void DrawText(char *string, int len, Math::Point pos, float width, int justif, float size, float stretch, FontType font, int eol);
void DrawText(char *string, Math::Point pos, float width, int justif, float size, float stretch, FontType font, int eol);
void DimText(char *string, char *format, int len, Math::Point pos, int justif, float size, float stretch, Math::Point &start, Math::Point &end);
void DimText(char *string, char *format, Math::Point pos, int justif, float size, float stretch, Math::Point &start, Math::Point &end);
void DimText(char *string, int len, Math::Point pos, int justif, float size, float stretch, FontType font, Math::Point &start, Math::Point &end);
void DimText(char *string, Math::Point pos, int justif, float size, float stretch, FontType font, Math::Point &start, Math::Point &end);
//! Returns the last encountered error
std::string GetError();
float RetAscent(float size, FontType font);
float RetDescent(float size, FontType font);
float RetHeight(float size, FontType font);
//! Initializes the font engine; must be called after SetDevice()
bool Create();
//! Frees resources before exit
void Destroy();
float RetStringWidth(char *string, char *format, int len, float size, float stretch);
float RetStringWidth(char *string, int len, float size, float stretch, FontType font);
float RetCharWidth(int character, float offset, float size, float stretch, FontType font);
//! Flushes cached textures
void FlushCache();
int Justif(char *string, char *format, int len, float width, float size, float stretch);
int Justif(char *string, int len, float width, float size, float stretch, FontType font);
int Detect(char *string, char *format, int len, float offset, float size, float stretch);
int Detect(char *string, int len, float offset, float size, float stretch, FontType font);
//! Draws text (multi-format)
void DrawText(const std::string &text, const std::vector<Gfx::FontMetaChar> &format,
float size, Math::Point pos, float width, Gfx::TextAlign align,
int eol);
//! Draws text (one font)
void DrawText(const std::string &text, Gfx::FontType font,
float size, Math::Point pos, float width, Gfx::TextAlign align,
int eol);
//! Calculates dimensions for text (multi-format)
void SizeText(const std::string &text, const std::vector<Gfx::FontMetaChar> &format,
float size, Math::Point pos, Gfx::TextAlign align,
Math::Point &start, Math::Point &end);
//! Calculates dimensions for text (one font)
void SizeText(const std::string &text, Gfx::FontType font,
float size, Math::Point pos, Gfx::TextAlign align,
Math::Point &start, Math::Point &end);
//! Returns the ascent font metric
float GetAscent(Gfx::FontType font, float size);
//! Returns the descent font metric
float GetDescent(Gfx::FontType font, float size);
//! Returns the height font metric
float GetHeight(Gfx::FontType font, float size);
//! Returns width of string (multi-format)
float GetStringWidth(const std::string &text,
const std::vector<Gfx::FontMetaChar> &format, float size);
//! Returns width of string (single font)
float GetStringWidth(const std::string &text, Gfx::FontType font, float size);
//! Returns width of single character
float GetCharWidth(Gfx::UTF8Char ch, Gfx::FontType font, float size, float offset);
//! Justifies a line of text (multi-format)
int Justify(const std::string &text, const std::vector<Gfx::FontMetaChar> &format,
float size, float width);
//! Justifies a line of text (one font)
int Justify(const std::string &text, Gfx::FontType font, float size, float width);
//! Returns the most suitable position to a given offset (multi-format)
int Detect(const std::string &text, const std::vector<Gfx::FontMetaChar> &format,
float size, float offset);
//! Returns the most suitable position to a given offset (one font)
int Detect(const std::string &text, Gfx::FontType font, float size, float offset);
protected:
void DrawString(char *string, char *format, int len, Math::Point pos, float width, float size, float stretch, int eol);
void DrawString(char *string, int len, Math::Point pos, float width, float size, float stretch, FontType font, int eol);
void DrawColor(Math::Point pos, float size, float width, int color);
void DrawChar(int character, Math::Point pos, float size, float stretch, FontType font);
Gfx::CachedFont* GetOrOpenFont(Gfx::FontType type, float size);
Gfx::CharTexture CreateCharTexture(Gfx::UTF8Char ch, Gfx::CachedFont* font);
void DrawString(const std::string &text, const std::vector<Gfx::FontMetaChar> &format,
float size, Math::Point pos, float width, int eol);
void DrawString(const std::string &text, Gfx::FontType font,
float size, Math::Point pos, float width, int eol);
void DrawHighlight(Gfx::FontHighlight hl, Math::Point pos, Math::Point size);
void DrawChar(Gfx::UTF8Char ch, Gfx::FontType font, float size, Math::Point &pos);
protected:
CInstanceManager* m_iMan;
Gfx::CEngine* m_engine;
Gfx::CDevice* m_device;
std::string m_error;
float m_defaultSize;
std::string m_fontPath;
std::map<Gfx::FontType, Gfx::MultisizeFont*> m_fonts;
Gfx::FontType m_lastFontType;
int m_lastFontSize;
Gfx::CachedFont* m_lastCachedFont;
};
}; // namespace Gfx

View File

@ -19,5 +19,638 @@
#include "graphics/engine/water.h"
#include "common/iman.h"
#include "graphics/engine/engine.h"
#include "graphics/engine/terrain.h"
#include "sound/sound.h"
const int WATERLINE_PREALLOCATE_COUNT = 500;
// TODO: remove the limit?
const int VAPOR_SIZE = 10;
Gfx::CWater::CWater(CInstanceManager* iMan, Gfx::CEngine* engine)
{
m_iMan = iMan;
m_iMan->AddInstance(CLASS_WATER, this);
m_engine = engine;
m_terrain = nullptr;
m_particule = nullptr;
m_sound = nullptr;
m_type[0] = WATER_NULL;
m_type[1] = WATER_NULL;
m_level = 0.0f;
m_draw = true;
m_lava = false;
m_color = 0xffffffff;
m_subdiv = 4;
m_line.reserve(WATERLINE_PREALLOCATE_COUNT);
std::vector<Gfx::WaterVapor>(VAPOR_SIZE).swap(m_vapor);
}
Gfx::CWater::~CWater()
{
m_iMan = nullptr;
m_engine = nullptr;
m_terrain = nullptr;
m_particule = nullptr;
m_sound = nullptr;
}
bool Gfx::CWater::EventProcess(const Event &event)
{
if (event.type == EVENT_FRAME)
return EventFrame(event);
return true;
}
bool Gfx::CWater::EventFrame(const Event &event)
{
if (m_engine->GetPause()) return true;
m_time += event.rTime;
if (m_type[0] == WATER_NULL) return true;
if (m_lava)
LavaFrame(event.rTime);
return true;
}
void Gfx::CWater::LavaFrame(float rTime)
{
if (m_particule == nullptr)
m_particule = static_cast<Gfx::CParticle*>( m_iMan->SearchInstance(CLASS_PARTICULE) );
for (int i = 0; i < static_cast<int>( m_vapor.size() ); i++)
VaporFrame(i, rTime);
if (m_time - m_lastLava >= 0.1f)
{
Math::Vector eye = m_engine->GetEyePt();
Math::Vector lookat = m_engine->GetLookatPt();
float distance = Math::Rand()*200.0f;
float shift = (Math::Rand()-0.5f)*200.0f;
Math::Vector dir = Normalize(lookat-eye);
Math::Vector pos = eye + dir*distance;
Math::Vector perp;
perp.x = -dir.z;
perp.y = dir.y;
perp.z = dir.x;
pos = pos + perp*shift;
float level = m_terrain->GetFloorLevel(pos, true);
if (level < m_level)
{
pos.y = m_level;
level = Math::Rand();
if (level < 0.8f)
{
if ( VaporCreate(Gfx::PARTIFIRE, pos, 0.02f+Math::Rand()*0.06f) )
m_lastLava = m_time;
}
else if (level < 0.9f)
{
if ( VaporCreate(Gfx::PARTIFLAME, pos, 0.5f+Math::Rand()*3.0f) )
m_lastLava = m_time;
}
else
{
if ( VaporCreate(Gfx::PARTIVAPOR, pos, 0.2f+Math::Rand()*2.0f) )
m_lastLava = m_time;
}
}
}
}
void Gfx::CWater::VaporFlush()
{
m_vapor.clear();
}
bool Gfx::CWater::VaporCreate(Gfx::ParticleType type, Math::Vector pos, float delay)
{
for (int i = 0; i < static_cast<int>( m_vapor.size() ); i++)
{
if (! m_vapor[i].used)
{
m_vapor[i].used = true;
m_vapor[i].type = type;
m_vapor[i].pos = pos;
m_vapor[i].delay = delay;
m_vapor[i].time = 0.0f;
m_vapor[i].last = 0.0f;
if (m_vapor[i].type == PARTIFIRE)
m_sound->Play(SOUND_BLUP, pos, 1.0f, 1.0f-Math::Rand()*0.5f);
if (m_vapor[i].type == PARTIVAPOR)
m_sound->Play(SOUND_PSHHH, pos, 0.3f, 2.0f);
return true;
}
}
return false;
}
void Gfx::CWater::VaporFrame(int i, float rTime)
{
m_vapor[i].time += rTime;
if (m_sound == nullptr)
m_sound = static_cast<CSoundInterface*>(m_iMan->SearchInstance(CLASS_SOUND));
if (m_vapor[i].time <= m_vapor[i].delay)
{
if (m_time-m_vapor[i].last >= m_engine->ParticleAdapt(0.02f))
{
m_vapor[i].last = m_time;
if (m_vapor[i].type == PARTIFIRE)
{
for (int j = 0; j < 10; j++)
{
Math::Vector pos = m_vapor[i].pos;
pos.x += (Math::Rand()-0.5f)*2.0f;
pos.z += (Math::Rand()-0.5f)*2.0f;
pos.y -= 1.0f;
Math::Vector speed;
speed.x = (Math::Rand()-0.5f)*6.0f;
speed.z = (Math::Rand()-0.5f)*6.0f;
speed.y = 8.0f+Math::Rand()*5.0f;
Math::Point dim;
dim.x = Math::Rand()*1.5f+1.5f;
dim.y = dim.x;
m_particule->CreateParticle(pos, speed, dim, PARTIERROR, 2.0f, 10.0f);
}
}
else if (m_vapor[i].type == PARTIFLAME)
{
Math::Vector pos = m_vapor[i].pos;
pos.x += (Math::Rand()-0.5f)*8.0f;
pos.z += (Math::Rand()-0.5f)*8.0f;
pos.y -= 2.0f;
Math::Vector speed;
speed.x = (Math::Rand()-0.5f)*2.0f;
speed.z = (Math::Rand()-0.5f)*2.0f;
speed.y = 4.0f+Math::Rand()*4.0f;
Math::Point dim;
dim.x = Math::Rand()*2.0f+2.0f;
dim.y = dim.x;
m_particule->CreateParticle(pos, speed, dim, PARTIFLAME);
}
else
{
Math::Vector pos = m_vapor[i].pos;
pos.x += (Math::Rand()-0.5f)*4.0f;
pos.z += (Math::Rand()-0.5f)*4.0f;
pos.y -= 2.0f;
Math::Vector speed;
speed.x = (Math::Rand()-0.5f)*2.0f;
speed.z = (Math::Rand()-0.5f)*2.0f;
speed.y = 8.0f+Math::Rand()*8.0f;
Math::Point dim;
dim.x = Math::Rand()*1.0f+1.0f;
dim.y = dim.x;
m_particule->CreateParticle(pos, speed, dim, PARTIVAPOR);
}
}
}
else
{
m_vapor[i].used = false;
}
}
void Gfx::CWater::AdjustLevel(Math::Vector &pos, Math::Vector &norm,
Math::Point &uv1, Math::Point &uv2)
{
float t1 = m_time*1.5f + pos.x*0.1f * pos.z*0.2f;
pos.y += sinf(t1)*m_eddy.y;
t1 = m_time*1.5f;
uv1.x = (pos.x+10000.0f)/40.0f+sinf(t1)*m_eddy.x*0.02f;
uv1.y = (pos.z+10000.0f)/40.0f-cosf(t1)*m_eddy.z*0.02f;
uv2.x = (pos.x+10010.0f)/20.0f+cosf(-t1)*m_eddy.x*0.02f;
uv2.y = (pos.z+10010.0f)/20.0f-sinf(-t1)*m_eddy.z*0.02f;
t1 = m_time*0.50f + pos.x*2.1f + pos.z*1.1f;
float t2 = m_time*0.75f + pos.x*2.0f + pos.z*1.0f;
norm = Math::Vector(sinf(t1)*m_glint, 1.0f, sinf(t2)*m_glint);
}
/** This surface prevents to see the sky (background) underwater! */
void Gfx::CWater::DrawBack()
{
/* TODO!
LPDIRECT3DDEVICE7 device;
D3DVERTEX2 vertex[4]; // 2 triangles
D3DMATERIAL7 material;
Math::Matrix matrix;
Math::Vector eye, lookat, n, p, p1, p2;
Math::Point uv1, uv2;
float deep, dist;
if ( !m_bDraw ) return;
if ( m_type[0] == WATER_NULL ) return;
if ( m_lineUsed == 0 ) return;
eye = m_engine->GetEyePt();
lookat = m_engine->GetLookatPt();
ZeroMemory( &material, sizeof(D3DMATERIAL7) );
material.diffuse = m_diffuse;
material.ambient = m_ambient;
m_engine->SetMaterial(material);
m_engine->SetTexture("", 0);
device = m_engine->GetD3DDevice();
device->SetRenderState(D3DRENDERSTATE_LIGHTING, false);
device->SetRenderState(D3DRENDERSTATE_ZENABLE, false);
device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false);
m_engine->SetState(D3DSTATENORMAL);
deep = m_engine->GetDeepView(0);
m_engine->SetDeepView(deep*2.0f, 0);
m_engine->SetFocus(m_engine->GetFocus());
m_engine->UpdateMatProj(); // twice the depth of view
matrix.LoadIdentity();
{
D3DMATRIX mat = MAT_TO_D3DMAT(matrix);
device->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat);
}
p.x = eye.x;
p.z = eye.z;
dist = Math::DistanceProjected(eye, lookat);
p.x = (lookat.x-eye.x)*deep*1.0f/dist + eye.x;
p.z = (lookat.z-eye.z)*deep*1.0f/dist + eye.z;
p1.x = (lookat.z-eye.z)*deep*2.0f/dist + p.x;
p1.z = -(lookat.x-eye.x)*deep*2.0f/dist + p.z;
p2.x = -(lookat.z-eye.z)*deep*2.0f/dist + p.x;
p2.z = (lookat.x-eye.x)*deep*2.0f/dist + p.z;
p1.y = -50.0f;
p2.y = m_level;
n.x = (lookat.x-eye.x)/dist;
n.z = (lookat.z-eye.z)/dist;
n.y = 0.0f;
uv1.x = uv1.y = 0.0f;
uv2.x = uv2.y = 0.0f;
vertex[0] = D3DVERTEX2(Math::Vector(p1.x, p2.y, p1.z), n, uv1.x,uv2.y);
vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p1.y, p1.z), n, uv1.x,uv1.y);
vertex[2] = D3DVERTEX2(Math::Vector(p2.x, p2.y, p2.z), n, uv2.x,uv2.y);
vertex[3] = D3DVERTEX2(Math::Vector(p2.x, p1.y, p2.z), n, uv2.x,uv1.y);
device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL);
m_engine->AddStatisticTriangle(2);
m_engine->SetDeepView(deep, 0);
m_engine->SetFocus(m_engine->GetFocus());
m_engine->UpdateMatProj(); // gives the initial depth of view
device->SetRenderState(D3DRENDERSTATE_LIGHTING, true);
device->SetRenderState(D3DRENDERSTATE_ZENABLE, true);
device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false);*/
}
void Gfx::CWater::DrawSurf()
{
/* TODO!
LPDIRECT3DDEVICE7 device;
D3DVERTEX2* vertex; // triangles
D3DMATERIAL7 material;
Math::Matrix matrix;
Math::Vector eye, lookat, n, pos, p;
Math::Point uv1, uv2;
bool bUnder;
DWORD flags;
float deep, size, sizez, radius;
int rankview, i, j, u;
if (! m_draw) return;
if (m_type[0] == Gfx::WATER_NULL) return;
if (m_line.empty()) return;
vertex = (D3DVERTEX2*)malloc(sizeof(D3DVERTEX2)*(m_brick+2)*2);
eye = m_engine->GetEyePt();
lookat = m_engine->GetLookatPt();
rankview = m_engine->GetRankView();
bUnder = ( rankview == 1);
device = m_engine->GetD3DDevice();
device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false);
matrix.LoadIdentity();
{
D3DMATRIX mat = MAT_TO_D3DMAT(matrix);
device->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat);
}
ZeroMemory( &material, sizeof(D3DMATERIAL7) );
material.diffuse = m_diffuse;
material.ambient = m_ambient;
m_engine->SetMaterial(material);
m_engine->SetTexture(m_filename, 0);
m_engine->SetTexture(m_filename, 1);
if ( m_type[rankview] == WATER_TT )
{
m_engine->SetState(D3DSTATETTb|D3DSTATEDUALw|D3DSTATEWRAP, m_color);
}
if ( m_type[rankview] == WATER_TO )
{
m_engine->SetState(D3DSTATENORMAL|D3DSTATEDUALw|D3DSTATEWRAP);
}
if ( m_type[rankview] == WATER_CT )
{
m_engine->SetState(D3DSTATETTb);
}
if ( m_type[rankview] == WATER_CO )
{
m_engine->SetState(D3DSTATENORMAL);
}
device->SetRenderState(D3DRENDERSTATE_FOGENABLE, true);
size = m_size/2.0f;
if ( bUnder ) sizez = -size;
else sizez = size;
// Draws all the lines.
deep = m_engine->GetDeepView(0)*1.5f;
for ( i=0 ; i<m_lineUsed ; i++ )
{
pos.y = m_level;
pos.z = m_line[i].pz;
pos.x = m_line[i].px1;
// Visible line?
p = pos;
p.x += size*(m_line[i].len-1);
radius = sqrtf(powf(size, 2.0f)+powf(size*m_line[i].len, 2.0f));
if ( Math::Distance(p, eye) > deep+radius ) continue;
D3DVECTOR pD3D = VEC_TO_D3DVEC(p);
device->ComputeSphereVisibility(&pD3D, &radius, 1, 0, &flags);
if ( flags & D3DSTATUS_CLIPINTERSECTIONALL ) continue;
u = 0;
p.x = pos.x-size;
p.z = pos.z-sizez;
p.y = pos.y;
AdjustLevel(p, n, uv1, uv2);
if ( bUnder ) n.y = -n.y;
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y);
p.x = pos.x-size;
p.z = pos.z+sizez;
p.y = pos.y;
AdjustLevel(p, n, uv1, uv2);
if ( bUnder ) n.y = -n.y;
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y);
for ( j=0 ; j<m_line[i].len ; j++ )
{
p.x = pos.x+size;
p.z = pos.z-sizez;
p.y = pos.y;
AdjustLevel(p, n, uv1, uv2);
if ( bUnder ) n.y = -n.y;
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y);
p.x = pos.x+size;
p.z = pos.z+sizez;
p.y = pos.y;
AdjustLevel(p, n, uv1, uv2);
if ( bUnder ) n.y = -n.y;
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y);
pos.x += size*2.0f;
}
device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, u, NULL);
m_engine->AddStatisticTriangle(u-2);
}
free(vertex);*/
}
bool Gfx::CWater::GetWater(int x, int y)
{
x *= m_subdiv;
y *= m_subdiv;
float size = m_size/m_subdiv;
float offset = m_brick*m_size/2.0f;
for (int dy = 0; dy <= m_subdiv; dy++)
{
for (int dx = 0; dx <= m_subdiv; dx++)
{
Math::Vector pos;
pos.x = (x+dx)*size - offset;
pos.z = (y+dy)*size - offset;
pos.y = 0.0f;
float level = m_terrain->GetFloorLevel(pos, true);
if (level < m_level+m_eddy.y)
return true;
}
}
return false;
}
void Gfx::CWater::CreateLine(int x, int y, int len)
{
Gfx::WaterLine line;
line.x = x;
line.y = y;
line.len = len;
float offset = m_brick*m_size/2.0f - m_size/2.0f;
line.px1 = m_size* line.x - offset;
line.px2 = m_size*(line.x+line.len) - offset;
line.pz = m_size* line.y - offset;
m_line.push_back(line);
}
void Gfx::CWater::Create(Gfx::WaterType type1, Gfx::WaterType type2, const std::string& fileName,
Gfx::Color diffuse, Gfx::Color ambient,
float level, float glint, Math::Vector eddy)
{
m_type[0] = type1;
m_type[1] = type2;
m_diffuse = diffuse;
m_ambient = ambient;
m_level = level;
m_glint = glint;
m_eddy = eddy;
m_time = 0.0f;
m_lastLava = 0.0f;
m_fileName = fileName;
VaporFlush();
if (! m_fileName.empty())
m_engine->LoadTexture(m_fileName);
if (m_terrain == nullptr)
m_terrain = static_cast<CTerrain*>(m_iMan->SearchInstance(CLASS_TERRAIN));
m_brick = m_terrain->GetBrick()*m_terrain->GetMosaic();
m_size = m_terrain->GetSize();
m_brick /= m_subdiv;
m_size *= m_subdiv;
if (m_type[0] == WATER_NULL)
return;
m_line.clear();
for (int y = 0; y < m_brick; y++)
{
int len = 0;
for (int x = 0; x < m_brick; x++)
{
if (GetWater(x,y)) // water here?
{
len ++;
if (len >= 5)
{
CreateLine(x-len+1, y, len);
len = 0;
}
}
else // dry?
{
if (len != 0)
{
CreateLine(x-len, y, len);
len = 0;
}
}
}
if (len != 0)
CreateLine(m_brick - len, y, len);
}
}
void Gfx::CWater::Flush()
{
m_type[0] = Gfx::WATER_NULL;
m_type[1] = Gfx::WATER_NULL;
m_level = 0.0f;
m_lava = false;
}
void Gfx::CWater::SetLevel(float level)
{
m_level = level;
Create(m_type[0], m_type[1], m_fileName, m_diffuse, m_ambient,
m_level, m_glint, m_eddy);
}
float Gfx::CWater::GetLevel()
{
return m_level;
}
float Gfx::CWater::GetLevel(CObject* object)
{
/* TODO!
ObjectType type = object->GetType();
if ( type == OBJECT_HUMAN ||
type == OBJECT_TECH )
{
return m_level-3.0f;
}
if ( type == OBJECT_MOBILEfa ||
type == OBJECT_MOBILEta ||
type == OBJECT_MOBILEwa ||
type == OBJECT_MOBILEia ||
type == OBJECT_MOBILEfc ||
type == OBJECT_MOBILEtc ||
type == OBJECT_MOBILEwc ||
type == OBJECT_MOBILEic ||
type == OBJECT_MOBILEfi ||
type == OBJECT_MOBILEti ||
type == OBJECT_MOBILEwi ||
type == OBJECT_MOBILEii ||
type == OBJECT_MOBILEfs ||
type == OBJECT_MOBILEts ||
type == OBJECT_MOBILEws ||
type == OBJECT_MOBILEis ||
type == OBJECT_MOBILErt ||
type == OBJECT_MOBILErc ||
type == OBJECT_MOBILErr ||
type == OBJECT_MOBILErs ||
type == OBJECT_MOBILEsa ||
type == OBJECT_MOBILEtg ||
type == OBJECT_MOBILEft ||
type == OBJECT_MOBILEtt ||
type == OBJECT_MOBILEwt ||
type == OBJECT_MOBILEit ||
type == OBJECT_MOBILEdr )
{
return m_level-2.0f;
}
*/
return m_level;
}
void Gfx::CWater::SetLava(bool lava)
{
m_lava = lava;
}
bool Gfx::CWater::GetLava()
{
return m_lava;
}
void Gfx::CWater::AdjustEye(Math::Vector &eye)
{
if (m_lava)
{
if (eye.y < m_level+2.0f)
eye.y = m_level+2.0f; // never under the lava
}
else
{
if (eye.y >= m_level-2.0f &&
eye.y <= m_level+2.0f) // close to the surface?
eye.y = m_level+2.0f; // bam, well above
}
}
// TODO implementation

View File

@ -15,54 +15,71 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// water.h
/**
* \file graphics/engine/water.h
* \brief Water rendering - Gfx::CWater class
*/
#pragma once
#include "graphics/engine/engine.h"
#include "graphics/engine/particle.h"
#include "common/event.h"
#include "graphics/engine/particle.h"
class CInstanceManager;
class CSound;
class CSoundInterface;
namespace Gfx {
class CEngine;
class CTerrain;
const short MAXWATERLINE = 500;
struct WaterLine
{
short x, y; // beginning
short len; // length by x
//! Beginning
short x, y;
//! Length by x
short len;
float px1, px2, pz;
WaterLine()
{
x = y = 0;
len = 0;
px1 = px2 = pz = 0.0f;
}
};
const short MAXWATVAPOR = 10;
struct WaterVapor
{
bool bUsed;
ParticleType type;
Math::Vector pos;
float delay;
float time;
float last;
};
bool used;
Gfx::ParticleType type;
Math::Vector pos;
float delay;
float time;
float last;
WaterVapor()
{
used = false;
type = Gfx::PARTIWATER;
delay = time = last = 0.0f;
}
};
enum WaterType
{
WATER_NULL = 0, // no water
WATER_TT = 1, // transparent texture
WATER_TO = 2, // opaque texture
WATER_CT = 3, // transparent color
WATER_CO = 4, // opaque color
//! No water
WATER_NULL = 0,
//! Transparent texture
WATER_TT = 1,
//! Opaque texture
WATER_TO = 2,
//! Transparent color
WATER_CT = 3,
//! Opaque color
WATER_CO = 4,
};
@ -72,63 +89,88 @@ public:
CWater(CInstanceManager* iMan, Gfx::CEngine* engine);
~CWater();
void SetGLDevice(Gfx::CDevice device);
void SetDevice(Gfx::CDevice* device);
bool EventProcess(const Event &event);
//! Removes all the water
void Flush();
bool Create(WaterType type1, WaterType type2, const char *filename, Gfx::Color diffuse, Gfx::Color ambient, float level, float glint, Math::Vector eddy);
//! Creates all expanses of water
void Create(WaterType type1, WaterType type2, const std::string& fileName,
Gfx::Color diffuse, Gfx::Color ambient, float level, float glint, Math::Vector eddy);
//! Draw the back surface of the water
void DrawBack();
//! Draws the flat surface of the water
void DrawSurf();
bool SetLevel(float level);
float RetLevel();
float RetLevel(CObject* object);
//! Changes the level of the water
void SetLevel(float level);
//! Returns the current level of water
float GetLevel();
//! Returns the current level of water for a given object
float GetLevel(CObject* object);
void SetLava(bool bLava);
bool RetLava();
//@{
//! Management of the mode of lava/water
void SetLava(bool lava);
bool GetLava();
//@}
//! Adjusts the eye of the camera, not to be in the water
void AdjustEye(Math::Vector &eye);
protected:
//! Makes water evolve
bool EventFrame(const Event &event);
//! Makes evolve the steam jets on the lava
void LavaFrame(float rTime);
//! Adjusts the position to normal, to imitate reflections on an expanse of water at rest
void AdjustLevel(Math::Vector &pos, Math::Vector &norm, Math::Point &uv1, Math::Point &uv2);
bool RetWater(int x, int y);
bool CreateLine(int x, int y, int len);
//! Indicates if there is water in a given position
bool GetWater(int x, int y);
//! Updates the positions, relative to the ground
void CreateLine(int x, int y, int len);
//! Removes all the steam jets
void VaporFlush();
//! Creates a new steam
bool VaporCreate(ParticleType type, Math::Vector pos, float delay);
//! Makes evolve a steam jet
void VaporFrame(int i, float rTime);
protected:
CInstanceManager* m_iMan;
CEngine* m_engine;
CDevice* m_pDevice;
CTerrain* m_terrain;
CParticle* m_particule;
CSound* m_sound;
CInstanceManager* m_iMan;
Gfx::CEngine* m_engine;
Gfx::CDevice* m_device;
Gfx::CTerrain* m_terrain;
Gfx::CParticle* m_particule;
CSoundInterface* m_sound;
WaterType m_type[2];
char m_filename[100];
float m_level; // overall level
float m_glint; // amplitude of reflections
Math::Vector m_eddy; // amplitude of swirls
Gfx::Color m_diffuse; // diffuse color
Gfx::Color m_ambient; // ambient color
std::string m_fileName;
//! Overall level
float m_level;
//! Amplitude of reflections
float m_glint;
//! Amplitude of swirls
Math::Vector m_eddy;
//! Diffuse color
Gfx::Color m_diffuse;
//! Ambient color
Gfx::Color m_ambient;
float m_time;
float m_lastLava;
int m_subdiv;
int m_subdiv;
int m_brick; // number of brick*mosaics
float m_size; // size of a item in an brick
//! Number of brick*mosaics
int m_brick;
//! Size of a item in an brick
float m_size;
int m_lineUsed;
WaterLine m_line[MAXWATERLINE];
std::vector<WaterLine> m_line;
std::vector<WaterVapor> m_vapor;
WaterVapor m_vapor[MAXWATVAPOR];
bool m_bDraw;
bool m_bLava;
long m_color;
bool m_draw;
bool m_lava;
long m_color;
};
}; // namespace Gfx

View File

@ -1,6 +1,7 @@
src/graphics/opengl
OpenGL engine implementation
Contains the concrete implementation using OpenGL of abstract CDevice class
from src/graphics/core
/**
* \dir graphics/opengl
* \brief OpenGL engine implementation
*
* Contains the concrete implementation using OpenGL of abstract CDevice class
* from src/graphics/core
*/

View File

@ -64,7 +64,6 @@ void Gfx::GLDeviceConfig::LoadDefault()
Gfx::CGLDevice::CGLDevice(const Gfx::GLDeviceConfig &config)
{
m_config = config;
m_wasInit = false;
m_lighting = false;
m_texturing = false;
}
@ -74,9 +73,11 @@ Gfx::CGLDevice::~CGLDevice()
{
}
bool Gfx::CGLDevice::GetWasInit()
void Gfx::CGLDevice::DebugHook()
{
return m_wasInit;
/* This function is only called here, so it can be used
* as a breakpoint when debugging using gDEBugger */
glColor3i(0, 0, 0);
}
std::string Gfx::CGLDevice::GetError()
@ -110,8 +111,6 @@ bool Gfx::CGLDevice::Create()
/* NOTE: when not using GLEW, extension testing is not performed, as it is assumed that
glext.h is up-to-date and the OpenGL shared library has the required functions present. */
m_wasInit = true;
// This is mostly done in all modern hardware by default
// DirectX doesn't even allow the option to turn off perspective correction anymore
// So turn it on permanently
@ -130,7 +129,7 @@ bool Gfx::CGLDevice::Create()
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, m_config.size.w, m_config.size.h);
glViewport(0, 0, m_config.size.x, m_config.size.y);
m_lights = std::vector<Gfx::Light>(GL_MAX_LIGHTS, Gfx::Light());
@ -158,8 +157,6 @@ void Gfx::CGLDevice::Destroy()
m_currentTextures.clear();
m_texturesEnabled.clear();
m_textureStageParams.clear();
m_wasInit = false;
}
void Gfx::CGLDevice::ConfigChanged(const Gfx::GLDeviceConfig& newConfig)
@ -385,18 +382,23 @@ bool Gfx::CGLDevice::GetLightEnabled(int index)
This struct must not be deleted in other way than through DeleteTexture() */
Gfx::Texture Gfx::CGLDevice::CreateTexture(CImage *image, const Gfx::TextureCreateParams &params)
{
Gfx::Texture result;
ImageData *data = image->GetData();
if (data == NULL)
{
m_error = "Invalid texture data";
return result; // invalid texture
return Gfx::Texture(); // invalid texture
}
return CreateTexture(data, params);
}
Gfx::Texture Gfx::CGLDevice::CreateTexture(ImageData *data, const Gfx::TextureCreateParams &params)
{
Gfx::Texture result;
result.valid = true;
result.size.w = data->surface->w;
result.size.h = data->surface->h;
result.size.x = data->surface->w;
result.size.y = data->surface->h;
// Use & enable 1st texture stage
glActiveTexture(GL_TEXTURE0);
@ -531,6 +533,24 @@ void Gfx::CGLDevice::SetTexture(int index, const Gfx::Texture &texture)
glDisable(GL_TEXTURE_2D);
}
void Gfx::CGLDevice::SetTexture(int index, unsigned int textureId)
{
assert(index >= 0);
assert(index < static_cast<int>( m_currentTextures.size() ));
// Enable the given texture stage
glActiveTexture(GL_TEXTURE0 + index);
glEnable(GL_TEXTURE_2D);
m_currentTextures[index].id = textureId;
glBindTexture(GL_TEXTURE_2D, textureId);
// Disable the stage if it is set so
if ( (! m_texturing) || (! m_texturesEnabled[index]) )
glDisable(GL_TEXTURE_2D);
}
/**
Returns the previously assigned texture or invalid texture if the given stage is not enabled. */
Gfx::Texture Gfx::CGLDevice::GetTexture(int index)
@ -1159,17 +1179,19 @@ void Gfx::CGLDevice::GetFogParams(Gfx::FogMode &mode, Gfx::Color &color, float &
void Gfx::CGLDevice::SetCullMode(Gfx::CullMode mode)
{
if (mode == Gfx::CULL_CW) glCullFace(GL_CW);
else if (mode == Gfx::CULL_CCW) glCullFace(GL_CCW);
// Cull clockwise back faces, so front face is the opposite
// (assuming GL_CULL_FACE is GL_BACK)
if (mode == Gfx::CULL_CW ) glFrontFace(GL_CCW);
else if (mode == Gfx::CULL_CCW) glFrontFace(GL_CW);
else assert(false);
}
Gfx::CullMode Gfx::CGLDevice::GetCullMode()
{
GLint flag = 0;
glGetIntegerv(GL_CULL_FACE, &flag);
if (flag == GL_CW) return Gfx::CULL_CW;
else if (flag == GL_CCW) return Gfx::CULL_CCW;
glGetIntegerv(GL_FRONT_FACE, &flag);
if (flag == GL_CW) return Gfx::CULL_CCW;
else if (flag == GL_CCW) return Gfx::CULL_CW;
else assert(false);
return Gfx::CULL_CW;
}

View File

@ -14,7 +14,10 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// gldevice.h
/**
* \file graphics/opengl/gldevice.h
* \brief OpenGL implementation - Gfx::CGLDevice class
*/
#pragma once
@ -73,7 +76,8 @@ public:
CGLDevice(const Gfx::GLDeviceConfig &config);
virtual ~CGLDevice();
virtual bool GetWasInit();
virtual void DebugHook();
virtual std::string GetError();
virtual bool Create();
@ -100,11 +104,13 @@ public:
virtual bool GetLightEnabled(int index);
virtual Gfx::Texture CreateTexture(CImage *image, const Gfx::TextureCreateParams &params);
virtual Gfx::Texture CreateTexture(ImageData *data, const Gfx::TextureCreateParams &params);
virtual void DestroyTexture(const Gfx::Texture &texture);
virtual void DestroyAllTextures();
virtual int GetMaxTextureCount();
virtual void SetTexture(int index, const Gfx::Texture &texture);
virtual void SetTexture(int index, unsigned int textureId);
virtual Gfx::Texture GetTexture(int index);
virtual void SetTextureEnabled(int index, bool enabled);
virtual bool GetTextureEnabled(int index);
@ -163,8 +169,6 @@ private:
private:
//! Current config
Gfx::GLDeviceConfig m_config;
//! Was initialized?
bool m_wasInit;
//! Last encountered error
std::string m_error;

View File

@ -1,3 +1,12 @@
src/math
/**
* \dir math
* \brief Common mathematical structures and functions
*/
Contains common mathematical structures and functions.
/**
* \namespace Math
* \brief Namespace for (new) math code
*
* This namespace was created to avoid clashing with old code, but now it still serves,
* defining a border between math and non-math-related code.
*/

View File

@ -14,14 +14,13 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
/** @defgroup MathAllModule math/all.h
Includes all other math module headers.
/**
* \file math/all.h
* \brief Includes all other math module headers
*/
#pragma once
/* @{ */ // start of group
#include "const.h"
#include "func.h"
#include "point.h"
@ -30,5 +29,3 @@
#include "geometry.h"
#include "conv.h"
/* @} */ // end of group

View File

@ -14,28 +14,30 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
/** @defgroup MathConstModule math/const.h
Contains the math constants used in math functions.
/**
* \file math/const.h
* \brief Constants used in math functions
*/
#pragma once
#include <cmath>
// Math module namespace
namespace Math
{
/* @{ */ // start of group
//! Tolerance level -- minimum accepted float value
const float TOLERANCE = 1e-6f;
//! Very small number (used in testing/returning some values)
const float VERY_SMALL = 1e-6f;
const float VERY_SMALL_NUM = 1e-6f;
//! Very big number (used in testing/returning some values)
const float VERY_BIG = 1e6f;
const float VERY_BIG_NUM = 1e6f;
//! Huge number
const float HUGE = 1.0e+38f;
const float HUGE_NUM = 1.0e+38f;
//! PI
const float PI = 3.14159265358979323846f;
@ -45,6 +47,8 @@ const float DEG_TO_RAD = 0.01745329251994329547f;
//! Radians to degrees multiplier
const float RAD_TO_DEG = 57.29577951308232286465f;
/* @} */ // end of group
//! Natural logarithm of 2
const float LOG_2 = log(2.0f);
}; // namespace Math

View File

@ -15,8 +15,9 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
/** @defgroup MathFuncModule math/func.h
Contains common math functions.
/**
* \file math/func.h
* \brief Common math functions
*/
#pragma once
@ -31,8 +32,6 @@
namespace Math
{
/* @{ */ // start of group
//! Compares \a a and \a b within \a tolerance
inline bool IsEqual(float a, float b, float tolerance = Math::TOLERANCE)
{
@ -127,6 +126,14 @@ inline float Rand()
return static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
}
//! Returns the next nearest power of two to \a x
inline int NextPowerOfTwo(int x)
{
double logbase2 = log(static_cast<float>(x)) / Math::LOG_2;
return static_cast<int>(pow(2, ceil(logbase2)) + 0.5);
}
//! Returns a normalized angle, that is in other words between 0 and 2 * PI
inline float NormAngle(float angle)
{
@ -180,11 +187,13 @@ inline float Direction(float a, float g)
//! Managing the dead zone of a joystick.
/**
\verbatimin: -1 0 1
\verbatim
in: -1 0 1
--|-------|----o----|-------|-->
<---->
dead
out: -1 0 0 1\endverbatim */
out: -1 0 0 1
\endverbatim */
inline float Neutral(float value, float dead)
{
if ( fabs(value) <= dead )
@ -218,7 +227,8 @@ inline float Smooth(float actual, float hope, float time)
//! Bounces any movement
/**
\verbatimout
\verbatim
out
|
1+------o-------o---
| o | o o | | bounce
@ -227,7 +237,8 @@ inline float Smooth(float actual, float hope, float time)
| o | |
-o------|-------+----> progress
0| | 1
|<---->|middle\endverbatim */
|<---->|middle
\endverbatim */
inline float Bounce(float progress, float middle = 0.3f, float bounce = 0.4f)
{
if ( progress < middle )
@ -242,6 +253,4 @@ inline float Bounce(float progress, float middle = 0.3f, float bounce = 0.4f)
}
}
/* @} */ // end of group
}; // namespace Math

View File

@ -15,9 +15,9 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
/** @defgroup MathGeometryModule math/geometry.h
Contains math functions related to 3D geometry calculations,
transformations, etc.
/**
* \file math/geometry.h
* \brief Math functions related to 3D geometry calculations, transformations, etc.
*/
#pragma once
@ -36,18 +36,15 @@
namespace Math
{
/* @{ */ // start of group
//! Returns py up on the line \a a - \a b
inline float MidPoint(const Math::Point &a, const Math::Point &b, float px)
{
if (IsEqual(a.x, b.x))
{
if (a.y < b.y)
return HUGE;
return Math::HUGE_NUM;
else
return -HUGE;
return -Math::HUGE_NUM;
}
return (b.y-a.y) * (px-a.x) / (b.x-a.x) + a.y;
}
@ -566,6 +563,4 @@ inline Math::Vector RotateView(Math::Vector center, float angleH, float angleV,
return eye+center;
}
/* @} */ // end of group
}; // namespace Math

View File

@ -14,31 +14,29 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
/** @defgroup MathIntPointModule math/intpoint.h
Contains the IntPoint struct.
/**
* \file math/intpoint.h
* \brief IntPoint struct
*/
#pragma once
namespace Math {
/* @{ */ // start of group
/**
* \struct IntPoint 2D Point with integer coords
* \struct IntPoint
* \brief 2D Point with integer coords
*
* Analog of WinAPI's POINT struct.
*/
struct IntPoint
{
//! X coord
long x;
int x;
//! Y coord
long y;
int y;
IntPoint(long aX = 0, long aY = 0) : x(aX), y(aY) {}
IntPoint(int aX = 0, int aY = 0) : x(aX), y(aY) {}
};
/* @} */ // end of group
}; // namespace Math

View File

@ -1,61 +0,0 @@
// * This file is part of the COLOBOT source code
// * Copyright (C) 2012, Polish Portal of Colobot (PPC)
// *
// * This program is free software: you can redistribute it and/or modify
// * it under the terms of the GNU General Public License as published by
// * the Free Software Foundation, either version 3 of the License, or
// * (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
/** @defgroup MathIntSizeModule math/intsize.h
Contains the IntSize struct.
*/
#pragma once
// Math module namespace
namespace Math
{
/* @{ */ // start of group
/** \struct IntSize math/size.h
\brief 2D size with integer dimensions */
struct IntSize
{
//! Width
int w;
//! Height
int h;
//! Constructs a zero size: (0,0)
inline IntSize()
{
LoadZero();
}
//! Constructs a size from given dimensions: (w,h)
inline explicit IntSize(int w, int h)
{
this->w = w;
this->h = h;
}
//! Sets the zero size: (0,0)
inline void LoadZero()
{
w = h = 0;
}
}; // struct Size
/* @} */ // end of group
}; // namespace Math

View File

@ -14,8 +14,9 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
/** @defgroup MathMatrixModule math/matrix.h
Contains the Matrix struct and related functions.
/**
* \file math/matrix.h
* \brief Matrix struct and related functions
*/
#pragma once
@ -32,8 +33,6 @@
namespace Math
{
/* @{ */ // start of group
/** \struct Matrix math/matrix.h
\brief 4x4 matrix
@ -42,11 +41,12 @@ namespace Math
The internal representation is a 16-value table in column-major order, thus:
\verbatim
\verbatim
m[0 ] m[4 ] m[8 ] m[12]
m[1 ] m[5 ] m[9 ] m[13]
m[2 ] m[6 ] m[10] m[14]
m[3 ] m[7 ] m[11] m[15] \endverbatim
m[3 ] m[7 ] m[11] m[15]
\endverbatim
This representation is native to OpenGL; DirectX requires transposing the matrix.
@ -405,11 +405,15 @@ inline Math::Matrix MultiplyMatrices(const Math::Matrix &left, const Math::Matri
}
//! Calculates the result of multiplying m * v
/** The multiplication is performed thus:
\verbatim [ m.m[0 ] m.m[4 ] m.m[8 ] m.m[12] ] [ v.x ]
/**
The multiplication is performed thus:
\verbatim
[ m.m[0 ] m.m[4 ] m.m[8 ] m.m[12] ] [ v.x ]
[ m.m[1 ] m.m[5 ] m.m[9 ] m.m[13] ] [ v.y ]
[ m.m[2 ] m.m[6 ] m.m[10] m.m[14] ] * [ v.z ]
[ m.m[3 ] m.m[7 ] m.m[11] m.m[15] ] [ 1 ] \endverbatim
[ m.m[3 ] m.m[7 ] m.m[11] m.m[15] ] [ 1 ]
\endverbatim
The result, a 4x1 vector is then converted to 3x1 by dividing
x,y,z coords by the fourth coord (w). */
@ -434,6 +438,4 @@ inline Math::Vector MatrixVectorMultiply(const Math::Matrix &m, const Math::Vect
return Math::Vector(x, y, z);
}
/* @} */ // end of group
}; // namespace Math

View File

@ -14,8 +14,9 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
/** @defgroup MathPointModule math/point.h
Contains the Point struct and related functions.
/**
* \file math/point.h
* \brief Point struct and related functions
*/
#pragma once
@ -31,8 +32,6 @@
namespace Math
{
/* @{ */ // start of group
/** \struct Point math/point.h
\brief 2D point
@ -188,6 +187,4 @@ inline float Distance(const Point &a, const Point &b)
return sqrtf((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
/* @} */ // end of group
}; // namespace Math

View File

@ -1,66 +0,0 @@
// * This file is part of the COLOBOT source code
// * Copyright (C) 2012, Polish Portal of Colobot (PPC)
// *
// * This program is free software: you can redistribute it and/or modify
// * it under the terms of the GNU General Public License as published by
// * the Free Software Foundation, either version 3 of the License, or
// * (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
/** @defgroup MathSizeModule math/size.h
Contains the Size struct.
*/
#pragma once
// Math module namespace
namespace Math
{
/* @{ */ // start of group
/** \struct Size math/size.h
\brief 2D size
Represents a 2D size (w, h).
Is separate from Math::Point to avoid confusion.
*/
struct Size
{
//! Width
float w;
//! Height
float h;
//! Constructs a zero size: (0,0)
inline Size()
{
LoadZero();
}
//! Constructs a size from given dimensions: (w,h)
inline explicit Size(float w, float h)
{
this->w = w;
this->h = h;
}
//! Sets the zero size: (0,0)
inline void LoadZero()
{
w = h = 0.0f;
}
}; // struct Size
/* @} */ // end of group
}; // namespace Math

View File

@ -14,8 +14,9 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
/** @defgroup MathVectorModule math/vector.h
Contains the Vector struct and related functions.
/**
* \file math/vector.h
* \brief Vector struct and related functions
*/
#pragma once
@ -31,8 +32,6 @@
namespace Math
{
/* @{ */ // start of group
/** \struct Vector math/vector.h
\brief 3D (3x1) vector
@ -263,6 +262,4 @@ inline float Distance(const Math::Vector &a, const Math::Vector &b)
(a.z-b.z)*(a.z-b.z) );
}
/* @} */ // end of group
}; // namespace Math

View File

@ -1,3 +1,7 @@
src/object
Contains modules of robots and buildings.
/**
* \dir object
* \brief Game engine
*
* Contains the main class of game engine - CRobotMain and the various in-game objects:
* CObject and related auto, motion and task subclasses.
*/

View File

@ -19,16 +19,12 @@
#pragma once
#include "old/d3dengine.h"
#include "old/camera.h"
#include "old/sound.h"
#include "graphics/engine/engine.h"
#include "graphics/engine/camera.h"
#include "sound/sound.h"
class CInstanceManager;
class CLight;
class CTerrain;
class CWater;
class CParticule;
class CPhysics;
class CBrain;
class CMotion;
@ -40,6 +36,7 @@ class CScript;
// The father of all parts must always be the part number zero!
const int OBJECTMAXPART = 40;
@ -306,7 +303,7 @@ enum ObjectMaterial
struct ObjectPart
{
char bUsed;
int object; // number of the object in CD3DEngine
int object; // number of the object in CEngine
int parentPart; // number of father part
int masterParti; // master canal of the particle
Math::Vector position;
@ -377,16 +374,16 @@ public:
int CreatePart();
void DeletePart(int part);
void SetObjectRank(int part, int objRank);
int RetObjectRank(int part);
int GetObjectRank(int part);
void SetObjectParent(int part, int parent);
void SetType(ObjectType type);
ObjectType RetType();
char* RetName();
ObjectType GetType();
char* GetName();
void SetOption(int option);
int RetOption();
int GetOption();
void SetID(int id);
int RetID();
int GetID();
bool Write(char *line);
bool Read(char *line);
@ -413,203 +410,205 @@ public:
bool WriteProgram(int rank, char* filename);
bool RunProgram(int rank);
int RetShadowLight();
int RetEffectLight();
int GetShadowLight();
int GetEffectLight();
void FlushCrashShere();
int CreateCrashSphere(Math::Vector pos, float radius, Sound sound, float hardness=0.45f);
int RetCrashSphereTotal();
int GetCrashSphereTotal();
bool GetCrashSphere(int rank, Math::Vector &pos, float &radius);
float RetCrashSphereHardness(int rank);
Sound RetCrashSphereSound(int rank);
float GetCrashSphereHardness(int rank);
Sound GetCrashSphereSound(int rank);
void DeleteCrashSphere(int rank);
void SetGlobalSphere(Math::Vector pos, float radius);
void GetGlobalSphere(Math::Vector &pos, float &radius);
void SetJotlerSphere(Math::Vector pos, float radius);
void GetJotlerSphere(Math::Vector &pos, float &radius);
void SetShieldRadius(float radius);
float RetShieldRadius();
float GetShieldRadius();
void SetFloorHeight(float height);
void FloorAdjust();
void SetLinVibration(Math::Vector dir);
Math::Vector RetLinVibration();
Math::Vector GetLinVibration();
void SetCirVibration(Math::Vector dir);
Math::Vector RetCirVibration();
Math::Vector GetCirVibration();
void SetInclinaison(Math::Vector dir);
Math::Vector RetInclinaison();
Math::Vector GetInclinaison();
void SetPosition(int part, const Math::Vector &pos);
Math::Vector RetPosition(int part);
Math::Vector GetPosition(int part);
void SetAngle(int part, const Math::Vector &angle);
Math::Vector RetAngle(int part);
Math::Vector GetAngle(int part);
void SetAngleY(int part, float angle);
void SetAngleX(int part, float angle);
void SetAngleZ(int part, float angle);
float RetAngleY(int part);
float RetAngleX(int part);
float RetAngleZ(int part);
float GetAngleY(int part);
float GetAngleX(int part);
float GetAngleZ(int part);
void SetZoom(int part, float zoom);
void SetZoom(int part, Math::Vector zoom);
Math::Vector RetZoom(int part);
Math::Vector GetZoom(int part);
void SetZoomX(int part, float zoom);
float RetZoomX(int part);
float GetZoomX(int part);
void SetZoomY(int part, float zoom);
float RetZoomY(int part);
float GetZoomY(int part);
void SetZoomZ(int part, float zoom);
float RetZoomZ(int part);
float GetZoomZ(int part);
float RetWaterLevel();
float GetWaterLevel();
void SetTrainer(bool bEnable);
bool RetTrainer();
bool GetTrainer();
void SetToy(bool bEnable);
bool RetToy();
bool GetToy();
void SetManual(bool bManual);
bool RetManual();
bool GetManual();
void SetResetCap(ResetCap cap);
ResetCap RetResetCap();
ResetCap GetResetCap();
void SetResetBusy(bool bBusy);
bool RetResetBusy();
bool GetResetBusy();
void SetResetPosition(const Math::Vector &pos);
Math::Vector RetResetPosition();
Math::Vector GetResetPosition();
void SetResetAngle(const Math::Vector &angle);
Math::Vector RetResetAngle();
Math::Vector GetResetAngle();
void SetResetRun(int run);
int RetResetRun();
int GetResetRun();
void SetMasterParticule(int part, int parti);
int RetMasterParticule(int part);
int GetMasterParticule(int part);
void SetPower(CObject* power);
CObject* RetPower();
CObject* GetPower();
void SetFret(CObject* fret);
CObject* RetFret();
CObject* GetFret();
void SetTruck(CObject* truck);
CObject* RetTruck();
CObject* GetTruck();
void SetTruckPart(int part);
int RetTruckPart();
int GetTruckPart();
void InfoFlush();
void DeleteInfo(int rank);
void SetInfo(int rank, Info info);
Info RetInfo(int rank);
int RetInfoTotal();
void SetInfoReturn(float value);
float RetInfoReturn();
Info GetInfo(int rank);
int GetInfoTotal();
void SetInfoGeturn(float value);
float GetInfoGeturn();
void SetInfoUpdate(bool bUpdate);
bool RetInfoUpdate();
bool GetInfoUpdate();
bool SetCmdLine(int rank, float value);
float RetCmdLine(int rank);
float GetCmdLine(int rank);
Math::Matrix* RetRotateMatrix(int part);
Math::Matrix* RetTranslateMatrix(int part);
Math::Matrix* RetTransformMatrix(int part);
Math::Matrix* RetWorldMatrix(int part);
Math::Matrix* GetRotateMatrix(int part);
Math::Matrix* GetTranslateMatrix(int part);
Math::Matrix* GetTransformMatrix(int part);
Math::Matrix* GetWorldMatrix(int part);
void SetViewFromHere(Math::Vector &eye, float &dirH, float &dirV, Math::Vector &lookat, Math::Vector &upVec, CameraType type);
void SetViewFromHere(Math::Vector &eye, float &dirH, float &dirV,
Math::Vector &lookat, Math::Vector &upVec,
Gfx::CameraType type);
void SetCharacter(Character* character);
void GetCharacter(Character* character);
Character* RetCharacter();
Character* GetCharacter();
float RetAbsTime();
float GetAbsTime();
void SetEnergy(float level);
float RetEnergy();
float GetEnergy();
void SetCapacity(float capacity);
float RetCapacity();
float GetCapacity();
void SetShield(float level);
float RetShield();
float GetShield();
void SetRange(float delay);
float RetRange();
float GetRange();
void SetTransparency(float value);
float RetTransparency();
float GetTransparency();
ObjectMaterial RetMaterial();
ObjectMaterial GetMaterial();
void SetGadget(bool bMode);
bool RetGadget();
bool GetGadget();
void SetFixed(bool bFixed);
bool RetFixed();
bool GetFixed();
void SetClip(bool bClip);
bool RetClip();
bool GetClip();
bool JostleObject(float force);
void StartDetectEffect(CObject *target, bool bFound);
void SetVirusMode(bool bEnable);
bool RetVirusMode();
float RetVirusTime();
bool GetVirusMode();
float GetVirusTime();
void SetCameraType(CameraType type);
CameraType RetCameraType();
void SetCameraType(Gfx::CameraType type);
Gfx::CameraType GetCameraType();
void SetCameraDist(float dist);
float RetCameraDist();
float GetCameraDist();
void SetCameraLock(bool bLock);
bool RetCameraLock();
bool GetCameraLock();
void SetHilite(bool bMode);
bool RetHilite();
bool GetHilite();
void SetSelect(bool bMode, bool bDisplayError=true);
bool RetSelect(bool bReal=false);
bool GetSelect(bool bReal=false);
void SetSelectable(bool bMode);
bool RetSelectable();
bool GetSelectable();
void SetActivity(bool bMode);
bool RetActivity();
bool GetActivity();
void SetVisible(bool bVisible);
bool RetVisible();
bool GetVisible();
void SetEnable(bool bEnable);
bool RetEnable();
bool GetEnable();
void SetCheckToken(bool bMode);
bool RetCheckToken();
bool GetCheckToken();
void SetProxyActivate(bool bActivate);
bool RetProxyActivate();
bool GetProxyActivate();
void SetProxyDistance(float distance);
float RetProxyDistance();
float GetProxyDistance();
void SetMagnifyDamage(float factor);
float RetMagnifyDamage();
float GetMagnifyDamage();
void SetParam(float value);
float RetParam();
float GetParam();
void SetExplo(bool bExplo);
bool RetExplo();
bool GetExplo();
void SetLock(bool bLock);
bool RetLock();
bool GetLock();
void SetCargo(bool bCargo);
bool RetCargo();
bool GetCargo();
void SetBurn(bool bBurn);
bool RetBurn();
bool GetBurn();
void SetDead(bool bDead);
bool RetDead();
bool RetRuin();
bool RetActif();
bool GetDead();
bool GetRuin();
bool GetActif();
void SetGunGoalV(float gunGoal);
void SetGunGoalH(float gunGoal);
float RetGunGoalV();
float RetGunGoalH();
float GetGunGoalV();
float GetGunGoalH();
bool StartShowLimit();
void StopShowLimit();
@ -618,16 +617,16 @@ public:
void CreateSelectParticule();
void SetRunScript(CScript* script);
CScript* RetRunScript();
CBotVar* RetBotVar();
CPhysics* RetPhysics();
CBrain* RetBrain();
CMotion* RetMotion();
CAuto* RetAuto();
CScript* GetRunScript();
CBotVar* GetBotVar();
CPhysics* GetPhysics();
CBrain* GetBrain();
CMotion* GetMotion();
CAuto* GetAuto();
void SetAuto(CAuto* automat);
void SetDefRank(int rank);
int RetDefRank();
int GetDefRank();
bool GetTooltipName(char* name);
@ -635,17 +634,17 @@ public:
CObject* SubDeselList();
void DeleteDeselList(CObject* pObj);
bool CreateShadowCircle(float radius, float intensity, D3DShadowType type=D3DSHADOWNORM);
bool CreateShadowLight(float height, D3DCOLORVALUE color);
bool CreateEffectLight(float height, D3DCOLORVALUE color);
bool CreateShadowCircle(float radius, float intensity, Gfx::EngineShadowType type = Gfx::ENG_SHADOW_NORM);
bool CreateShadowLight(float height, Gfx::Color color);
bool CreateEffectLight(float height, Gfx::Color color);
void FlatParent();
bool RetTraceDown();
bool GetTraceDown();
void SetTraceDown(bool bDown);
int RetTraceColor();
int GetTraceColor();
void SetTraceColor(int color);
float RetTraceWidth();
float GetTraceWidth();
void SetTraceWidth(float width);
protected:
@ -663,19 +662,19 @@ protected:
protected:
CInstanceManager* m_iMan;
CD3DEngine* m_engine;
CLight* m_light;
CTerrain* m_terrain;
CWater* m_water;
CCamera* m_camera;
CParticule* m_particule;
Gfx::CEngine* m_engine;
Gfx::CLightManager* m_lightMan;
Gfx::CTerrain* m_terrain;
Gfx::CWater* m_water;
Gfx::CCamera* m_camera;
Gfx::CParticle* m_particle;
CPhysics* m_physics;
CBrain* m_brain;
CMotion* m_motion;
CAuto* m_auto;
CDisplayText* m_displayText;
CRobotMain* m_main;
CSound* m_sound;
CSoundInterface* m_sound;
CBotVar* m_botVar;
CScript* m_runScript;
@ -732,7 +731,7 @@ protected:
float m_showLimitRadius;
float m_gunGoalV;
float m_gunGoalH;
CameraType m_cameraType;
Gfx::CameraType m_cameraType;
float m_cameraDist;
bool m_bCameraLock;
int m_defRank;
@ -767,7 +766,7 @@ protected:
int m_infoTotal;
Info m_info[OBJECTMAXINFO];
float m_infoReturn;
float m_infoGeturn;
bool m_bInfoUpdate;
float m_cmdLine[OBJECTMAXCMDLINE];

View File

@ -722,7 +722,7 @@ CRobotMain::CRobotMain(CInstanceManager* iMan)
g_unit = 4.0f;
m_gamerName[0] = 0;
GetLocalProfileString("Gamer", "LastName", m_gamerName, 100);
GetProfile()->GetLocalProfileString("Gamer", "LastName", m_gamerName, 100);
SetGlobalGamerName(m_gamerName);
ReadFreeParam();
m_dialog->SetupRecall();

View File

@ -1,3 +1,4 @@
src/physics
Contains the physics module.
/**
* \dir physics
* \brief Physics engine
*/

View File

@ -19,23 +19,27 @@
#pragma once
#include "old/d3dengine.h"
#include "common/misc.h"
#include "object/object.h"
#include "math/vector.h"
class CInstanceManager;
class CD3DEngine;
class CLight;
class CParticule;
class CTerrain;
class CWater;
class CCamera;
class CObject;
class CBrain;
class CMotion;
class CSound;
namespace Gfx
{
class CEngine;
class CLight;
class CParticule;
class CTerrain;
class CWater;
};
enum PhysicsType
{
@ -98,64 +102,64 @@ public:
void SetMotion(CMotion* motion);
void SetType(PhysicsType type);
PhysicsType RetType();
PhysicsType GetType();
bool Write(char *line);
bool Read(char *line);
void SetGravity(float value);
float RetGravity();
float GetGravity();
float RetFloorHeight();
float GetFloorHeight();
void SetLinMotion(PhysicsMode mode, Math::Vector value);
Math::Vector RetLinMotion(PhysicsMode mode);
Math::Vector GetLinMotion(PhysicsMode mode);
void SetLinMotionX(PhysicsMode mode, float value);
void SetLinMotionY(PhysicsMode mode, float value);
void SetLinMotionZ(PhysicsMode mode, float value);
float RetLinMotionX(PhysicsMode mode);
float RetLinMotionY(PhysicsMode mode);
float RetLinMotionZ(PhysicsMode mode);
float GetLinMotionX(PhysicsMode mode);
float GetLinMotionY(PhysicsMode mode);
float GetLinMotionZ(PhysicsMode mode);
void SetCirMotion(PhysicsMode mode, Math::Vector value);
Math::Vector RetCirMotion(PhysicsMode mode);
Math::Vector GetCirMotion(PhysicsMode mode);
void SetCirMotionX(PhysicsMode mode, float value);
void SetCirMotionY(PhysicsMode mode, float value);
void SetCirMotionZ(PhysicsMode mode, float value);
float RetCirMotionX(PhysicsMode mode);
float RetCirMotionY(PhysicsMode mode);
float RetCirMotionZ(PhysicsMode mode);
float GetCirMotionX(PhysicsMode mode);
float GetCirMotionY(PhysicsMode mode);
float GetCirMotionZ(PhysicsMode mode);
float RetLinStopLength(PhysicsMode sMode=MO_ADVSPEED, PhysicsMode aMode=MO_STOACCEL);
float RetCirStopLength();
float RetLinMaxLength(float dir);
float RetLinTimeLength(float dist, float dir=1.0f);
float RetLinLength(float dist);
float GetLinStopLength(PhysicsMode sMode=MO_ADVSPEED, PhysicsMode aMode=MO_STOACCEL);
float GetCirStopLength();
float GetLinMaxLength(float dir);
float GetLinTimeLength(float dist, float dir=1.0f);
float GetLinLength(float dist);
void SetMotor(bool bState);
bool RetMotor();
bool GetMotor();
void SetLand(bool bState);
bool RetLand();
bool GetLand();
void SetSwim(bool bState);
bool RetSwim();
bool GetSwim();
void SetCollision(bool bCollision);
bool RetCollision();
bool GetCollision();
void SetFreeze(bool bFreeze);
bool RetFreeze();
bool GetFreeze();
void SetReactorRange(float range);
float RetReactorRange();
float GetReactorRange();
void SetMotorSpeed(Math::Vector speed);
void SetMotorSpeedX(float speed);
void SetMotorSpeedY(float speed);
void SetMotorSpeedZ(float speed);
Math::Vector RetMotorSpeed();
float RetMotorSpeedX();
float RetMotorSpeedY();
float RetMotorSpeedZ();
Math::Vector GetMotorSpeed();
float GetMotorSpeedX();
float GetMotorSpeedY();
float GetMotorSpeedZ();
void CreateInterface(bool bSelect);
Error RetError();
Error GetError();
protected:
bool EventFrame(const Event &event);
@ -186,12 +190,12 @@ protected:
protected:
CInstanceManager* m_iMan;
CD3DEngine* m_engine;
CLight* m_light;
CParticule* m_particule;
CTerrain* m_terrain;
CWater* m_water;
CCamera* m_camera;
Gfx::CEngine* m_engine;
Gfx::CLightManager* m_lightMan;
Gfx::CParticle* m_particle;
Gfx::CTerrain* m_terrain;
Gfx::CWater* m_water;
Gfx::CCamera* m_camera;
CObject* m_object;
CBrain* m_brain;
CMotion* m_motion;

View File

@ -0,0 +1,65 @@
// * This file is part of the COLOBOT source code
// * Copyright (C) 2012, Polish Portal of Colobot (PPC)
// *
// * This program is free software: you can redistribute it and/or modify
// * it under the terms of the GNU General Public License as published by
// * the Free Software Foundation, either version 3 of the License, or
// * (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// plugininterface.h
/**
* @file plugin/plugininterface.h
* @brief Generic plugin interface
*/
#pragma once
#include <string>
#define PLUGIN_INTERFACE(class_type) \
static class_type* Plugin##class_type; \
extern "C" void InstallPluginEntry() { Plugin##class_type = new class_type(); Plugin##class_type->InstallPlugin(); } \
extern "C" bool UninstallPluginEntry(std::string &reason) { bool result = Plugin##class_type->UninstallPlugin(reason); \
if (!result) \
return false; \
delete Plugin##class_type; \
return true; } \
extern "C" CPluginInterface* GetPluginInterfaceEntry() { return static_cast<CPluginInterface*>(Plugin##class_type); }
/**
* @class CPluginInterface
*
* @brief Generic plugin interface. All plugins that will be managed by plugin manager have to derive from this class.
*
*/
class CPluginInterface {
public:
/** Function to get plugin name or description
* @return returns plugin name
*/
virtual std::string PluginName() = 0;
/** Function to get plugin version. 1 means version 0.01, 2 means 0.02 etc.
* @return number indicating plugin version
*/
virtual int PluginVersion() = 0;
/** Function to initialize plugin
*/
virtual void InstallPlugin() = 0;
/** Function called before removing plugin
*/
virtual bool UninstallPlugin(std::string &) = 0;
};

View File

@ -0,0 +1,126 @@
// * This file is part of the COLOBOT source code
// * Copyright (C) 2012 Polish Portal of Colobot (PPC)
// *
// * This program is free software: you can redistribute it and/or modify
// * it under the terms of the GNU General Public License as published by
// * the Free Software Foundation, either version 3 of the License, or
// * (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// pluginloader.cpp
#include "pluginloader.h"
CPluginLoader::CPluginLoader(std::string filename)
{
mInterface = nullptr;
mFilename = filename;
mLoaded = false;
}
std::string CPluginLoader::GetName()
{
if (mLoaded)
return mInterface->PluginName();
return "(not loaded)";
}
int CPluginLoader::GetVersion()
{
if (mLoaded)
return mInterface->PluginVersion();
return 0;
}
bool CPluginLoader::IsLoaded()
{
return mLoaded;
}
bool CPluginLoader::UnloadPlugin()
{
if (!mLoaded) {
GetLogger()->Warn("Plugin %s is not loaded.\n");
return true;
}
bool (*uninstall)(std::string &) = (bool (*)(std::string &)) lt_dlsym(mHandle, "UninstallPluginEntry");
if (!uninstall) {
GetLogger()->Error("Error getting UninstallPluginEntry for plugin %s: %s\n", mFilename.c_str(), lt_dlerror());
return false;
}
std::string reason;
if (!uninstall(reason)) {
GetLogger()->Error("Could not unload plugin %s: %s\n", mFilename.c_str(), reason.c_str());
return false;
}
lt_dlclose(mHandle);
mLoaded = false;
return true;
}
bool CPluginLoader::LoadPlugin()
{
if (mFilename.length() == 0) {
GetLogger()->Warn("No plugin filename specified.\n");
return false;
}
mHandle = lt_dlopenext(mFilename.c_str());
if (!mHandle) {
GetLogger()->Error("Error loading plugin %s: %s\n", mFilename.c_str(), lt_dlerror());
return false;
}
void (*install)() = (void (*)()) lt_dlsym(mHandle, "InstallPluginEntry");
if (!install) {
GetLogger()->Error("Error getting InstallPluginEntry for plugin %s: %s\n", mFilename.c_str(), lt_dlerror());
return false;
}
CPluginInterface* (*getInterface)() = (CPluginInterface* (*)()) lt_dlsym(mHandle, "GetPluginInterfaceEntry");
if (!getInterface) {
GetLogger()->Error("Error getting GetPluginInterfaceEntry for plugin %s: %s\n", mFilename.c_str(), lt_dlerror());
return false;
}
install();
mInterface = getInterface();
mLoaded = true;
return true;
}
bool CPluginLoader::SetFilename(std::string filename)
{
bool ok = true;
if (mLoaded)
ok = UnloadPlugin();
if (ok)
mFilename = filename;
return ok;
}
std::string CPluginLoader::GetFilename()
{
return mFilename;
}

View File

@ -0,0 +1,88 @@
// * This file is part of the COLOBOT source code
// * Copyright (C) 2012, Polish Portal of Colobot (PPC)
// *
// * This program is free software: you can redistribute it and/or modify
// * it under the terms of the GNU General Public License as published by
// * the Free Software Foundation, either version 3 of the License, or
// * (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// pluginloader.h
/**
* @file plugin/pluginloader.h
* @brief Plugin loader interface
*/
#pragma once
#include <ltdl.h>
#include <string>
#include <common/logger.h>
#include "plugininterface.h"
/**
* @class CPluginLoader
*
* @brief Plugin loader interface. Plugin manager uses this class to load plugins.
*
*/
class CPluginLoader {
public:
/** Class contructor
* @param std::string plugin filename
*/
CPluginLoader(std::string);
/** Function to get plugin name or description
* @return returns plugin name
*/
std::string GetName();
/** Function to get plugin version
* @return returns plugin version
*/
int GetVersion();
/** Function to unload plugin
* @return returns true on success
*/
bool UnloadPlugin();
/** Function to load plugin
* @return returns true on success
*/
bool LoadPlugin();
/** Function to check if plugin is loaded
* @return returns true if plugin is loaded
*/
bool IsLoaded();
/** Function to set plugin filename
* @return returns true on success. Action can fail if plugin was loaded and cannot be unloaded
*/
bool SetFilename(std::string);
/** Function to get plugin filename
* @return returns plugin filename
*/
std::string GetFilename();
private:
CPluginInterface* mInterface;
std::string mFilename;
lt_dlhandle mHandle;
bool mLoaded;
};

View File

@ -0,0 +1,132 @@
// * This file is part of the COLOBOT source code
// * Copyright (C) 2012 Polish Portal of Colobot (PPC)
// *
// * This program is free software: you can redistribute it and/or modify
// * it under the terms of the GNU General Public License as published by
// * the Free Software Foundation, either version 3 of the License, or
// * (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// pluginmanager.cpp
#include "pluginmanager.h"
template<> CPluginManager* CSingleton<CPluginManager>::mInstance = nullptr;
CPluginManager::CPluginManager()
{
lt_dlinit();
}
CPluginManager::~CPluginManager()
{
UnloadAllPlugins();
lt_dlexit();
}
void CPluginManager::LoadFromProfile()
{
std::vector< std::string > dirs = GetProfile()->GetLocalProfileSection("Plugins", "Path");
std::vector< std::string > plugins = GetProfile()->GetLocalProfileSection("Plugins", "File");
for (std::string dir : dirs)
m_folders.insert(dir);
for (std::string plugin : plugins) {
GetLogger()->Info("Trying to load plugin %s...\n", plugin.c_str());
LoadPlugin(plugin);
}
}
bool CPluginManager::LoadPlugin(std::string filename)
{
bool result = false;
CPluginLoader *loader = new CPluginLoader("");
for (std::string dir : m_folders) {
loader->SetFilename(dir + "/" + filename);
result = loader->LoadPlugin();
if (result) {
GetLogger()->Info("Plugin %s (%s) version %0.2f loaded!\n", filename.c_str(), loader->GetName().c_str(), loader->GetVersion() / 100.0f);
m_plugins.push_back(loader);
break;
}
}
return result;
}
bool CPluginManager::UnloadPlugin(std::string filename)
{
std::vector<CPluginLoader *>::iterator it;
GetLogger()->Info("Trying to unload plugin %s...\n", filename.c_str());
for (it = m_plugins.begin(); it != m_plugins.end(); it++) {
CPluginLoader *plugin = *it;
if (NameEndsWith(plugin->GetFilename(), filename)) {
m_plugins.erase(it);
plugin->UnloadPlugin();
delete plugin;
return true;
}
}
return false;
}
bool CPluginManager::AddSearchDirectory(std::string dir)
{
m_folders.insert(dir);
return true;
}
bool CPluginManager::RemoveSearchDirectory(std::string dir)
{
m_folders.erase(dir);
return false;
}
bool CPluginManager::UnloadAllPlugins()
{
bool allOk = true;
std::vector<CPluginLoader *>::iterator it;
for (it = m_plugins.begin(); it != m_plugins.end(); it++) {
CPluginLoader *plugin = *it;
bool result;
GetLogger()->Info("Trying to unload plugin %s (%s)...\n", plugin->GetFilename().c_str(), plugin->GetName().c_str());
result = plugin->UnloadPlugin();
if (!result) {
allOk = false;
continue;
}
delete plugin;
m_plugins.erase(it);
}
return allOk;
}
bool CPluginManager::NameEndsWith(std::string filename, std::string ending)
{
if (filename.length() > ending.length()) {
std::string fileEnd = filename.substr(filename.length() - ending.length());
return (fileEnd == ending);
}
return false;
}

View File

@ -0,0 +1,88 @@
// * This file is part of the COLOBOT source code
// * Copyright (C) 2012, Polish Portal of Colobot (PPC)
// *
// * This program is free software: you can redistribute it and/or modify
// * it under the terms of the GNU General Public License as published by
// * the Free Software Foundation, either version 3 of the License, or
// * (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
// pluginmanager.h
/**
* @file plugin/pluginmanager.h
* @brief Plugin manager class.
*/
#pragma once
#include <string>
#include <set>
#include <vector>
#include <common/logger.h>
#include <common/profile.h>
#include <common/singleton.h>
#include "pluginloader.h"
/**
* @class CPluginManager
*
* @brief Plugin manager class. Plugin manager can load plugins from colobot.ini or manually specified files.
*
*/
class CPluginManager : public CSingleton<CPluginManager> {
public:
CPluginManager();
~CPluginManager();
/** Function loads plugin list and path list from profile file
*/
void LoadFromProfile();
/** Function loads specified plugin
* @param std::string plugin filename
* @return returns true on success
*/
bool LoadPlugin(std::string);
/** Function unloads specified plugin
* @param std::string plugin filename
* @return returns true on success
*/
bool UnloadPlugin(std::string);
/** Function adds path to be checked when searching for plugin file. If path was already added it will be ignored
* @param std::string plugin search path
* @return returns true on success
*/
bool AddSearchDirectory(std::string);
/** Function removes path from list
* @param std::string plugin search path
* @return returns true on success
*/
bool RemoveSearchDirectory(std::string);
/** Function tries to unload all plugins
* @return returns true on success
*/
bool UnloadAllPlugins();
private:
bool NameEndsWith(std::string, std::string);
std::set< std::string > m_folders;
std::vector<CPluginLoader *> m_plugins;
};

View File

@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 2.8)
set(CMAKE_BUILD_TYPE debug)
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g -O0 -std=c++11 -rdynamic")
add_executable(manager_test manager_test.cpp ../../common/logger.cpp ../../common/profile.cpp ../../common/iman.cpp ../pluginmanager.cpp ../pluginloader.cpp)
include_directories(".")
include_directories("../../")
include_directories("../../../")
target_link_libraries(manager_test ltdl)

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