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(OpenGL 1.4 REQUIRED)
find_package(SDL 1.2.10 REQUIRED) find_package(SDL 1.2.10 REQUIRED)
find_package(SDL_image 1.2 REQUIRED) find_package(SDL_image 1.2 REQUIRED)
find_package(SDL_ttf 2.0 REQUIRED)
find_package(PNG 1.2 REQUIRED) find_package(PNG 1.2 REQUIRED)
# GLEW requirement depends on platform # 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") SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${colobot_SOURCE_DIR}/cmake")
# Subdirectory with sources # 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/restext.cpp
common/stringutils.cpp common/stringutils.cpp
graphics/core/color.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/cloud.cpp
graphics/engine/engine.cpp graphics/engine/engine.cpp
graphics/engine/lightman.cpp graphics/engine/lightman.cpp
@ -176,6 +176,7 @@ graphics/opengl/gldevice.cpp
set(LIBS set(LIBS
${SDL_LIBRARY} ${SDL_LIBRARY}
${SDLIMAGE_LIBRARY} ${SDLIMAGE_LIBRARY}
${SDLTTF_LIBRARY}
${OPENGL_LIBRARY} ${OPENGL_LIBRARY}
${PNG_LIBRARIES} ${PNG_LIBRARIES}
${OPTIONAL_LIBS} ${OPTIONAL_LIBS}

View File

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

View File

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

View File

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

View File

@ -15,7 +15,10 @@
// * You should have received a copy of the GNU General Public License // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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/app.h"
#include "app/system.h" #include "app/system.h"

View File

@ -15,7 +15,10 @@
// * You should have received a copy of the GNU General Public License // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once
@ -26,7 +29,7 @@
/* Dialog utils */ /* Dialog utils */
/** /**
* \enum SysDialogType * \enum SystemDialogType
* \brief Type of system dialog * \brief Type of system dialog
*/ */
enum SystemDialogType enum SystemDialogType
@ -44,7 +47,7 @@ enum SystemDialogType
}; };
/** /**
* \enum SysDialogResult * \enum SystemDialogResult
* \brief Result of system dialog * \brief Result of system dialog
* *
* Means which button was pressed. * Means which button was pressed.

View File

@ -15,10 +15,13 @@
// * You should have received a copy of the GNU General Public License // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 /* NOTE: code is contained in this header;
from system.h. There is no separate .cpp module for simplicity.*/ * there is no separate .cpp module for simplicity */
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>

View File

@ -15,10 +15,13 @@
// * You should have received a copy of the GNU General Public License // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 /* NOTE: code is contained in this header;
from system.h. There is no separate .cpp module for simplicity.*/ * there is no separate .cpp module for simplicity */
#include <SDL/SDL.h> #include <SDL/SDL.h>

View File

@ -15,10 +15,13 @@
// * You should have received a copy of the GNU General Public License // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 /* NOTE: code is contained in this header;
from system.h. There is no separate .cpp module for simplicity.*/ * there is no separate .cpp module for simplicity */
#include <windows.h> #include <windows.h>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -17,98 +17,89 @@
// profile.cpp // profile.cpp
#include <stdio.h> #include <common/profile.h>
#include <d3d.h>
#include <stdlib.h>
#include "common/language.h"
#include "common/struct.h"
#include "common/profile.h"
template<> CProfile* CSingleton<CProfile>::mInstance = nullptr;
static char g_filename[100];
CProfile::CProfile()
bool InitCurrentDirectory()
{ {
#if _SCHOOL m_ini = new CSimpleIniA();
_fullpath(g_filename, "ceebot.ini", 100); m_ini->SetUnicode();
#else m_ini->SetMultiKey();
_fullpath(g_filename, "colobot.ini", 100);
#endif
return true;
} }
bool SetLocalProfileString(char* section, char* key, char* string) CProfile::~CProfile()
{ {
WritePrivateProfileString(section, key, string, g_filename); m_ini->Reset();
return true; delete m_ini;
} }
bool GetLocalProfileString(char* section, char* key, char* buffer, int max)
{
int nb;
nb = GetPrivateProfileString(section, key, "", buffer, max, g_filename); bool CProfile::InitCurrentDirectory()
if ( nb == 0 ) {
{ bool result = m_ini->LoadFile("colobot.ini") == SI_OK;
buffer[0] = 0; return result;
return false; }
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; 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; return true;
} }
bool GetLocalProfileInt(char* section, char* key, int &value)
{
char s[20];
int nb;
nb = GetPrivateProfileString(section, key, "", s, 20, g_filename); std::vector< std::string > CProfile::GetLocalProfileSection(std::string section, std::string key)
if ( nb == 0 ) {
{ std::vector< std::string > ret_list;
value = 0;
return false; 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 #pragma once
#include <cstdlib>
#include <vector>
#include <utility>
extern bool InitCurrentDirectory(); #include <lib/simpleini/SimpleIni.h>
extern bool SetLocalProfileString(char* section, char* key, char* string);
extern bool GetLocalProfileString(char* section, char* key, char* buffer, int max); #include <common/singleton.h>
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); * @file common/profile.h
extern bool GetLocalProfileFloat(char* section, char* key, float &value); * @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 StrUtils::Utf8StringLength(const std::string &str)
{ {
size_t result = 0; 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]; i += Utf8CharSizeAt(str, i);
if ((ch & 0x80) == 0)
++result; ++result;
else if ((ch & 0xC0) == 0xC0)
result += 2;
else
result += 3;
} }
return result; return result;
} }

View File

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

View File

@ -15,7 +15,10 @@
// * You should have received a copy of the GNU General Public License // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -29,6 +29,66 @@
#include "physics/physics.h" #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) //! Changes the level of transparency of an object and objects transported (battery & cargo)
void SetTransparency(CObject* obj, float value) void SetTransparency(CObject* obj, float value)
{ {
@ -332,7 +392,7 @@ void Gfx::CCamera::SetType(CameraType type)
SetSmooth(Gfx::CAM_SMOOTH_NORM); SetSmooth(Gfx::CAM_SMOOTH_NORM);
} }
CameraType Gfx::CCamera::GetType() Gfx::CameraType Gfx::CCamera::GetType()
{ {
return m_type; return m_type;
} }
@ -342,7 +402,7 @@ void Gfx::CCamera::SetSmooth(CameraSmooth type)
m_smooth = type; m_smooth = type;
} }
CameraSmooth Gfx::CCamera::GetSmoth() Gfx::CameraSmooth Gfx::CCamera::GetSmoth()
{ {
return m_smooth; return m_smooth;
} }
@ -692,7 +752,7 @@ void Gfx::CCamera::OverFrame(const Event &event)
} }
else else
{ {
color = Gfx::Color(0.0f. 0.0f, 0.0f); color = Gfx::Color(0.0f, 0.0f, 0.0f);
} }
color.a = 0.0f; color.a = 0.0f;
m_engine->SetOverColor(color, m_overMode); 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++) 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 == NULL) break;
if (obj->GetTruck()) continue; // battery or cargo? 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_SAFE ||
iType == OBJECT_HUSTON ) continue; iType == OBJECT_HUSTON ) continue;
ObjType oType = obj->GetType(); ObjectType oType = obj->GetType();
if ( oType == OBJECT_HUMAN || if ( oType == OBJECT_HUMAN ||
oType == OBJECT_TECH || oType == OBJECT_TECH ||
oType == OBJECT_TOTO || oType == OBJECT_TOTO ||
@ -995,7 +1055,6 @@ bool Gfx::CCamera::EventProcess(const Event &event)
{ {
switch (event.type) switch (event.type)
{ {
// TODO: frame update event
case EVENT_FRAME: case EVENT_FRAME:
EventFrame(event); EventFrame(event);
break; break;
@ -1004,11 +1063,11 @@ bool Gfx::CCamera::EventProcess(const Event &event)
EventMouseMove(event); EventMouseMove(event);
break; 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_WHEELUP ) EventMouseWheel(+1);
if ( event.param == VK_WHEELDOWN ) EventMouseWheel(-1); if ( event.param == VK_WHEELDOWN ) EventMouseWheel(-1);
break; break;*/
default: default:
break; break;
@ -1489,8 +1548,6 @@ bool Gfx::CCamera::EventFrameFix(const Event &event)
bool Gfx::CCamera::EventFrameExplo(const Event &event) bool Gfx::CCamera::EventFrameExplo(const Event &event)
{ {
float factor = m_heightEye * 0.5f + 30.0f;
if (m_mouseDirH != 0.0f) if (m_mouseDirH != 0.0f)
m_directionH -= m_mouseDirH * event.rTime * 0.7f * m_speed; 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; Math::Vector lookatPt, upVec;
m_cameraObj->SetViewFromHere(m_eyePt, m_directionH, m_directionV, 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 eye = m_effectOffset * 0.3f + m_eyePt;
Math::Vector lookat = m_effectOffset * 0.3f + lookatPt; 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 // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once
@ -353,13 +356,13 @@ protected:
float m_centeringTime; float m_centeringTime;
float m_centeringProgress; float m_centeringProgress;
CameraEffect m_effectType; Gfx::CameraEffect m_effectType;
Math::Vector m_effectPos; Math::Vector m_effectPos;
float m_effectForce; float m_effectForce;
float m_effectProgress; float m_effectProgress;
Math::Vector m_effectOffset; Math::Vector m_effectOffset;
OverEffect m_overType; Gfx::CameraOverEffect m_overType;
float m_overForce; float m_overForce;
float m_overTime; float m_overTime;
Gfx::Color m_overColorBase; Gfx::Color m_overColorBase;

View File

@ -19,5 +19,265 @@
#include "graphics/engine/cloud.h" #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 // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once
@ -24,6 +27,9 @@
#include "math/point.h" #include "math/point.h"
#include "math/vector.h" #include "math/vector.h"
#include <vector>
#include <string>
class CInstanceManager; class CInstanceManager;
@ -34,13 +40,20 @@ namespace Gfx {
class CEngine; class CEngine;
class CTerrain; class CTerrain;
const short MAXCLOUDLINE = 100;
struct CloudLine struct CloudLine
{ {
short x, y; // beginning //! Beginning
short len; // in length x short x, y;
//! In length x
short len;
float px1, px2, pz; float px1, px2, pz;
CloudLine()
{
x = y = 0;
len = 0;
px1 = px2 = pz = 0;
}
}; };
@ -51,43 +64,59 @@ public:
~CCloud(); ~CCloud();
bool EventProcess(const Event &event); bool EventProcess(const Event &event);
//! Removes all the clouds
void Flush(); 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(); void Draw();
bool SetLevel(float level); //! Modifies the cloud level
float RetLevel(); void SetLevel(float level);
//! Returns the current level of clouds
float GetLevel();
void SetEnable(bool bEnable); //! Activate management of clouds
bool RetEnable(); void SetEnable(bool enable);
bool GetEnable();
protected: protected:
//! Makes the clouds evolve
bool EventFrame(const Event &event); bool EventFrame(const Event &event);
void AdjustLevel(Math::Vector &pos, Math::Vector &eye, float deep, Math::Point &uv1, Math::Point &uv2); //! Adjusts the position to normal, to imitate the clouds at movement
bool CreateLine(int x, int y, int len); 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: protected:
CInstanceManager* m_iMan; CInstanceManager* m_iMan;
CEngine* m_engine; Gfx::CEngine* m_engine;
CTerrain* m_terrain; Gfx::CTerrain* m_terrain;
char m_filename[100]; std::string m_fileName;
float m_level; // overall level //! Overall level
Math::Point m_speed; // feedrate (wind) float m_level;
Gfx::Color m_diffuse; // diffuse color //! Feedrate (wind)
Gfx::Color m_ambient; // ambient color Math::Point m_speed;
//! Diffuse color
Gfx::Color m_diffuse;
//! Ambient color
Gfx::Color m_ambient;
float m_time; float m_time;
float m_lastTest; float m_lastTest;
int m_subdiv; int m_subdiv;
Math::Vector m_wind; // wind speed //! Wind speed
int m_brick; // brick mosaic Math::Vector m_wind;
float m_size; // size of a brick element //! Brick mosaic
int m_brick;
//! Size of a brick element
float m_size;
int m_lineUsed; std::vector<Gfx::CloudLine> m_line;
CloudLine m_line[MAXCLOUDLINE];
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 // * 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) // * Copyright (C) 2012, Polish Portal of Colobot (PPC)
// * // *
// * This program is free software: you can redistribute it and/or modify // * 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 // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once
#include "app/system.h"
#include "common/event.h" #include "common/event.h"
#include "graphics/core/color.h" #include "graphics/core/color.h"
#include "graphics/core/material.h" #include "graphics/core/material.h"
#include "graphics/core/texture.h" #include "graphics/core/texture.h"
#include "graphics/core/vertex.h" #include "graphics/core/vertex.h"
#include "math/intpoint.h" #include "math/intpoint.h"
#include "math/intsize.h"
#include "math/matrix.h" #include "math/matrix.h"
#include "math/point.h" #include "math/point.h"
#include "math/vector.h" #include "math/vector.h"
@ -35,12 +37,13 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <map> #include <map>
#include <set>
class CApplication; class CApplication;
class CInstanceManager; class CInstanceManager;
class CObject; class CObject;
class CSound; class CSoundInterface;
namespace Gfx { namespace Gfx {
@ -76,7 +79,7 @@ struct EngineTriangle
Gfx::VertexTex2 triangle[3]; Gfx::VertexTex2 triangle[3];
//! Material //! Material
Gfx::Material material; Gfx::Material material;
//! Render state (TODO: ?) //! Render state
int state; int state;
//! 1st texture //! 1st texture
Gfx::Texture tex1; Gfx::Texture tex1;
@ -169,7 +172,10 @@ struct EngineObjLevel5
Gfx::EngineTriangleType type; Gfx::EngineTriangleType type;
std::vector<Gfx::VertexTex2> vertices; std::vector<Gfx::VertexTex2> vertices;
EngineObjLevel5(); EngineObjLevel5()
{
state = 0;
}
}; };
/** /**
@ -181,7 +187,10 @@ struct EngineObjLevel4
std::vector<Gfx::EngineObjLevel5> up; std::vector<Gfx::EngineObjLevel5> up;
Gfx::EngineObjLevel3* down; Gfx::EngineObjLevel3* down;
EngineObjLevel4(); EngineObjLevel4()
{
reserved = 0;
}
}; };
/** /**
@ -194,7 +203,10 @@ struct EngineObjLevel3
std::vector<Gfx::EngineObjLevel4> up; std::vector<Gfx::EngineObjLevel4> up;
Gfx::EngineObjLevel2* down; Gfx::EngineObjLevel2* down;
EngineObjLevel3(); EngineObjLevel3()
{
min = max = 0.0f;
}
}; };
/** /**
@ -206,7 +218,10 @@ struct EngineObjLevel2
std::vector<Gfx::EngineObjLevel3> up; std::vector<Gfx::EngineObjLevel3> up;
Gfx::EngineObjLevel1* down; Gfx::EngineObjLevel1* down;
EngineObjLevel2(); EngineObjLevel2()
{
objRank = 0;
}
}; };
/** /**
@ -218,7 +233,7 @@ struct EngineObjLevel1
Gfx::Texture tex2; Gfx::Texture tex2;
std::vector<Gfx::EngineObjLevel2> up; std::vector<Gfx::EngineObjLevel2> up;
EngineObjLevel1(); EngineObjLevel1() {}
}; };
/** /**
@ -297,12 +312,14 @@ struct EngineGroundSpot
\brief Phase of life of an EngineGroundMark */ \brief Phase of life of an EngineGroundMark */
enum EngineGroundMarkPhase enum EngineGroundMarkPhase
{ {
//! Null phase
ENG_GR_MARK_PHASE_NULL = 0,
//! Increase //! Increase
ENG_GR_MARK_PHASE_INC = 1, ENG_GR_MARK_PHASE_INC = 1,
//! Fixed //! Fixed
ENG_GR_MARK_PHASE_FIX = 2, ENG_GR_MARK_PHASE_FIX = 2,
//! Decrease //! Decrease
ENG_GR_MARK_PHASE_DEC = 2 ENG_GR_MARK_PHASE_DEC = 3
}; };
/** /**
@ -407,7 +424,13 @@ enum EngineRenderState
//! The transparent color (black = no) //! The transparent color (black = no)
ENG_RSTATE_TCOLOR_BLACK = (1<<16), ENG_RSTATE_TCOLOR_BLACK = (1<<16),
//! The transparent color (white = no) //! 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 class CEngine
{ {
public: public:
CEngine(CInstanceManager *iMan, CApplication *app); CEngine(CInstanceManager* iMan, CApplication* app);
~CEngine(); ~CEngine();
//! Returns whether the device was initialized //! Sets the device to be used
bool GetWasInit(); void SetDevice(Gfx::CDevice* device);
//! Returns the last error encountered //! Returns the current device
std::string GetError(); 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(); bool Create();
//! Frees all resources before exit //! Frees all resources before exit
void Destroy(); 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) //! Resets some states and flushes textures after device was changed (e.g. resoulution changed)
void ResetAfterDeviceChanged(); void ResetAfterDeviceChanged();
void SetTerrain(Gfx::CTerrain* terrain);
//! Called once per frame, the call is the entry point for rendering
void Render();
//! Processes incoming event //! Processes incoming event
bool ProcessEvent(const Event &event); bool ProcessEvent(const Event& event);
//! Renders a single frame //! Called once per frame, the call is the entry point for animating the scene
bool Render(); 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); void SetPause(bool pause);
bool GetPause(); bool GetPause();
//@}
//@{
//! Management of lock for the duration of movie sequence
void SetMovieLock(bool lock); void SetMovieLock(bool lock);
bool GetMovieLock(); 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); void SetRenderEnable(bool enable);
int OneTimeSceneInit(); //! Returns current size of viewport window
int InitDeviceObjects(); Math::IntPoint GetWindowSize();
int DeleteDeviceObjects(); //! Returns the last size of viewport window
int RestoreSurfaces(); Math::IntPoint GetLastWindowSize();
int FrameMove(float rTime);
void StepSimulation(float rTime); //@{
int FinalCleanup(); //! 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); void AddStatisticTriangle(int nb);
//! Returns the number of triangles in current frame
int GetStatisticTriangle(); 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(); /* *************** Object management *************** */
Math::Matrix* GetMatLeftView();
Math::Matrix* GetMatRightView();
void TimeInit();
void TimeEnterGel();
void TimeExitGel();
float TimeGet();
int GetRestCreate();
int CreateObject(); int CreateObject();
void FlushObject(); void FlushObject();
bool DeleteObject(int objRank); bool DeleteObject(int objRank);
bool SetDrawWorld(int objRank, bool draw); bool SetDrawWorld(int objRank, bool draw);
bool SetDrawFront(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, int state, std::string texName1, std::string texName2,
float min, float max, bool globalUpdate); 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, int state, std::string texName1, std::string texName2,
float min, float max, bool globalUpdate); 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, std::string texName1, std::string texName2,
float min, float max, bool globalUpdate); 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, int state, std::string texName1, std::string texName2,
float min, float max); float min, float max);
void ChangeLOD(); void ChangeLOD();
bool ChangeSecondTexture(int objRank, char* texName2); bool ChangeSecondTexture(int objRank, const std::string& texName2);
int GetTotalTriangles(int objRank); int GetTotalTriangles(int objRank);
int GetTriangles(int objRank, float min, float max, Gfx::EngineTriangle* buffer, int size, float percent); 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 GetBBox(int objRank, Math::Vector& min, Math::Vector& max);
bool ChangeTextureMapping(int objRank, const Gfx::Material &mat, int state, bool ChangeTextureMapping(int objRank, const Gfx::Material& mat, int state,
const std::string &texName1, const std::string &texName2, const std::string& texName1, const std::string& texName2,
float min, float max, Gfx::EngineTextureMapping mode, float min, float max, Gfx::EngineTextureMapping mode,
float au, float bu, float av, float bv); float au, float bu, float av, float bv);
bool TrackTextureMapping(int objRank, const Gfx::Material &mat, int state, bool TrackTextureMapping(int objRank, const Gfx::Material& mat, int state,
const std::string &texName1, const std::string &texName2, const std::string& texName1, const std::string& texName2,
float min, float max, Gfx::EngineTextureMapping mode, float min, float max, Gfx::EngineTextureMapping mode,
float pos, float factor, float tl, float ts, float tt); float pos, float factor, float tl, float ts, float tt);
bool SetObjectTransform(int objRank, const Math::Matrix &transform); bool SetObjectTransform(int objRank, const Math::Matrix& transform);
bool GetObjectTransform(int objRank, Math::Matrix &transform); bool GetObjectTransform(int objRank, Math::Matrix& transform);
bool SetObjectType(int objRank, Gfx::EngineObjectType type); bool SetObjectType(int objRank, Gfx::EngineObjectType type);
Gfx::EngineObjectType GetObjectType(int objRank); Gfx::EngineObjectType GetObjectType(int objRank);
bool SetObjectTransparency(int objRank, float value); bool SetObjectTransparency(int objRank, float value);
@ -627,20 +674,25 @@ public:
void ShadowDelete(int objRank); void ShadowDelete(int objRank);
bool SetObjectShadowHide(int objRank, bool hide); bool SetObjectShadowHide(int objRank, bool hide);
bool SetObjectShadowType(int objRank, Gfx::EngineShadowType type); bool SetObjectShadowType(int objRank, Gfx::EngineShadowType type);
bool SetObjectShadowPos(int objRank, const Math::Vector &pos); bool SetObjectShadowPos(int objRank, const Math::Vector& pos);
bool SetObjectShadowNormal(int objRank, const Math::Vector &n); bool SetObjectShadowNormal(int objRank, const Math::Vector& n);
bool SetObjectShadowAngle(int objRank, float angle); bool SetObjectShadowAngle(int objRank, float angle);
bool SetObjectShadowRadius(int objRank, float radius); bool SetObjectShadowRadius(int objRank, float radius);
bool SetObjectShadowIntensity(int objRank, float intensity); bool SetObjectShadowIntensity(int objRank, float intensity);
bool SetObjectShadowHeight(int objRank, float h); bool SetObjectShadowHeight(int objRank, float h);
float GetObjectShadowRadius(int objRank); 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(); void GroundSpotFlush();
int GroundSpotCreate(); int GroundSpotCreate();
void GroundSpotDelete(int rank); 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 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 SetObjectGroundSpotMinMax(int rank, float min, float max);
bool SetObjectGroundSpotSmooth(int rank, float smooth); bool SetObjectGroundSpotSmooth(int rank, float smooth);
@ -649,216 +701,356 @@ public:
int dx, int dy, char* table); int dx, int dy, char* table);
bool GroundMarkDelete(int rank); bool GroundMarkDelete(int rank);
//! Updates the state after creating objects
void Update(); 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, /* *************** Mode setting *************** */
const Gfx::TextureCreateParams &params);
Gfx::Texture CreateTexture(const std::string &texName);
void DestroyTexture(const std::string &texName);
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(); 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); void SetLimitLOD(int rank, float limit);
float GetLimitLOD(int rank, bool last=false); float GetLimitLOD(int rank, bool last=false);
//@}
//! Defines of the distance field of vision
void SetTerrainVision(float 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); void SetGroundSpot(bool mode);
bool GetGroundSpot(); bool GetGroundSpot();
//@}
//@{
//! Management of the global mode of shading
void SetShadow(bool mode); void SetShadow(bool mode);
bool GetShadow(); bool GetShadow();
//@}
//@{
//! Management of the global mode of contamination
void SetDirty(bool mode); void SetDirty(bool mode);
bool GetDirty(); bool GetDirty();
//@}
//@{
//! Management of the global mode of horizontal fog patches
void SetFog(bool mode); void SetFog(bool mode);
bool GetFog(); bool GetFog();
//@}
//! Indicates whether it is possible to give a color SetState
bool GetStateColor(); bool GetStateColor();
//@{
//! Management of the global mode of secondary texturing
void SetSecondTexture(int texNum); void SetSecondTexture(int texNum);
int GetSecondTexture(); int GetSecondTexture();
//@}
//@{
//! Management of view mode
void SetRankView(int rank); void SetRankView(int rank);
int GetRankView(); int GetRankView();
//@}
//! Whether to draw the world
void SetDrawWorld(bool draw); void SetDrawWorld(bool draw);
//! Whether to draw the world on the interface
void SetDrawFront(bool draw); 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); 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(); 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); 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); void SetDeepView(float length, int rank = 0, bool ref=false);
float GetDeepView(int rank = 0); 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); void SetFogStart(float start, int rank = 0);
float GetFogStart(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(), Gfx::Color cloudUp = Gfx::Color(), Gfx::Color cloudDown = Gfx::Color(),
bool full = false, bool quarter = false); bool full = false, bool quarter = false);
void GetBackground(const std::string &name, Gfx::Color &up, Gfx::Color &down, void GetBackground(std::string& name, Gfx::Color& up, Gfx::Color& down,
Gfx::Color &cloudUp, Gfx::Color &cloudDown, Gfx::Color& cloudUp, Gfx::Color& cloudDown,
bool &full, bool &quarter); 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);
//! 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); void SetParticleDensity(float value);
float GetParticleDensity(); float GetParticleDensity();
//@}
//! Adapts particle factor according to particle density
float ParticleAdapt(float factor); float ParticleAdapt(float factor);
//@{
//! Management of the distance of clipping.
void SetClippingDistance(float value); void SetClippingDistance(float value);
float GetClippingDistance(); float GetClippingDistance();
//@}
//@{
//! Management of objects detals.
void SetObjectDetail(float value); void SetObjectDetail(float value);
float GetObjectDetail(); float GetObjectDetail();
//@}
//@{
//! The amount of management objects gadgets
void SetGadgetQuantity(float value); void SetGadgetQuantity(float value);
float GetGadgetQuantity(); float GetGadgetQuantity();
//@}
//@{
//! Management the quality of textures
void SetTextureQuality(int value); void SetTextureQuality(int value);
int GetTextureQuality(); int GetTextureQuality();
//@}
//@{
//! Management mode of toto
void SetTotoMode(bool present); void SetTotoMode(bool present);
bool GetTotoMode(); bool GetTotoMode();
//@}
//@{
//! Management the mode of foreground
void SetLensMode(bool present); void SetLensMode(bool present);
bool GetLensMode(); bool GetLensMode();
//@}
//@{
//! Management the mode of water
void SetWaterMode(bool present); void SetWaterMode(bool present);
bool GetWaterMode(); bool GetWaterMode();
//@}
void SetLightingMode(bool present); void SetLightingMode(bool present);
bool GetLightingMode(); bool GetLightingMode();
//@{
//! Management the mode of sky
void SetSkyMode(bool present); void SetSkyMode(bool present);
bool GetSkyMode(); bool GetSkyMode();
//@}
//@{
//! Management the mode of background
void SetBackForce(bool present); void SetBackForce(bool present);
bool GetBackForce(); bool GetBackForce();
//@}
//@{
//! Management the mode of planets
void SetPlanetMode(bool present); void SetPlanetMode(bool present);
bool GetPlanetMode(); bool GetPlanetMode();
//@}
//@{
//! Managing the mode of dynamic lights.
void SetLightMode(bool present); void SetLightMode(bool present);
bool GetLightMode(); bool GetLightMode();
//@}
//@{
// TODO: move to more appropriate class ?
//! Management of the indentation mode while editing (CEdit)
void SetEditIndentMode(bool autoIndent); void SetEditIndentMode(bool autoIndent);
bool GetEditIndentMode(); bool GetEditIndentMode();
//@}
//@{
// TODO: move to more appropriate class ?
//! Management of tab indent when editing (CEdit)
void SetEditIndentValue(int value); void SetEditIndentValue(int value);
int GetEditIndentValue(); int GetEditIndentValue();
//@}
//@{
//! Management of game speed
void SetSpeed(float speed); void SetSpeed(float speed);
float GetSpeed(); float GetSpeed();
//@{
//! Management of precision of robot tracks
void SetTracePrecision(float factor); void SetTracePrecision(float factor);
float GetTracePrecision(); float GetTracePrecision();
//@}
void SetFocus(float focus); //@{
float GetFocus(); //! Management of mouse cursor visibility
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);
void SetMouseVisible(bool show); void SetMouseVisible(bool show);
bool GetMouseVisible(); bool GetMouseVisible();
//@}
//@{
//! Management of mouse cursor position
void SetMousePos(Math::Point pos); void SetMousePos(Math::Point pos);
Math::Point GetMousePos(); Math::Point GetMousePos();
//@}
//@{
//! Management of mouse cursor type
void SetMouseType(Gfx::EngineMouseType type); void SetMouseType(Gfx::EngineMouseType type);
Gfx::EngineMouseType GetMouseType(); 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, //! Resets the projection matrix after changes
Gfx::Color colorRef2, Gfx::Color colorNew2, void UpdateMatProj();
float tolerance1, float tolerance2,
Math::Point ts, Math::Point ti, //! Updates the scene after a change of parameters
Math::Point *pExclu=0, float shift=0.0f, bool hSV=false); void ApplyChange();
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);
protected: protected:
//! Prepares the interface for 3D scene
void Draw3DScene();
//! Draws the user interface over the scene
void DrawInterface();
void SetUp3DView(); //! Updates the textures used for drawing ground spot
bool Draw3DScene(); void UpdateGroundSpotTextures();
void SetUpInterfaceView(); //! Draws shadows
bool DrawInterface();
void DrawGroundSpot();
void DrawShadow(); void DrawShadow();
//! Draws the gradient background
void DrawBackground(); void DrawBackground();
void DrawBackgroundGradient(Gfx::Color up, Gfx::Color down); //! Draws the gradient background
void DrawBackgroundImageQuarter(Math::Point p1, Math::Point p2, char *name); 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(); void DrawBackgroundImage();
//! Draws all the planets
void DrawPlanet(); void DrawPlanet();
void DrawFrontsize(); //! Draws the image foreground
void DrawForegroundImage();
//! Draws the foreground color
void DrawOverColor(); void DrawOverColor();
void DrawHilite(); //! Draws the rectangle of the object highlighted
void DrawHighlight();
//! Draws the mouse cursor
void DrawMouse(); void DrawMouse();
//! Draw part of mouse cursor sprite
void DrawMouseSprite(Math::Point pos, Math::Point dim, int icon); void DrawMouseSprite(Math::Point pos, Math::Point dim, int icon);
/* //! Tests whether the given object is visible
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);*/
bool IsVisible(int objRank); bool IsVisible(int objRank);
//! Detects whether an object is affected by the mouse
bool DetectBBox(int objRank, Math::Point 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); //! Compute and return the 2D box on screen of any object
bool TransformPoint(Math::Vector &p2D, int objRank, Math::Vector p3D); 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(); void ComputeDistance();
//! Updates all the geometric parameters of objects
void UpdateGeometry(); void UpdateGeometry();
protected: protected:
CInstanceManager* m_iMan; CInstanceManager* m_iMan;
CApplication* m_app; CApplication* m_app;
CSound* m_sound; CSoundInterface* m_sound;
Gfx::CDevice* m_device; Gfx::CDevice* m_device;
Gfx::CText* m_text; Gfx::CText* m_text;
Gfx::CLightManager* m_lightMan; Gfx::CLightManager* m_lightMan;
@ -869,51 +1061,54 @@ protected:
Gfx::CPlanet* m_planet; Gfx::CPlanet* m_planet;
Gfx::CTerrain* m_terrain; Gfx::CTerrain* m_terrain;
bool m_wasInit; //! Last encountered error
std::string m_error; std::string m_error;
//! Whether to show stats (FPS, etc) //! Whether to show stats (FPS, etc)
bool m_showStats; bool m_showStats;
int m_blackSrcBlend[2]; //! Speed of animation
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;
float m_speed; float m_speed;
//! Pause mode
bool m_pause; bool m_pause;
//! Rendering enabled?
bool m_render; bool m_render;
//! Lock for duration of movie?
bool m_movieLock; bool m_movieLock;
//! Current size of window //! Projection matrix for 3D scene
Math::IntSize m_size; Math::Matrix m_matProj;
Math::IntSize m_lastSize; //! 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; std::vector<Gfx::EngineObjLevel1> m_objectTree;
//! Object parameters
std::vector<Gfx::EngineObject> m_objects; std::vector<Gfx::EngineObject> m_objects;
std::vector<Gfx::EngineShadow> m_shadow; //! Shadow list
std::vector<Gfx::EngineGroundSpot> m_groundSpot; std::vector<Gfx::EngineShadow> m_shadows;
//! Ground spot list
std::vector<Gfx::EngineGroundSpot> m_groundSpots;
//! Ground mark
Gfx::EngineGroundMark m_groundMark; Gfx::EngineGroundMark m_groundMark;
//! Location of camera
Math::Vector m_eyePt; Math::Vector m_eyePt;
//! Camera target
Math::Vector m_lookatPt; Math::Vector m_lookatPt;
float m_eyeDirH; float m_eyeDirH;
float m_eyeDirV; float m_eyeDirV;
@ -926,7 +1121,6 @@ protected:
Gfx::Color m_waterAddColor; Gfx::Color m_waterAddColor;
int m_statisticTriangle; int m_statisticTriangle;
bool m_updateGeometry; bool m_updateGeometry;
//char m_infoText[10][200];
int m_alphaMode; int m_alphaMode;
bool m_stateColor; bool m_stateColor;
bool m_forceStateColor; bool m_forceStateColor;
@ -946,11 +1140,11 @@ protected:
bool m_overFront; bool m_overFront;
Gfx::Color m_overColor; Gfx::Color m_overColor;
int m_overMode; int m_overMode;
std::string m_frontsizeName; std::string m_foregroundName;
bool m_drawWorld; bool m_drawWorld;
bool m_drawFront; bool m_drawFront;
float m_limitLOD[2]; float m_limitLOD[2];
float m_particuleDensity; float m_particleDensity;
float m_clippingDistance; float m_clippingDistance;
float m_lastClippingDistance; float m_lastClippingDistance;
float m_objectDetail; float m_objectDetail;
@ -969,34 +1163,53 @@ protected:
int m_editIndentValue; int m_editIndentValue;
float m_tracePrecision; float m_tracePrecision;
int m_hiliteRank[100]; //! Ranks of highlighted objects
bool m_hilite; int m_highlightRank[100];
Math::Point m_hiliteP1; //! Highlight visible?
Math::Point m_hiliteP2; bool m_highlight;
//! Time counter for highlight animation
int m_lastState; float m_highlightTime;
Gfx::Color m_lastColor; //@{
char m_lastTexture[2][50]; //! Highlight rectangle points
Gfx::Material m_lastMaterial; Math::Point m_highlightP1;
Math::Point m_highlightP2;
//@}
//! Texture directory name
std::string m_texPath; std::string m_texPath;
//! Default texture create params
Gfx::TextureCreateParams m_defaultTexParams; Gfx::TextureCreateParams m_defaultTexParams;
//! Map of loaded textures (by name)
std::map<std::string, Gfx::Texture> m_texNameMap; std::map<std::string, Gfx::Texture> m_texNameMap;
//! Reverse map of loaded textures (by texture)
std::map<Gfx::Texture, std::string> m_revTexNameMap; 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]; Gfx::EngineMouse m_mice[Gfx::ENG_MOUSE_COUNT];
//! Texture with mouse cursors
Gfx::Texture m_miceTexture; Gfx::Texture m_miceTexture;
//! Size of mouse cursor
Math::Point m_mouseSize; Math::Point m_mouseSize;
//! Type of mouse cursor
Gfx::EngineMouseType m_mouseType; Gfx::EngineMouseType m_mouseType;
//! Position of mouse in interface coords
Math::Point m_mousePos; Math::Point m_mousePos;
//! Is mouse visible?
bool m_mouseVisible; bool m_mouseVisible;
//LPDIRECTDRAWSURFACE7 m_imageSurface; //! Last engine render state (-1 at the beginning of frame)
//DDSURFACEDESC2 m_imageDDSD; int m_lastState;
//WORD* m_imageCopy; //! Last color set with render state
//int m_imageDX; Gfx::Color m_lastColor;
//int m_imageDY; //! Last texture names for 2 used texture stages
std::string m_lastTexture[2];
//! Last material
Gfx::Material m_lastMaterial;
}; };
}; // namespace Gfx }; // namespace Gfx

View File

@ -15,7 +15,10 @@
// * You should have received a copy of the GNU General Public License // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once

View File

@ -19,5 +19,71 @@
#include "graphics/engine/lightning.h" #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 // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once
@ -73,7 +76,7 @@ protected:
float m_sleep; float m_sleep;
float m_delay; float m_delay;
float m_magnetic; float m_magnetic;
BlitzPhase m_phase; Gfx::BlitzPhase m_phase;
float m_time; float m_time;
float m_speed; float m_speed;
float m_progress; float m_progress;

View File

@ -15,7 +15,10 @@
// * You should have received a copy of the GNU General Public License // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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/engine/engine.h"
#include "graphics/core/vertex.h" #include "graphics/core/vertex.h"

View File

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

View File

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

View File

@ -19,5 +19,161 @@
#include "graphics/engine/pyro.h" #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 // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once
#include "common/misc.h" #include "common/misc.h"
#include "graphics/engine/engine.h" #include "graphics/engine/engine.h"
//#include "object/object.h" #include "object/object.h"
// TEMPORARILY!
enum ObjectType {};
class CInstanceManager; class CInstanceManager;
@ -90,13 +91,14 @@ struct PyroLightOper
class CPyro { class CPyro
{
public: public:
CPyro(CInstanceManager* iMan); CPyro(CInstanceManager* iMan);
~CPyro(); ~CPyro();
void DeleteObject(bool bAll=false); void DeleteObject(bool all=false);
bool Create(PyroType type, CObject* pObj, float force=1.0f); bool Create(Gfx::PyroType type, CObject* pObj, float force=1.0f);
bool EventProcess(const Event &event); bool EventProcess(const Event &event);
Error IsEnded(); Error IsEnded();
void CutObjectLink(CObject* pObj); void CutObjectLink(CObject* pObj);
@ -104,7 +106,7 @@ public:
protected: protected:
void DisplayError(PyroType type, CObject* pObj); void DisplayError(PyroType type, CObject* pObj);
bool CreateLight(Math::Vector pos, float height); 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); void CreateTriangle(CObject* pObj, ObjectType oType, int part);
@ -127,21 +129,21 @@ protected:
void LightOperFrame(float rTime); void LightOperFrame(float rTime);
protected: protected:
CInstanceManager* m_iMan; CInstanceManager* m_iMan;
CEngine* m_engine; Gfx::CEngine* m_engine;
CTerrain* m_terrain; Gfx::CTerrain* m_terrain;
CCamera* m_camera; Gfx::CCamera* m_camera;
CParticle* m_particule; Gfx::CParticle* m_particule;
CLight* m_light; Gfx::CLightManager* m_lightMan;
CObject* m_object; CObject* m_object;
CDisplayText* m_displayText; CDisplayText* m_displayText;
CRobotMain* m_main; CRobotMain* m_main;
CSound* m_sound; CSound* m_sound;
Math::Vector m_pos; // center of the effect Math::Vector m_pos; // center of the effect
Math::Vector m_posPower; // center of the battery Math::Vector m_posPower; // center of the battery
bool m_bPower; // battery exists? bool m_power; // battery exists?
PyroType m_type; Gfx::PyroType m_type;
float m_force; float m_force;
float m_size; float m_size;
float m_progress; float m_progress;
@ -153,22 +155,22 @@ protected:
int m_lightRank; int m_lightRank;
int m_lightOperTotal; int m_lightOperTotal;
PyroLightOper m_lightOper[10]; Gfx::PyroLightOper m_lightOper[10];
float m_lightHeight; float m_lightHeight;
ObjectType m_burnType; ObjectType m_burnType;
int m_burnPartTotal; int m_burnPartTotal;
PyroBurnPart m_burnPart[10]; Gfx::PyroBurnPart m_burnPart[10];
int m_burnKeepPart[10]; int m_burnKeepPart[10];
float m_burnFall; float m_burnFall;
float m_fallFloor; float m_fallFloor;
float m_fallSpeed; float m_fallSpeed;
float m_fallBulletTime; float m_fallBulletTime;
bool m_bFallEnding; bool m_fallEnding;
int m_crashSphereUsed; // number of spheres used int m_crashSphereUsed; // number of spheres used
Math::Vector m_crashSpherePos[50]; Math::Vector m_crashSpherePos[50];
float m_crashSphereRadius[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 // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once
@ -40,56 +43,72 @@ enum TerrainRes
TR_STONE = 1, TR_STONE = 1,
TR_URANIUM = 2, TR_URANIUM = 2,
TR_POWER = 3, TR_POWER = 3,
TR_KEYa = 4, TR_KEY_A = 4,
TR_KEYb = 5, TR_KEY_B = 5,
TR_KEYc = 6, TR_KEY_C = 6,
TR_KEYd = 7, TR_KEY_D = 7,
}; };
const short MAXBUILDINGLEVEL = 100;
struct BuildingLevel struct BuildingLevel
{ {
Math::Vector center; Math::Vector center;
float factor; float factor;
float min; float min;
float max; float max;
float level; float level;
float height; float height;
float bboxMinX; float bboxMinX;
float bboxMaxX; float bboxMaxX;
float bboxMinZ; float bboxMinZ;
float bboxMaxZ; float bboxMaxZ;
BuildingLevel()
{
factor = min = max = level = height = 0.0f;
bboxMinX = bboxMaxX = bboxMinZ = bboxMaxZ = 0.0f;
}
}; };
const short MAXMATTERRAIN = 100;
struct TerrainMaterial struct TerrainMaterial
{ {
short id; short id;
char texName[20]; std::string texName;
float u,v; float u,v;
float hardness; float hardness;
char mat[4]; // up, right, down, left 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 struct DotLevel
{ {
short id; short id;
char mat[4]; // up, right, down, left 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 struct FlyingLimit
{ {
Math::Vector center; Math::Vector center;
float extRadius; float extRadius;
float intRadius; float intRadius;
float maxHeight; float maxHeight;
FlyingLimit()
{
extRadius = intRadius = maxHeight = 0.0f;
}
}; };
@ -100,72 +119,124 @@ public:
CTerrain(CInstanceManager* iMan); CTerrain(CInstanceManager* iMan);
~CTerrain(); ~CTerrain();
bool Generate(int mosaic, int brickP2, float size, float vision, int depth, float hardness); //! Generates a new flat terrain
bool InitTextures(char* baseName, int* table, int dx, int dy); 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(); 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); 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); bool LevelGenerate(int *id, float min, float max, float slope, float freq, Math::Vector center, float radius);
//! Initializes a completely flat terrain
void FlushRelief(); void FlushRelief();
bool ReliefFromBMP(const char* filename, float scaleRelief, bool adjustBorder); //! Load relief from a PNG file
bool ReliefFromDXF(const char* filename, float scaleRelief); bool ReliefFromPNG(const std::string& filename, float scaleRelief, bool adjustBorder);
bool ResFromBMP(const char* filename); //! Load resources from a PNG file
bool CreateObjects(bool bMultiRes); bool ResFromPNG(const std::string& filename);
bool Terraform(const Math::Vector &p1, const Math::Vector &p2, float height); //! 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); //! Gives the exact slope of the terrain of a place given
float RetCoarseSlope(const Math::Vector &pos); float GetFineSlope(const Math::Vector& pos);
bool GetNormal(Math::Vector &n, const Math::Vector &p); //! Gives the approximate slope of the terrain of a specific location
float RetFloorLevel(const Math::Vector &p, bool bBrut=false, bool bWater=false); float GetCoarseSlope(const Math::Vector& pos);
float RetFloorHeight(const Math::Vector &p, bool bBrut=false, bool bWater=false); //! Gives the normal vector at the position p (x,-,z) of the ground
bool MoveOnFloor(Math::Vector &p, bool bBrut=false, bool bWater=false); bool GetNormal(Math::Vector& n, const Math::Vector &p);
bool ValidPosition(Math::Vector &p, float marging); //! returns the height of the ground
TerrainRes RetResource(const Math::Vector &p); 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); void LimitPos(Math::Vector &pos);
//! Empty the table of elevations
void FlushBuildingLevel(); void FlushBuildingLevel();
//! Adds a new elevation for a building
bool AddBuildingLevel(Math::Vector center, float min, float max, float height, float factor); 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); bool UpdateBuildingLevel(Math::Vector center);
//! Removes the elevation for a building when it was destroyed
bool DeleteBuildingLevel(Math::Vector center); bool DeleteBuildingLevel(Math::Vector center);
float RetBuildingFactor(const Math::Vector &p); //! Returns the influence factor whether a position is on a possible rise
float RetHardness(const Math::Vector &p); float GetBuildingFactor(const Math::Vector& p);
float GetHardness(const Math::Vector& p);
int RetMosaic(); int GetMosaic();
int RetBrick(); int GetBrick();
float RetSize(); float GetSize();
float RetScaleRelief(); float GetScaleRelief();
//! Shows the flat areas on the ground
void GroundFlat(Math::Vector pos); 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); void SetFlyingMaxHeight(float height);
float RetFlyingMaxHeight(); float GetFlyingMaxHeight();
//@}
//! Empty the table of flying limits
void FlushFlyingLimit(); void FlushFlyingLimit();
bool AddFlyingLimit(Math::Vector center, float extRadius, float intRadius, float maxHeight); //! Adds a new flying limit
float RetFlyingLimit(Math::Vector pos, bool bNoLimit); 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: protected:
//! Adds a point of elevation in the buffer of relief
bool ReliefAddDot(Math::Vector pos, float scaleRelief); bool ReliefAddDot(Math::Vector pos, float scaleRelief);
//! Adjust the edges of each mosaic to be compatible with all lower resolutions
void AdjustRelief(); void AdjustRelief();
Math::Vector RetVector(int x, int y); //! Calculates a vector of the terrain
Gfx::VertexTex2 RetVertex(int x, int y, int step); Math::Vector GetVector(int x, int y);
bool CreateMosaic(int ox, int oy, int step, int objRank, const Gfx::Material &mat, float min, float max); //! Calculates a vertex of the terrain
bool CreateSquare(bool bMultiRes, int x, int y); 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); //! Seeks a materials based on theirs identifier
void LevelTextureName(int x, int y, char *name, Math::Point &uv); Gfx::TerrainMaterial* LevelSearchMat(int id);
float LevelRetHeight(int x, int y); //! 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); bool LevelGetDot(int x, int y, float min, float max, float slope);
//! Seeks if material exists
int LevelTestMat(char *mat); 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); 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); bool LevelIfDot(int x, int y, int id, char *mat);
//! Modifies the state of a point
bool LevelPutDot(int x, int y, int id); bool LevelPutDot(int x, int y, int id);
//! Initializes a table with empty levels
void LevelOpenTable(); void LevelOpenTable();
//! Closes the level table
void LevelCloseTable(); void LevelCloseTable();
//! Adjusts a position according to a possible rise
void AdjustBuildingLevel(Math::Vector &p); void AdjustBuildingLevel(Math::Vector &p);
protected: protected:
@ -173,39 +244,49 @@ protected:
CEngine* m_engine; CEngine* m_engine;
CWater* m_water; CWater* m_water;
int m_mosaic; // number of mosaics //! Number of mosaics
int m_brick; // number of bricks per mosaics int m_mosaic;
float m_size; // size of an item in an brick //! Number of bricks per mosaics
float m_vision; // vision before a change of resolution int m_brick;
float* m_relief; // table of the relief int m_levelDotSize;
int* m_texture; // table of textures //! Size of an item in a brick
int* m_objRank; // table of rows of objects float m_size;
bool m_bMultiText; //! Vision before a change of resolution
bool m_bLevelText; float m_vision;
float m_scaleMapping; // scale of the mapping //! 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; float m_scaleRelief;
int m_subdivMapping; int m_subdivMapping;
int m_depth; // number of different resolutions (1,2,3,4) //! Number of different resolutions (1,2,3,4)
char m_texBaseName[20]; int m_depth;
char m_texBaseExt[10]; std::string m_texBaseName;
std::string m_texBaseExt;
float m_defHardness; float m_defHardness;
TerrainMaterial m_levelMat[MAXMATTERRAIN+1]; std::vector<TerrainMaterial> m_levelMat;
int m_levelMatTotal; std::vector<Gfx::DotLevel> m_levelDot;
int m_levelMatMax; int m_levelMatMax;
int m_levelDotSize;
DotLevel* m_levelDot;
int m_levelID; int m_levelID;
int m_buildingUsed; std::vector<Gfx::BuildingLevel> m_buildingLevels;
BuildingLevel m_buildingTable[MAXBUILDINGLEVEL];
unsigned char* m_resources; //! Wind speed
Math::Vector m_wind; // wind speed Math::Vector m_wind;
//! Global flying height limit
float m_flyingMaxHeight; float m_flyingMaxHeight;
int m_flyingLimitTotal; //! List of local flight limits
FlyingLimit m_flyingLimit[MAXFLYINGLIMIT]; std::vector<Gfx::FlyingLimit> m_flyingLimits;
}; };
}; // namespace Gfx }; // namespace Gfx

View File

@ -19,5 +19,784 @@
#include "graphics/engine/text.h" #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 // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once
#include "graphics/engine/engine.h"
#include "graphics/core/device.h"
#include "math/point.h" #include "math/point.h"
#include <vector>
#include <map>
class CInstanceManager; class CInstanceManager;
namespace Gfx { namespace Gfx {
const float SMALLFONT = 10.0f; class CEngine;
const float BIGFONT = 15.0f; 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 enum FontType
{ {
FONT_COLOBOT = 0, //! Flag for bold font subtype
FONT_COURIER = 1, FONT_BOLD = 0x04,
FONT_BUTTON = 2, //! 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 enum FontTitle
{ {
TITLE_BIG = 0x04, FONT_TITLE_BIG = 0x01 << 4,
TITLE_NORM = 0x08, FONT_TITLE_NORM = 0x02 << 4,
TITLE_LITTLE = 0x0c, 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, FONT_HIGHLIGHT_NONE = 0x00 << 6,
COLOR_TOKEN = 0x20, FONT_HIGHLIGHT_LINK = 0x01 << 6,
COLOR_TYPE = 0x30, FONT_HIGHLIGHT_TOKEN = 0x02 << 6,
COLOR_CONST = 0x40, FONT_HIGHLIGHT_TYPE = 0x03 << 6,
COLOR_REM = 0x50, FONT_HIGHLIGHT_CONST = 0x04 << 6,
COLOR_KEY = 0x60, FONT_HIGHLIGHT_REM = 0x05 << 6,
COLOR_TABLE = 0x70, FONT_HIGHLIGHT_KEY = 0x06 << 6,
FONT_HIGHLIGHT_TABLE = 0x07 << 6,
}; };
const short FONT_MASK = 0x03; /**
const short TITLE_MASK = 0x0c; \enum FontMask
const short COLOR_MASK = 0x70; \brief Masks in FontMetaChar for different attributes */
const short IMAGE_MASK = 0x80; 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: public:
CText(CInstanceManager *iMan, Gfx::CEngine* engine); CText(CInstanceManager *iMan, Gfx::CEngine* engine);
~CText(); ~CText();
//! Sets the device to be used
void SetDevice(Gfx::CDevice *device); 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); //! Returns the last encountered error
void DrawText(char *string, char *format, Math::Point pos, float width, int justif, float size, float stretch, int eol); std::string GetError();
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);
float RetAscent(float size, FontType font); //! Initializes the font engine; must be called after SetDevice()
float RetDescent(float size, FontType font); bool Create();
float RetHeight(float size, FontType font); //! Frees resources before exit
void Destroy();
float RetStringWidth(char *string, char *format, int len, float size, float stretch); //! Flushes cached textures
float RetStringWidth(char *string, int len, float size, float stretch, FontType font); void FlushCache();
float RetCharWidth(int character, float offset, float size, float stretch, FontType font);
int Justif(char *string, char *format, int len, float width, float size, float stretch); //! Draws text (multi-format)
int Justif(char *string, int len, float width, float size, float stretch, FontType font); void DrawText(const std::string &text, const std::vector<Gfx::FontMetaChar> &format,
int Detect(char *string, char *format, int len, float offset, float size, float stretch); float size, Math::Point pos, float width, Gfx::TextAlign align,
int Detect(char *string, int len, float offset, float size, float stretch, FontType font); 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: protected:
void DrawString(char *string, char *format, int len, Math::Point pos, float width, float size, float stretch, int eol); Gfx::CachedFont* GetOrOpenFont(Gfx::FontType type, float size);
void DrawString(char *string, int len, Math::Point pos, float width, float size, float stretch, FontType font, int eol); Gfx::CharTexture CreateCharTexture(Gfx::UTF8Char ch, Gfx::CachedFont* font);
void DrawColor(Math::Point pos, float size, float width, int color);
void DrawChar(int character, Math::Point pos, float size, float stretch, FontType 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: protected:
CInstanceManager* m_iMan; CInstanceManager* m_iMan;
Gfx::CEngine* m_engine; Gfx::CEngine* m_engine;
Gfx::CDevice* m_device; 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 }; // namespace Gfx

View File

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

View File

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

View File

@ -64,7 +64,6 @@ void Gfx::GLDeviceConfig::LoadDefault()
Gfx::CGLDevice::CGLDevice(const Gfx::GLDeviceConfig &config) Gfx::CGLDevice::CGLDevice(const Gfx::GLDeviceConfig &config)
{ {
m_config = config; m_config = config;
m_wasInit = false;
m_lighting = false; m_lighting = false;
m_texturing = 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() 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 /* 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. */ 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 // This is mostly done in all modern hardware by default
// DirectX doesn't even allow the option to turn off perspective correction anymore // DirectX doesn't even allow the option to turn off perspective correction anymore
// So turn it on permanently // So turn it on permanently
@ -130,7 +129,7 @@ bool Gfx::CGLDevice::Create()
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); 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()); m_lights = std::vector<Gfx::Light>(GL_MAX_LIGHTS, Gfx::Light());
@ -158,8 +157,6 @@ void Gfx::CGLDevice::Destroy()
m_currentTextures.clear(); m_currentTextures.clear();
m_texturesEnabled.clear(); m_texturesEnabled.clear();
m_textureStageParams.clear(); m_textureStageParams.clear();
m_wasInit = false;
} }
void Gfx::CGLDevice::ConfigChanged(const Gfx::GLDeviceConfig& newConfig) 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() */ 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 Gfx::CGLDevice::CreateTexture(CImage *image, const Gfx::TextureCreateParams &params)
{ {
Gfx::Texture result;
ImageData *data = image->GetData(); ImageData *data = image->GetData();
if (data == NULL) if (data == NULL)
{ {
m_error = "Invalid texture data"; 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.valid = true;
result.size.w = data->surface->w; result.size.x = data->surface->w;
result.size.h = data->surface->h; result.size.y = data->surface->h;
// Use & enable 1st texture stage // Use & enable 1st texture stage
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
@ -531,6 +533,24 @@ void Gfx::CGLDevice::SetTexture(int index, const Gfx::Texture &texture)
glDisable(GL_TEXTURE_2D); 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. */ Returns the previously assigned texture or invalid texture if the given stage is not enabled. */
Gfx::Texture Gfx::CGLDevice::GetTexture(int index) 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) void Gfx::CGLDevice::SetCullMode(Gfx::CullMode mode)
{ {
if (mode == Gfx::CULL_CW) glCullFace(GL_CW); // Cull clockwise back faces, so front face is the opposite
else if (mode == Gfx::CULL_CCW) glCullFace(GL_CCW); // (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); else assert(false);
} }
Gfx::CullMode Gfx::CGLDevice::GetCullMode() Gfx::CullMode Gfx::CGLDevice::GetCullMode()
{ {
GLint flag = 0; GLint flag = 0;
glGetIntegerv(GL_CULL_FACE, &flag); glGetIntegerv(GL_FRONT_FACE, &flag);
if (flag == GL_CW) return Gfx::CULL_CW; if (flag == GL_CW) return Gfx::CULL_CCW;
else if (flag == GL_CCW) return Gfx::CULL_CCW; else if (flag == GL_CCW) return Gfx::CULL_CW;
else assert(false); else assert(false);
return Gfx::CULL_CW; return Gfx::CULL_CW;
} }

View File

@ -14,7 +14,10 @@
// * You should have received a copy of the GNU General Public License // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once
@ -73,7 +76,8 @@ public:
CGLDevice(const Gfx::GLDeviceConfig &config); CGLDevice(const Gfx::GLDeviceConfig &config);
virtual ~CGLDevice(); virtual ~CGLDevice();
virtual bool GetWasInit(); virtual void DebugHook();
virtual std::string GetError(); virtual std::string GetError();
virtual bool Create(); virtual bool Create();
@ -100,11 +104,13 @@ public:
virtual bool GetLightEnabled(int index); virtual bool GetLightEnabled(int index);
virtual Gfx::Texture CreateTexture(CImage *image, const Gfx::TextureCreateParams &params); 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 DestroyTexture(const Gfx::Texture &texture);
virtual void DestroyAllTextures(); virtual void DestroyAllTextures();
virtual int GetMaxTextureCount(); virtual int GetMaxTextureCount();
virtual void SetTexture(int index, const Gfx::Texture &texture); virtual void SetTexture(int index, const Gfx::Texture &texture);
virtual void SetTexture(int index, unsigned int textureId);
virtual Gfx::Texture GetTexture(int index); virtual Gfx::Texture GetTexture(int index);
virtual void SetTextureEnabled(int index, bool enabled); virtual void SetTextureEnabled(int index, bool enabled);
virtual bool GetTextureEnabled(int index); virtual bool GetTextureEnabled(int index);
@ -163,8 +169,6 @@ private:
private: private:
//! Current config //! Current config
Gfx::GLDeviceConfig m_config; Gfx::GLDeviceConfig m_config;
//! Was initialized?
bool m_wasInit;
//! Last encountered error //! Last encountered error
std::string m_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 // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once
/* @{ */ // start of group
#include "const.h" #include "const.h"
#include "func.h" #include "func.h"
#include "point.h" #include "point.h"
@ -30,5 +29,3 @@
#include "geometry.h" #include "geometry.h"
#include "conv.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 // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once
#include <cmath>
// Math module namespace // Math module namespace
namespace Math namespace Math
{ {
/* @{ */ // start of group
//! Tolerance level -- minimum accepted float value //! Tolerance level -- minimum accepted float value
const float TOLERANCE = 1e-6f; const float TOLERANCE = 1e-6f;
//! Very small number (used in testing/returning some values) //! 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) //! Very big number (used in testing/returning some values)
const float VERY_BIG = 1e6f; const float VERY_BIG_NUM = 1e6f;
//! Huge number //! Huge number
const float HUGE = 1.0e+38f; const float HUGE_NUM = 1.0e+38f;
//! PI //! PI
const float PI = 3.14159265358979323846f; const float PI = 3.14159265358979323846f;
@ -45,6 +47,8 @@ const float DEG_TO_RAD = 0.01745329251994329547f;
//! Radians to degrees multiplier //! Radians to degrees multiplier
const float RAD_TO_DEG = 57.29577951308232286465f; const float RAD_TO_DEG = 57.29577951308232286465f;
/* @} */ // end of group //! Natural logarithm of 2
const float LOG_2 = log(2.0f);
}; // namespace Math }; // namespace Math

View File

@ -15,8 +15,9 @@
// * You should have received a copy of the GNU General Public License // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once
@ -31,8 +32,6 @@
namespace Math namespace Math
{ {
/* @{ */ // start of group
//! Compares \a a and \a b within \a tolerance //! Compares \a a and \a b within \a tolerance
inline bool IsEqual(float a, float b, float tolerance = Math::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); 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 //! Returns a normalized angle, that is in other words between 0 and 2 * PI
inline float NormAngle(float angle) inline float NormAngle(float angle)
{ {
@ -180,11 +187,13 @@ inline float Direction(float a, float g)
//! Managing the dead zone of a joystick. //! Managing the dead zone of a joystick.
/** /**
\verbatimin: -1 0 1 \verbatim
in: -1 0 1
--|-------|----o----|-------|--> --|-------|----o----|-------|-->
<----> <---->
dead dead
out: -1 0 0 1\endverbatim */ out: -1 0 0 1
\endverbatim */
inline float Neutral(float value, float dead) inline float Neutral(float value, float dead)
{ {
if ( fabs(value) <= dead ) if ( fabs(value) <= dead )
@ -218,7 +227,8 @@ inline float Smooth(float actual, float hope, float time)
//! Bounces any movement //! Bounces any movement
/** /**
\verbatimout \verbatim
out
| |
1+------o-------o--- 1+------o-------o---
| o | o o | | bounce | o | o o | | bounce
@ -227,7 +237,8 @@ inline float Smooth(float actual, float hope, float time)
| o | | | o | |
-o------|-------+----> progress -o------|-------+----> progress
0| | 1 0| | 1
|<---->|middle\endverbatim */ |<---->|middle
\endverbatim */
inline float Bounce(float progress, float middle = 0.3f, float bounce = 0.4f) inline float Bounce(float progress, float middle = 0.3f, float bounce = 0.4f)
{ {
if ( progress < middle ) 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 }; // namespace Math

View File

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

View File

@ -14,31 +14,29 @@
// * You should have received a copy of the GNU General Public License // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once
namespace Math { 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. * Analog of WinAPI's POINT struct.
*/ */
struct IntPoint struct IntPoint
{ {
//! X coord //! X coord
long x; int x;
//! Y coord //! 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 }; // 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 // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once
@ -32,8 +33,6 @@
namespace Math namespace Math
{ {
/* @{ */ // start of group
/** \struct Matrix math/matrix.h /** \struct Matrix math/matrix.h
\brief 4x4 matrix \brief 4x4 matrix
@ -42,11 +41,12 @@ namespace Math
The internal representation is a 16-value table in column-major order, thus: The internal representation is a 16-value table in column-major order, thus:
\verbatim \verbatim
m[0 ] m[4 ] m[8 ] m[12] m[0 ] m[4 ] m[8 ] m[12]
m[1 ] m[5 ] m[9 ] m[13] m[1 ] m[5 ] m[9 ] m[13]
m[2 ] m[6 ] m[10] m[14] 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. 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 //! 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[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[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 The result, a 4x1 vector is then converted to 3x1 by dividing
x,y,z coords by the fourth coord (w). */ 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); return Math::Vector(x, y, z);
} }
/* @} */ // end of group
}; // namespace Math }; // namespace Math

View File

@ -14,8 +14,9 @@
// * You should have received a copy of the GNU General Public License // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once
@ -31,8 +32,6 @@
namespace Math namespace Math
{ {
/* @{ */ // start of group
/** \struct Point math/point.h /** \struct Point math/point.h
\brief 2D point \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)); return sqrtf((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
} }
/* @} */ // end of group
}; // namespace Math }; // 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 // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #pragma once
@ -31,8 +32,6 @@
namespace Math namespace Math
{ {
/* @{ */ // start of group
/** \struct Vector math/vector.h /** \struct Vector math/vector.h
\brief 3D (3x1) vector \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) ); (a.z-b.z)*(a.z-b.z) );
} }
/* @} */ // end of group
}; // namespace Math }; // namespace Math

View File

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

View File

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

View File

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

View File

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