Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
O
openjazz
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PocketInsanity
openjazz
Commits
d804c074
Commit
d804c074
authored
Jul 10, 2010
by
alistert
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added support for JJ2 animations. Made player animations use pointers instead of indices.
parent
14296d13
Changes
31
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
464 additions
and
451 deletions
+464
-451
OpenJazz.h
src/OpenJazz.h
+1
-0
baselevel.cpp
src/baselevel.cpp
+0
-3
baselevel.h
src/baselevel.h
+0
-1
bonus.cpp
src/bonus/bonus.cpp
+18
-11
bonus.h
src/bonus/bonus.h
+1
-0
game.cpp
src/game/game.cpp
+21
-2
game.h
src/game/game.h
+4
-3
anim.cpp
src/io/gfx/anim.cpp
+20
-0
anim.h
src/io/gfx/anim.h
+11
-11
sprite.h
src/io/gfx/sprite.h
+2
-2
jj2event.cpp
src/jj2level/jj2event/jj2event.cpp
+2
-0
jj2event.h
src/jj2level/jj2event/jj2event.h
+2
-1
jj2eventframe.cpp
src/jj2level/jj2event/jj2eventframe.cpp
+9
-8
jj2level.cpp
src/jj2level/jj2level.cpp
+11
-2
jj2level.h
src/jj2level/jj2level.h
+8
-5
jj2levelframe.cpp
src/jj2level/jj2levelframe.cpp
+1
-1
jj2levelload.cpp
src/jj2level/jj2levelload.cpp
+151
-276
bullet.cpp
src/level/bullet.cpp
+1
-1
level.cpp
src/level/level.cpp
+2
-0
level.h
src/level/level.h
+1
-0
levelload.cpp
src/level/levelload.cpp
+18
-12
bonusplayer.cpp
src/player/bonusplayer.cpp
+4
-4
bonusplayer.h
src/player/bonusplayer.h
+5
-3
jj2levelplayer.cpp
src/player/jj2levelplayer.cpp
+15
-20
jj2levelplayer.h
src/player/jj2levelplayer.h
+110
-41
jj2levelplayerframe.cpp
src/player/jj2levelplayerframe.cpp
+26
-29
levelplayer.cpp
src/player/levelplayer.cpp
+7
-5
levelplayer.h
src/player/levelplayer.h
+5
-3
levelplayerframe.cpp
src/player/levelplayerframe.cpp
+1
-1
player.cpp
src/player/player.cpp
+5
-4
player.h
src/player/player.h
+2
-2
No files found.
src/OpenJazz.h
View file @
d804c074
...
...
@@ -84,6 +84,7 @@
#define F_PANEL "PANEL.000"
#define F_SOUNDS "SOUNDS.000"
#define F_BONUS "BONUS.000"
#define F_ANIMS_J2A "ANIMS.J2A"
#define F_BONUS_0SC "BONUS.0SC"
#define F_END_0SC "END.0SC"
...
...
src/baselevel.cpp
View file @
d804c074
...
...
@@ -46,7 +46,6 @@ BaseLevel::BaseLevel () {
smoothfps
=
50.0
f
;
paletteEffects
=
NULL
;
spriteSet
=
NULL
;
paused
=
false
;
...
...
@@ -66,8 +65,6 @@ BaseLevel::~BaseLevel () {
if
(
paletteEffects
)
delete
paletteEffects
;
if
(
spriteSet
)
delete
[]
spriteSet
;
return
;
}
...
...
src/baselevel.h
View file @
d804c074
...
...
@@ -69,7 +69,6 @@ class BaseLevel {
SetupMenu
setupMenu
;
protected
:
Sprite
*
spriteSet
;
PaletteEffect
*
paletteEffects
;
SDL_Color
palette
[
256
];
int
sprites
;
...
...
src/bonus/bonus.cpp
View file @
d804c074
...
...
@@ -185,6 +185,7 @@ int Bonus::loadTiles (char *fileName) {
Bonus
::
Bonus
(
char
*
fileName
,
unsigned
char
diff
)
{
Anim
*
pAnims
[
BPANIMS
];
File
*
file
;
unsigned
char
*
buffer
;
char
*
string
,
*
fileString
;
...
...
@@ -214,7 +215,16 @@ Bonus::Bonus (char * fileName, unsigned char diff) {
}
// Load sprites
loadSprites
();
count
=
loadSprites
();
if
(
count
<
0
)
{
delete
file
;
delete
font
;
throw
count
;
}
// Load tileset
...
...
@@ -324,26 +334,21 @@ Bonus::Bonus (char * fileName, unsigned char diff) {
// Generate player's animation set references
string
=
new
char
[
PANIMS
];
for
(
count
=
0
;
count
<
PANIMS
;
count
++
)
string
[
count
]
=
count
&
31
;
for
(
count
=
0
;
count
<
BPANIMS
;
count
++
)
pAnims
[
count
]
=
animSet
+
count
;
// Set the players' initial values
if
(
game
)
{
game
->
setCheckpoint
(
x
,
y
);
for
(
count
=
0
;
count
<
nPlayers
;
count
++
)
game
->
resetPlayer
(
players
+
count
,
LT_BONUS
,
string
);
for
(
count
=
0
;
count
<
nPlayers
;
count
++
)
game
->
resetPlayer
(
players
+
count
,
LT_BONUS
,
pAnims
);
}
else
{
localPlayer
->
reset
(
LT_BONUS
,
string
,
x
,
y
);
localPlayer
->
reset
(
LT_BONUS
,
pAnims
,
x
,
y
);
}
delete
[]
string
;
delete
file
;
...
...
@@ -376,6 +381,8 @@ Bonus::~Bonus () {
SDL_FreeSurface
(
tileSet
);
delete
[]
spriteSet
;
delete
font
;
return
;
...
...
@@ -667,7 +674,7 @@ void Bonus::draw () {
// Show the player
bonusPlayer
->
draw
(
ticks
,
animSet
);
bonusPlayer
->
draw
(
ticks
);
// Show gem count
...
...
src/bonus/bonus.h
View file @
d804c074
...
...
@@ -60,6 +60,7 @@ class Bonus : public BaseLevel {
SDL_Surface
*
tileSet
;
SDL_Surface
*
background
;
Font
*
font
;
Sprite
*
spriteSet
;
Anim
animSet
[
BANIMS
];
BonusGridElement
grid
[
BLH
][
BLW
];
char
mask
[
60
][
64
];
// At most 60 tiles, all with 8 * 8 masks
...
...
src/game/game.cpp
View file @
d804c074
...
...
@@ -343,10 +343,29 @@ void Game::resetPlayer (Player *player) {
}
void
Game
::
resetPlayer
(
Player
*
player
,
LevelType
levelType
,
char
*
anims
)
{
void
Game
::
resetPlayer
(
Player
*
player
,
LevelType
levelType
,
Anim
**
anims
)
{
Anim
*
pAnims
[
PANIMS
];
int
count
;
if
(
anims
)
{
player
->
reset
(
levelType
,
anims
,
checkX
,
checkY
);
}
else
if
(
level
)
{
for
(
count
=
0
;
count
<
PANIMS
;
count
++
)
pAnims
[
count
]
=
level
->
getAnim
(
0
);
player
->
reset
(
levelType
,
pAnims
,
checkX
,
checkY
);
}
else
if
(
jj2Level
)
{
pAnims
[
0
]
=
jj2Level
->
getAnim
(
54
,
0
,
false
);
pAnims
[
1
]
=
jj2Level
->
getAnim
(
54
,
0
,
true
);
player
->
reset
(
levelType
,
pAnims
,
checkX
,
checkY
);
}
return
;
}
...
...
src/game/game.h
View file @
d804c074
...
...
@@ -64,7 +64,7 @@
#define MTL_G_PROPS 8
#define MTL_G_PJOIN 10
#define MTL_G_PQUIT 3
#define MTL_G_LEVEL 4
#define MTL_G_LEVEL 4
/* + amount of level data */
#define MTL_G_CHECK 4
#define MTL_G_SCORE 3
...
...
@@ -72,7 +72,7 @@
#define MTL_L_GRID 6
#define MTL_L_STAGE 3
#define MTL_P_ANIMS
(PANIMS + 3)
#define MTL_P_ANIMS
3
/* + PANIMS, BPANIMS, or 1 (for JJ2) */
#define MTL_P_TEMP 46
#define BUFFER_LENGTH 255
/* Should always be big enough to hold any message */
...
...
@@ -80,6 +80,7 @@
// Classes
class
Anim
;
class
File
;
class
Game
{
...
...
@@ -104,7 +105,7 @@ class Game {
virtual
void
score
(
unsigned
char
team
);
virtual
void
setCheckpoint
(
unsigned
char
gridX
,
unsigned
char
gridY
);
void
resetPlayer
(
Player
*
player
);
void
resetPlayer
(
Player
*
player
,
LevelType
levelType
,
char
*
anims
);
void
resetPlayer
(
Player
*
player
,
LevelType
levelType
,
Anim
*
*
anims
);
};
...
...
src/io/gfx/anim.cpp
View file @
d804c074
...
...
@@ -28,6 +28,10 @@
Anim
::
Anim
()
{
sprites
=
new
Sprite
*
[
19
];
xOffsets
=
new
signed
char
[
19
];
yOffsets
=
new
signed
char
[
19
];
frame
=
0
;
yOffset
=
0
;
ignoreDefaultYOffset
=
false
;
...
...
@@ -39,6 +43,10 @@ Anim::Anim () {
Anim
::~
Anim
()
{
delete
[]
sprites
;
delete
[]
xOffsets
;
delete
[]
yOffsets
;
return
;
}
...
...
@@ -46,6 +54,18 @@ Anim::~Anim () {
void
Anim
::
setData
(
int
amount
,
signed
char
sX
,
signed
char
sY
,
signed
char
aX
,
signed
char
aY
,
unsigned
char
a
,
signed
char
y
)
{
if
(
amount
>
19
)
{
delete
[]
sprites
;
delete
[]
xOffsets
;
delete
[]
yOffsets
;
sprites
=
new
Sprite
*
[
amount
];
xOffsets
=
new
signed
char
[
amount
];
yOffsets
=
new
signed
char
[
amount
];
}
frames
=
amount
;
shootX
=
sX
;
shootY
=
sY
;
...
...
src/io/gfx/anim.h
View file @
d804c074
...
...
@@ -36,15 +36,15 @@ class Sprite;
class
Anim
{
private
:
Sprite
*
sprites
[
19
];
Sprite
**
sprites
;
signed
char
*
xOffsets
;
signed
char
*
yOffsets
;
bool
ignoreDefaultYOffset
;
signed
char
shootX
;
signed
char
shootY
;
signed
char
accessoryX
;
signed
char
accessoryY
;
signed
char
yOffset
;
signed
char
xOffsets
[
19
];
signed
char
yOffsets
[
19
];
unsigned
char
frames
;
// Number of frames
unsigned
char
frame
;
// Current frame
unsigned
char
accessory
;
// Number of an animation that is an accessory to this animation
...
...
src/io/gfx/sprite.h
View file @
d804c074
...
...
@@ -38,8 +38,8 @@ class Sprite {
SDL_Surface
*
pixels
;
public
:
unsigned
char
xOffset
;
unsigned
char
yOffset
;
short
int
xOffset
;
short
int
yOffset
;
Sprite
();
~
Sprite
();
...
...
src/jj2level/jj2event/jj2event.cpp
View file @
d804c074
...
...
@@ -47,6 +47,8 @@ JJ2Event::JJ2Event (JJ2Event* newNext, unsigned char gridX, unsigned char gridY,
hits
=
0
;
endTime
=
0
;
facing
=
true
;
return
;
}
...
...
src/jj2level/jj2event/jj2event.h
View file @
d804c074
...
...
@@ -40,6 +40,7 @@ class JJ2Event : public Movable {
unsigned
char
anim
;
unsigned
char
frame
;
unsigned
int
flashTime
;
bool
facing
;
JJ2Event
*
remove
();
void
destroy
(
unsigned
int
ticks
);
...
...
@@ -51,7 +52,7 @@ class JJ2Event : public Movable {
unsigned
char
getType
();
JJ2Event
*
step
(
int
ticks
,
int
msps
);
void
draw
(
int
change
);
void
draw
(
unsigned
int
ticks
,
int
change
);
};
...
...
src/jj2level/jj2event/jj2eventframe.cpp
View file @
d804c074
...
...
@@ -97,12 +97,12 @@ JJ2Event* JJ2Event::step (int ticks, int msps) {
}
void
JJ2Event
::
draw
(
int
change
)
{
void
JJ2Event
::
draw
(
unsigned
int
ticks
,
int
change
)
{
Anim
*
an
;
int
drawX
,
drawY
;
if
(
next
)
next
->
draw
(
change
);
if
(
next
)
next
->
draw
(
ticks
,
change
);
// Don't draw if too far off-screen
if
((
x
<
viewX
-
F64
)
||
(
y
<
viewY
-
F64
)
||
...
...
@@ -115,37 +115,37 @@ void JJ2Event::draw (int change) {
case
60
:
// Frozen green spring
an
=
jj2Level
->
getAnim
(
35
);
an
=
jj2Level
->
getAnim
(
92
,
5
,
!
facing
);
break
;
case
62
:
// Spring crate
an
=
jj2Level
->
getAnim
(
37
);
an
=
jj2Level
->
getAnim
(
92
,
0
,
!
facing
);
break
;
case
83
:
// Checkpoint
an
=
jj2Level
->
getAnim
(
49
);
an
=
jj2Level
->
getAnim
(
67
,
14
,
!
facing
);
break
;
case
85
:
// Red spring
an
=
jj2Level
->
getAnim
(
32
);
an
=
jj2Level
->
getAnim
(
92
,
7
,
!
facing
);
break
;
case
86
:
// Green spring
an
=
jj2Level
->
getAnim
(
35
);
an
=
jj2Level
->
getAnim
(
92
,
5
,
!
facing
);
break
;
case
87
:
// Blue spring
an
=
jj2Level
->
getAnim
(
37
);
an
=
jj2Level
->
getAnim
(
92
,
0
,
!
facing
);
break
;
...
...
@@ -158,6 +158,7 @@ void JJ2Event::draw (int change) {
}
an
->
setFrame
((
int
)
ticks
/
60
,
true
);
an
->
draw
(
drawX
,
drawY
);
return
;
...
...
src/jj2level/jj2level.cpp
View file @
d804c074
...
...
@@ -77,6 +77,15 @@ JJ2Level::~JJ2Level () {
delete
[]
musicFile
;
delete
[]
nextLevel
;
for
(
count
=
0
;
count
<
nAnimSets
;
count
++
)
{
if
(
animSets
[
count
])
delete
[]
animSets
[
count
];
}
delete
[]
animSets
;
delete
[]
spriteSet
;
SDL_FreeSurface
(
flippedTileSet
);
SDL_FreeSurface
(
tileSet
);
...
...
@@ -196,9 +205,9 @@ Sprite* JJ2Level::getSprite (unsigned char sprite) {
}
Anim
*
JJ2Level
::
getAnim
(
unsigned
char
anim
)
{
Anim
*
JJ2Level
::
getAnim
(
int
set
,
int
anim
,
bool
flipped
)
{
return
animSet
+
anim
;
return
(
flipped
?
flippedAnimSets
:
animSets
)[
set
]
+
anim
;
}
...
...
src/jj2level/jj2level.h
View file @
d804c074
...
...
@@ -105,19 +105,22 @@ class JJ2Level : public BaseLevel {
char
*
flippedMask
;
char
*
musicFile
;
char
*
nextLevel
;
Anim
animSet
[
128
];
int
soundMap
[
32
];
Sprite
*
spriteSet
;
Sprite
*
flippedSpriteSet
;
Anim
**
animSets
;
Anim
**
flippedAnimSets
;
JJ2Layer
*
layers
[
LAYERS
];
JJ2Layer
*
layer
;
JJ2Modifier
**
mods
;
int
nAnimSets
;
bool
TSF
;
unsigned
char
difficulty
;
fixed
waterLevel
;
fixed
waterLevelTarget
;
fixed
waterLevelSpeed
;
void
loadSprite
(
File
*
file
,
Sprite
*
sprite
);
int
loadSprites
(
char
*
fileName
);
void
loadSprite
(
unsigned
char
*
parameters
,
unsigned
char
*
compressedPixels
,
Sprite
*
sprite
,
Sprite
*
flippedSprite
);
int
loadSprites
();
int
loadTiles
(
char
*
fileName
);
int
load
(
char
*
fileName
,
unsigned
char
diff
,
bool
checkpoint
);
...
...
@@ -130,7 +133,7 @@ class JJ2Level : public BaseLevel {
bool
checkMaskDown
(
fixed
x
,
fixed
y
,
bool
drop
);
bool
checkMaskUp
(
fixed
x
,
fixed
y
);
Anim
*
getAnim
(
unsigned
char
anim
);
Anim
*
getAnim
(
int
set
,
int
anim
,
bool
flipped
);
JJ2Modifier
*
getModifier
(
unsigned
char
gridX
,
unsigned
char
gridY
);
Sprite
*
getSprite
(
unsigned
char
sprite
);
fixed
getWaterLevel
();
...
...
src/jj2level/jj2levelframe.cpp
View file @
d804c074
...
...
@@ -122,7 +122,7 @@ void JJ2Level::draw () {
// Show the events
if
(
events
)
events
->
draw
(
change
);
if
(
events
)
events
->
draw
(
ticks
,
change
);
// Show the players
...
...
src/jj2level/jj2levelload.cpp
View file @
d804c074
This diff is collapsed.
Click to expand it.
src/level/bullet.cpp
View file @
d804c074
...
...
@@ -79,7 +79,7 @@ Bullet::Bullet (LevelPlayer* sourcePlayer, bool lower, unsigned int ticks) {
}
anim
=
level
->
getAnim
(
source
->
getAnim
()
);
anim
=
source
->
getAnim
(
);
x
=
source
->
getX
()
+
anim
->
getShootX
()
+
PXO_MID
-
F4
;
y
=
source
->
getY
()
+
anim
->
getShootY
()
-
F4
;
...
...
src/level/level.cpp
View file @
d804c074
...
...
@@ -116,6 +116,8 @@ Level::~Level () {
delete
[]
sceneFile
;
delete
[]
musicFile
;
delete
[]
spriteSet
;
SDL_FreeSurface
(
tileSet
);
deletePanel
();
...
...
src/level/level.h
View file @
d804c074
...
...
@@ -100,6 +100,7 @@ class Level : public BaseLevel {
Event
*
events
;
char
*
musicFile
;
char
*
sceneFile
;
Sprite
*
spriteSet
;
Anim
animSet
[
ANIMS
];
char
miscAnims
[
4
];
signed
char
bulletSet
[
BULLETS
][
BLENGTH
];
...
...
src/level/levelload.cpp
View file @
d804c074
...
...
@@ -408,12 +408,13 @@ int Level::loadTiles (char* fileName) {
}
int
Level
::
load
(
char
*
fileName
,
unsigned
char
diff
,
bool
checkpoint
)
{
int
Level
::
load
(
char
*
fileName
,
unsigned
char
diff
,
bool
checkpoint
)
{
File
*
file
;
unsigned
char
*
buffer
;
const
char
*
ext
;
char
*
string
;
Anim
*
pAnims
[
PANIMS
];
File
*
file
;
unsigned
char
*
buffer
;
const
char
*
ext
;
char
*
string
;
int
tiles
;
int
count
,
x
,
y
,
type
;
unsigned
char
startX
,
startY
;
...
...
@@ -874,36 +875,41 @@ int Level::load (char *fileName, unsigned char diff, bool checkpoint) {
// Load player's animation set references
buffer
=
file
->
loadRLE
(
PANIMS
*
2
);
string
=
new
char
[
PANIMS
+
3
];
string
=
new
char
[
MTL_P_ANIMS
+
PANIMS
];
for
(
x
=
0
;
x
<
PANIMS
;
x
++
)
{
for
(
x
=
0
;
x
<
PANIMS
;
x
++
)
string
[
x
+
3
]
=
buffer
[
x
<<
1
];
pAnims
[
x
]
=
animSet
+
buffer
[
x
<<
1
];
string
[
MTL_P_ANIMS
+
x
]
=
buffer
[
x
<<
1
];
}
delete
[]
buffer
;
if
(
gameMode
)
{
string
[
0
]
=
MTL_P_ANIMS
;
string
[
0
]
=
MTL_P_ANIMS
+
PANIMS
;
string
[
1
]
=
MT_P_ANIMS
;
string
[
2
]
=
0
;
game
->
send
((
unsigned
char
*
)
string
);
}
delete
[]
string
;
// Set the players' initial values
if
(
game
)
{
if
(
!
checkpoint
)
game
->
setCheckpoint
(
startX
,
startY
);
for
(
count
=
0
;
count
<
nPlayers
;
count
++
)
game
->
resetPlayer
(
players
+
count
,
LT_LEVEL
,
string
+
3
);
for
(
count
=
0
;
count
<
nPlayers
;
count
++
)
game
->
resetPlayer
(
players
+
count
,
LT_LEVEL
,
pAnims
);
}
else
{
localPlayer
->
reset
(
LT_LEVEL
,
string
+
3
,
startX
,
startY
);
localPlayer
->
reset
(
LT_LEVEL
,
pAnims
,
startX
,
startY
);
}
delete
[]
string
;
// Load miscellaneous animations
miscAnims
[
0
]
=
file
->
loadChar
();
...
...
src/player/bonusplayer.cpp
View file @
d804c074
...
...
@@ -37,14 +37,14 @@
#include <string.h>
BonusPlayer
::
BonusPlayer
(
Player
*
parent
,
char
*
newAnims
,
unsigned
char
startX
,
unsigned
char
startY
)
{
BonusPlayer
::
BonusPlayer
(
Player
*
parent
,
Anim
*
*
newAnims
,
unsigned
char
startX
,
unsigned
char
startY
)
{
int
count
;
player
=
parent
;
memcpy
(
anims
,
newAnims
,
PANIMS
);
memcpy
(
anims
,
newAnims
,
BPANIMS
*
sizeof
(
Anim
*
)
);
x
=
TTOF
(
startX
)
+
F16
;
y
=
TTOF
(
startY
)
+
F16
;
...
...
@@ -184,11 +184,11 @@ void BonusPlayer::step (unsigned int ticks, int msps, Bonus* bonus) {
}
void
BonusPlayer
::
draw
(
unsigned
int
ticks
,
Anim
*
animSet
)
{
void
BonusPlayer
::
draw
(
unsigned
int
ticks
)
{
Anim
*
anim
;
anim
=
anim
Set
+
anim
s
[
animType
];
anim
=
anims
[
animType
];
anim
->
disableDefaultOffset
();
anim
->
setFrame
(
ticks
/
75
,
true
);
if
(
canvasW
<=
SW
)
anim
->
draw
(
ITOF
((
canvasW
-
anim
->
getWidth
())
>>
1
),
ITOF
(
canvasH
-
anim
->
getHeight
()
-
28
));
...
...
src/player/bonusplayer.h
View file @
d804c074
...
...
@@ -41,6 +41,8 @@
#define PA_CRASH 5
#define PA_OTHER 6
#define BPANIMS 7
// Player speeds
#define PRS_REVERSE ITOF(-32)
#define PRS_RUN ITOF(64)
...
...
@@ -61,7 +63,7 @@ class BonusPlayer {
private
:
SDL_Color
palette
[
256
];
char
anims
[
PANIMS
];
Anim
*
anims
[
B
PANIMS
];
fixed
x
,
y
,
direction
,
dr
;
unsigned
char
animType
;
int
gems
;
...
...
@@ -69,7 +71,7 @@ class BonusPlayer {
public
:
Player
*
player
;
BonusPlayer
(
Player
*
parent
,
char
*
newAnims
,
unsigned
char
startX
,
unsigned
char
startY
);
BonusPlayer
(
Player
*
parent
,
Anim
*
*
newAnims
,
unsigned
char
startX
,
unsigned
char
startY
);
~
BonusPlayer
();
void
addGem
();
...
...
@@ -79,7 +81,7 @@ class BonusPlayer {
fixed
getY
();
void
step
(
unsigned
int
ticks
,
int
msps
,
Bonus
*
bonus
);
void
draw
(
unsigned
int
ticks
,
Anim
*
animSet
);
void
draw
(
unsigned
int
ticks
);
};
...
...
src/player/jj2levelplayer.cpp
View file @
d804c074
...
...
@@ -37,7 +37,7 @@
#include <string.h>
JJ2LevelPlayer
::
JJ2LevelPlayer
(
Player
*
parent
,
char
*
newAnims
,
unsigned
char
startX
,
unsigned
char
startY
,
bool
hasBird
)
{
JJ2LevelPlayer
::
JJ2LevelPlayer
(
Player
*
parent
,
Anim
*
*
newAnims
,
unsigned
char
startX
,
unsigned
char
startY
,
bool
hasBird
)
{
int
offsets
[
14
]
=
{
JJ2PCO_GREY
,
JJ2PCO_SGREEN
,
JJ2PCO_BLUE
,
JJ2PCO_RED
,
JJ2PCO_LGREEN
,
JJ2PCO_LEVEL1
,
JJ2PCO_YELLOW
,
JJ2PCO_LEVEL2
,
...
...
@@ -52,8 +52,8 @@ JJ2LevelPlayer::JJ2LevelPlayer (Player* parent, char* newAnims, unsigned char st
player
=
parent
;
if
(
newAnims
)
memcpy
(
anims
,
newAnims
,
PANIMS
)
;
else
memset
(
anims
,
0
,
PANIMS
)
;
anims
=
newAnims
[
0
]
;
flippedAnims
=
newAnims
[
1
]
;
bird
=
hasBird
;
...
...
@@ -74,8 +74,8 @@ JJ2LevelPlayer::JJ2LevelPlayer (Player* parent, char* newAnims, unsigned char st
length
=
lengths
[
player
->
cols
[
0
]];
for
(
count
=
0
;
count
<
16
;
count
++
)
palette
[
count
+
48
].
r
=
palette
[
count
+
48
].
g
=
palette
[
count
+
48
].
b
=
(
count
*
length
/
16
)
+
start
;
palette
[
count
+
16
].
r
=
palette
[
count
+
16
].
g
=
palette
[
count
+
16
].
b
=
(
count
*
length
/
8
)
+
start
;
// Bandana colours
...
...
@@ -84,8 +84,8 @@ JJ2LevelPlayer::JJ2LevelPlayer (Player* parent, char* newAnims, unsigned char st
length
=
lengths
[
player
->
cols
[
1
]];
for
(
count
=
0
;
count
<
16
;
count
++
)
palette
[
count
+
32
].
r
=
palette
[
count
+
32
].
g
=
palette
[
count
+
32
].
b
=
(
count
*
length
/
16
)
+
start
;
palette
[
count
+
24
].
r
=
palette
[
count
+
24
].
g
=
palette
[
count
+
24
].
b
=
(
count
*
length
/
8
)
+
start
;
// Gun colours
...
...
@@ -94,8 +94,8 @@ JJ2LevelPlayer::JJ2LevelPlayer (Player* parent, char* newAnims, unsigned char st
length
=
lengths
[
player
->
cols
[
2
]];
for
(
count
=
0
;
count
<
9
;
count
++
)
palette
[
count
+
23
].
r
=
palette
[
count
+
23
].
g
=
palette
[
count
+
23
].
b
=
(
count
*
length
/
9
)
+
start
;
palette
[
count
+
32
].
r
=
palette
[
count
+
32
].
g
=
palette
[
count
+
32
].
b
=
(
count
*
length
/
8
)
+
start
;
// Wristband colours
...
...
@@ -104,16 +104,10 @@ JJ2LevelPlayer::JJ2LevelPlayer (Player* parent, char* newAnims, unsigned char st
length
=
lengths
[
player
->
cols
[
3
]];
for
(
count
=
0
;
count
<
8
;
count
++
)
palette
[
count
+
88
].
r
=
palette
[
count
+
88
].
g
=
palette
[
count
+
88
].
b
=
palette
[
count
+
40
].
r
=
palette
[
count
+
40
].
g
=
palette
[
count
+
40
].
b
=
(
count
*
length
/
8
)
+
start
;
// Fix creepy black eyes
for
(
count
=
0
;
count
<
16
;
count
++
)
palette
[
count
].
r
=
palette
[
count
].
g
=
palette
[
count
].
b
=
(
count
>>
1
)
+
64
;
return
;
}
...
...
@@ -132,7 +126,7 @@ void JJ2LevelPlayer::reset (unsigned char startX, unsigned char startY) {
energy
=
5
;
floating
=
false
;
facing
=
true
;
animType
=
PA_
R
STAND
;
animType
=
PA_STAND
;
event
=
LPE_NONE
;
reaction
=
JJ2PR_NONE
;
reactionTime
=
0
;
...
...
@@ -179,9 +173,9 @@ void JJ2LevelPlayer::centreY () {
}
unsigned
char
JJ2LevelPlayer
::
getAnim
()
{
Anim
*
JJ2LevelPlayer
::
getAnim
()
{
return
anims
[
animType
]
;
return
(
facing
?
anims
:
flippedAnims
)
+
animType
;
}
...
...
@@ -600,7 +594,8 @@ void JJ2LevelPlayer::receive (unsigned char *buffer) {
case
MT_P_ANIMS
:
memcpy
(
anims
,
(
char
*
)
buffer
+
3
,
PANIMS
);
anims
=
jj2Level
->
getAnim
(
buffer
[
3
],
0
,
false
);
flippedAnims
=
jj2Level
->
getAnim
(
buffer
[
3
],
0
,
true
);
break
;
...
...
src/player/jj2levelplayer.h
View file @
d804c074
...
...
@@ -73,44 +73,112 @@
#define JJ2PCL_LEVEL5 16
// Animations
#define PA_LWALK 0
#define PA_RWALK 1
#define PA_LJUMP 2
#define PA_RJUMP 3
#define PA_LSPIN 4
#define PA_RSPIN 5
#define PA_LSHOOT 6
#define PA_RSHOOT 7
#define PA_LCROUCH 8
#define PA_RCROUCH 9
#define PA_LFALL 10
#define PA_RFALL 11
#define PA_LHURT 12
#define PA_RHURT 13
#define PA_LLEAN 14
#define PA_RLEAN 15
#define PA_LBOARD 16
#define PA_RBOARD 17
#define PA_LSTAND 18
#define PA_RSTAND 19
#define PA_LEAT 20
#define PA_REAT 21
#define PA_LEDGE 22
#define PA_REDGE 23
#define PA_LOOKUP 24
#define PA_LOOKDOWN 25
#define PA_LSWIM 26
#define PA_RSWIM 27
#define PA_LRUN 28
#define PA_RRUN 29
#define PA_LDIE 30
#define PA_RDIE 31
#define PA_LSTOP 32
#define PA_RSTOP 33
#define PA_LHALT 34
/* Yeah, I was wondering the same thing... */
#define PA_RHALT 35
#define PA_RSPRING 36
#define PA_LSPRING 37
/* Surely these are the wrong way round? */
#define PA_WOOZYSHAKE 0
#define PA_BOARD 1
#define PA_BOARDSW 2
#define PA_STOMP 3
#define PA_DEAD 4
#define PA_DIE 5
#define PA_CROUCH1 6
#define PA_CROUCHED 7
#define PA_CROUCHSHOOT 8
#define PA_CROUCH2 9
#define PA_EXIT1 10
#define PA_VINE 11
#define PA_EXIT2 12
#define PA_FALL 13
#define PA_STOMPING 14
#define PA_LAND 15
#define PA_STANDSHOOT 16
#define PA_STANDSHOOTUP 17
#define PA_WHIP1 18
#define PA_UNFROG 19
#define PA_MOUNT 20
#define PA_HOOKWHIP 21
#define PA_HOOKDIAG 22
#define PA_HOOKSHOOTUP 23
#define PA_HOOK1 24
#define PA_HOOK2 25
#define PA_HOOKWHIPUP 26
#define PA_HOOKSHOOT 27
#define PA_HELI 28
#define PA_HELIWHIP 29
#define PA_HELISHOOT 30
#define PA_HPOLE 31
#define PA_HURT1 32
#define PA_WAIT1 33
#define PA_WAIT2 34
#define PA_WAIT3 35
#define PA_WAIT4 36
#define PA_WAIT5 37
#define PA_FALLWHIP 38
#define PA_FALLSHOOT 39
#define PA_FLOAT1 40
#define PA_FLOAT2 41
#define PA_UP1 42
#define PA_EDGE 43
#define PA_CARRY 44
#define PA_UNLOAD 45
#define PA_LOAD 46
#define PA_LOOKUP1 47
#define PA_WALK45 48
#define PA_WALK90 49
#define PA_WALK135 50
#define PA_WALK180 51
#define PA_WALK225 52
#define PA_WALK270 53
#define PA_WALK315 54
#define PA_WOOZYWALK 55
#define PA_PUSH 56
#define PA_WHIP2 57
#define PA_EXIT3 58
#define PA_SPEED1 59
#define PA_SPEED2 60
#define PA_FALLMOVE 61
#define PA_MYSTERY1 62
#define PA_JUMP2 63
#define PA_FALLMOVEWHIP 64
#define PA_MYSTERY2 65
#define PA_JUMPSHOOTUP 66
#define PA_BALL 67
#define PA_WALKSHOOT 68
#define PA_WALKDIAG 69
#define PA_RUN 70
#define PA_SPEEDRUN 71
#define PA_STOP1 72
#define PA_MYSTERY3 73
#define PA_STOP2 74
#define PA_UP2 75
#define PA_STAND 76
#define PA_POWER 77
#define PA_POWEREND 78
#define PA_POWERSTART 79
#define PA_WOOZYSTAND 80
#define PA_SWIMDOWN 81
#define PA_SWIM 82
#define PA_SWIMDIAGDOWN 83
#define PA_SWIMDIAGUP 84
#define PA_SWIMUP 85
#define PA_VINESDIAG 86
#define PA_WARPOUT 87
#define PA_WARPFALLIN 88
#define PA_WARPFALL 89
#define PA_WARPFALLOUT 90
#define PA_WARPIN 91
#define PA_VPOLE 92
#define PA_CROUCH3 93
#define PA_CROUCH4 94
#define PA_FALLSTRANGE1 95
#define PA_HURT2 96
#define PA_WAIT6 97
#define PA_FALLSTRANGE2 98
#define PA_CROUCH5 99
#define PA_LOOKUP2 100
#define PA_WALK2 101
#define PA_WORRY 102
#define PA_LOOKUP3 103
#define JJ2PANIMS 104
/* Number of player animations. */
// Player reaction times
#define PRT_HURT 1000
...
...
@@ -180,9 +248,10 @@ class JJ2LevelPlayer : public Movable {
private
:
bool
bird
;
// Placeholder for eventual JJ2Bird object
Anim
*
anims
;
Anim
*
flippedAnims
;
JJ2Modifier
*
mod
;
SDL_Color
palette
[
256
];
char
anims
[
PANIMS
];
int
energy
;
JJ2Shield
shield
;
int
floating
;
/* 0 = normal, 1 = helicopter ears, 2 = boarding */
...
...
@@ -207,13 +276,13 @@ class JJ2LevelPlayer : public Movable {
public
:
Player
*
player
;
JJ2LevelPlayer
(
Player
*
parent
,
char
*
newAnims
,
unsigned
char
startX
,
unsigned
char
startY
,
bool
hasBird
);
JJ2LevelPlayer
(
Player
*
parent
,
Anim
*
*
newAnims
,
unsigned
char
startX
,
unsigned
char
startY
,
bool
hasBird
);
~
JJ2LevelPlayer
();
void
reset
(
unsigned
char
startX
,
unsigned
char
startY
);
void
addGem
(
int
colour
);
unsigned
char
getAnim
();
Anim
*
getAnim
();
int
getEnemies
();
int
getEnergy
();
bool
getFacing
();
...
...
src/player/jj2levelplayerframe.cpp
View file @
d804c074
...
...
@@ -188,7 +188,7 @@ void JJ2LevelPlayer::control (unsigned int ticks, int msps) {
dx
=
0
;
dy
=
0
;
animType
=
facing
?
PA_RDIE
:
PA_L
DIE
;
animType
=
PA_
DIE
;
return
;
...
...
@@ -443,7 +443,7 @@ void JJ2LevelPlayer::control (unsigned int ticks, int msps) {
if
(
ticks
>
fireTime
)
{
// Make sure bullet position is taken from correct animation
if
(
platform
)
animType
=
facing
?
PA_RSHOOT
:
PA_LSHOOT
;
if
(
platform
)
animType
=
PA_STANDSHOOT
;
// TODO: Create new bullet
...
...
@@ -494,55 +494,53 @@ void JJ2LevelPlayer::control (unsigned int ticks, int msps) {
// Choose animation
if
((
reaction
==
JJ2PR_HURT
)
&&
(
reactionTime
-
ticks
>
PRT_HURT
-
PRT_HURTANIM
))
animType
=
facing
?
PA_RHURT
:
PA_LHURT
;
animType
=
PA_HURT1
;
else
if
(
y
+
PYO_MID
>
jj2Level
->
getWaterLevel
())
animType
=
facing
?
PA_RSWIM
:
PA_L
SWIM
;
animType
=
PA_
SWIM
;
else
if
(
floating
)
animType
=
facing
?
PA_RBOARD
:
PA_L
BOARD
;
else
if
(
floating
)
animType
=
PA_
BOARD
;
else
if
(
dy
<
0
)
{
if
(
event
==
LPE_SPRING
)
animType
=
facing
?
PA_RSPRING
:
PA_LSPRING
;
else
animType
=
facing
?
PA_RJUMP
:
PA_LJUMP
;
if
(
event
==
LPE_SPRING
)
animType
=
PA_FLOAT1
;
else
animType
=
PA_JUMP2
;
}
else
if
(
platform
)
{
if
(
dx
)
{
if
(
dx
<=
-
PXS_RUN
)
animType
=
PA_
L
RUN
;
else
if
(
dx
>=
PXS_RUN
)
animType
=
PA_R
R
UN
;
else
if
((
dx
<
0
)
&&
facing
)
animType
=
PA_
LSTOP
;
else
if
((
dx
>
0
)
&&
!
facing
)
animType
=
PA_
RSTOP
;
else
animType
=
facing
?
PA_RWALK
:
PA_LWALK
;
if
(
dx
<=
-
PXS_RUN
)
animType
=
PA_RUN
;
else
if
(
dx
>=
PXS_RUN
)
animType
=
PA_RUN
;
else
if
((
dx
<
0
)
&&
facing
)
animType
=
PA_
STOP1
;
else
if
((
dx
>
0
)
&&
!
facing
)
animType
=
PA_
STOP1
;
else
animType
=
PA_WALK2
;
}
else
if
(
!
jj2Level
->
checkMaskDown
(
x
+
PXO_ML
,
y
+
F12
,
drop
)
&&
!
jj2Level
->
checkMaskDown
(
x
+
PXO_L
,
y
+
F2
,
drop
)
/*
&&
(event !=
3) && (event != 4)*/
)
animType
=
PA_
L
EDGE
;
!
jj2Level
->
checkMaskDown
(
x
+
PXO_L
,
y
+
F2
,
drop
)
&&
(
event
!=
LPE_PLATFORM
)
)
animType
=
PA_EDGE
;
else
if
(
!
jj2Level
->
checkMaskDown
(
x
+
PXO_MR
,
y
+
F12
,
drop
)
&&
!
jj2Level
->
checkMaskDown
(
x
+
PXO_R
,
y
+
F2
,
drop
)
/*
&&
(event !=
3) && (event != 4)*/
)
animType
=
PA_
R
EDGE
;
!
jj2Level
->
checkMaskDown
(
x
+
PXO_R
,
y
+
F2
,
drop
)
&&
(
event
!=
LPE_PLATFORM
)
)
animType
=
PA_EDGE
;
else
if
((
lookTime
<
0
)
&&
((
int
)
ticks
>
1000
-
lookTime
))
animType
=
PA_LOOKUP
;
animType
=
PA_LOOKUP
1
;
else
if
(
lookTime
>
0
)
{
if
((
int
)
ticks
<
1000
+
lookTime
)
animType
=
facing
?
PA_RCROUCH
:
PA_LCROUCH
;
else
animType
=
PA_
LOOKDOWN
;
if
((
int
)
ticks
<
1000
+
lookTime
)
animType
=
PA_CROUCHED
;
else
animType
=
PA_
CROUCH1
;
}
else
if
(
player
->
pcontrols
[
C_FIRE
])
animType
=
facing
?
PA_RSHOOT
:
PA_LSHOOT
;
else
if
(
player
->
pcontrols
[
C_FIRE
])
animType
=
PA_STANDSHOOT
;
else
animType
=
facing
?
PA_RSTAND
:
PA_LSTAND
;
else
animType
=
PA_STAND
;
}
else
animType
=
facing
?
PA_RFALL
:
PA_L
FALL
;
}
else
animType
=
PA_
FALL
;
return
;
...
...
@@ -811,15 +809,14 @@ void JJ2LevelPlayer::draw (unsigned int ticks, int change) {
// Choose sprite
an
=
jj2Level
->
getAnim
(
getAnim
()
);
an
=
getAnim
(
);
an
->
setFrame
(
frame
,
reaction
!=
JJ2PR_KILLED
);
// Show the player
// Use player colour
an
->
setPalette
(
palette
,
23
,
41
);
an
->
setPalette
(
palette
,
88
,
8
);
an
->
setPalette
(
palette
,
16
,
32
);
// Flash on and off if hurt
if
((
reaction
!=
JJ2PR_HURT
)
||
((
ticks
/
30
)
&
2
))
{
...
...
src/player/levelplayer.cpp
View file @
d804c074
...
...
@@ -39,7 +39,7 @@
#include <string.h>
LevelPlayer
::
LevelPlayer
(
Player
*
parent
,
char
*
newAnims
,
unsigned
char
startX
,
unsigned
char
startY
,
bool
hasBird
)
{
LevelPlayer
::
LevelPlayer
(
Player
*
parent
,
Anim
*
*
newAnims
,
unsigned
char
startX
,
unsigned
char
startY
,
bool
hasBird
)
{
int
offsets
[
15
]
=
{
PCO_GREY
,
PCO_SGREEN
,
PCO_BLUE
,
PCO_RED
,
PCO_LGREEN
,
PCO_LEVEL1
,
PCO_YELLOW
,
PCO_LEVEL2
,
PCO_ORANGE
,
PCO_LEVEL3
,
PCO_LEVEL4
,
...
...
@@ -49,8 +49,7 @@ LevelPlayer::LevelPlayer (Player* parent, char* newAnims, unsigned char startX,
player
=
parent
;
if
(
newAnims
)
memcpy
(
anims
,
newAnims
,
PANIMS
);
else
memset
(
anims
,
0
,
PANIMS
);
memcpy
(
anims
,
newAnims
,
PANIMS
*
sizeof
(
Anim
*
));
if
(
hasBird
)
bird
=
new
Bird
(
this
,
startX
,
startY
-
2
);
else
bird
=
NULL
;
...
...
@@ -165,7 +164,7 @@ void LevelPlayer::clearEvent (unsigned char gridX, unsigned char gridY) {
}
unsigned
char
LevelPlayer
::
getAnim
()
{
Anim
*
LevelPlayer
::
getAnim
()
{
return
anims
[
animType
];
...
...
@@ -680,13 +679,16 @@ void LevelPlayer::send (unsigned char *buffer) {
void
LevelPlayer
::
receive
(
unsigned
char
*
buffer
)
{
int
count
;
// Interpret data received from client/server
switch
(
buffer
[
1
])
{
case
MT_P_ANIMS
:
memcpy
(
anims
,
(
char
*
)
buffer
+
3
,
PANIMS
);
for
(
count
=
0
;
count
<
PANIMS
;
count
++
)
anims
[
count
]
=
level
->
getAnim
(
buffer
[
MTL_P_ANIMS
+
count
]);
break
;
...
...
src/player/levelplayer.h
View file @
d804c074
...
...
@@ -96,6 +96,8 @@
#define PA_RSPRING 36
#define PA_LSPRING 37
/* Surely these are the wrong way round? */
#define PANIMS 38
/* Number of player animations. May be higher. */
// Player reaction times
#define PRT_HURT 1000
#define PRT_HURTANIM 200
...
...
@@ -150,7 +152,7 @@ class LevelPlayer : public Movable {
private
:
Bird
*
bird
;
SDL_Color
palette
[
256
];
char
anims
[
PANIMS
];
Anim
*
anims
[
PANIMS
];
int
energy
;
int
shield
;
/* 0 = none, 1 = 1 yellow, 2 = 2 yellow, 3 = 1 orange, 4 = 2 orange, 5 = 3 orange, 6 = 4 orange */
bool
floating
;
/* false = normal, true = boarding/bird/etc. */
...
...
@@ -174,14 +176,14 @@ class LevelPlayer : public Movable {
public
:
Player
*
player
;
LevelPlayer
(
Player
*
parent
,
char
*
newAnims
,
unsigned
char
startX
,
unsigned
char
startY
,
bool
hasBird
);
LevelPlayer
(
Player
*
parent
,
Anim
*
*
newAnims
,
unsigned
char
startX
,
unsigned
char
startY
,
bool
hasBird
);
~
LevelPlayer
();
void
reset
(
unsigned
char
startX
,
unsigned
char
startY
);
void
addItem
();
void
clearEvent
(
unsigned
char
gridX
,
unsigned
char
gridY
);
unsigned
char
getAnim
();
Anim
*
getAnim
();
int
getEnemies
();
int
getEnergy
();
bool
getFacing
();
...
...
src/player/levelplayerframe.cpp
View file @
d804c074
...
...
@@ -688,7 +688,7 @@ void LevelPlayer::draw (unsigned int ticks, int change) {
// Choose sprite
an
=
level
->
getAnim
(
getAnim
())
;
an
=
anims
[
animType
]
;
an
->
setFrame
(
frame
,
reaction
!=
PR_KILLED
);
...
...
src/player/player.cpp
View file @
d804c074
...
...
@@ -126,13 +126,14 @@ void Player::deinit () {
void
Player
::
reset
(
unsigned
char
x
,
unsigned
char
y
)
{
if
(
levelPlayer
)
levelPlayer
->
reset
(
x
,
y
);
else
if
(
jj2LevelPlayer
)
jj2LevelPlayer
->
reset
(
x
,
y
);
return
;
}
void
Player
::
reset
(
LevelType
levelType
,
char
*
newAnims
,
unsigned
char
x
,
unsigned
char
y
)
{
void
Player
::
reset
(
LevelType
levelType
,
Anim
**
anims
,
unsigned
char
x
,
unsigned
char
y
)
{
int
count
;
...
...
@@ -163,19 +164,19 @@ void Player::reset (LevelType levelType, char* newAnims, unsigned char x, unsign
case
LT_LEVEL
:
levelPlayer
=
new
LevelPlayer
(
this
,
newAnims
,
x
,
y
,
bird
);
levelPlayer
=
new
LevelPlayer
(
this
,
anims
,
x
,
y
,
bird
);
break
;
case
LT_BONUS
:
bonusPlayer
=
new
BonusPlayer
(
this
,
newAnims
,
x
,
y
);
bonusPlayer
=
new
BonusPlayer
(
this
,
anims
,
x
,
y
);
break
;
case
LT_JJ2LEVEL
:
jj2LevelPlayer
=
new
JJ2LevelPlayer
(
this
,
newAnims
,
x
,
y
,
bird
);
jj2LevelPlayer
=
new
JJ2LevelPlayer
(
this
,
anims
,
x
,
y
,
bird
);
break
;
...
...
src/player/player.h
View file @
d804c074
...
...
@@ -44,7 +44,6 @@
#define CHAR_WBAND 8
// General
#define PANIMS 38
/* Number of player animations. Is probably higher. */
#define PCONTROLS 8
/* Number of player controls. */
#define PCOLOURS 4
/* Number of configurable colour ranges */
...
...
@@ -79,6 +78,7 @@ enum PlayerEvent {
// Classes
class
Anim
;
class
LevelPlayer
;
class
BonusPlayer
;
class
JJ2LevelPlayer
;
...
...
@@ -111,7 +111,7 @@ class Player {
void
init
(
char
*
playerName
,
unsigned
char
*
cols
,
unsigned
char
newTeam
);
void
deinit
();
void
reset
(
unsigned
char
x
,
unsigned
char
y
);
void
reset
(
LevelType
levelType
,
char
*
newA
nims
,
unsigned
char
x
,
unsigned
char
y
);
void
reset
(
LevelType
levelType
,
Anim
**
a
nims
,
unsigned
char
x
,
unsigned
char
y
);
void
addLife
();
void
addScore
(
int
addedScore
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment