December 21, 2024, 03:20:43 PM
Homepage
Home
Help
Search
Login
Register
Wiki
Imprint
Warhammer Dark Omen Forum
|
Modifications
|
Tools
Decoding & Encoding Dark Omen Videos
Username
1 Hour
1 Day
1 Week
1 Month
Forever
Password
Pages: [
1
]
Go Down
Print
Author
Topic: Decoding & Encoding Dark Omen Videos (Read 2985 times)
0 Members and 1 Guest are viewing this topic.
olly
Global Spokesperson
Offline
Posts: 2300
Decoding & Encoding Dark Omen Videos
«
on:
November 17, 2014, 10:00:43 PM »
DMJC kindly pointed out that his fellow Wing Commander modders created a Decompressor for the Privateer 2 - TGV Videos, that should work for Dark Omen Movies. We already have other players but hopefully one day the following code could be reversed to encode videos, so we can add new movies into Dark Omen.
<DMJC> I've seen it done for other games, like Wing Commander Prophecy
<DMJC> Mario "HCL" Brito might be worth contacting
<DMJC> hcl.solsector.net
<DMJC> he's done tons of hex/code injection game editing
<Olly> cool
<DMJC> the movie player he wrote actually plays dark omen videos. Turns out they're identical to Privateer 2: The Darkening's format
<DMJC> mplayer/ffmpeg can also decode them
<Olly> can anything encode them so i can have new custom vids for DO? as we have lots of movie players ( i think the need for speed ones play them as well)
<DMJC> do you want DO to play the same format, or would you rather it play a better quality format?
<DMJC> he's hacked Wing Commander Prophecy to play DVD VOB files that were developer-only
<DMJC> might be possible to do the same to Dark Omen
<Olly> i see would be cool
<DMJC>
http://hcl.solsector.net/information/video_p2.cpp
video decompression code for Dark Omen
<DMJC> I think if you reverse the code
<DMJC> it'll encode Dark Omen format videos
<Olly> would be great
// Privateer 2 - TGV Video Decompressor
// code reconstruction by Mario Brito (
mbrito@dei.uc.pt
)
void bytecopy(BYTE * dest, BYTE * src, int count)
{
for (int i = 0; i < count; i ++)
dest
= src
;
}
// generic compression algorithm: used here to decompress keyframes, but also has other
// uses, both in Privateer 2 and StarLancer, to compress generic files.
void unpack (unsigned char * in, unsigned char * out) {
if ( (in[0] & 1) == 0)
in += 2;
else
in += 5;
int size = (in[0] << 16) + (in[1] <<
+ in[2];
in += 3;
int counter = 0;
while ( size > 0 ) {
if ( in[0] & 0x80 ) { // 1
if (in[0] & 0x40 ) { // 11
if ( in[0] & 0x20 ) { // 111
// no compression, just copy.
if ( in[0] >= 0xFC ) {
counter = (in[0] & 3); // number of bytes to copy
in ++;
memcpy(out, in, counter);
in += counter;
out += counter;
size = 0;
} else {
counter = (((in[0] & 31) + 1) << 2); // number of dwords to copy
in ++;
memcpy(out, in, counter);
size -= counter;
in += counter;
out += counter;
}
} else { // 110
int size1 = (in[0] & 3);
int position = -(((in[0] & 0x10) << 12) + (in[1] <<
+ in[2]) - 1;
int size2 = ((in[0] & 0xC) << 6) + in[3] + 5;
in += 4;
memcpy(out, in, size1);
size -= size1;
in += size1;
out += size1;
bytecopy(out, out + position, size2);
size -= size2;
out += size2;
}
} else { // 10
int size1 = ( ( in[1] & 0xC0) >> 6 );
int position = -(((in[1] & 0x3f) <<
+ in[2]) - 1;
int size2 = (in[0] & 0x3f) + 4;
in += 3;
memcpy (out, in, size1);
size -= size1;
in += size1;
out += size1;
bytecopy (out, out + position, size2);
size -= size2;
out += size2;
}
} else { // 0
int size1 = (in[0] & 3);
int position = -( ((in[0] & 0x60) << 3) + in[1] ) - 1;
int size2 = ((in[0] & 0x1c) >> 2) + 3;
in += 2;
memcpy (out, in, size1);
size -= size1;
in += size1;
out += size1;
bytecopy (out, out + position, size2);
size -= size2;
out += size2;
}
}
}
void do_frame(short val[], int dimx, int dimy, char src[], char dest[])
{
int ebp_4 = dimx >> 2;
int ebp_14 = (val[0] << 4);
char * ebp_8 = table_23c0030 - ebp_14; // this is correct
int edx = dimx;
int ecx = edx * 3;
int * esi = table_20d3048;
char * edi = dest;
int ebp_24;
int eax;
char * ebx;
int disp = 0;
int ebp_28 = dimy >> 2;
while (ebp_28 > 0) {
ebp_24 = ebp_4;
while (ebp_24 > 0) {
//__asm int 3
eax = *esi; esi ++;
if (eax < (ebp_14>>4))
{
//__asm int 3
ebx = src + disp + table_de0038[eax];
memcpy (edi, ebx, 4);
memcpy (edi+dimx, ebx+dimx, 4);
memcpy (edi+2*dimx, ebx+2*dimx, 4);
memcpy (edi+3*dimx, ebx+3*dimx, 4);
}
else
{
//__asm int 3
ebx = ebp_8 + eax*16;
memcpy (edi, ebx, 4);
memcpy (edi+dimx, ebx+4, 4);
memcpy (edi+2*dimx, ebx+8, 4);
memcpy (edi+3*dimx, ebx+0xc, 4);
}
edi += 4; disp +=4;
ebp_24 --;
}
edi += ecx; disp +=ecx;
ebp_28 --;
}
}
void build_table_20d3048(short val[], int dimx, int dimy, int in[], int out[])
{
int ebx = 0;
int ecx = val[3];
int esp = val[3];
int edx = ((dimx * dimy) >> 4) - 4;
int eax = 1 << ecx;
int ebp = eax - 1;
int write = 0;
while (edx >= 0)
{
unsigned int c;
eax = ecx = ebx;
eax >>= 3; ecx &= 7;
//eax = in[eax]; // not dword alligned
memcpy (&c, ((char *)in) + eax, 4);
eax = c >> ecx;
ecx = eax; ecx &= ebp; out[write] = ecx;
ecx = esp;
eax >>= ecx; eax &= ebp; out[write+1] = eax;
eax = (ecx * 2 + ebx);
ecx = eax;
eax >>=3; ecx &= 7;
//eax = in[eax]; // not dword alligned
memcpy (&c, ((char *)in) + eax, 4);
eax = c >> ecx;
ecx = eax; ecx &= ebp; out[write+2] = ecx;
ecx = esp;
eax >>= ecx; eax &= ebp; out[write+3] = eax;
write += 4;
edx -= 4;
ebx += ecx*4;
}
offset += (ebx/8);
}
void build_table_23c0030_pt2(short val[], int in[], char out[])
{
int src = 0;
int dest = 0;
for (int i = 0; i < val[2]; i ++)
{
int ebp_8 = in[src+1];
for (int j = 15; j >= 0; j--)
{
out[dest+j] = ((char*)in)[(ebp_8 & 3)+src*4];
ebp_8 >>= 2;
}
src += 2;
dest += 16;
}
}
void build_table_de0038(short val[], int dimx, int dimy, int in[], int out[])
{
for (int i = 0; i < val[0]; i ++)
out
= in[i*2 + 1] * dimx + in[i*2];
}
void build_table_23b0030(short val[], int in[], int out[])
{
int ebp_20 = val[0] * 2;
int ebp_1c = 10;
int ebp_14 = (ebp_20 - 1) * ebp_1c;
int * ebp_4 = ebp_20 + out;
int ebp_10 = (1 << (ebp_1c - 1));
int ebp_8 = ( -1 << ebp_1c );
int ebp_18;
for (ebp_18 = 0; ebp_18 < ebp_20; ebp_18 ++)
{
int c;
memcpy(&c, ((char *) in) + (ebp_14 >> 3), 4);
int val = ( c >> (ebp_14 & 7) ) & ( (1 << ebp_1c) - 1 );
ebp_14 -= ebp_1c;
if (val & ebp_10)
val |= ebp_8;
ebp_4 --;
*ebp_4 = val;
}
}
void uncompress_frame(int dimx, int dimy, int image[] /* in */, short ** frame0 /* out */ )
{
int dim, i;
memcpy(&dim, image, 4);
if (dim == ((dimy << 16) | dimx))
{
// kVGT
for (i = 0; i < 256; i ++)
memcpy (pal[0].color+i, ((char *)image) + 12 + 3*i, 3);
SDL_SetColors(back, pal[0].color, 0,256);
unpack ( ((unsigned char *)image) + 12 + 768 , (unsigned char*)buffer1);
// update frame
if (interlaced)
do_interlace((char*)*frame0, buffer1, dimx, dimy);
else
memcpy (*frame0, buffer1, dimx*dimy);
//printf ("Key frame\n");
}
else
{
// fVGT
short val[4];
offset = (((char *)image) + 0xc);
// get the 4 short values from memory
memcpy (val, image, 4*sizeof(short));
// step A
build_table_23b0030(val, (int *)(offset), table_23b0030);
// step B
build_table_de0038(val, dimx, dimy, table_23b0030, table_de0038);
// memcpy step
offset += (((val[0] * 20 + 0x1f) & 0xffffffe0) >> 3);
memcpy(table_23c0030, offset, val[1] << 4);
// step C
offset += val[1] << 4;
build_table_23c0030_pt2(val, (int *)(offset), table_23c0030 + (val[1] << 4) );
offset += val[2] * 8;
// step D
build_table_20d3048(val, dimx, dimy, (int *)(offset), table_20d3048);
// step E
//do_frame(val, dimx, dimy, buffer1, (char *)(*frame0));
//memcpy (buffer1, *frame0, dimx*dimy);
//printf ("offset = %p\n", offset - ((char *)image));
memset(buffer2, 0, dimx*dimy);
do_frame(val, dimx, dimy, buffer1, buffer2);
memcpy (buffer1, buffer2, dimx*dimy);
if (interlaced)
do_interlace((char*)*frame0, buffer2, dimx, dimy);
else
memcpy (*frame0, buffer2, dimx*dimy);
}
}
«
Last Edit: November 17, 2014, 10:06:57 PM by olly
»
Logged
and back in Nuln, the ageing Graf Berhardt smiled his secret smile of pride whenever he heard the latest tales of his eldest son's ever growing chain of glorious victories -(sothr manual)
Pages: [
1
]
Go Up
Print
Jump to:
Please select a destination:
-----------------------------
Warhammer Dark Omen Community
-----------------------------
=> News
=> Tavern
===> Introduction
=> Website Related
-----------------------------
Warhammer Dark Omen
-----------------------------
=> Singleplayer
=> Multiplayer
===> Rules and Standards
===> Tournaments
===> Armybuilds
=====> Empire Armybuilds
=====> Greenskin Armybuilds
=====> Undead Armybuilds
===> Tactics
=====> Empire Tactics
=====> Greenskins Tactics
=====> Undeads Tactics
===> Dark Omen Expanded
===> Black Prophecy (Dark Omen Mod)
=> Help Section
=> Tactical wargaming and other Warhammer games
-----------------------------
Multiplayer Campaign
-----------------------------
=> Dark Omen Conquest
-----------------------------
The Remake Project
-----------------------------
=> OMG WARTBED
=> Bright Portents
=> General Suggestions
-----------------------------
Modifications
-----------------------------
=> 3D Scenery Models
=> Maps
=> 2D Sprites
=> Troops
=> Tools
=> Campaigns
Loading...