Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F628970
ThemeManager.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
Unknown
Size
21 KB
Referenced Files
None
Subscribers
None
ThemeManager.cpp
View Options
/****************************************************************************
** Copyright (C) 2011 Luka Horvat <redreaper132 at gmail.com>
** Copyright (C) 2011 Edward Lii <edward_iii at myway.com>
** Copyright (C) 2011 O. Bahri Gordebak <gordebak at gmail.com>
**
**
** This file may be used under the terms of the GNU General Public
** License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of
** this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**
****************************************************************************/
#include
"ThemeManager.h"
#include
"POASerializer.h"
#include
"Functions.h"
#include
"FileManager.h"
#include
"Game.h"
#include
<string.h>
#include
<iostream>
using
namespace
std
;
//The ThemeStack that is be used by the GameState.
ThemeStack
objThemes
;
bool
ThemeManager::loadFile
(
const
string
&
fileName
){
POASerializer
objSerializer
;
TreeStorageNode
objNode
;
//First we destroy the current ThemeManager.
destroy
();
//Now we try to load the file, if it fails we return false.
if
(
!
objSerializer
.
loadNodeFromFile
(
fileName
.
c_str
(),
&
objNode
,
true
))
return
false
;
//Set the themePath.
themePath
=
pathFromFileName
(
fileName
);
//Retrieve the name of the theme from the file.
{
vector
<
string
>
&
v
=
objNode
.
attributes
[
"name"
];
if
(
v
.
size
()
>
0
)
themeName
=
v
[
0
];
}
//Loop the subnodes of the theme.
for
(
unsigned
int
i
=
0
;
i
<
objNode
.
subNodes
.
size
();
i
++
){
TreeStorageNode
*
obj
=
objNode
.
subNodes
[
i
];
//Check if it's a block or a background.
if
(
obj
->
name
==
"block"
&&
obj
->
value
.
size
()
>
0
){
map
<
string
,
int
>::
iterator
it
=
Game
::
blockNameMap
.
find
(
obj
->
value
[
0
]);
if
(
it
!=
Game
::
blockNameMap
.
end
()){
int
idx
=
it
->
second
;
if
(
!
objBlocks
[
idx
])
objBlocks
[
idx
]
=
new
ThemeBlock
;
if
(
!
objBlocks
[
idx
]
->
loadFromNode
(
obj
,
themePath
)){
delete
objBlocks
[
idx
];
objBlocks
[
idx
]
=
NULL
;
return
false
;
}
}
}
else
if
(
obj
->
name
==
"background"
&&
obj
->
value
.
size
()
>
0
){
if
(
!
objBackground
)
objBackground
=
new
ThemeBackground
();
if
(
!
objBackground
->
addPictureFromNode
(
obj
,
themePath
)){
delete
objBackground
;
objBackground
=
NULL
;
return
false
;
}
}
else
if
(
obj
->
name
==
"character"
&&
obj
->
value
.
size
()
>
0
){
if
(
obj
->
value
[
0
]
==
"Shadow"
){
if
(
!
shadow
)
shadow
=
new
ThemeCharacter
();
if
(
!
shadow
->
loadFromNode
(
obj
,
themePath
)){
delete
shadow
;
shadow
=
NULL
;
return
false
;
}
}
else
if
(
obj
->
value
[
0
]
==
"Player"
){
if
(
!
player
)
player
=
new
ThemeCharacter
();
if
(
!
player
->
loadFromNode
(
obj
,
themePath
)){
delete
player
;
player
=
NULL
;
return
false
;
}
}
}
}
//Done and nothing went wrong so return true.
return
true
;
}
bool
ThemeBlock::loadFromNode
(
TreeStorageNode
*
objNode
,
string
themePath
){
destroy
();
//Loop the subNodes.
for
(
unsigned
int
i
=
0
;
i
<
objNode
->
subNodes
.
size
();
i
++
){
TreeStorageNode
*
obj
=
objNode
->
subNodes
[
i
];
//Check if the subnode is an editorPicture or a blockState.
if
(
obj
->
name
==
"editorPicture"
){
if
(
!
editorPicture
.
loadFromNode
(
obj
,
themePath
))
return
false
;
}
else
if
(
obj
->
name
==
"blockState"
&&
obj
->
value
.
size
()
>
0
){
string
&
s
=
obj
->
value
[
0
];
map
<
string
,
ThemeBlockState
*>::
iterator
it
=
blockStates
.
find
(
s
);
if
(
it
==
blockStates
.
end
())
blockStates
[
s
]
=
new
ThemeBlockState
;
if
(
!
blockStates
[
s
]
->
loadFromNode
(
obj
,
themePath
))
return
false
;
}
}
//Done and nothing went wrong so return true.
return
true
;
}
bool
ThemeBlockState::loadFromNode
(
TreeStorageNode
*
objNode
,
string
themePath
){
destroy
();
//Retrieve the oneTimeAnimation attribute.
{
vector
<
string
>
&
v
=
objNode
->
attributes
[
"oneTimeAnimation"
];
//Check if there are enough values for the oneTimeAnimation attribute.
if
(
v
.
size
()
>=
2
&&
!
v
[
0
].
empty
()){
oneTimeAnimationLength
=
atoi
(
v
[
0
].
c_str
());
nextState
=
v
[
1
];
}
}
//Loop the subNodes.
for
(
unsigned
int
i
=
0
;
i
<
objNode
->
subNodes
.
size
();
i
++
){
TreeStorageNode
*
obj
=
objNode
->
subNodes
[
i
];
if
(
obj
->
name
==
"object"
){
ThemeObject
*
obj1
=
new
ThemeObject
();
if
(
!
obj1
->
loadFromNode
(
obj
,
themePath
)){
delete
obj1
;
return
false
;
}
themeObjects
.
push_back
(
obj1
);
}
}
//Done and nothing went wrong so return true.
return
true
;
}
bool
ThemeCharacter::loadFromNode
(
TreeStorageNode
*
objNode
,
string
themePath
){
destroy
();
//Loop the subNodes.
for
(
unsigned
int
i
=
0
;
i
<
objNode
->
subNodes
.
size
();
i
++
){
TreeStorageNode
*
obj
=
objNode
->
subNodes
[
i
];
//Check if the subnode is an characterState.
if
(
obj
->
name
==
"characterState"
&&
obj
->
value
.
size
()
>
0
){
string
&
s
=
obj
->
value
[
0
];
map
<
string
,
ThemeCharacterState
*>::
iterator
it
=
characterStates
.
find
(
s
);
if
(
it
==
characterStates
.
end
())
characterStates
[
s
]
=
new
ThemeCharacterState
;
if
(
!
characterStates
[
s
]
->
loadFromNode
(
obj
,
themePath
))
return
false
;
}
}
//Done and nothing went wrong so return true.
return
true
;
}
bool
ThemeCharacterState::loadFromNode
(
TreeStorageNode
*
objNode
,
string
themePath
){
destroy
();
//Retrieve the oneTimeAnimation attribute.
{
vector
<
string
>
&
v
=
objNode
->
attributes
[
"oneTimeAnimation"
];
//Check if there are enough values for the oneTimeAnimation attribute.
if
(
v
.
size
()
>=
2
&&
!
v
[
0
].
empty
()){
oneTimeAnimationLength
=
atoi
(
v
[
0
].
c_str
());
nextState
=
v
[
1
];
}
}
//Loop the subNodes.
for
(
unsigned
int
i
=
0
;
i
<
objNode
->
subNodes
.
size
();
i
++
){
TreeStorageNode
*
obj
=
objNode
->
subNodes
[
i
];
if
(
obj
->
name
==
"object"
){
ThemeObject
*
obj1
=
new
ThemeObject
();
if
(
!
obj1
->
loadFromNode
(
obj
,
themePath
)){
delete
obj1
;
return
false
;
}
themeObjects
.
push_back
(
obj1
);
}
}
//Done and nothing went wrong so return true.
return
true
;
}
bool
ThemeObject::loadFromNode
(
TreeStorageNode
*
objNode
,
string
themePath
){
destroy
();
//Retrieve the animation attribute.
{
vector
<
string
>
&
v
=
objNode
->
attributes
[
"animation"
];
if
(
v
.
size
()
>=
2
){
animationLength
=
atoi
(
v
[
0
].
c_str
());
animationLoopPoint
=
atoi
(
v
[
1
].
c_str
());
}
}
//Retrieve the oneTimeAnimation attribute.
{
vector
<
string
>
&
v
=
objNode
->
attributes
[
"oneTimeAnimation"
];
if
(
v
.
size
()
>=
2
){
animationLength
=
atoi
(
v
[
0
].
c_str
());
animationLoopPoint
=
atoi
(
v
[
1
].
c_str
())
|
0x80000000
;
}
}
//Retrieve the invisibleAtRunTime attribute.
{
vector
<
string
>
&
v
=
objNode
->
attributes
[
"invisibleAtRunTime"
];
if
(
v
.
size
()
>
0
&&
!
v
[
0
].
empty
()){
invisibleAtRunTime
=
atoi
(
v
[
0
].
c_str
())
?
true
:
false
;
}
}
//Retrieve the invisibleAtDesignTime attribute.
{
vector
<
string
>
&
v
=
objNode
->
attributes
[
"invisibleAtDesignTime"
];
if
(
v
.
size
()
>
0
&&
!
v
[
0
].
empty
()){
invisibleAtDesignTime
=
atoi
(
v
[
0
].
c_str
())
?
true
:
false
;
}
}
//Loop the subnodes.
for
(
unsigned
int
i
=
0
;
i
<
objNode
->
subNodes
.
size
();
i
++
){
TreeStorageNode
*
obj
=
objNode
->
subNodes
[
i
];
if
(
obj
->
name
==
"picture"
||
obj
->
name
==
"pictureAnimation"
){
if
(
!
picture
.
loadFromNode
(
obj
,
themePath
)){
return
false
;
}
}
else
if
(
obj
->
name
==
"editorPicture"
){
if
(
!
editorPicture
.
loadFromNode
(
obj
,
themePath
)){
return
false
;
}
}
else
if
(
obj
->
name
==
"optionalPicture"
&&
obj
->
value
.
size
()
>=
6
){
ThemePicture
*
objPic
=
new
ThemePicture
();
double
f
=
atof
(
obj
->
value
[
5
].
c_str
());
if
(
!
objPic
->
loadFromNode
(
obj
,
themePath
)){
delete
objPic
;
return
false
;
}
optionalPicture
.
push_back
(
pair
<
double
,
ThemePicture
*>
(
f
,
objPic
));
}
else
if
(
obj
->
name
==
"offset"
||
obj
->
name
==
"offsetAnimation"
){
if
(
!
offset
.
loadFromNode
(
obj
))
return
false
;
}
}
//Done and nothing went wrong so return true.
return
true
;
}
bool
ThemePicture::loadFromNode
(
TreeStorageNode
*
objNode
,
string
themePath
){
destroy
();
//Check if the node has enough values.
if
(
objNode
->
value
.
size
()
>
0
){
//Load teh picture.
picture
=
loadImage
(
themePath
+
objNode
->
value
[
0
]);
if
(
picture
==
NULL
)
return
false
;
//Check if it's an animation.
if
(
objNode
->
name
==
"pictureAnimation"
){
if
(
!
offset
.
loadFromNode
(
objNode
))
return
false
;
return
true
;
}
else
if
(
objNode
->
value
.
size
()
>=
5
){
typeOffsetPoint
r
=
{
atoi
(
objNode
->
value
[
1
].
c_str
()),
atoi
(
objNode
->
value
[
2
].
c_str
()),
atoi
(
objNode
->
value
[
3
].
c_str
()),
atoi
(
objNode
->
value
[
4
].
c_str
()),
0
,
0
};
offset
.
offsetData
.
push_back
(
r
);
offset
.
length
=
0
;
return
true
;
}
}
//Done and nothing went wrong so return true.
return
false
;
}
bool
ThemeOffsetData::loadFromNode
(
TreeStorageNode
*
objNode
){
destroy
();
//Check what kind of offset it is.
if
(
objNode
->
name
==
"pictureAnimation"
){
for
(
unsigned
int
i
=
0
;
i
<
objNode
->
subNodes
.
size
();
i
++
){
TreeStorageNode
*
obj
=
objNode
->
subNodes
[
i
];
if
(
obj
->
name
==
"point"
&&
obj
->
value
.
size
()
>=
4
){
typeOffsetPoint
r
=
{
atoi
(
obj
->
value
[
0
].
c_str
()),
atoi
(
obj
->
value
[
1
].
c_str
()),
atoi
(
obj
->
value
[
2
].
c_str
()),
atoi
(
obj
->
value
[
3
].
c_str
()),
1
,
1
};
if
(
obj
->
value
.
size
()
>=
5
)
r
.
frameCount
=
atoi
(
obj
->
value
[
4
].
c_str
());
if
(
obj
->
value
.
size
()
>=
6
)
r
.
frameDisplayTime
=
atoi
(
obj
->
value
[
5
].
c_str
());
offsetData
.
push_back
(
r
);
length
+=
r
.
frameCount
*
r
.
frameDisplayTime
;
}
}
return
true
;
}
else
if
(
objNode
->
name
==
"offsetAnimation"
){
for
(
unsigned
int
i
=
0
;
i
<
objNode
->
subNodes
.
size
();
i
++
){
TreeStorageNode
*
obj
=
objNode
->
subNodes
[
i
];
if
(
obj
->
name
==
"point"
&&
obj
->
value
.
size
()
>=
2
){
typeOffsetPoint
r
=
{
atoi
(
obj
->
value
[
0
].
c_str
()),
atoi
(
obj
->
value
[
1
].
c_str
()),
0
,
0
,
1
,
1
};
if
(
obj
->
value
.
size
()
>=
3
)
r
.
frameCount
=
atoi
(
obj
->
value
[
2
].
c_str
());
if
(
obj
->
value
.
size
()
>=
4
)
r
.
frameDisplayTime
=
atoi
(
obj
->
value
[
3
].
c_str
());
offsetData
.
push_back
(
r
);
length
+=
r
.
frameCount
*
r
.
frameDisplayTime
;
}
}
return
true
;
}
else
if
(
objNode
->
name
==
"offset"
&&
objNode
->
value
.
size
()
>=
2
){
typeOffsetPoint
r
=
{
atoi
(
objNode
->
value
[
0
].
c_str
()),
atoi
(
objNode
->
value
[
1
].
c_str
()),
0
,
0
,
0
,
0
};
offsetData
.
push_back
(
r
);
length
=
0
;
return
true
;
}
//Done and nothing went wrong so return true.
return
false
;
}
void
ThemeObjectInstance::draw
(
SDL_Surface
*
dest
,
int
x
,
int
y
,
SDL_Rect
*
clipRect
){
//Get the picture.
SDL_Surface
*
src
=
picture
->
picture
;
if
(
src
==
NULL
)
return
;
int
ex
=
0
,
ey
=
0
,
xx
=
0
,
yy
=
0
,
ww
=
0
,
hh
=
0
;
int
animationNew
=
animation
&
0x7FFFFFFF
;
{
vector
<
typeOffsetPoint
>
&
v
=
picture
->
offset
.
offsetData
;
if
(
picture
->
offset
.
length
==
0
||
animationNew
<
v
[
0
].
frameDisplayTime
){
xx
=
v
[
0
].
x
;
yy
=
v
[
0
].
y
;
ww
=
v
[
0
].
w
;
hh
=
v
[
0
].
h
;
}
else
if
(
animationNew
>=
picture
->
offset
.
length
){
int
i
=
v
.
size
()
-1
;
xx
=
v
[
i
].
x
;
yy
=
v
[
i
].
y
;
ww
=
v
[
i
].
w
;
hh
=
v
[
i
].
h
;
}
else
{
int
t
=
animationNew
-
v
[
0
].
frameDisplayTime
;
for
(
unsigned
int
i
=
1
;
i
<
v
.
size
();
i
++
){
int
tt
=
t
/
v
[
i
].
frameDisplayTime
;
if
(
tt
>=
0
&&
tt
<
v
[
i
].
frameCount
){
xx
=
(
int
)((
float
)
v
[
i
-1
].
x
+
(
float
)(
v
[
i
].
x
-
v
[
i
-1
].
x
)
*
(
float
)(
tt
+
1
)
/
(
float
)
v
[
i
].
frameCount
+
0.5f
);
yy
=
(
int
)((
float
)
v
[
i
-1
].
y
+
(
float
)(
v
[
i
].
y
-
v
[
i
-1
].
y
)
*
(
float
)(
tt
+
1
)
/
(
float
)
v
[
i
].
frameCount
+
0.5f
);
ww
=
(
int
)((
float
)
v
[
i
-1
].
w
+
(
float
)(
v
[
i
].
w
-
v
[
i
-1
].
w
)
*
(
float
)(
tt
+
1
)
/
(
float
)
v
[
i
].
frameCount
+
0.5f
);
hh
=
(
int
)((
float
)
v
[
i
-1
].
h
+
(
float
)(
v
[
i
].
h
-
v
[
i
-1
].
h
)
*
(
float
)(
tt
+
1
)
/
(
float
)
v
[
i
].
frameCount
+
0.5f
);
break
;
}
else
{
t
-=
v
[
i
].
frameCount
*
v
[
i
].
frameDisplayTime
;
}
}
}
}
//Get the offset.
{
vector
<
typeOffsetPoint
>
&
v
=
parent
->
offset
.
offsetData
;
if
(
v
.
empty
()){
ex
=
0
;
ey
=
0
;
}
else
if
(
parent
->
offset
.
length
==
0
||
animationNew
<
v
[
0
].
frameDisplayTime
){
ex
=
v
[
0
].
x
;
ey
=
v
[
0
].
y
;
}
else
if
(
animationNew
>=
parent
->
offset
.
length
){
int
i
=
v
.
size
()
-1
;
ex
=
v
[
i
].
x
;
ey
=
v
[
i
].
y
;
}
else
{
int
t
=
animationNew
-
v
[
0
].
frameDisplayTime
;
for
(
unsigned
int
i
=
1
;
i
<
v
.
size
();
i
++
){
int
tt
=
t
/
v
[
i
].
frameDisplayTime
;
if
(
tt
>=
0
&&
tt
<
v
[
i
].
frameCount
){
ex
=
(
int
)((
float
)
v
[
i
-1
].
x
+
(
float
)(
v
[
i
].
x
-
v
[
i
-1
].
x
)
*
(
float
)(
tt
+
1
)
/
(
float
)
v
[
i
].
frameCount
+
0.5f
);
ey
=
(
int
)((
float
)
v
[
i
-1
].
y
+
(
float
)(
v
[
i
].
y
-
v
[
i
-1
].
y
)
*
(
float
)(
tt
+
1
)
/
(
float
)
v
[
i
].
frameCount
+
0.5f
);
break
;
}
else
{
t
-=
v
[
i
].
frameCount
*
v
[
i
].
frameDisplayTime
;
}
}
}
}
//And finally draw the ThemeObjectInstance.
if
(
clipRect
){
int
d
;
d
=
clipRect
->
x
-
ex
;
if
(
d
>
0
){
ex
+=
d
;
xx
+=
d
;
ww
-=
d
;
}
d
=
clipRect
->
y
-
ey
;
if
(
d
>
0
){
ey
+=
d
;
yy
+=
d
;
hh
-=
d
;
}
if
(
ww
>
clipRect
->
w
)
ww
=
clipRect
->
w
;
if
(
hh
>
clipRect
->
h
)
hh
=
clipRect
->
h
;
}
if
(
ww
>
0
&&
hh
>
0
){
SDL_Rect
r1
=
{
xx
,
yy
,
ww
,
hh
};
SDL_Rect
r2
=
{
x
+
ex
,
y
+
ey
,
0
,
0
};
SDL_BlitSurface
(
src
,
&
r1
,
dest
,
&
r2
);
}
}
void
ThemeObjectInstance::updateAnimation
(){
//First get the animation length.
int
m
;
m
=
parent
->
animationLength
;
//If it's higher than 0 then we have an animation.
if
(
m
>
0
&&
animation
>=
0
){
//Increase the animation frame.
animation
++
;
//Check if the animation is beyond the length, if so set it to the looppoint.
if
(
animation
>=
m
)
animation
=
parent
->
animationLoopPoint
;
}
}
void
ThemeBlockInstance::updateAnimation
(){
//Make sure the currentState isn't null.
if
(
currentState
!=
NULL
){
//Call the updateAnimation method of the currentState.
currentState
->
updateAnimation
();
//Get the length of the animation.
int
m
=
currentState
->
parent
->
oneTimeAnimationLength
;
//If it's higher than 0 then we have an animation.
//Also check if it's past the lenght, meaning done.
if
(
m
>
0
&&
currentState
->
animation
>=
m
){
//Now we can change the state to the nextState.
changeState
(
currentState
->
parent
->
nextState
);
}
}
}
void
ThemeCharacterInstance::updateAnimation
(){
//Make sure the currentState isn't null.
if
(
currentState
!=
NULL
){
//Call the updateAnimation method of the currentState.
currentState
->
updateAnimation
();
//Get the length of the animation.
int
m
=
currentState
->
parent
->
oneTimeAnimationLength
;
//If it's higher than 0 then we have an animation.
//Also check if it's past the lenght, meaning done.
if
(
m
>
0
&&
currentState
->
animation
>=
m
){
//Now we can change the state to the nextState.
changeState
(
currentState
->
parent
->
nextState
);
}
}
}
void
ThemeBlock::createInstance
(
ThemeBlockInstance
*
obj
){
//Make sure the given ThemeBlockInstance is ready.
obj
->
blockStates
.
clear
();
obj
->
currentState
=
NULL
;
//Loop through the blockstates.
for
(
map
<
string
,
ThemeBlockState
*>::
iterator
it
=
blockStates
.
begin
();
it
!=
blockStates
.
end
();
it
++
){
//Get the themeBlockStateInstance of the given ThemeBlockInstance.
ThemeBlockStateInstance
&
obj1
=
obj
->
blockStates
[
it
->
first
];
//Set the parent of the state instance.
obj1
.
parent
=
it
->
second
;
//Get the vector with themeObjects.
vector
<
ThemeObject
*>
&
v
=
it
->
second
->
themeObjects
;
//Loop through them.
for
(
unsigned
int
i
=
0
;
i
<
v
.
size
();
i
++
){
//Create an instance for every one.
ThemeObjectInstance
p
;
//Set the parent.
p
.
parent
=
v
[
i
];
//Choose the picture.
if
(
stateID
==
STATE_LEVEL_EDITOR
){
if
(
p
.
parent
->
invisibleAtDesignTime
)
continue
;
if
(
p
.
parent
->
editorPicture
.
picture
!=
NULL
)
p
.
picture
=&
p
.
parent
->
editorPicture
;
}
else
{
if
(
p
.
parent
->
invisibleAtRunTime
)
continue
;
}
//Get the number of optional Pictures.
int
m
=
p
.
parent
->
optionalPicture
.
size
();
//If p.picture is null, not an editor picture, and there are optional pictures then give one random.
if
(
p
.
picture
==
NULL
&&
m
>
0
){
double
f
=
0.0
,
f1
=
1.0
/
256.0
;
for
(
int
j
=
0
;
j
<
8
;
j
++
){
f
+=
f1
*
(
double
)(
rand
()
&
0xff
);
f1
*=
(
1.0
/
256.0
);
}
for
(
int
j
=
0
;
j
<
m
;
j
++
){
f
-=
p
.
parent
->
optionalPicture
[
j
].
first
;
if
(
f
<
0.0
){
p
.
picture
=
p
.
parent
->
optionalPicture
[
j
].
second
;
break
;
}
}
}
//If random turned out to give nothing then give the non optional picture.
if
(
p
.
picture
==
NULL
&&
p
.
parent
->
picture
.
picture
!=
NULL
)
p
.
picture
=&
p
.
parent
->
picture
;
//If the picture isn't null then can we give it to the ThemeBlockStateInstance.
if
(
p
.
picture
!=
NULL
)
obj1
.
objects
.
push_back
(
p
);
}
}
//Change the state to the default one.
//FIXME: Is that needed?
obj
->
changeState
(
"default"
);
}
void
ThemeCharacter::createInstance
(
ThemeCharacterInstance
*
obj
){
//Make sure the given ThemeCharacterInstance is ready.
obj
->
characterStates
.
clear
();
obj
->
currentState
=
NULL
;
//Loop through the characterstates.
for
(
map
<
string
,
ThemeCharacterState
*>::
iterator
it
=
characterStates
.
begin
();
it
!=
characterStates
.
end
();
it
++
){
//Get the themeCharacterStateInstance of the given ThemeCharacterInstance.
ThemeCharacterStateInstance
&
obj1
=
obj
->
characterStates
[
it
->
first
];
//Set the parent of the state instance.
obj1
.
parent
=
it
->
second
;
//Get the vector with themeObjects.
vector
<
ThemeObject
*>
&
v
=
it
->
second
->
themeObjects
;
//Loop through them.
for
(
unsigned
int
i
=
0
;
i
<
v
.
size
();
i
++
){
//Create an instance for every one.
ThemeObjectInstance
p
;
//Set the parent.
p
.
parent
=
v
[
i
];
//Make sure it isn't invisible at runtime.
if
(
p
.
parent
->
invisibleAtRunTime
)
continue
;
//Get the number of optional Pictures.
int
m
=
p
.
parent
->
optionalPicture
.
size
();
//If p.picture is null, not an editor picture, and there are optional pictures then give one random.
if
(
p
.
picture
==
NULL
&&
m
>
0
){
double
f
=
0.0
,
f1
=
1.0
/
256.0
;
for
(
int
j
=
0
;
j
<
8
;
j
++
){
f
+=
f1
*
(
double
)(
rand
()
&
0xff
);
f1
*=
(
1.0
/
256.0
);
}
for
(
int
j
=
0
;
j
<
m
;
j
++
){
f
-=
p
.
parent
->
optionalPicture
[
j
].
first
;
if
(
f
<
0.0
){
p
.
picture
=
p
.
parent
->
optionalPicture
[
j
].
second
;
break
;
}
}
}
//If random turned out to give nothing then give the non optional picture.
if
(
p
.
picture
==
NULL
&&
p
.
parent
->
picture
.
picture
!=
NULL
)
p
.
picture
=&
p
.
parent
->
picture
;
//If the picture isn't null then can we give it to the ThemeCharacterStateInstance.
if
(
p
.
picture
!=
NULL
)
obj1
.
objects
.
push_back
(
p
);
}
}
//Set it to the standing right state.
obj
->
changeState
(
"right"
);
}
void
ThemePicture::draw
(
SDL_Surface
*
dest
,
int
x
,
int
y
,
int
animation
,
SDL_Rect
*
clipRect
){
//Get the Picture.
if
(
picture
==
NULL
)
return
;
int
ex
=
0
,
ey
=
0
,
xx
,
yy
,
ww
,
hh
;
{
vector
<
typeOffsetPoint
>
&
v
=
offset
.
offsetData
;
if
(
offset
.
length
==
0
||
animation
<
v
[
0
].
frameDisplayTime
){
xx
=
v
[
0
].
x
;
yy
=
v
[
0
].
y
;
ww
=
v
[
0
].
w
;
hh
=
v
[
0
].
h
;
}
else
if
(
animation
>=
offset
.
length
){
int
i
=
v
.
size
()
-1
;
xx
=
v
[
i
].
x
;
yy
=
v
[
i
].
y
;
ww
=
v
[
i
].
w
;
hh
=
v
[
i
].
h
;
}
else
{
int
t
=
animation
-
v
[
0
].
frameDisplayTime
;
for
(
unsigned
int
i
=
1
;
i
<
v
.
size
();
i
++
){
int
tt
=
t
/
v
[
i
].
frameDisplayTime
;
if
(
tt
>=
0
&&
tt
<
v
[
i
].
frameCount
){
xx
=
(
int
)((
float
)
v
[
i
-1
].
x
+
(
float
)(
v
[
i
].
x
-
v
[
i
-1
].
x
)
*
(
float
)(
tt
+
1
)
/
(
float
)
v
[
i
].
frameCount
+
0.5f
);
yy
=
(
int
)((
float
)
v
[
i
-1
].
y
+
(
float
)(
v
[
i
].
y
-
v
[
i
-1
].
y
)
*
(
float
)(
tt
+
1
)
/
(
float
)
v
[
i
].
frameCount
+
0.5f
);
ww
=
(
int
)((
float
)
v
[
i
-1
].
w
+
(
float
)(
v
[
i
].
w
-
v
[
i
-1
].
w
)
*
(
float
)(
tt
+
1
)
/
(
float
)
v
[
i
].
frameCount
+
0.5f
);
hh
=
(
int
)((
float
)
v
[
i
-1
].
h
+
(
float
)(
v
[
i
].
h
-
v
[
i
-1
].
h
)
*
(
float
)(
tt
+
1
)
/
(
float
)
v
[
i
].
frameCount
+
0.5f
);
break
;
}
else
{
t
-=
v
[
i
].
frameCount
*
v
[
i
].
frameDisplayTime
;
}
}
}
}
//Draw the Picture.
if
(
clipRect
){
int
d
;
d
=
clipRect
->
x
-
ex
;
if
(
d
>
0
){
ex
+=
d
;
xx
+=
d
;
ww
-=
d
;
}
d
=
clipRect
->
y
-
ey
;
if
(
d
>
0
){
ey
+=
d
;
yy
+=
d
;
hh
-=
d
;
}
if
(
ww
>
clipRect
->
w
)
ww
=
clipRect
->
w
;
if
(
hh
>
clipRect
->
h
)
hh
=
clipRect
->
h
;
}
if
(
ww
>
0
&&
hh
>
0
){
SDL_Rect
r1
=
{
xx
,
yy
,
ww
,
hh
};
SDL_Rect
r2
=
{
x
+
ex
,
y
+
ey
,
0
,
0
};
SDL_BlitSurface
(
picture
,
&
r1
,
dest
,
&
r2
);
}
}
void
ThemeBackgroundPicture::draw
(
SDL_Surface
*
dest
){
//Check if the picture is visible.
if
(
!
(
picture
&&
srcSize
.
w
>
0
&&
srcSize
.
h
>
0
&&
destSize
.
w
>
0
&&
destSize
.
h
>
0
))
return
;
//Calculate the draw area.
int
sx
=
(
int
)((
float
)
destSize
.
x
+
currentX
-
cameraX
*
(
float
)
camera
.
x
+
0.5f
);
int
sy
=
(
int
)((
float
)
destSize
.
y
+
currentY
-
cameraY
*
(
float
)
camera
.
y
+
0.5f
);
int
ex
,
ey
;
//Include repeating.
if
(
repeatX
){
sx
%=
destSize
.
w
;
if
(
sx
>
0
)
sx
-=
destSize
.
w
;
ex
=
SCREEN_WIDTH
;
}
else
{
if
(
sx
<=-
(
int
)
destSize
.
w
||
sx
>=
SCREEN_WIDTH
)
return
;
ex
=
sx
+
1
;
}
if
(
repeatY
){
sy
%=
destSize
.
h
;
if
(
sy
>
0
)
sy
-=
destSize
.
h
;
ey
=
SCREEN_HEIGHT
;
}
else
{
if
(
sy
<=-
(
int
)
destSize
.
h
||
sy
>=
SCREEN_HEIGHT
)
return
;
ey
=
sy
+
1
;
}
//And finally draw the ThemeBackgroundPicture.
for
(
int
x
=
sx
;
x
<
ex
;
x
+=
destSize
.
w
){
for
(
int
y
=
sy
;
y
<
ey
;
y
+=
destSize
.
h
){
SDL_Rect
r
=
{
x
,
y
,
0
,
0
};
SDL_BlitSurface
(
picture
,
&
srcSize
,
dest
,
&
r
);
}
}
}
bool
ThemeBackgroundPicture::loadFromNode
(
TreeStorageNode
*
objNode
,
string
themePath
){
//Load the picture.
picture
=
loadImage
(
themePath
+
objNode
->
value
[
0
]);
if
(
picture
==
NULL
)
return
false
;
//Retrieve the source size.
{
vector
<
string
>
&
v
=
objNode
->
attributes
[
"srcSize"
];
if
(
v
.
size
()
>=
4
){
srcSize
.
x
=
atoi
(
v
[
0
].
c_str
());
srcSize
.
y
=
atoi
(
v
[
1
].
c_str
());
srcSize
.
w
=
atoi
(
v
[
2
].
c_str
());
srcSize
.
h
=
atoi
(
v
[
3
].
c_str
());
}
else
{
srcSize
.
x
=
0
;
srcSize
.
y
=
0
;
srcSize
.
w
=
picture
->
w
;
srcSize
.
h
=
picture
->
h
;
}
}
//Retrieve the destinaction size.
{
vector
<
string
>
&
v
=
objNode
->
attributes
[
"destSize"
];
if
(
v
.
size
()
>=
4
){
destSize
.
x
=
atoi
(
v
[
0
].
c_str
());
destSize
.
y
=
atoi
(
v
[
1
].
c_str
());
destSize
.
w
=
atoi
(
v
[
2
].
c_str
());
destSize
.
h
=
atoi
(
v
[
3
].
c_str
());
}
else
{
destSize
.
x
=
0
;
destSize
.
y
=
0
;
destSize
.
w
=
srcSize
.
w
;
destSize
.
h
=
srcSize
.
w
;
}
}
//Retrieve if it should be repeated.
{
vector
<
string
>
&
v
=
objNode
->
attributes
[
"repeat"
];
if
(
v
.
size
()
>=
2
){
repeatX
=
atoi
(
v
[
0
].
c_str
())
?
true
:
false
;
repeatY
=
atoi
(
v
[
1
].
c_str
())
?
true
:
false
;
}
else
{
repeatX
=
true
;
repeatY
=
true
;
}
}
//Retrieve the speed.
{
vector
<
string
>
&
v
=
objNode
->
attributes
[
"speed"
];
if
(
v
.
size
()
>=
2
){
speedX
=
atof
(
v
[
0
].
c_str
());
speedY
=
atof
(
v
[
1
].
c_str
());
}
else
{
speedX
=
0.0f
;
speedY
=
0.0f
;
}
}
//Retrieve the camera speed.
{
vector
<
string
>
&
v
=
objNode
->
attributes
[
"cameraSpeed"
];
if
(
v
.
size
()
>=
2
){
cameraX
=
atof
(
v
[
0
].
c_str
());
cameraY
=
atof
(
v
[
1
].
c_str
());
}
else
{
cameraX
=
0.0f
;
cameraY
=
0.0f
;
}
}
//Done and nothing went wrong so return true.
return
true
;
}
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sun, Nov 15, 5:36 AM (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
152089
Default Alt Text
ThemeManager.cpp (21 KB)
Attached To
Mode
R79 meandmyshadow
Attached
Detach File
Event Timeline