66
77#ifdef USE_PROFILER
88#include "DebugMenu/MenuData.c"
9+ #endif
10+
11+
12+ #ifdef USE_FASTANIM
13+ static int bi = 0 ;
14+
15+ // do NOT inline, byte budget
16+ int GetSignedBits (unsigned int * vertData , int bits )
17+ {
18+ int const b = bi >> 5 ;
19+ int const e = 32 - bits ;
20+ int const s = e - (bi & 31 );
21+ int const ret = s < 0 ?
22+ (vertData [b ] << - s ) | (vertData [b + 1 ] >> (s & 31 )) :
23+ vertData [b ] >> s ;
24+ bi += bits ;
25+ return (ret << e ) >> e ;
26+ }
27+
28+ #define END_OF_LIST 0xFFFFFFFF
29+ #define DRAW_CMD_FLAG_NEW_VERTEX (1 << 2)
30+ void FastAnim_Decompress (struct ModelAnim * ma , u_int * pCmd )
31+ {
32+ int * addrArray = 0x1f800000 ;
33+
34+ printf ("Run Animation: %s\n" , ma -> name );
35+
36+ for (int i = 0 ; i < (ma -> numFrames & 0x7fff ); i ++ )
37+ {
38+ // really only need 256*3, but this is safety
39+ if (DECOMP_MEMPACK_GetFreeBytes () < 256 * 4 )
40+ {
41+ printf ("Skip Animation: %s\n" , ma -> name );
42+ return ;
43+ }
44+
45+ // bump animations crash the game?
46+ if (ma -> name [0 ] != 't' )
47+ return ;
48+
49+ char * firstFrame = MODELANIM_GETFRAME (ma );
50+ struct ModelFrame * mf = & firstFrame [ma -> frameSize * i ];
51+
52+ // may be compressed vertData, or uncompresed
53+ char * vertData = MODELFRAME_GETVERT (mf );
54+
55+ // pCmd[0] is number of commands
56+ pCmd ++ ;
57+
58+ // compression
59+ int x_alu = 0 ;
60+ int y_alu = 0 ;
61+ int z_alu = 0 ;
62+ bi = 0 ;
63+
64+ int vertexIndex = 0 ;
65+ int stripLength = 0 ;
66+
67+ unsigned char * writePtr = sdata -> PtrMempack -> firstFreeByte ;
68+
69+ // keep record
70+ addrArray [i ] = writePtr ;
71+
72+ //loop commands until we hit the end marker
73+ for (
74+ /* */ ;
75+ * pCmd != END_OF_LIST ;
76+
77+ pCmd ++ , stripLength ++
78+ )
79+ {
80+ u_short flags = (* pCmd >> (8 * 3 )) & 0xFF ; //8 bits
81+
82+ // TODO: adjust naming of NEW_VERTEX
83+ if ((flags & DRAW_CMD_FLAG_NEW_VERTEX ) != 0 )
84+ continue ;
85+
86+ //store temporal vertex packed uint
87+ u_int temporal = ma -> ptrDeltaArray [vertexIndex ];
88+
89+ u_char XBits = (temporal >> 6 ) & 7 ;
90+ u_char YBits = (temporal >> 3 ) & 7 ;
91+ u_char ZBits = (temporal ) & 7 ;
92+
93+ u_char bx = (temporal >> 0x19 ) << 1 ;
94+ u_char by = (temporal << 7 ) >> 0x18 ;
95+ u_char bz = (temporal << 0xf ) >> 0x18 ;
96+
97+ // If reading a full 8 bits (7+1)
98+ // reset accumulator, this is an
99+ // uncompressed 1-byte number
100+ if (XBits == 7 ) x_alu = 0 ;
101+ if (YBits == 7 ) y_alu = 0 ;
102+ if (ZBits == 7 ) z_alu = 0 ;
103+
104+ // Read NumBits+1, where the first
105+ // extra (+1) bit, determines negative
106+
107+ // convert XZY frame data
108+ int newX = GetSignedBits (vertData , XBits + 1 );
109+ int newY = GetSignedBits (vertData , YBits + 1 );
110+ int newZ = GetSignedBits (vertData , ZBits + 1 );
111+
112+ //calculate decompressed coord value
113+ x_alu = (x_alu + (int )newX + bx );
114+ y_alu = (y_alu + (int )newY + by );
115+ z_alu = (z_alu + (int )newZ + bz );
116+
117+ //store values to stack index, axis swap is important
118+ writePtr [0 ] = x_alu ;
119+ writePtr [1 ] = z_alu ;
120+ writePtr [2 ] = y_alu ;
121+ writePtr += 3 ;
122+
123+ vertexIndex ++ ;
124+ }
125+
126+ sdata -> PtrMempack -> firstFreeByte = writePtr ;
127+ }
128+
129+ // if all frames are finished in this animation,
130+ // remove ptrDeltaArray to signify as decompressed,
131+ ma -> ptrDeltaArray = 0 ;
132+
133+ for (int i = 0 ; i < (ma -> numFrames & 0x7fff ); i ++ )
134+ {
135+ char * firstFrame = MODELANIM_GETFRAME (ma );
136+ struct ModelFrame * mf = & firstFrame [ma -> frameSize * i ];
137+
138+ mf -> vertexOffset = (unsigned int )addrArray [i ] - (unsigned int )mf ;
139+ }
140+ }
141+ #endif
142+
143+ #if 0
144+
145+ // temporary solution, plays animations
146+ // at 30fps while rest of the game is 60fps
147+ int frameIndex = FPS_HALF (curr -> animFrame );
148+
149+ // Get first frame, then current frame
150+ char * firstFrame = MODELANIM_GETFRAME (ma );
151+ mf = & firstFrame [ma -> frameSize * frameIndex ];
152+
153+ char * vertData = MODELFRAME_GETVERT (mf );
154+
155+ Decompressed
156+
157+ // Copy uncompressed vertices to scratchpad
158+ CompVertex * ptrVerts = (CompVertex * )vertData ;
159+
160+ stack [stackIndex ].X = ptrVerts [vertexIndex ].X ;
161+ stack [stackIndex ].Y = ptrVerts [vertexIndex ].Y ;
162+ stack [stackIndex ].Z = ptrVerts [vertexIndex ].Z ;
163+
164+ Compressed
165+
166+ //store temporal vertex packed uint
167+ u_int temporal = ma -> ptrDeltaArray [vertexIndex ];
168+
169+ //printf("temporal: %08x\n", temporal);
170+
171+ //extract data from packed uint
172+ //deltaArray bits: 0bXXXXXXXZZZZZZZZYYYYYYYYAAABBBCCC
173+
174+ u_char XBits = (temporal >> 6 ) & 7 ;
175+ u_char YBits = (temporal >> 3 ) & 7 ;
176+ u_char ZBits = (temporal ) & 7 ;
177+
178+ u_char bx = (temporal >> 0x19 ) << 1 ;
179+ u_char by = (temporal << 7 ) >> 0x18 ;
180+ u_char bz = (temporal << 0xf ) >> 0x18 ;
181+
182+ // If reading a full 8 bits (7+1)
183+ // reset accumulator, this is an
184+ // uncompressed 1-byte number
185+ if (XBits == 7 ) x_alu = 0 ;
186+ if (YBits == 7 ) y_alu = 0 ;
187+ if (ZBits == 7 ) z_alu = 0 ;
188+
189+ // Read NumBits+1, where the first
190+ // extra (+1) bit, determines negative
191+
192+ // convert XZY frame data
193+ int newX = GetSignedBits (vertData , XBits + 1 );
194+ int newY = GetSignedBits (vertData , YBits + 1 );
195+ int newZ = GetSignedBits (vertData , ZBits + 1 );
196+
197+ //calculate decompressed coord value
198+ x_alu = (x_alu + (int )newX + bx );
199+ y_alu = (y_alu + (int )newY + by );
200+ z_alu = (z_alu + (int )newZ + bz );
201+
202+ //store values to stack index, axis swap is important
203+ stack [stackIndex ].X = x_alu ;
204+ stack [stackIndex ].Y = z_alu ;
205+ stack [stackIndex ].Z = y_alu ;
206+
9207#endif
0 commit comments