Wing Commander
Reconstructed Win32 source (1996)
Toggle main menu visibility
Loading...
Searching...
No Matches
nearheap.c
Go to the documentation of this file.
1
/**
2
* @file
3
* @ingroup data
4
* @brief Near-heap descriptor allocation and compaction carried over from DOS.
5
*
6
* Address range 40e890-40efdf.
7
*/
8
#include <process.h>
9
#include "
wc1.h
"
10
11
/* Linker commons defined here; LINK orders them by identifier hash. */
12
int
nNearHeapSize
;
/* 0x005a811c */
13
int
nNearHeapBase
;
/* 0x005a8120 */
14
int
nCurrentNearHeapFirstDescriptor
;
/* 0x005a8124 */
15
void
*
pCurrentNearHeapAlloc
;
/* 0x005a8128 */
16
short
nNavMapMaximumPositionX
;
/* 0x005a812c */
17
short
nNavigationMapMinimumCoordX
;
/* 0x005a812e */
18
unsigned
short
awMapNavObjectiveLabelIndex
[16];
/* 0x005a8130 */
19
short
nNavMapMaximumPosY
;
/* 0x005a8150 */
20
short
nNavMapCentreX
;
/* 0x005a8152 */
21
short
nNavigationMapMinimumPositionY
;
/* 0x005a8154 */
22
TextContext
stCurrentNavMapTxtCtx
;
/* 0x005a8160 */
23
24
/* Function start: 0x40E890 */
25
unsigned
short
MergeAdjacentNearHeapBlocks
(
int
descriptorAddress)
26
{
27
NearHeapBlock
*block;
28
29
block =
DosNearPtrToFar
(descriptorAddress);
30
if
((block->
sizeAndFlags
& 0x80000000) == 0 &&
31
(block[1].
sizeAndFlags
& 0x80000000) == 0 &&
32
block->
address
+ (block->
sizeAndFlags
& 0xfffff) ==
33
block[1].
address
) {
34
block[1].
address
= block->
address
;
35
block[1].
sizeAndFlags
+= block->
sizeAndFlags
& 0xfffff;
36
while
(descriptorAddress >
nCurrentNearHeapFirstDescriptor
) {
37
descriptorAddress -= 8;
38
block =
DosNearPtrToFar
(descriptorAddress);
39
block[1].
address
= block->
address
;
40
block[1].
sizeAndFlags
= block->
sizeAndFlags
;
41
}
42
nCurrentNearHeapFirstDescriptor
+= 8;
43
return
1;
44
}
45
return
0;
46
}
47
48
/* Function start: 0x40E900 */
49
int
ReleaseNearHeapBlock
(
int
descriptorAddress)
50
{
51
NearHeapBlock
*block;
52
53
block =
DosNearPtrToFar
(descriptorAddress);
54
block->
sizeAndFlags
&= 0x7fffffff;
55
if
(descriptorAddress + 8 <
56
nNearHeapBase
+
nNearHeapSize
&&
57
MergeAdjacentNearHeapBlocks
(descriptorAddress) != 0)
58
descriptorAddress += 8;
59
if
(descriptorAddress >
nCurrentNearHeapFirstDescriptor
)
60
MergeAdjacentNearHeapBlocks
(descriptorAddress - 8);
61
return
descriptorAddress;
62
}
63
64
static
short
nNearHeapActive
= 0;
/* 0x004688c0 */
65
short
nNearHeapMaxDescriptors
= 0x80;
/* 0x004688c4 */
66
static
unsigned
int
nNearHeapRelocationBytes
= 0;
/* 0x004688c8 */
67
68
/* Function start: 0x40E950 */
69
void
PurgeNearHeapBlocks
(
unsigned
short
flags)
70
{
71
NearHeapBlock
*block;
72
int
descriptorAddress;
73
74
if
(
nNearHeapActive
!= 0) {
75
if
((flags & 0x10) != 0) {
76
nCurrentNearHeapFirstDescriptor
=
nNearHeapBase
+
nNearHeapSize
- 8;
77
block =
DosNearPtrToFar
(
nCurrentNearHeapFirstDescriptor
);
78
block->
address
=
nNearHeapBase
;
79
block->
sizeAndFlags
=
80
nNearHeapSize
-
nNearHeapMaxDescriptors
* 8;
81
return
;
82
}
83
descriptorAddress =
nNearHeapBase
+
84
nNearHeapSize
- 8;
85
for
(; descriptorAddress >=
nCurrentNearHeapFirstDescriptor
;
86
descriptorAddress -= 8) {
87
block =
DosNearPtrToFar
(descriptorAddress);
88
if
((block->
sizeAndFlags
& 0x40000000) == 0)
89
descriptorAddress =
ReleaseNearHeapBlock
(descriptorAddress);
90
}
91
}
92
}
93
94
/* Function start: 0x40E9E0 */
95
unsigned
short
InitializeNearHeap
(
void
)
96
{
97
if
(
nNearHeapActive
== 0) {
98
nNearHeapSize
= (short)
GetNavRangeSentinel
();
99
pCurrentNearHeapAlloc
= 0;
100
if
(
nNearHeapMaxDescriptors
* 8 <
nNearHeapSize
)
101
pCurrentNearHeapAlloc
=
102
AllocateTaggedMemory
(
nNearHeapSize
, 0);
103
if
(
pCurrentNearHeapAlloc
!= 0) {
104
nNearHeapActive
++;
105
nNearHeapBase
=
106
DosFarPtrToNear
(
pCurrentNearHeapAlloc
);
107
if
(*(
unsigned
short
*)0x00400013 == 0x270) {
108
nNearHeapRelocationBytes
=
109
0x9c000 -
nNearHeapSize
-
nNearHeapBase
;
110
nNearHeapSize
=
111
0x98000 -
nNearHeapRelocationBytes
-
nNearHeapBase
;
112
if
(
nNearHeapMaxDescriptors
* 8 <
113
nNearHeapSize
) {
114
DosMemcpy
(
115
DosNearPtrToFar
(
116
nNearHeapBase
+
117
nNearHeapSize
),
118
DosNearPtrToFar
(
119
0x9c000 -
120
nNearHeapRelocationBytes
),
121
nNearHeapRelocationBytes
);
122
}
else
{
123
FreeIfNotNull
(
pCurrentNearHeapAlloc
);
124
nNearHeapActive
= 0;
125
}
126
}
127
if
(
nNearHeapActive
!= 0)
128
PurgeNearHeapBlocks
(0x10);
129
}
130
}
131
return
nNearHeapActive
;
132
}
133
134
/* Function start: 0x40EB10 */
135
/* Nothing in the shipped executable calls this. It undoes
136
InitializeNearHeap: copies the relocated bytes back below 0x9C000 and
137
frees the heap's allocation. */
138
void
ShutdownNearHeap
(
void
)
139
{
140
int
relocationBytes;
141
142
relocationBytes =
nNearHeapRelocationBytes
;
143
if
(relocationBytes != 0)
144
DosMemcpy
(
DosNearPtrToFar
(0x9c000 - relocationBytes),
145
DosNearPtrToFar
(
nNearHeapBase
+
nNearHeapSize
),
146
relocationBytes);
147
if
(
nNearHeapActive
!= 0)
148
FreeIfNotNull
(
pCurrentNearHeapAlloc
);
149
nNearHeapActive
= 0;
150
}
151
152
/* Function start: 0x40EB70 */
153
void
*
AllocateNearHeapBlockFromEnd
(
int
size,
unsigned
short
flags)
154
{
155
int
descriptorAddress;
156
int
shiftAddress;
157
int
blockSize;
158
NearHeapBlock
*block;
159
NearHeapBlock
*lastBlock;
160
int
allocationAddress;
161
unsigned
int
allocationFlags;
162
unsigned
short
alignment;
163
164
if
(size <= 0)
165
return
0;
166
allocationFlags = 0x80000000;
167
alignment = flags & 3;
168
if
(alignment == 1) {
169
allocationFlags = 0x90000000;
170
size++;
171
}
else
if
(alignment == 2) {
172
allocationFlags = 0xa0000000;
173
size += 0xf;
174
}
175
if
((flags & 0x10) != 0)
176
allocationFlags |= 0x40000000;
177
178
allocationAddress = 0;
179
descriptorAddress =
180
nNearHeapBase
+
nNearHeapSize
- 8;
181
for
(; descriptorAddress >=
nCurrentNearHeapFirstDescriptor
;
182
descriptorAddress -= 8) {
183
block =
DosNearPtrToFar
(descriptorAddress);
184
blockSize = block->
sizeAndFlags
& 0xfffff;
185
if
((block->
sizeAndFlags
& 0x80000000) != 0)
186
continue
;
187
if
(blockSize < size)
188
continue
;
189
if
(blockSize > size) {
190
if
(
nNearHeapBase
-
191
nNearHeapMaxDescriptors
* 8 +
192
nNearHeapSize
>=
193
nCurrentNearHeapFirstDescriptor
) {
194
lastBlock =
DosNearPtrToFar
(
195
nNearHeapBase
+
196
nNearHeapSize
- 8);
197
if
((lastBlock->
sizeAndFlags
& 0x80000000) == 0) {
198
blockSize = lastBlock->
sizeAndFlags
& 0xfffff;
199
if
(lastBlock->
address
+ blockSize ==
200
nCurrentNearHeapFirstDescriptor
&&
201
blockSize > 8) {
202
lastBlock->
sizeAndFlags
-= 8;
203
nNearHeapMaxDescriptors
++;
204
}
205
}
206
}
207
208
if
(
nNearHeapBase
-
209
nNearHeapMaxDescriptors
* 8 +
210
nNearHeapSize
>=
211
nCurrentNearHeapFirstDescriptor
)
212
continue
;
213
214
nCurrentNearHeapFirstDescriptor
-= 8;
215
shiftAddress =
nCurrentNearHeapFirstDescriptor
;
216
for
(; descriptorAddress > shiftAddress; shiftAddress += 8) {
217
block =
DosNearPtrToFar
(shiftAddress);
218
block->
address
= block[1].
address
;
219
block->
sizeAndFlags
= block[1].
sizeAndFlags
;
220
}
221
descriptorAddress -= 8;
222
block =
DosNearPtrToFar
(descriptorAddress);
223
blockSize = block->
sizeAndFlags
- size;
224
block->
sizeAndFlags
= blockSize;
225
block[1].
address
+= blockSize & 0xffffff;
226
blockSize = allocationFlags + size;
227
block[1].
sizeAndFlags
= blockSize;
228
allocationAddress = block[1].
address
;
229
break
;
230
}
231
block->
sizeAndFlags
|= allocationFlags;
232
allocationAddress = block->
address
;
233
break
;
234
}
235
236
if
(allocationAddress != 0) {
237
if
(alignment == 1)
238
allocationAddress = (allocationAddress + 1) & 0xfffffffe;
239
else
if
(alignment == 2)
240
allocationAddress = (allocationAddress + 0xf) & 0xfffffff0;
241
}
242
return
DosNearPtrToFar
(allocationAddress);
243
}
244
245
/* Function start: 0x40ED30 */
246
void
*
AllocateNearHeapBlockByFlags
(
int
size,
unsigned
short
flags)
247
{
248
int
blockSize;
249
int
descriptorAddress;
250
int
shiftAddress;
251
NearHeapBlock
*block;
252
int
allocationAddress;
253
unsigned
int
sizeAndFlags;
254
unsigned
int
allocationFlags;
255
unsigned
short
alignment;
256
257
if
((flags & 0x20) != 0)
258
return
AllocateNearHeapBlockFromEnd
(size, flags);
259
if
(size <= 0)
260
return
0;
261
allocationFlags = 0x80000000;
262
alignment = flags & 3;
263
if
(alignment == 1) {
264
allocationFlags = 0x90000000;
265
size++;
266
}
else
if
(alignment == 2) {
267
allocationFlags = 0xa0000000;
268
size += 0xf;
269
}
270
if
((flags & 0x10) != 0)
271
allocationFlags |= 0x40000000;
272
273
allocationAddress = 0;
274
descriptorAddress =
nCurrentNearHeapFirstDescriptor
;
275
for
(; descriptorAddress <
276
nNearHeapBase
+
nNearHeapSize
;
277
descriptorAddress += 8) {
278
block =
DosNearPtrToFar
(descriptorAddress);
279
sizeAndFlags = block->
sizeAndFlags
;
280
blockSize = sizeAndFlags & 0xfffff;
281
if
((sizeAndFlags & 0x80000000) != 0)
282
continue
;
283
if
(blockSize < size)
284
continue
;
285
if
(blockSize > size) {
286
if
(
nNearHeapBase
-
287
nNearHeapMaxDescriptors
* 8 +
288
nNearHeapSize
>=
289
nCurrentNearHeapFirstDescriptor
) {
290
block =
DosNearPtrToFar
(
291
nNearHeapBase
+
292
nNearHeapSize
- 8);
293
if
((block->
sizeAndFlags
& 0x80000000) == 0) {
294
blockSize = block->
sizeAndFlags
& 0xfffff;
295
if
(block->
address
+ blockSize ==
296
nCurrentNearHeapFirstDescriptor
&&
297
blockSize > 8) {
298
block->
sizeAndFlags
-= 8;
299
nNearHeapMaxDescriptors
++;
300
}
301
}
302
}
303
304
if
(
nNearHeapBase
-
305
nNearHeapMaxDescriptors
* 8 +
306
nNearHeapSize
>=
307
nCurrentNearHeapFirstDescriptor
)
308
continue
;
309
310
nCurrentNearHeapFirstDescriptor
-= 8;
311
shiftAddress =
nCurrentNearHeapFirstDescriptor
;
312
for
(; descriptorAddress > shiftAddress; shiftAddress += 8) {
313
block =
DosNearPtrToFar
(shiftAddress);
314
block->
address
= block[1].
address
;
315
block->
sizeAndFlags
= block[1].
sizeAndFlags
;
316
}
317
descriptorAddress -= 8;
318
block =
DosNearPtrToFar
(descriptorAddress);
319
block->
sizeAndFlags
= allocationFlags + size;
320
block[1].
address
+= size;
321
block[1].
sizeAndFlags
-= size;
322
allocationAddress = block->
address
;
323
break
;
324
}
325
block->
sizeAndFlags
|= allocationFlags;
326
allocationAddress = block->
address
;
327
break
;
328
}
329
330
if
(allocationAddress != 0) {
331
if
(alignment == 1)
332
allocationAddress = (allocationAddress + 1) & 0xfffffffe;
333
else
if
(alignment == 2)
334
allocationAddress = (allocationAddress + 0xf) & 0xfffffff0;
335
}
336
return
DosNearPtrToFar
(allocationAddress);
337
}
338
339
/* Function start: 0x40EF00 */
340
/* Nothing in the shipped executable calls this. Releases the near heap
341
block that contains the given pointer. */
342
void
FreeNearHeapBlock
(
void
*pointer)
343
{
344
int
descriptorAddress;
345
NearHeapBlock
*block;
346
int
address;
347
int
blockAddress;
348
349
address =
DosFarPtrToNear
(pointer);
350
descriptorAddress =
351
nNearHeapBase
+
nNearHeapSize
- 8;
352
for
(; descriptorAddress >=
nCurrentNearHeapFirstDescriptor
;
353
descriptorAddress -= 8) {
354
block =
DosNearPtrToFar
(descriptorAddress);
355
blockAddress = block->
address
;
356
if
(blockAddress <= address &&
357
blockAddress + (block->
sizeAndFlags
& 0xfffff) >
358
address) {
359
ReleaseNearHeapBlock
(descriptorAddress);
360
break
;
361
}
362
}
363
}
364
365
/* Function start: 0x40EF60 */
366
/* Nothing in the shipped executable calls this. Returns the usable size of
367
the near heap block that contains the given pointer, or 0. */
368
int
GetNearHeapBlockSize
(
void
*pointer)
369
{
370
NearHeapBlock
*block;
371
int
descriptorAddress;
372
int
size;
373
int
address;
374
375
size = 0;
376
address =
DosFarPtrToNear
(pointer);
377
descriptorAddress =
378
nNearHeapBase
+
nNearHeapSize
- 8;
379
for
(; descriptorAddress >=
nCurrentNearHeapFirstDescriptor
;
380
descriptorAddress -= 8) {
381
block =
DosNearPtrToFar
(descriptorAddress);
382
if
(address >= block->
address
&&
383
block->
address
+ (block->
sizeAndFlags
& 0xfffff) >
384
address) {
385
size = block->
sizeAndFlags
& 0xfffff;
386
if
((block->
sizeAndFlags
& 0x10000000) != 0)
387
size--;
388
else
if
((block->
sizeAndFlags
& 0x20000000) != 0)
389
size -= 0xf;
390
break
;
391
}
392
}
393
return
size;
394
}
stCurrentNavMapTxtCtx
TextContext stCurrentNavMapTxtCtx
Definition
nearheap.c:22
nNavMapMaximumPosY
short nNavMapMaximumPosY
Definition
nearheap.c:19
awMapNavObjectiveLabelIndex
unsigned short awMapNavObjectiveLabelIndex[16]
Definition
nearheap.c:18
nCurrentNearHeapFirstDescriptor
int nCurrentNearHeapFirstDescriptor
Definition
nearheap.c:14
nNearHeapBase
int nNearHeapBase
Definition
nearheap.c:13
nNavMapMaximumPositionX
short nNavMapMaximumPositionX
Definition
nearheap.c:16
nNearHeapSize
int nNearHeapSize
Definition
nearheap.c:12
pCurrentNearHeapAlloc
void * pCurrentNearHeapAlloc
Definition
nearheap.c:15
nNavigationMapMinimumCoordX
short nNavigationMapMinimumCoordX
Definition
nearheap.c:17
nNearHeapMaxDescriptors
short nNearHeapMaxDescriptors
Definition
nearheap.c:65
nNavMapCentreX
short nNavMapCentreX
Definition
nearheap.c:20
nNavigationMapMinimumPositionY
short nNavigationMapMinimumPositionY
Definition
nearheap.c:21
ShutdownNearHeap
void ShutdownNearHeap(void)
Definition
nearheap.c:138
nNearHeapActive
static short nNearHeapActive
Definition
nearheap.c:64
GetNearHeapBlockSize
int GetNearHeapBlockSize(void *pointer)
Definition
nearheap.c:368
nNearHeapRelocationBytes
static unsigned int nNearHeapRelocationBytes
Definition
nearheap.c:66
FreeNearHeapBlock
void FreeNearHeapBlock(void *pointer)
Definition
nearheap.c:342
NearHeapBlock
Definition
wcdata.h:330
NearHeapBlock::sizeAndFlags
int sizeAndFlags
Definition
wcdata.h:332
NearHeapBlock::address
int address
Definition
wcdata.h:331
TextContext
Definition
wc1base.h:235
wc1.h
Umbrella header for the game core.
AllocateTaggedMemory
void * AllocateTaggedMemory(int size, unsigned short flags)
Definition
ending.c:31
DosNearPtrToFar
void *__stdcall DosNearPtrToFar(unsigned int v)
Definition
strdos.c:31
MergeAdjacentNearHeapBlocks
unsigned short MergeAdjacentNearHeapBlocks(int descriptorAddress)
Definition
nearheap.c:25
InitializeNearHeap
unsigned short InitializeNearHeap(void)
Definition
nearheap.c:95
DosFarPtrToNear
unsigned int __stdcall DosFarPtrToNear(void *v)
Definition
strdos.c:25
PurgeNearHeapBlocks
void PurgeNearHeapBlocks(unsigned short flags)
Definition
nearheap.c:69
DosMemcpy
void __stdcall DosMemcpy(void *dst, const void *src, unsigned short n)
ReleaseNearHeapBlock
int ReleaseNearHeapBlock(int descriptorAddress)
Definition
nearheap.c:49
AllocateNearHeapBlockByFlags
void * AllocateNearHeapBlockByFlags(int size, unsigned short flags)
Definition
nearheap.c:246
GetNavRangeSentinel
unsigned short GetNavRangeSentinel(void)
Definition
eventmgr.c:1102
AllocateNearHeapBlockFromEnd
void * AllocateNearHeapBlockFromEnd(int size, unsigned short flags)
Definition
nearheap.c:153
FreeIfNotNull
void FreeIfNotNull(void *p)
Definition
eventmgr.c:1147
src
nearheap.c
Generated by
1.18.0