1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#include "common.h"
#include "patcher.h"
RwTexture*
RwTextureGtaStreamRead(RwStream *stream)
{
RwUInt32 size, version;
RwTexture *tex;
if(!RwStreamFindChunk(stream, rwID_TEXTURENATIVE, &size, &version))
return nil;
// TODO: unused timing
if(!RWSRCGLOBAL(stdFunc[rwSTANDARDNATIVETEXTUREREAD](stream, &tex, size)))
return nil;
return tex;
}
RwTexture*
destroyTexture(RwTexture *texture, void *data)
{
RwTextureDestroy(texture);
return texture;
}
RwTexDictionary*
RwTexDictionaryGtaStreamRead(RwStream *stream)
{
RwUInt32 size, version;
RwInt32 numTextures;
RwTexDictionary *texDict;
RwTexture *tex;
if(!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version))
return nil;
assert(size == 4);
if(RwStreamRead(stream, &numTextures, size) != size)
return nil;
texDict = RwTexDictionaryCreate();
if(texDict == nil)
return nil;
while(numTextures--){
tex = RwTextureGtaStreamRead(stream);
if(tex == nil){
RwTexDictionaryForAllTextures(texDict, destroyTexture, nil);
RwTexDictionaryDestroy(texDict);
return nil;
}
RwTexDictionaryAddTexture(texDict, tex);
}
return texDict;
}
static int32 numberTextures = -1;
static int32 streamPosition;
RwTexDictionary*
RwTexDictionaryGtaStreamRead1(RwStream *stream)
{
RwUInt32 size, version;
RwInt32 numTextures;
RwTexDictionary *texDict;
RwTexture *tex;
numberTextures = 0;
if(!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version))
return nil;
assert(size == 4);
if(RwStreamRead(stream, &numTextures, size) != size)
return nil;
texDict = RwTexDictionaryCreate();
if(texDict == nil)
return nil;
numberTextures = numTextures/2;
while(numTextures > numberTextures){
numTextures--;
tex = RwTextureGtaStreamRead(stream);
if(tex == nil){
RwTexDictionaryForAllTextures(texDict, destroyTexture, nil);
RwTexDictionaryDestroy(texDict);
return nil;
}
RwTexDictionaryAddTexture(texDict, tex);
}
numberTextures = numTextures;
streamPosition = stream->Type.memory.position;
return texDict;
}
RwTexDictionary*
RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary *texDict)
{
RwTexture *tex;
RwStreamSkip(stream, streamPosition - stream->Type.memory.position);
while(numberTextures--){
tex = RwTextureGtaStreamRead(stream);
if(tex == nil){
RwTexDictionaryForAllTextures(texDict, destroyTexture, nil);
RwTexDictionaryDestroy(texDict);
return nil;
}
RwTexDictionaryAddTexture(texDict, tex);
}
return texDict;
}
STARTPATCHES
InjectHook(0x592380, RwTextureGtaStreamRead, PATCH_JUMP);
InjectHook(0x5924A0, RwTexDictionaryGtaStreamRead, PATCH_JUMP);
InjectHook(0x592550, RwTexDictionaryGtaStreamRead1, PATCH_JUMP);
InjectHook(0x592650, RwTexDictionaryGtaStreamRead2, PATCH_JUMP);
ENDPATCHES
|