Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F619831
RlePack.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
16 KB
Referenced Files
None
Subscribers
None
RlePack.cpp
View Options
/***************************************************************************
RlePack.cpp - description
-------------------
begin : Mon Sep 24 2001
copyright : (C) 2001 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#include
"RlePack.h"
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
"SDL.h"
#include
"common.h"
/// Sanity: This is the maximal number of entries in a .DAT file.
#define MAXDATACOUNT 65530
inline
void
ChangeEndian32
(
Uint32
&
a_riArg
)
{
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
char
*
pcArg
=
(
char
*
)
&
a_riArg
;
char
cTemp
;
cTemp
=
pcArg
[
0
];
pcArg
[
0
]
=
pcArg
[
3
];
pcArg
[
3
]
=
cTemp
;
cTemp
=
pcArg
[
1
];
pcArg
[
1
]
=
pcArg
[
2
];
pcArg
[
2
]
=
cTemp
;
#endif
}
inline
void
ChangeEndian16
(
Uint16
&
a_riArg
)
{
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
char
*
pcArg
=
(
char
*
)
&
a_riArg
;
char
cTemp
;
cTemp
=
pcArg
[
0
];
pcArg
[
0
]
=
pcArg
[
1
];
pcArg
[
1
]
=
cTemp
;
#endif
}
inline
Uint32
ConvertEndian32
(
Uint32
a_iArg
)
{
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
char
*
pcArg
=
(
char
*
)
&
a_iArg
;
char
cTemp
;
cTemp
=
pcArg
[
0
];
pcArg
[
0
]
=
pcArg
[
3
];
pcArg
[
3
]
=
cTemp
;
cTemp
=
pcArg
[
1
];
pcArg
[
1
]
=
pcArg
[
2
];
pcArg
[
2
]
=
cTemp
;
#endif
return
a_iArg
;
}
inline
Uint16
ConvertEndian16
(
Uint16
a_iArg
)
{
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
char
*
pcArg
=
(
char
*
)
&
a_iArg
;
char
cTemp
;
cTemp
=
pcArg
[
0
];
pcArg
[
0
]
=
pcArg
[
1
];
pcArg
[
1
]
=
cTemp
;
#endif
return
a_iArg
;
}
typedef
struct
RLE_SPRITE
/* a RLE compressed sprite */
{
Uint16
dummy
;
// For better alignment... NASTY NASTY HACK!!
Uint16
color_depth
;
/* color depth of the image */
Uint16
w
,
h
;
/* width and height in pixels */
Uint32
size
;
signed
char
dat
[
0
];
}
RLE_SPRITE
;
struct
RlePack_P
{
SDL_Color
m_aoPalette
[
256
];
SDL_Color
m_aoTintedPalette
[
256
];
TintEnum
m_enTint
;
int
m_iCount
;
int
m_iArraysize
;
RLE_SPRITE
**
m_pSprites
;
void
*
m_pData
;
int
m_iColorCount
;
int
m_iColorOffset
;
};
RlePack
::
RlePack
(
const
char
*
a_pcFilename
,
int
a_iNumColors
)
{
p
=
new
RlePack_P
;
p
->
m_enTint
=
NO_TINT
;
p
->
m_iCount
=
0
;
p
->
m_iArraysize
=
0
;
p
->
m_pSprites
=
NULL
;
p
->
m_pData
=
NULL
;
p
->
m_iColorCount
=
0
;
p
->
m_iColorOffset
=
0
;
// Load file and stuff
LoadFile
(
a_pcFilename
,
a_iNumColors
);
}
RlePack
::~
RlePack
()
{
if
(
!
p
)
return
;
if
(
p
->
m_pSprites
)
{
delete
[]
p
->
m_pSprites
;
p
->
m_pSprites
=
NULL
;
}
free
(
p
->
m_pData
);
delete
(
p
);
p
=
NULL
;
}
void
RlePack
::
Clear
()
{
if
(
p
&&
p
->
m_pSprites
)
{
delete
[]
p
->
m_pSprites
;
p
->
m_pSprites
=
NULL
;
}
}
int
RlePack
::
LoadFile
(
const
char
*
a_pcFilename
,
int
a_iNumColors
)
{
FILE
*
f
;
f
=
fopen
(
a_pcFilename
,
"rb"
);
if
(
f
==
NULL
)
{
debug
(
"Can't open file '%s'.
\n
"
,
a_pcFilename
);
return
-1
;
}
fseek
(
f
,
0
,
SEEK_END
);
long
iFileSize
=
ftell
(
f
);
p
->
m_pData
=
malloc
(
iFileSize
);
if
(
NULL
==
p
->
m_pData
)
{
fclose
(
f
);
return
-1
;
}
fseek
(
f
,
0
,
SEEK_SET
);
int
iRead
=
fread
(
p
->
m_pData
,
1
,
iFileSize
,
f
);
fclose
(
f
);
p
->
m_iColorCount
=
a_iNumColors
;
if
(
iFileSize
!=
iRead
)
{
debug
(
"Warning RlePack(): iFileSize=%d, iRead=%d
\n
"
,
iFileSize
,
iRead
);
}
struct
SHeader
{
char
acDummy
[
8
];
Uint32
iDatacount
;
}
*
poHeader
=
(
SHeader
*
)
p
->
m_pData
;
ChangeEndian32
(
poHeader
->
iDatacount
);
debug
(
"File '%s' contains %d entries.
\n
"
,
a_pcFilename
,
poHeader
->
iDatacount
);
if
(
poHeader
->
iDatacount
>
MAXDATACOUNT
)
poHeader
->
iDatacount
=
MAXDATACOUNT
;
// Sanity
p
->
m_iArraysize
=
poHeader
->
iDatacount
;
p
->
m_pSprites
=
new
RLE_SPRITE
*
[
poHeader
->
iDatacount
];
char
*
pcNext
=
((
char
*
)
p
->
m_pData
)
+
sizeof
(
SHeader
);
char
*
pcEnd
=
((
char
*
)
p
->
m_pData
)
+
iFileSize
;
while
(
pcNext
<
pcEnd
-
4
)
{
if
(
0
==
strncmp
(
pcNext
,
"prop"
,
4
)
)
{
struct
SProperty
{
char
acName
[
4
];
Uint32
iSize
;
}
*
poProperty
=
(
SProperty
*
)
(
pcNext
+
4
);
ChangeEndian32
(
poProperty
->
iSize
);
pcNext
+=
4
+
sizeof
(
SProperty
)
+
poProperty
->
iSize
;
}
else
if
(
0
==
strncmp
(
pcNext
,
"RLE "
,
4
)
)
{
struct
SRLE
{
RLE_SPRITE
oSprite
;
}
*
poRle
=
(
SRLE
*
)
(
pcNext
+
10
);
poRle
->
oSprite
.
color_depth
=
ConvertEndian16
(
poRle
->
oSprite
.
color_depth
);
poRle
->
oSprite
.
w
=
ConvertEndian16
(
poRle
->
oSprite
.
w
);
poRle
->
oSprite
.
h
=
ConvertEndian16
(
poRle
->
oSprite
.
h
);
poRle
->
oSprite
.
size
=
ConvertEndian32
(
poRle
->
oSprite
.
size
);
p
->
m_pSprites
[
p
->
m_iCount
]
=
&
(
poRle
->
oSprite
);
p
->
m_iCount
++
;
pcNext
+=
10
+
sizeof
(
SRLE
)
+
poRle
->
oSprite
.
size
;
}
else
if
(
0
==
strncmp
(
pcNext
,
"PAL "
,
4
)
)
{
struct
SPAL
{
Uint32
iLength1
;
Uint32
iLength
;
SDL_Color
aoColors
[
256
];
}
*
poPal
=
(
SPAL
*
)
(
pcNext
+
4
);
ChangeEndian32
(
poPal
->
iLength
);
int
iNumColors
=
poPal
->
iLength
>
1024
?
1024
:
poPal
->
iLength
;
iNumColors
/=
4
;
for
(
int
i
=
0
;
i
<
iNumColors
;
i
++
)
{
p
->
m_aoPalette
[
i
].
r
=
poPal
->
aoColors
[
i
].
r
*
4
;
p
->
m_aoPalette
[
i
].
g
=
poPal
->
aoColors
[
i
].
g
*
4
;
p
->
m_aoPalette
[
i
].
b
=
poPal
->
aoColors
[
i
].
b
*
4
;
p
->
m_aoPalette
[
i
].
unused
=
0
;
p
->
m_aoTintedPalette
[
i
]
=
p
->
m_aoPalette
[
i
];
}
pcNext
+=
4
+
8
+
poPal
->
iLength
;
}
else
{
struct
SUnknown
{
Uint32
iSize
;
}
*
poUnknown
=
(
SUnknown
*
)
(
pcNext
+
4
);
ChangeEndian32
(
poUnknown
->
iSize
);
debug
(
"Unknown: '%4s', size: %d
\n
"
,
pcNext
,
poUnknown
->
iSize
);
pcNext
+=
4
+
sizeof
(
SUnknown
)
+
poUnknown
->
iSize
;
}
}
return
p
->
m_iCount
;
#if 0
int datacount;
#define READDW(I) { \
unsigned char data[4]; \
fread( data, 4, 1, f ); \
(I) = (data[0]<<24) + (data[1]<<16) + (data[2]<<8) + data[3]; }
#define READW(I) { \
unsigned char data[2]; \
fread( data, 2, 1, f ); \
(I) = (data[0]<<8) + data[1]; }
#define READCH(S,C) { \
fread( S, C, 1, f ); S[C] = 0; }
fseek( f, 8, SEEK_SET ); // Skip header
READDW( datacount );
debug( "File '%s' contains %d entries.\n", filename, datacount );
if (datacount>500) datacount = 500; // Sanity
p->arraysize = datacount;
p->sprites = new RLE_SPRITE*[ datacount ];
while( (!feof(f)) && (!ferror(f)) && (datacount>0) )
{
char s[10];
READCH( s, 4 );
if ( !strcmp( s, "prop" )) // Found a property
{
fseek( f, 4, SEEK_CUR );
unsigned int propsize;
READDW( propsize );
fseek( f, propsize, SEEK_CUR );
}
else if (!strcmp( s, "RLE " )) // Found an RLE_SPRITE
{
datacount--;
unsigned int length, bpp, width, height, size;
READDW( length );
READDW( length );
READW( bpp );
READW( width );
READW( height );
READDW( size );
RLE_SPRITE* sprite = (RLE_SPRITE*) malloc( sizeof(RLE_SPRITE) + size );
p->sprites[ p->count ] = sprite;
(p->count)++;
sprite->w = width;
sprite->h = height;
sprite->color_depth = bpp;
sprite->size = size;
fread( sprite->dat, 1, size, f );
}
else if (!strcmp( s, "PAL ")) // Found a palette
{
datacount--;
unsigned int length, pallength;
READDW( length );
READDW( length );
pallength = length>1024 ? 1024 : length;
pallength /= 4;
for (unsigned int i=0; i< pallength; i++)
{
char c[4];
fread( c, 4, 1, f );
p->palette[i].r = c[0]*4;
p->palette[i].g = c[1]*4;
p->palette[i].b = c[2]*4;
p->palette[i].unused = 0;
}
fseek( f, length - pallength*4, SEEK_CUR );
}
else // Found something else
{
debug( "Unknown: %s.", s );
datacount--;
unsigned int length;
READDW( length );
READDW( length );
fseek( f, length, SEEK_CUR );
}
}
fclose( f );
#endif
}
int
RlePack
::
Count
()
{
return
p
->
m_iCount
;
}
void
OffsetRLESprite
(
RLE_SPRITE
*
spr
,
int
offset
)
// Static method
{
if
(
!
spr
||
!
offset
)
return
;
signed
char
*
s
=
spr
->
dat
;
signed
char
c
;
int
y
;
for
(
y
=
0
;
y
<
spr
->
h
;
y
++
)
{
c
=
*
s
++
;
while
(
c
)
{
// For positive c: solid pixels.
for
(
;
c
>
0
;
c
--
)
{
*
s
=
(
*
s
)
+
offset
;
s
++
;
}
c
=
*
s
++
;
}
}
}
void
RlePack
::
OffsetSprites
(
int
a_iOffset
)
{
if
(
(
a_iOffset
<=
0
)
||
(
a_iOffset
>
255
)
)
return
;
p
->
m_iColorOffset
=
a_iOffset
;
int
i
;
// Offset every RLE_SPRITE
for
(
i
=
0
;
i
<
p
->
m_iCount
;
++
i
)
{
OffsetRLESprite
(
p
->
m_pSprites
[
i
],
a_iOffset
);
}
}
void
RlePack
::
SetTint
(
TintEnum
a_enTint
)
{
int
i
;
switch
(
a_enTint
)
{
case
ZOMBIE_TINT
:
{
for
(
i
=
0
;
i
<
p
->
m_iColorCount
;
++
i
)
{
p
->
m_aoTintedPalette
[
i
].
r
=
0
;
p
->
m_aoTintedPalette
[
i
].
g
=
p
->
m_aoPalette
[
i
].
g
;
p
->
m_aoTintedPalette
[
i
].
b
=
0
;
}
break
;
}
case
GRAY_TINT
:
{
int
j
;
for
(
i
=
0
;
i
<
p
->
m_iColorCount
;
++
i
)
{
j
=
(
p
->
m_aoPalette
[
i
].
r
+
p
->
m_aoPalette
[
i
].
g
+
p
->
m_aoPalette
[
i
].
b
)
/
4
;
p
->
m_aoTintedPalette
[
i
].
r
=
j
;
p
->
m_aoTintedPalette
[
i
].
g
=
j
;
p
->
m_aoTintedPalette
[
i
].
b
=
j
;
}
break
;
}
case
DARK_TINT
:
{
for
(
i
=
0
;
i
<
p
->
m_iColorCount
;
++
i
)
{
p
->
m_aoTintedPalette
[
i
].
r
=
int
(
p
->
m_aoPalette
[
i
].
r
)
*
2
/
3
;
p
->
m_aoTintedPalette
[
i
].
g
=
int
(
p
->
m_aoPalette
[
i
].
g
)
*
2
/
3
;
p
->
m_aoTintedPalette
[
i
].
b
=
int
(
p
->
m_aoPalette
[
i
].
b
)
*
2
/
3
;
}
break
;
}
case
INVERTED_TINT
:
{
for
(
i
=
0
;
i
<
p
->
m_iColorCount
;
++
i
)
{
p
->
m_aoTintedPalette
[
i
].
r
=
255
-
p
->
m_aoPalette
[
i
].
r
;
p
->
m_aoTintedPalette
[
i
].
g
=
255
-
p
->
m_aoPalette
[
i
].
g
;
p
->
m_aoTintedPalette
[
i
].
b
=
255
-
p
->
m_aoPalette
[
i
].
b
;
}
break
;
}
case
NO_TINT
:
default
:
{
for
(
i
=
0
;
i
<
p
->
m_iColorCount
;
++
i
)
{
p
->
m_aoTintedPalette
[
i
]
=
p
->
m_aoPalette
[
i
];
}
break
;
}
}
// end of switch( a_enTint )
}
void
RlePack
::
ApplyPalette
()
{
SDL_SetColors
(
gamescreen
,
p
->
m_aoTintedPalette
,
p
->
m_iColorOffset
,
p
->
m_iColorCount
);
}
int
RlePack
::
GetWidth
(
int
a_iIndex
)
{
if
(
(
a_iIndex
<
0
)
||
(
a_iIndex
>=
p
->
m_iCount
)
)
return
-1
;
RLE_SPRITE
*
poSprite
=
p
->
m_pSprites
[
a_iIndex
];
if
(
!
poSprite
)
return
-1
;
return
poSprite
->
w
;
}
int
RlePack
::
GetHeight
(
int
a_iIndex
)
{
if
(
(
a_iIndex
<
0
)
||
(
a_iIndex
>=
p
->
m_iCount
)
)
return
-1
;
RLE_SPRITE
*
poSprite
=
p
->
m_pSprites
[
a_iIndex
];
if
(
!
poSprite
)
return
-1
;
return
poSprite
->
h
;
}
void
draw_rle_sprite_v_flip
(
RLE_SPRITE
*
src
,
int
dx
,
int
dy
)
// static method
{
#define RLE_PTR signed char*
#define RLE_IS_EOL(c) ((c) == 0)
#define PIXEL_PTR unsigned char*
#define OFFSET_PIXEL_PTR(p,x) ((PIXEL_PTR) (p) + (x))
#define INC_PIXEL_PTR(p) ((p)++)
#define DEC_PIXEL_PTR(p) ((p)--)
#define PUT_PIXEL(p,c) (*((unsigned char *)(p)) = (c))
//#define PUT_PIXEL(p,c) bmp_write8((unsigned long) (p), (c))
int
x
,
y
,
w
,
h
;
// width and height of visible area
int
dxbeg
,
dybeg
;
// beginning in destination
int
sxbeg
,
sybeg
;
// beginning in source
RLE_PTR
s
;
SDL_Surface
*
dst
=
gamescreen
;
// Clip to dst->clip_rect
int
dst_cl
=
dst
->
clip_rect
.
x
;
int
dst_cr
=
dst
->
clip_rect
.
w
+
dst_cl
-
1
;
int
dst_ct
=
dst
->
clip_rect
.
y
;
int
dst_cb
=
dst
->
clip_rect
.
h
+
dst_ct
;
// if (dst->clip)
if
(
1
)
{
int
tmp
;
dxbeg
=
dx
;
if
(
dst_cl
>
dx
)
dxbeg
=
dst_cl
;
tmp
=
dx
+
src
->
w
-
dst_cr
;
sxbeg
=
((
tmp
<
0
)
?
0
:
tmp
);
tmp
=
dx
+
src
->
w
;
if
(
tmp
>
dst_cr
)
tmp
=
dst_cr
;
w
=
tmp
-
dxbeg
;
if
(
w
<=
0
)
return
;
tmp
=
dst_ct
-
dy
;
sybeg
=
((
tmp
<
0
)
?
0
:
tmp
);
dybeg
=
sybeg
+
dy
;
tmp
=
dst_cb
-
dy
;
h
=
((
tmp
>
src
->
h
)
?
src
->
h
:
tmp
)
-
sybeg
;
if
(
h
<=
0
)
return
;
}
else
{
w
=
src
->
w
;
h
=
src
->
h
;
sxbeg
=
0
;
sybeg
=
0
;
dxbeg
=
dx
;
dybeg
=
dy
;
}
s
=
(
RLE_PTR
)
(
src
->
dat
);
dxbeg
+=
w
;
/* Clip top. */
for
(
y
=
sybeg
-
1
;
y
>=
0
;
y
--
)
{
long
c
=
*
s
++
;
while
(
!
RLE_IS_EOL
(
c
))
{
if
(
c
>
0
)
s
+=
c
;
c
=
*
s
++
;
}
}
//@@@ bmp_select(dst);
/* Visible part. */
for
(
y
=
0
;
y
<
h
;
y
++
)
{
//@@@ PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
PIXEL_PTR
d
=
(
PIXEL_PTR
)
dst
->
pixels
;
d
+=
(
dybeg
+
y
)
*
dst
->
pitch
;
d
=
OFFSET_PIXEL_PTR
(
d
,
dxbeg
);
long
c
=
*
s
++
;
/* Clip left. */
for
(
x
=
sxbeg
;
x
>
0
;
)
{
if
(
RLE_IS_EOL
(
c
))
goto
next_line
;
else
if
(
c
>
0
)
{
/* Run of solid pixels. */
if
((
x
-
c
)
>=
0
)
{
/* Fully clipped. */
x
-=
c
;
s
+=
c
;
}
else
{
/* Visible on the right. */
c
-=
x
;
s
+=
x
;
break
;
}
}
else
{
/* Run of transparent pixels. */
if
((
x
+
c
)
>=
0
)
{
/* Fully clipped. */
x
+=
c
;
}
else
{
/* Visible on the right. */
c
+=
x
;
break
;
}
}
c
=
*
s
++
;
}
/* Visible part. */
for
(
x
=
w
;
x
>
0
;
)
{
if
(
RLE_IS_EOL
(
c
))
goto
next_line
;
else
if
(
c
>
0
)
{
/* Run of solid pixels. */
if
((
x
-
c
)
>=
0
)
{
/* Fully visible. */
x
-=
c
;
for
(
c
--
;
c
>=
0
;
s
++
,
DEC_PIXEL_PTR
(
d
),
c
--
)
{
unsigned
long
col
=
*
s
;
PUT_PIXEL
(
d
,
col
);
}
}
else
{
/* Clipped on the right. */
c
-=
x
;
for
(
x
--
;
x
>=
0
;
s
++
,
DEC_PIXEL_PTR
(
d
),
x
--
)
{
unsigned
long
col
=
*
s
;
PUT_PIXEL
(
d
,
col
);
}
break
;
}
}
else
{
/* Run of transparent pixels. */
x
+=
c
;
d
=
OFFSET_PIXEL_PTR
(
d
,
c
);
}
c
=
*
s
++
;
}
/* Clip right. */
while
(
!
RLE_IS_EOL
(
c
))
{
if
(
c
>
0
)
s
+=
c
;
c
=
*
s
++
;
}
next_line
:
;
}
//@@@bmp_unwrite_line(dst);
}
void
draw_rle_sprite
(
RLE_SPRITE
*
src
,
int
dx
,
int
dy
)
// static method
{
#define RLE_PTR signed char*
#define RLE_IS_EOL(c) ((c) == 0)
#define PIXEL_PTR unsigned char*
#define OFFSET_PIXEL_PTR(p,x) ((PIXEL_PTR) (p) + (x))
#define INC_PIXEL_PTR(p) ((p)++)
#define DEC_PIXEL_PTR(p) ((p)--)
#define PUT_PIXEL(p,c) (*((unsigned char *)(p)) = (c))
//#define PUT_PIXEL(p,c) bmp_write8((unsigned long) (p), (c))
int
x
,
y
,
w
,
h
;
// width and height of visible area
int
dxbeg
,
dybeg
;
// beginning in destination
int
sxbeg
,
sybeg
;
// beginning in source
RLE_PTR
s
;
SDL_Surface
*
dst
=
gamescreen
;
// Clip to dst->clip_rect
int
dst_cl
=
dst
->
clip_rect
.
x
;
int
dst_cr
=
dst
->
clip_rect
.
w
+
dst_cl
;
int
dst_ct
=
dst
->
clip_rect
.
y
;
int
dst_cb
=
dst
->
clip_rect
.
h
+
dst_ct
;
// if (dst->clip)
if
(
1
)
{
int
tmp
;
tmp
=
dst_cl
-
dx
;
sxbeg
=
((
tmp
<
0
)
?
0
:
tmp
);
dxbeg
=
sxbeg
+
dx
;
tmp
=
dst_cr
-
dx
;
w
=
((
tmp
>
src
->
w
)
?
src
->
w
:
tmp
)
-
sxbeg
;
if
(
w
<=
0
)
return
;
tmp
=
dst_ct
-
dy
;
sybeg
=
((
tmp
<
0
)
?
0
:
tmp
);
dybeg
=
sybeg
+
dy
;
tmp
=
dst_cb
-
dy
;
h
=
((
tmp
>
src
->
h
)
?
src
->
h
:
tmp
)
-
sybeg
;
if
(
h
<=
0
)
return
;
}
else
{
w
=
src
->
w
;
h
=
src
->
h
;
sxbeg
=
0
;
sybeg
=
0
;
dxbeg
=
dx
;
dybeg
=
dy
;
}
s
=
(
RLE_PTR
)
(
src
->
dat
);
/* Clip top. */
for
(
y
=
sybeg
-
1
;
y
>=
0
;
y
--
)
{
long
c
=
*
s
++
;
while
(
!
RLE_IS_EOL
(
c
))
{
if
(
c
>
0
)
s
+=
c
;
c
=
*
s
++
;
}
}
//@@@ bmp_select(dst);
/* Visible part. */
for
(
y
=
0
;
y
<
h
;
y
++
)
{
//@@@ PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
PIXEL_PTR
d
=
(
PIXEL_PTR
)
dst
->
pixels
;
d
+=
(
dybeg
+
y
)
*
dst
->
pitch
;
d
=
OFFSET_PIXEL_PTR
(
d
,
dxbeg
);
long
c
=
*
s
++
;
/* Clip left. */
for
(
x
=
sxbeg
;
x
>
0
;
)
{
if
(
RLE_IS_EOL
(
c
))
goto
next_line
;
else
if
(
c
>
0
)
{
/* Run of solid pixels. */
if
((
x
-
c
)
>=
0
)
{
/* Fully clipped. */
x
-=
c
;
s
+=
c
;
}
else
{
/* Visible on the right. */
c
-=
x
;
s
+=
x
;
break
;
}
}
else
{
/* Run of transparent pixels. */
if
((
x
+
c
)
>=
0
)
{
/* Fully clipped. */
x
+=
c
;
}
else
{
/* Visible on the right. */
c
+=
x
;
break
;
}
}
c
=
*
s
++
;
}
/* Visible part. */
for
(
x
=
w
;
x
>
0
;
)
{
if
(
RLE_IS_EOL
(
c
))
goto
next_line
;
else
if
(
c
>
0
)
{
/* Run of solid pixels. */
if
((
x
-
c
)
>=
0
)
{
/* Fully visible. */
x
-=
c
;
for
(
c
--
;
c
>=
0
;
s
++
,
INC_PIXEL_PTR
(
d
),
c
--
)
{
unsigned
long
col
=
*
s
;
PUT_PIXEL
(
d
,
col
);
}
}
else
{
/* Clipped on the right. */
c
-=
x
;
for
(
x
--
;
x
>=
0
;
s
++
,
INC_PIXEL_PTR
(
d
),
x
--
)
{
unsigned
long
col
=
*
s
;
PUT_PIXEL
(
d
,
col
);
}
break
;
}
}
else
{
/* Run of transparent pixels. */
x
+=
c
;
d
=
OFFSET_PIXEL_PTR
(
d
,
-
c
);
}
c
=
*
s
++
;
}
/* Clip right. */
while
(
!
RLE_IS_EOL
(
c
))
{
if
(
c
>
0
)
s
+=
c
;
c
=
*
s
++
;
}
next_line
:
;
}
//@@@bmp_unwrite_line(dst);
}
void
RlePack
::
Draw
(
int
a_iIndex
,
int
a_iX
,
int
a_iY
,
bool
a_bFlipped
)
{
if
(
(
a_iIndex
<
0
)
||
(
a_iIndex
>=
p
->
m_iCount
)
)
return
;
RLE_SPRITE
*
poSprite
=
p
->
m_pSprites
[
a_iIndex
];
if
(
!
poSprite
)
return
;
if
(
a_bFlipped
)
draw_rle_sprite_v_flip
(
poSprite
,
a_iX
,
a_iY
);
else
draw_rle_sprite
(
poSprite
,
a_iX
,
a_iY
);
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sat, Nov 14, 5:14 PM (12 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
133411
Default Alt Text
RlePack.cpp (16 KB)
Attached To
Mode
R76 OpenMortal
Attached
Detach File
Event Timeline