Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
2d01693
build(x64): add MinGW-w64 x86_64 toolchain and preset
Aug 30, 2026
ab96fb3
build(x64): lift the 32-bit-only MinGW guard for the experimental x64…
Aug 30, 2026
d959556
build(x64): enable Miles and Bink on x64, make DX8 headers-only
Aug 31, 2026
aca4219
fix(x64): add pointer-sized integer types, fix truncating casts
Aug 31, 2026
b1f7b9a
fix(x64): port CONTEXT register access in both crash handlers
Aug 31, 2026
58e1761
fix(x64): match Win32 callback and DbgHelp signatures to the 64-bit ABI
Aug 31, 2026
257cd79
fix(x64): widen every DbgHelp entry point the name-table fix rearmed
Aug 31, 2026
1a179da
fix(x64): replace the three inline-assembly #error guards
Aug 31, 2026
f42edfa
fix(x64): make WWSaveLoad object-token size honest in SimplePersistFa…
Aug 31, 2026
609b16c
fix(x64): clear the last 10 core WW3D2 truncating casts, unblock Game…
Aug 31, 2026
0f177a0
fix(x64): repair VC6 build broken by BaseTypeCore.h, fix G3's increme…
Sep 1, 2026
2c2bc27
fix(x64): port StackDump and DbgHelpLoader, the third crash handler
MeneerHaas Sep 2, 2026
a316ced
fix(x64): write the same 4-byte identity token the persist loaders read
MeneerHaas Sep 2, 2026
d4dd7b8
fix(x64): give StackWalk64 a real context and the AMD64 machine type
MeneerHaas Sep 2, 2026
336a6c3
docs(x64): drop references to files that live only in the fork
MeneerHaas Sep 2, 2026
83d1913
fix(x64): keep the remapped attachment pointer at token width
MeneerHaas Sep 2, 2026
06c4a08
fix(x64): read persisted pointer identities at the width the chunk holds
MeneerHaas Sep 2, 2026
2582cba
fix(x64): guard the width-aware identity read to x64
MeneerHaas Sep 2, 2026
e468662
fix(x64): keep the stdint include SoundSceneObj compiled with
MeneerHaas Sep 2, 2026
b719eee
revert(x64): return the identity-width work to its verified state
MeneerHaas Sep 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,12 @@ if(MINGW)
include(cmake/widl.cmake)
endif()

# Find/Add build dependencies and stubs shared by all projects
if((WIN32 OR "${CMAKE_SYSTEM}" MATCHES "Windows") AND ${CMAKE_SIZEOF_VOID_P} EQUAL 4)
# Find/Add build dependencies and stubs shared by all projects.
# Miles and Bink are source-only stubs with no architecture dependency, so they
# build for any pointer size. DX8 is gated separately inside dx8.cmake: its
# headers are architecture-independent but MinGW-w64 x86_64 ships no libd3d8.a
# and no libd3dx8d.a, so the link libraries are 32-bit only.
if(WIN32 OR "${CMAKE_SYSTEM}" MATCHES "Windows")
include(cmake/miles.cmake)
include(cmake/bink.cmake)
include(cmake/dx8.cmake)
Expand Down
11 changes: 11 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,17 @@
"cacheVariables": {
"RTS_BUILD_OPTION_PROFILE": "ON"
}
},
{
"name": "mingw-w64-x86_64",
"displayName": "MinGW-w64 64-bit (x86_64) Release",
"generator": "Unix Makefiles",
"binaryDir": "${sourceDir}/build/${presetName}",
"toolchainFile": "${sourceDir}/cmake/toolchains/mingw-w64-x86_64.cmake",
"cacheVariables": {
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
"CMAKE_BUILD_TYPE": "Release"
}
}
],
"buildPresets": [
Expand Down
1 change: 1 addition & 0 deletions Core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ target_include_directories(corei_libraries_source_wwvegas INTERFACE "Libraries/S
target_include_directories(corei_main INTERFACE "Main")

target_sources(corei_libraries_include PRIVATE
Libraries/Include/Lib/arch_context.h
Libraries/Include/Lib/BaseType.h
Libraries/Include/Lib/BaseTypeCore.h
Libraries/Include/Lib/trig.h
Expand Down
8 changes: 8 additions & 0 deletions Core/Libraries/Include/Lib/BaseTypeCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,11 @@ typedef bool Bool; //
// note, the types below should use "long long", but MSVC doesn't support it yet
typedef int64_t Int64; // 8 bytes
typedef uint64_t UnsignedInt64; // 8 bytes

// Pointer-sized integers. Required for 64-bit targets: Windows is LLP64, so
// `long` stays 32 bits on x86-64 and cannot hold a pointer. Use these for
// values that must round-trip through a pointer — never for values that are
// written to a file, sent over the network, or stored in a savegame, because
// their width changes with the target.
typedef uintptr_t UnsignedIntPtr; // 4 bytes on 32-bit, 8 on 64-bit
typedef intptr_t IntPtr; // 4 bytes on 32-bit, 8 on 64-bit
85 changes: 85 additions & 0 deletions Core/Libraries/Include/Lib/arch_context.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2026 TheSuperHackers
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

// FILE: arch_context.h //////////////////////////////////////////////////////
//
// Maps the x86-32 Win32 CONTEXT register field names used throughout the
// two crash handlers (Core/Libraries/Source/WWVegas/WWLib/Except.cpp and
// Core/Libraries/Source/debug/debug_except.cpp) onto whichever field names
// the target architecture's CONTEXT struct actually has, plus the machine
// constant the stack-walk call sites need.
//
// On x86-32 the general-purpose registers are Eip/Esp/Ebp/Eax/Ebx/Ecx/Edx/
// Esi/Edi. On x86-64 they are Rip/Rsp/Rbp/Rax/Rbx/Rcx/Rdx/Rsi/Rdi and are
// twice as wide. CTX_PC/CTX_STACK/CTX_FRAME/CTX_AX/CTX_BX/CTX_CX/CTX_DX/
// CTX_SI/CTX_DI hide that difference behind one name per register so call
// sites don't need an #ifdef each. On x86-32 every one of these macros
// expands to exactly the original field access (e.g. CTX_PC(ctx) is
// ((ctx).Eip)), so the 32-bit build is unaffected.
//
// Deliberately NOT using the WOW64_* structures/constants GCC suggests
// (WOW64_FLOATING_SAVE_AREA, WOW64_SIZE_OF_80387_REGISTERS, ...): those
// describe a 32-bit process as inspected from a 64-bit one, not a native
// 64-bit process's own FPU/SSE state. Taking that suggestion would compile
// cleanly and read the wrong bytes -- a crash dump that is silently
// corrupt is worse than no crash dump. The FPU/SSE save area itself is a
// structural difference (CONTEXT.FltSave, an XMM_SAVE_AREA32, vs the
// 32-bit FLOATING_SAVE_AREA) rather than a field rename, so it is not
// covered by macros here -- the two crash handlers guard that block with
// their own #if per architecture, mirroring what the 32-bit block reports.

#pragma once

#include <windows.h>

#if defined(_WIN64) || defined(__x86_64__)

#define CTX_PC(ctx) ((ctx).Rip)
#define CTX_STACK(ctx) ((ctx).Rsp)
#define CTX_FRAME(ctx) ((ctx).Rbp)
#define CTX_AX(ctx) ((ctx).Rax)
#define CTX_BX(ctx) ((ctx).Rbx)
#define CTX_CX(ctx) ((ctx).Rcx)
#define CTX_DX(ctx) ((ctx).Rdx)
#define CTX_SI(ctx) ((ctx).Rsi)
#define CTX_DI(ctx) ((ctx).Rdi)

// Hex-digit width of a full register dump column, for the stream-based
// (Debug::Width()) register printers in debug_except.cpp -- 16 digits show
// a full 64-bit register instead of just its low half.
#define CTX_REG_WIDTH 16

#define CTX_STACKWALK_MACHINE IMAGE_FILE_MACHINE_AMD64

#else

#define CTX_PC(ctx) ((ctx).Eip)
#define CTX_STACK(ctx) ((ctx).Esp)
#define CTX_FRAME(ctx) ((ctx).Ebp)
#define CTX_AX(ctx) ((ctx).Eax)
#define CTX_BX(ctx) ((ctx).Ebx)
#define CTX_CX(ctx) ((ctx).Ecx)
#define CTX_DX(ctx) ((ctx).Edx)
#define CTX_SI(ctx) ((ctx).Esi)
#define CTX_DI(ctx) ((ctx).Edi)

#define CTX_REG_WIDTH 8

#define CTX_STACKWALK_MACHINE IMAGE_FILE_MACHINE_I386

#endif
5 changes: 3 additions & 2 deletions Core/Libraries/Source/Compression/EAC/huffencode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#define __HUFWRITE 1

#include <string.h>
#include <Utility/stdint_adapter.h>
#include "codex.h"
#include "huffcodex.h"

Expand Down Expand Up @@ -1050,8 +1051,8 @@ static void HUFF_pack(struct HuffEncodeContext *EC,
if (!i3)
HUFF_writecode(EC,dest,i);

if (((long) bptr1- (long) EC->buffer) >= (long)(EC->plen+curpc))
curpc = (long) bptr1 - (long) EC->buffer - EC->plen;
if (((intptr_t) bptr1- (intptr_t) EC->buffer) >= (intptr_t)(EC->plen+curpc))
curpc = (intptr_t) bptr1 - (intptr_t) EC->buffer - EC->plen;
}

/* write EOF ([clue] 0gn [10]) */
Expand Down
15 changes: 14 additions & 1 deletion Core/Libraries/Source/WWVegas/WW3D2/dx8webbrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
#include "dx8webbrowser.h"
#include "ww3d.h"
#include "dx8wrapper.h"
// Only pulls the pointer-sized-int typedefs (uintptr_t); avoids dragging in
// BaseTypeCore.h's warning-as-error pragmas into a file that never had them.
#include <Utility/stdint_adapter.h>

#if ENABLE_EMBEDDED_BROWSER

Expand Down Expand Up @@ -193,7 +196,17 @@ void DX8WebBrowser::CreateBrowser(const char* browsername, const char* url, int
if(pBrowser)
{
_bstr_t brsname(browsername);
pBrowser->CreateBrowser(brsname, _bstr_t(url), reinterpret_cast<long>(hWnd), x, y, w, h, options, gamedispatch);
// TODO(x64-hwnd-truncation): IFEBrowserEngine2::CreateBrowser's
// parentwindow parameter is `long` per BrowserEngine.idl -- a fixed
// COM/oleautomation ABI width we don't control (dual/oleautomation
// interfaces cannot carry 64-bit ints as `long`; that's a VT_I4).
// On x64, HWND is a full 8-byte handle and this truncates it. NOT
// FIXED: the top 32 bits of the window handle are silently dropped
// whenever this path runs on a 64-bit target. Widening the local
// would not help -- the COM call still narrows to `long` regardless
// -- so the truncation is made explicit and legal here instead of
// left as a compile error.
pBrowser->CreateBrowser(brsname, _bstr_t(url), (long)(uintptr_t)hWnd, x, y, w, h, options, gamedispatch);
pBrowser->SetUpdateRate(brsname, updateticks);
}
}
Expand Down
17 changes: 16 additions & 1 deletion Core/Libraries/Source/WWVegas/WW3D2/rendobj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1219,14 +1219,22 @@ PersistClass * RenderObjPersistFactoryClass::Load(ChunkLoadClass & cload) const
char name[64];
name[0] = '\0';

// Read exactly what Save wrote: a fixed-width 4-byte identity token, not
// sizeof(old_obj). On x86-64 sizeof(RenderObjClass*) is 8, so reading
// sizeof(old_obj) here (as READ_MICRO_CHUNK would) would ask for more
// bytes than the legacy 4-byte micro chunk holds; ChunkLoadClass::Read
// then refuses to read anything at all and old_obj stays null, silently
// poisoning SaveLoadSystemClass's pointer remap table. See persistfactory.h.
uint32 old_obj_token = 0;

while (cload.Open_Chunk()) {
switch (cload.Cur_Chunk_ID()) {

case RENDOBJFACTORY_CHUNKID_VARIABLES:

while (cload.Open_Micro_Chunk()) {
switch(cload.Cur_Micro_Chunk_ID()) {
READ_MICRO_CHUNK(cload,RENDOBJFACTORY_VARIABLE_OBJPOINTER,old_obj);
case (RENDOBJFACTORY_VARIABLE_OBJPOINTER): cload.Read(&old_obj_token,sizeof(old_obj_token)); break;
READ_MICRO_CHUNK(cload,RENDOBJFACTORY_VARIABLE_TRANSFORM,tm);
READ_MICRO_CHUNK_STRING(cload,RENDOBJFACTORY_VARIABLE_NAME,name,sizeof(name));
}
Expand Down Expand Up @@ -1269,6 +1277,7 @@ PersistClass * RenderObjPersistFactoryClass::Load(ChunkLoadClass & cload) const
new_obj->Set_Transform(tm);
}

old_obj = (RenderObjClass *)(uintptr_t)old_obj_token;
SaveLoadSystemClass::Register_Pointer(old_obj,new_obj);
return new_obj;
}
Expand All @@ -1280,7 +1289,13 @@ void RenderObjPersistFactoryClass::Save(ChunkSaveClass & csave,PersistClass * ob
const Matrix3D& tm = robj->Get_Transform();

csave.Begin_Chunk(RENDOBJFACTORY_CHUNKID_VARIABLES);
#if defined(_WIN64) || defined(__x86_64__)
// TheSuperHackers @fix MeneerHaas 02/09/2026 Write the 4-byte identity token the loader reads; see persistfactory.h.
uint32 robj_token = (uint32)(uintptr_t)robj;
WRITE_MICRO_CHUNK(csave,RENDOBJFACTORY_VARIABLE_OBJPOINTER,robj_token);
#else
WRITE_MICRO_CHUNK(csave,RENDOBJFACTORY_VARIABLE_OBJPOINTER,robj);
#endif
WRITE_MICRO_CHUNK_STRING(csave,RENDOBJFACTORY_VARIABLE_NAME,name);
WRITE_MICRO_CHUNK(csave,RENDOBJFACTORY_VARIABLE_TRANSFORM,tm);
csave.End_Chunk();
Expand Down
12 changes: 10 additions & 2 deletions Core/Libraries/Source/WWVegas/WW3D2/surfaceclass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
#include "WWMath/vector2i.h"
#include "colorspace.h"
#include "WWLib/bound.h"
// Only pulls the pointer-sized-int typedefs (uintptr_t); avoids dragging in
// BaseTypeCore.h's warning-as-error pragmas into a file that never had them.
#include <Utility/stdint_adapter.h>
#include <d3dx8.h>

void Convert_Pixel(Vector3 &rgb, const SurfaceClass::SurfaceDescription &sd, const unsigned char * pixel)
Expand Down Expand Up @@ -575,7 +578,10 @@ void SurfaceClass::FindBB(Vector2i *min,Vector2i*max)
for (x = min->I; x < max->I; x++) {

// HY - this is not endian safe
unsigned char *alpha=(unsigned char*) ((unsigned int)lock_rect.pBits+(y-min->J)*lock_rect.Pitch+(x-min->I)*size);
// pBits is a live D3D-locked surface pointer; the arithmetic below
// walks it row/column by row/column and stays runtime-only (never
// serialized), so widen the holder to pointer size on x64.
unsigned char *alpha=(unsigned char*) ((uintptr_t)lock_rect.pBits+(y-min->J)*lock_rect.Pitch+(x-min->I)*size);
unsigned char myalpha=alpha[size-1];
myalpha=(myalpha>>(8-alphabits)) & mask;
if (myalpha) {
Expand Down Expand Up @@ -649,7 +655,9 @@ bool SurfaceClass::Is_Transparent_Column(unsigned int column)
for (y = 0; y < (int) sd.Height; y++)
{
// HY - this is not endian safe
unsigned char *alpha=(unsigned char*) ((unsigned int)lock_rect.pBits+y*lock_rect.Pitch);
// Same live D3D-locked surface pointer as above: runtime-only, widen
// the holder to pointer size on x64.
unsigned char *alpha=(unsigned char*) ((uintptr_t)lock_rect.pBits+y*lock_rect.Pitch);
unsigned char myalpha=alpha[size-1];
myalpha=(myalpha>>(8-alphabits)) & mask;
if (myalpha) {
Expand Down
19 changes: 17 additions & 2 deletions Core/Libraries/Source/WWVegas/WWAudio/AudibleSound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1654,8 +1654,14 @@ AudibleSoundClass::Save (ChunkSaveClass &csave)
WRITE_MICRO_CHUNK_STRING (csave, VARID_FILENAME, m_Buffer->Get_Filename ());
}

#if defined(_WIN64) || defined(__x86_64__)
// TheSuperHackers @fix MeneerHaas 02/09/2026 Write the 4-byte identity token the loader reads; see persistfactory.h.
uint32 this_ptr_token = (uint32)(uintptr_t)this;
WRITE_MICRO_CHUNK (csave, VARID_THIS_PTR, this_ptr_token);
#else
AudibleSoundClass *this_ptr = this;
WRITE_MICRO_CHUNK (csave, VARID_THIS_PTR, this_ptr);
#endif

csave.End_Chunk ();

Expand Down Expand Up @@ -1712,8 +1718,17 @@ AudibleSoundClass::Load (ChunkLoadClass &cload)

case VARID_THIS_PTR:
{
AudibleSoundClass *old_ptr = nullptr;
cload.Read(&old_ptr, sizeof (old_ptr));
// Read exactly what Save wrote: a fixed-width 4-byte
// identity token, not sizeof(old_ptr). On x86-64
// sizeof(AudibleSoundClass*) is 8, so reading
// sizeof(old_ptr) here would ask for more bytes than
// the legacy 4-byte micro chunk holds; ChunkLoadClass::Read
// then refuses to read anything at all and old_ptr
// stays null, silently poisoning SaveLoadSystemClass's
// pointer remap table. See persistfactory.h.
uint32 old_ptr_token = 0;
cload.Read(&old_ptr_token, sizeof (old_ptr_token));
AudibleSoundClass *old_ptr = (AudibleSoundClass *)(uintptr_t)old_ptr_token;
SaveLoadSystemClass::Register_Pointer (old_ptr, this);
}
break;
Expand Down
5 changes: 4 additions & 1 deletion Core/Libraries/Source/WWVegas/WWAudio/AudibleSound.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ class SoundHandleClass;
//
// Typedefs
//
typedef unsigned long MILES_HANDLE;
// Miles Sound System handles are pointers under the hood; this must be
// pointer-sized to round-trip through Get_2D_Sample/Get_3D_Sample without
// truncation on 64-bit targets. Runtime-only, never serialized.
typedef uintptr_t MILES_HANDLE;

typedef enum
{
Expand Down
2 changes: 1 addition & 1 deletion Core/Libraries/Source/WWVegas/WWAudio/SoundScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ SoundSceneClass::Collect_Logical_Sounds (unsigned int milliseconds, int listener
// Is the sound ready to notify?
//
if (sound_obj->Allow_Notify (timestamp)) {
listener->On_Event (AudioCallbackClass::EVENT_LOGICAL_HEARD, (uint32)listener, (uint32)sound_obj);
listener->On_Event (AudioCallbackClass::EVENT_LOGICAL_HEARD, (uintptr_t)listener, (uintptr_t)sound_obj);
}
}
}
Expand Down
36 changes: 36 additions & 0 deletions Core/Libraries/Source/WWVegas/WWAudio/SoundSceneObj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@


#include "SoundSceneObj.h"
#include <Utility/stdint_adapter.h>
#include "WW3D2/camera.h"
#include "WW3D2/rendobj.h"
#include "WWSaveLoad/persistfactory.h"
Expand Down Expand Up @@ -259,10 +260,22 @@ SoundSceneObjClass::Save (ChunkSaveClass &csave)
csave.End_Chunk ();

csave.Begin_Chunk (CHUNKID_VARIABLES);
#if defined(_WIN64) || defined(__x86_64__)
// TheSuperHackers @fix MeneerHaas 02/09/2026 Persisted pointers are 4-byte identity tokens: that is what the
// legacy files hold and what RenderObjPersistFactory registers, so the remap below can match.
uint32 attached_obj_token = (uint32)(uintptr_t)m_AttachedObject;
WRITE_MICRO_CHUNK (csave, VARID_ATTACHED_OBJ, attached_obj_token);
#else
WRITE_MICRO_CHUNK (csave, VARID_ATTACHED_OBJ, m_AttachedObject);
#endif
WRITE_MICRO_CHUNK (csave, VARID_ATTACHED_BONE, m_AttachedBone);
WRITE_MICRO_CHUNK (csave, VARID_USER_DATA, m_UserData);
#if defined(_WIN64) || defined(__x86_64__)
uint32 user_obj_token = (uint32)(uintptr_t)m_UserObj;
WRITE_MICRO_CHUNK (csave, VARID_USER_OBJ, user_obj_token);
#else
WRITE_MICRO_CHUNK (csave, VARID_USER_OBJ, m_UserObj);
#endif
WRITE_MICRO_CHUNK (csave, VARID_ID, m_ID);
csave.End_Chunk ();
return true;
Expand Down Expand Up @@ -294,10 +307,33 @@ SoundSceneObjClass::Load (ChunkLoadClass &cload)
while (cload.Open_Micro_Chunk ()) {
switch (cload.Cur_Micro_Chunk_ID ()) {

#if defined(_WIN64) || defined(__x86_64__)
// TheSuperHackers @fix MeneerHaas 02/09/2026 Read exactly the 4 bytes Save wrote; sizeof(pointer)
// is 8 here, and ChunkLoadClass::Read refuses a short chunk outright, leaving the
// member unset and poisoning the pointer remap.
case VARID_ATTACHED_OBJ:
{
uint32 attached_obj_token = 0;
cload.Read (&attached_obj_token, sizeof (attached_obj_token));
m_AttachedObject = (RenderObjClass *)(uintptr_t)attached_obj_token;
break;
}
#else
READ_MICRO_CHUNK (cload, VARID_ATTACHED_OBJ, m_AttachedObject);
#endif
READ_MICRO_CHUNK (cload, VARID_ATTACHED_BONE, m_AttachedBone);
READ_MICRO_CHUNK (cload, VARID_USER_DATA, m_UserData);
#if defined(_WIN64) || defined(__x86_64__)
case VARID_USER_OBJ:
{
uint32 user_obj_token = 0;
cload.Read (&user_obj_token, sizeof (user_obj_token));
m_UserObj = (RefCountClass *)(uintptr_t)user_obj_token;
break;
}
#else
READ_MICRO_CHUNK (cload, VARID_USER_OBJ, m_UserObj);
#endif
READ_MICRO_CHUNK (cload, VARID_ID, id);
}

Expand Down
Loading